Added initial contract tests
added testing_framework

Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/b293ee8a
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/b293ee8a
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/b293ee8a

Branch: refs/heads/add-contract-tests
Commit: b293ee8a928fc8a4f84810f41f3235e5a547c23b
Parents: eb7760d
Author: Claude Warren <[email protected]>
Authored: Sun Apr 26 20:41:15 2015 +0100
Committer: Claude Warren <[email protected]>
Committed: Sat May 9 15:27:19 2015 +0100

----------------------------------------------------------------------
 jena-core/pom.xml                               |   14 +
 .../apache/jena/graph/GraphContractTest.java    | 1720 ++++++++++++++++++
 .../graph/GraphEventManagerContractTest.java    |  514 ++++++
 .../jena/graph/GraphMakerContractTest.java      |  314 ++++
 .../graph/GraphWithPerformContractTest.java     |   86 +
 .../jena/graph/RecordingGraphListener.java      |   92 +
 .../graph/TransactionHandlerContractTest.java   |  149 ++
 .../apache/jena/graph/compose/DeltaTest.java    |  110 ++
 .../jena/graph/compose/DifferenceTest.java      |   97 +
 .../jena/graph/compose/IntersectionTest.java    |  109 ++
 .../apache/jena/graph/compose/UnionTest.java    |  185 ++
 .../jena/graph/impl/TestCollectionGraph.java    |   42 +-
 .../jena/graph/impl/TestWrappedGraph.java       |   63 +
 .../graph/impl/TripleStoreContractTest.java     |  176 ++
 .../apache/jena/mem/BunchMapContractTest.java   |  163 ++
 .../java/org/apache/jena/mem/GraphMemTest.java  |  115 ++
 .../apache/jena/mem/GraphTripleStoreTest.java   |   51 +
 .../jena/mem/TripleBunchContractTest.java       |  205 +++
 .../AbstractGraphProducer.java                  |  104 ++
 .../AbstractInfModelProducer.java               |   91 +
 .../AbstractModelProducer.java                  |   88 +
 .../AbstractRecordingListener.java              |  190 ++
 .../testing_framework/ContractTemplate.java     |   17 +
 .../GraphEventManagerProducerInterface.java     |   35 +
 .../jena/testing_framework/GraphHelper.java     |  508 ++++++
 .../GraphProducerInterface.java                 |   41 +
 .../testing_framework/IContainerProducer.java   |   19 +
 .../testing_framework/IIteratorProducer.java    |   42 +
 .../jena/testing_framework/INodeProducer.java   |   39 +
 .../testing_framework/IResourceProducer.java    |   10 +
 .../testing_framework/IStatementProducer.java   |   45 +
 .../testing_framework/ITripleStoreProducer.java |   35 +
 .../jena/testing_framework/ModelHelper.java     |  409 +++++
 .../jena/testing_framework/NodeCreateUtils.java |  177 ++
 .../NodeProducerInterface.java                  |   32 +
 .../jena/testing_framework/TestFileData.java    |  380 ++++
 .../jena/testing_framework/TestUtils.java       |  320 ++++
 .../testing_framework/manifest/Manifest.java    |  228 +++
 .../manifest/ManifestException.java             |   48 +
 .../manifest/ManifestFile.java                  |   38 +
 .../manifest/ManifestItem.java                  |   53 +
 .../manifest/ManifestItemHandler.java           |   35 +
 .../manifest/ManifestSuite.java                 |  143 ++
 .../manifest/ManifestTest.java                  |   13 +
 .../manifest/ManifestTestRunner.java            |   75 +
 .../jena/testing_framework/package-info.java    |  109 ++
 .../testing_framework/tuples/TupleItem.java     |   84 +
 .../jena/testing_framework/tuples/TupleSet.java |  274 +++
 48 files changed, 7880 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/pom.xml
----------------------------------------------------------------------
diff --git a/jena-core/pom.xml b/jena-core/pom.xml
index 6cb0722..a29e559 100644
--- a/jena-core/pom.xml
+++ b/jena-core/pom.xml
@@ -75,6 +75,20 @@
       <scope>test</scope>
     </dependency>
 
+       <dependency>
+               <groupId>org.xenei</groupId>
+               <artifactId>junit-contracts</artifactId>
+               <version>0.0.5</version>
+               <scope>test</scope>
+       </dependency>
+       
+       <dependency>
+               <groupId>org.mockito</groupId>
+               <artifactId>mockito-all</artifactId>
+               <version>1.9.5</version>
+               <scope>test</scope>
+       </dependency>
+
   </dependencies>
 
   <build>

http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/src/test/java/org/apache/jena/graph/GraphContractTest.java
----------------------------------------------------------------------
diff --git 
a/jena-core/src/test/java/org/apache/jena/graph/GraphContractTest.java 
b/jena-core/src/test/java/org/apache/jena/graph/GraphContractTest.java
new file mode 100644
index 0000000..cf79da5
--- /dev/null
+++ b/jena-core/src/test/java/org/apache/jena/graph/GraphContractTest.java
@@ -0,0 +1,1720 @@
+/*
+ * 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 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 org.junit.After;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xenei.junit.contract.Contract;
+import org.xenei.junit.contract.ContractTest;
+
+import static org.junit.Assert.*;
+
+import org.apache.jena.graph.Capabilities;
+import org.apache.jena.graph.Graph;
+import org.apache.jena.graph.GraphStatisticsHandler;
+import org.apache.jena.graph.GraphUtil;
+import org.apache.jena.graph.Node;
+import org.apache.jena.graph.Triple;
+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.ContractTemplate;
+import org.apache.jena.testing_framework.NodeCreateUtils;
+import org.apache.jena.util.iterator.ClosableIterator;
+import org.apache.jena.util.iterator.ExtendedIterator;
+import org.apache.jena.util.iterator.Map1;
+
+import static org.apache.jena.testing_framework.GraphHelper.*;
+
+/**
+ * AbstractTestGraph provides a bunch of basic tests for something that 
purports
+ * to be a Graph. The abstract method getGraph must be overridden in subclasses
+ * to deliver a Graph of interest.
+ */
+@Contract(Graph.class)
+public class GraphContractTest<T extends Graph> extends
+               ContractTemplate<AbstractGraphProducer<T>> {
+
+       private static final Logger LOG = LoggerFactory
+                       .getLogger(GraphContractTest.class);
+
+       protected RecordingGraphListener GL = new RecordingGraphListener();
+
+       @Contract.Inject
+       public final void setGraphContractTestProducer(
+                       AbstractGraphProducer<T> graphProducer) {
+               super.setProducer(graphProducer);
+       }
+
+       @After
+       public final void afterGraphContractTest() {
+               getProducer().cleanUp();
+               GL.clear();
+       }
+
+       @ContractTest
+       public void testAdd_Triple() {
+               Graph graph = getProducer().newInstance();
+               graph.getEventManager().register(GL);
+               txnBegin(graph);
+               graph.add(triple("S P O"));
+               txnCommit(graph);
+               GL.assertHasStart("add", graph, triple("S P O"));
+               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() {
+               Graph graph = getProducer().newInstance();
+               Graph base = copy(graph);
+
+               graph.getEventManager().register(GL);
+               txnBegin(graph);
+               graph.clear();
+               txnCommit(graph);
+               assertEmpty(graph, base);
+               GL.assertHasStart("someEvent", graph, GraphEvents.removeAll);
+               GL.clear();
+
+               // test after adding
+               graph = graphWith(getProducer().newInstance(),
+                               "S P O; S e:ff 27; _1 P P3; S4 P4 'en'");
+               graph.getEventManager().register(GL);
+               txnBegin(graph);
+               graph.clear();
+               txnCommit(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(getProducer().newInstance(),
+                               "S P O; S P2 O2; S3 P P3");
+               graph.getEventManager().register(GL);
+               assertFalse("Graph was constructed closed", graph.isClosed());
+
+               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(getProducer().newInstance(),
+                               "S P O; S2 P2 O2; S3 P3 O3");
+
+               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(getProducer().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("??");
+               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");
+               if (getProducer().newInstance().getCapabilities()
+                               .handlesLiteralTyping()) {
+                       Graph g1 = graphWith(getProducer().newInstance(),
+                                       "x P '1'xsd:integer");
+                       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(getProducer().newInstance(), "x P 
'1'xsd:int");
+                       assertTrue("Literal equality with '1'xsd:integer 
failed",
+                                       g2.contains(x, P, 
node("'1'xsd:integer")));
+                       //
+                       Graph g3 = graphWith(getProducer().newInstance(),
+                                       "x P '123'xsd:string");
+                       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(getProducer().newInstance(),
+                               "s P o; _x _R _y; x S 0");
+               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_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(getProducer().newInstance(), "x R y; a P 
b");
+               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(getProducer().newInstance(),
+                               "S P O; S2 P2 O2; S3 P3 O3");
+
+               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(getProducer().newInstance(), "s P o; s Q 
r");
+               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() {
+
+               if (getProducer().newInstance().getCapabilities()
+                               .handlesLiteralTyping()) {
+                       Graph g1 = graphWith(getProducer().newInstance(),
+                                       "x P '1'xsd:integer");
+                       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(getProducer().newInstance(), "x P 
'1'xsd:int");
+                       assertTrue("did not find x P '1'xsd:integer",
+                                       g2.contains(triple("x P 
'1'xsd:integer")));
+                       //
+                       Graph g3 = graphWith(getProducer().newInstance(),
+                                       "x P '123'xsd:string");
+                       assertTrue("did not find x P '123'xsd:string",
+                                       g3.contains(triple("x P '123'")));
+               }
+       }
+
+       @ContractTest
+       public void testContains_Triple_Concrete() {
+               Graph g = graphWith(getProducer().newInstance(),
+                               "s P o; _x _R _y; x S 0");
+               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(getProducer().newInstance(), "x R y; a P 
b");
+               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(getProducer().newInstance(),
+                               "S P O; S2 P2 O2; S3 P3 O3");
+               Graph base = getProducer().newInstance();
+               graph.getEventManager().register(GL);
+               txnBegin(graph);
+               graph.delete(triple("S P O"));
+               txnCommit(graph);
+               GL.assertContains("delete", graph, triple("S P O"));
+               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")));
+
+               // 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);
+               }
+               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 = getProducer().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 = getProducer().newInstance();
+               Graph[] depGraphs = getProducer().getDependsOn(g);
+               if (depGraphs != null) {
+                       for (Graph dg : depGraphs) {
+                               assertTrue(
+                                               String.format("Graph %s should 
depend upon %s", g, dg),
+                                               g.dependsOn(dg));
+                       }
+               }
+               depGraphs = getProducer().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(getProducer().newInstance(),
+                               "S P O; S2 P2 O2; S3 P3 O3");
+               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());
+
+       }
+
+       @ContractTest
+       public void testFind_Node_Node_Node_ByFluidTriple() {
+               Node x = node("x");
+               Node y = node("y");
+               Node z = node("z");
+               Graph g = graphWith(getProducer().newInstance(), "x y z ");
+               Set<Triple> expect = tripleSet("x y z");
+               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());
+       }
+
+       @ContractTest
+       public void testFind_Node_Node_Node_ProgrammaticValues() {
+               Graph g = getProducer().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);
+                       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());
+               }
+       }
+
+       @ContractTest
+       public void 
testFind_Node_Node_Node_MatchLanguagedLiteralCaseInsensitive() {
+               Graph m = graphWith(getProducer().newInstance(), "a p 
'chat'en");
+               if (m.getCapabilities().handlesLiteralTyping()) {
+                       Node chaten = node("'chat'en"), chatEN = 
node("'chat'EN");
+                       assertDiffer(chaten, chatEN);
+                       assertTrue(chaten.sameValueAs(chatEN));
+                       assertEquals(chaten.getIndexingValue(), 
chatEN.getIndexingValue());
+                       assertEquals(1, m.find(Node.ANY, Node.ANY, 
chaten).toList().size());
+                       assertEquals(1, m.find(Node.ANY, Node.ANY, 
chatEN).toList().size());
+               }
+       }
+
+       @ContractTest
+       public void testFind_Node_Node_Node_NoMatchAgainstUnlanguagesLiteral() {
+               Graph m = graphWith(getProducer().newInstance(),
+                               "a p 'chat'en; a p 'chat'");
+               if (m.getCapabilities().handlesLiteralTyping()) {
+                       Node chaten = node("'chat'en"), chatEN = 
node("'chat'EN");
+                       assertDiffer(chaten, chatEN);
+                       assertTrue(chaten.sameValueAs(chatEN));
+                       assertEquals(chaten.getIndexingValue(), 
chatEN.getIndexingValue());
+                       assertEquals(1, m.find(Node.ANY, Node.ANY, 
chaten).toList().size());
+                       assertEquals(1, m.find(Node.ANY, Node.ANY, 
chatEN).toList().size());
+               }
+       }
+
+       @ContractTest
+       public void testFind_Triple() {
+               Graph graph = graphWith(getProducer().newInstance(),
+                               "S P O; S2 P2 O2; S3 P3 O3");
+               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());
+
+       }
+
+       @ContractTest
+       public void testFind_Triple_ByFluidTriple() {
+               Graph g = graphWith(getProducer().newInstance(), "x y z ");
+               Set<Triple> expect = tripleSet("x y z");
+               assertEquals(expect, g.find(triple("?? y z")).toSet());
+               assertEquals(expect, g.find(triple("x ?? z")).toSet());
+               assertEquals(expect, g.find(triple("x y ??")).toSet());
+       }
+
+       @ContractTest
+       public void testFind_Triple_ProgrammaticValues() {
+               Graph g = getProducer().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);
+                       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());
+               }
+       }
+
+       @ContractTest
+       public void testFind_Triple_MatchLanguagedLiteralCaseInsensitive() {
+               Graph m = graphWith(getProducer().newInstance(), "a p 
'chat'en");
+               //if (m.getCapabilities().handlesLiteralTyping()) {
+                       Node chaten = node("'chat'en"), chatEN = 
node("'chat'EN");
+                       assertDiffer(chaten, chatEN);
+                       assertTrue(chaten.sameValueAs(chatEN));
+                       assertEquals(chaten.getIndexingValue(), 
chatEN.getIndexingValue());
+                       assertEquals(1, m.find(new Triple(Node.ANY, Node.ANY, 
chaten))
+                                       .toList().size());
+                       assertEquals(1, m.find(new Triple(Node.ANY, Node.ANY, 
chatEN))
+                                       .toList().size());
+               //}
+       }
+
+       @ContractTest
+       public void testFind_Triple_NoMatchAgainstUnlanguagesLiteral() {
+               Graph m = graphWith(getProducer().newInstance(),
+                               "a p 'chat'en; a p 'chat'");
+               //if (m.getCapabilities().handlesLiteralTyping()) {
+                       Node chaten = node("'chat'en"), chatEN = 
node("'chat'EN");
+                       assertDiffer(chaten, chatEN);
+                       assertTrue(chaten.sameValueAs(chatEN));
+                       assertEquals(chaten.getIndexingValue(), 
chatEN.getIndexingValue());
+                       assertEquals(1, m.find(new Triple(Node.ANY, Node.ANY, 
chaten))
+                                       .toList().size());
+                       assertEquals(1, m.find(new Triple(Node.ANY, Node.ANY, 
chatEN))
+                                       .toList().size());
+               //}
+       }
+
+       @ContractTest
+       public void testGetCapabilities() {
+               Graph g = getProducer().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.addAllowed(true);
+               } catch (Exception e) {
+                       fail("addAllowed( boolean ) threw Exception: " + 
e.toString());
+               }
+               try {
+                       c.deleteAllowed();
+               } catch (Exception e) {
+                       fail("deleteAllowed() threw Exception: " + 
e.toString());
+               }
+               try {
+                       c.deleteAllowed(true);
+               } catch (Exception e) {
+                       fail("deleteAllowed( boolean ) threw Exception: " + 
e.toString());
+               }
+               try {
+                       c.canBeEmpty();
+               } catch (Exception e) {
+                       fail("canBeEmpty() threw Exception: " + e.toString());
+               }
+       }
+
+       @ContractTest
+       public void testGetEventManager() {
+               assertNotNull("Must return an EventManager", getProducer()
+                               .newInstance().getEventManager());
+       }
+
+       @ContractTest
+       public void testGetPrefixMapping() {
+               Graph g = getProducer().newInstance();
+               PrefixMapping pm = g.getPrefixMapping();
+               assertNotNull("Must return prefix mapping", pm);
+               assertSame("getPrefixMapping must always return the same 
object", pm,
+                               g.getPrefixMapping());
+
+       
+               pm.setNsPrefix("pfx1", "http://example.com/";);
+               pm.setNsPrefix("pfx2", "scheme:rope/string#");
+
+               // assert same after adding to other mapl
+               assertSame("getPrefixMapping must always return the same 
object", pm,
+                               g.getPrefixMapping());
+
+       }
+
+       @ContractTest
+       public void testGetStatisticsHandler() {
+               Graph g = getProducer().newInstance();
+               GraphStatisticsHandler sh = g.getStatisticsHandler();
+               if (sh != null) {
+                       assertSame(
+                                       "getStatisticsHandler must always 
return the same object",
+                                       sh, g.getStatisticsHandler());
+               }
+       }
+
+       @ContractTest
+       public void testGetTransactionHandler() {
+               Graph g = getProducer().newInstance();
+               assertNotNull("Must return a Transaction handler",
+                               g.getTransactionHandler());
+       }
+
+       @ContractTest
+       public void testIsClosed() {
+               Graph g = getProducer().newInstance();
+               assertFalse("Graph created in closed state", g.isClosed());
+               g.close();
+               assertTrue("Graph does not report closed state after close 
called",
+                               g.isClosed());
+       }
+
+       @ContractTest
+       public void testIsEmpty() {
+               Graph g = getProducer().newInstance();
+               if (!g.isEmpty()) {
+                       LOG.warn(String.format(
+                                       "Graph type %s can not be empty (Empty 
test skipped)",
+                                       g.getClass()));
+               } else {
+                       graphAddTxn(g, "S P O");
+                       assertFalse("Graph reports empty after add", 
g.isEmpty());
+                       txnBegin(g);
+                       g.add(NodeCreateUtils.createTriple("Foo B C"));
+                       g.delete(NodeCreateUtils.createTriple("S P O"));
+                       txnCommit(g);
+                       assertFalse("Should not report empty", g.isEmpty());
+                       txnBegin(g);
+                       g.delete(NodeCreateUtils.createTriple("Foo B C"));
+                       txnCommit(g);
+                       assertTrue("Should report empty after all entries 
deleted",
+                                       g.isEmpty());
+               }
+       }
+
+       @ContractTest
+       public void testIsIsomorphicWith_Graph() {
+               Graph graph = getProducer().newInstance();
+               Graph g2 = memGraph();
+               assertTrue("Empty graphs should be isomorphic",
+                               graph.isIsomorphicWith(g2));
+
+               graph = graphWith(getProducer().newInstance(),
+                               "S P O; S2 P2 O2; S3 P3 O3");
+               g2 = graphWith("S3 P3 O3; S2 P2 O2; S P O");
+               assertTrue("Should be isomorphic", graph.isIsomorphicWith(g2));
+               txnBegin(graph);
+               graph.add(triple("_1, P4 S4"));
+               txnCommit(graph);
+
+               txnBegin(g2);
+               g2.add(triple("_2, P4 S4"));
+               txnCommit(g2);
+               assertTrue("Should be isomorphic after adding anonymous nodes",
+                               graph.isIsomorphicWith(g2));
+
+               txnBegin(graph);
+               graph.add(triple("_1, P3 S4"));
+               txnCommit(graph);
+
+               txnBegin(g2);
+               g2.add(triple("_2, P4 S4"));
+               txnCommit(g2);
+               assertFalse("Should not be isomorphic", 
graph.isIsomorphicWith(g2));
+       }
+
+       private Graph copy(Graph g) {
+               Graph result = getProducer().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 = getProducer().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);
+                               assertIsomorphic(cases[i][1], expected, 
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(getProducer().newInstance(), "S P O");
+               ExtendedIterator<Triple> it = g.find(NodeCreateUtils
+                               .createTriple(findRemove));
+               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();
+                       assertFalse(
+                                       "delete failed but capailities 
indicates it should work", g
+                                                       
.getCapabilities().iteratorRemoveAllowed());
+               }
+       }
+
+       /**
+        * 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 = getProducer().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);
+                       assertTrue(g.contains(r, p, Node.ANY));
+                       assertEquals(1, g.find(r, p, Node.ANY).toList().size());
+               } catch (Exception e) {
+                       txnRollback(g);
+                       fail(e.getMessage());
+               }
+       }
+
+       /**
+        * Check that contains respects by-value semantics.
+        */
+
+       @ContractTest
+       public void testAGraph() {
+               String title = this.getClass().getName();
+               Graph g = getProducer().newInstance();
+               int baseSize = g.size();
+               graphAddTxn(g, "x R y; p S q; a T b");
+               /* */
+               assertContainsAll(title + ": simple graph", g, "x R y; p S q; a 
T b");
+               assertEquals(title + ": size", baseSize + 3, g.size());
+
+               graphAddTxn(g,
+                               "spindizzies lift cities; Diracs communicate 
instantaneously");
+               assertEquals(title + ": size after adding", baseSize + 5, 
g.size());
+               txnBegin(g);
+               g.delete(triple("x R y"));
+               g.delete(triple("a T b"));
+               txnCommit(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());
+               it.close();
+       }
+
+       // public void testStuff()
+       // {
+       // // testAGraph( "StoreMem", new GraphMem() );
+       // // testAGraph( "StoreMemBySubject", new GraphMem() );
+       // // String [] empty = new String [] {};
+       // // Graph g = graphWith( "x R y; p S q; a T b" );
+       // // /* */
+       // // assertContainsAll( "simple graph", g, "x R y; p S q; a T b" );
+       // // graphAdd( g,
+       // "spindizzies lift cities; Diracs communicate instantaneously" );
+       // // g.delete( triple( "x R y" ) );
+       // // g.delete( triple( "a T b" ) );
+       // // assertContainsAll( "modified simple graph", g,
+       // "p S q; spindizzies lift cities; Diracs communicate instantaneously" 
);
+       // // assertOmitsAll( "modified simple graph", g, "x R y; a T b" );
+       // }
+
+       // /**
+       // Test that Graphs have transaction support methods, and that if they 
fail
+       // on some g they fail because they do not support the operation.
+       // */
+       // @ContractTest
+       // public void testHasTransactions()
+       // {
+       // Graph g = getProducer().newInstance();
+       // TransactionHandler th = g.getTransactionHandler();
+       // th.transactionsSupported();
+       // try { th.begin(); } catch (UnsupportedOperationException x) {}
+       // try { th.abort(); } catch (UnsupportedOperationException x) {}
+       // try { th.begin(); th.commit(); } catch 
(UnsupportedOperationException x)
+       // {}
+       // /* */
+       // Command cmd = new Command()
+       // { @Override
+       // public Object execute() { return null; } };
+       // try { th.executeInTransaction( cmd ); }
+       // catch (UnsupportedOperationException x) {}
+       // }
+       //
+       // @ContractTest
+       // public void testExecuteInTransactionCatchesThrowable()
+       // {Graph g = getProducer().newInstance();
+       // TransactionHandler th = g.getTransactionHandler();
+       // if (th.transactionsSupported())
+       // {
+       // Command cmd = new Command()
+       // { @Override
+       // public Object execute() throws Error { throw new Error(); } };
+       // try { th.executeInTransaction( cmd ); }
+       // catch (JenaException x) {}
+       // }
+       // }
+
+       @ContractTest
+       public void testAddWithReificationPreamble() {
+               Graph g = getProducer().newInstance();
+               txnBegin(g);
+               xSPO(g);
+               txnCommit(g);
+               assertFalse(g.isEmpty());
+       }
+
+       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 = getProducer().newInstance();
+               if (g.getCapabilities().iteratorRemoveAllowed()) {
+                       try {
+                               graphAddTxn(g, "c S d; e:ff GGG hhhh; _i J 27; 
Ell Em 'en'");
+                               Iterator<Triple> it = new 
TrackingTripleIterator(
+                                               g.find(Triple.ANY)) {
+                                       @Override
+                                       public void remove() {
+                                               super.remove(); // removes 
current
+                                               g.delete(current); // no-op.
+                                       }
+                               };
+                               while (it.hasNext()) {
+                                       it.next();
+                                       it.remove();
+                               }
+                               assertTrue(g.isEmpty());
+                       } catch (UnsupportedOperationException e) {
+                               fail("Error attempting to remove nodes " + 
e.getMessage());
+                       }
+               }
+       }
+
+       /**
+        * 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 FileNotFoundException
+        */
+       @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)
+                       throws URISyntaxException, MalformedURLException {
+               testIsomorphismFile(i, "N-TRIPLE", "nt", result);
+       }
+
+       private void testIsomorphismXMLFile(int i, boolean result)
+                       throws URISyntaxException, MalformedURLException {
+               testIsomorphismFile(i, "RDF/XML", "rdf", result);
+
+       }
+
+       private InputStream getInputStream(int n, int n2, String suffix)
+                       throws URISyntaxException, MalformedURLException {
+               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) throws URISyntaxException, 
MalformedURLException {
+
+               Graph g1 = getProducer().newInstance();
+               Graph g2 = getProducer().newInstance();
+               Model m1 = ModelFactory.createModelForGraph(g1);
+               Model m2 = ModelFactory.createModelForGraph(g2);
+
+               m1.read(getInputStream(n, 1, suffix), 
"http://www.example.org/";, lang);
+
+               m2.read(getInputStream(n, 2, suffix), 
"http://www.example.org/";, lang);
+
+               boolean rslt = g1.isIsomorphicWith(g2) == result;
+               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 = getProducer().newInstance();
+               result.close();
+               return result;
+       }
+
+       // @ContractTest
+       // public void testTransactionCommit()
+       // {
+       // Graph g = getProducer().newInstance();
+       // if (g.getTransactionHandler().transactionsSupported())
+       // {
+       // Graph initial = graphWithTxn( "initial hasValue 42; also hasURI 
hello" );
+       // Graph extra = graphWithTxn( "extra hasValue 17; also hasURI world" );
+       // //File foo = FileUtils.tempFileName( "fileGraph", ".nt" );
+       //
+       // //Graph g = new FileGraph( foo, true, true );
+       //
+       // GraphUtil.addInto( g, initial );
+       // g.getTransactionHandler().begin();
+       // GraphUtil.addInto( g, extra );
+       // g.getTransactionHandler().commit();
+       // Graph union = graphWithTxn( "" );
+       // GraphUtil.addInto(union, initial );
+       // GraphUtil.addInto(union, extra );
+       // assertIsomorphic( union, g );
+       // //Model inFile = ModelFactory.createDefaultModel();
+       // //inFile.read( "file:///" + foo, "N-TRIPLES" );
+       // //assertIsomorphic( union, inFile.getGraph() );
+       // }
+       // }
+       //
+       // @ContractTest
+       // public void testTransactionAbort()
+       // {
+       // Graph g = getProducer().newInstance();
+       // if (g.getTransactionHandler().transactionsSupported())
+       // {
+       // Graph initial = graphWithTxn( "initial hasValue 42; also hasURI 
hello" );
+       // Graph extra = graphWithTxn( "extra hasValue 17; also hasURI world" );
+       // File foo = FileUtils.tempFileName( "fileGraph", ".n3" );
+       // //Graph g = new FileGraph( foo, true, true );
+       // GraphUtil.addInto( g, initial );
+       // g.getTransactionHandler().begin();
+       // GraphUtil.addInto( g, extra );
+       // g.getTransactionHandler().abort();
+       // assertIsomorphic( initial, g );
+       // }
+       // }
+       //
+       // @ContractTest
+       // public void testTransactionCommitThenAbort()
+       // {
+       // Graph g = getProducer().newInstance();
+       // if (g.getTransactionHandler().transactionsSupported())
+       // {
+       // Graph initial = graphWithTxn( "Foo pings B; B pings C" );
+       // Graph extra = graphWithTxn( "C pingedBy B; fileGraph rdf:type Graph" 
);
+       // //Graph g = getProducer().newInstance();
+       // //File foo = FileUtils.tempFileName( "fileGraph", ".nt" );
+       // //Graph g = new FileGraph( foo, true, true );
+       // g.getTransactionHandler().begin();
+       // GraphUtil.addInto( g, initial );
+       // g.getTransactionHandler().commit();
+       // g.getTransactionHandler().begin();
+       // GraphUtil.addInto( g, extra );
+       // g.getTransactionHandler().abort();
+       // assertIsomorphic( initial, g );
+       // //Model inFile = ModelFactory.createDefaultModel();
+       // // inFile.read( "file:///" + foo, "N-TRIPLES" );
+       // //assertIsomorphic( initial, inFile.getGraph() );
+       // }
+       // }
+
+       /**
+        * 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(getProducer().newInstance(), "a R b; b 
S e");
+               Graph dest = graphWith(getProducer().newInstance(), "b R d");
+               GraphExtract e = new GraphExtract(TripleBoundary.stopNowhere);
+               e.extractInto(dest, node("a"), source);
+               assertIsomorphic(
+                               graphWith(getProducer().newInstance(), "a R b; 
b S e; b R d"),
+                               dest);
+       }
+
+       /**
+        * 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(getProducer().newInstance(), "a R b; b 
S e");
+               if (graph.getCapabilities().iteratorRemoveAllowed()) {
+                       try {
+                               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());
+                               rtr.next();
+                               rtr.remove();
+                               rtr.close();
+                               GL.assertHas("delete", graph, toRemove);
+                       } catch (UnsupportedOperationException e) {
+                               fail("Error attempting to remove nodes " + 
e.getMessage());
+                       }
+
+               }
+       }
+
+       @ContractTest
+       public void testTransactionHandler_Commit() {
+               Graph g = getProducer().newInstance();
+               if (g.getTransactionHandler().transactionsSupported()) {
+                       Graph initial = graphWith(getProducer().newInstance(),
+                                       "initial hasValue 42; also hasURI 
hello");
+                       Graph extra = graphWith(getProducer().newInstance(),
+                                       "extra hasValue 17; also hasURI world");
+
+                       GraphUtil.addInto(g, initial);
+                       g.getTransactionHandler().begin();
+                       GraphUtil.addInto(g, extra);
+                       g.getTransactionHandler().commit();
+                       Graph union = memGraph();
+                       GraphUtil.addInto(union, initial);
+                       GraphUtil.addInto(union, extra);
+                       assertIsomorphic(union, g);
+                       // Model inFiIProducer<TransactionHandler>le =
+                       // ModelFactory.createDefaultModel();
+                       // inFile.read( "file:///" + foo, "N-TRIPLES" );
+                       // assertIsomorphic( union, inFile.getGraph() );
+               }
+       }
+
+       @ContractTest
+       public void testTransactionHandler_Abort() {
+               Graph g = getProducer().newInstance();
+               if (g.getTransactionHandler().transactionsSupported()) {
+                       Graph initial = graphWith(getProducer().newInstance(),
+                                       "initial hasValue 42; also hasURI 
hello");
+                       Graph extra = graphWith(getProducer().newInstance(),
+                                       "extra hasValue 17; also hasURI world");
+                       GraphUtil.addInto(g, initial);
+                       g.getTransactionHandler().begin();
+                       GraphUtil.addInto(g, extra);
+                       g.getTransactionHandler().abort();
+                       assertIsomorphic(initial, g);
+               }
+       }
+
+       @ContractTest
+       public void testTransactionHandler_CommitThenAbort() {
+               Graph g = getProducer().newInstance();
+               if (g.getTransactionHandler().transactionsSupported()) {
+                       Graph initial = graphWith(getProducer().newInstance(),
+                                       "Foo pings B; B pings C");
+                       Graph extra = graphWith(getProducer().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();
+                       assertIsomorphic(initial, g);
+                       // 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 Map1<Triple, Node> getObject = new Map1<Triple, 
Node>() {
+               @Override
+               public Node map1(Triple o) {
+                       return o.getObject();
+               }
+       };
+
+       private void testLiteralTypingBasedFind(final String data, final int 
size,
+                       final String search, final String results, boolean 
reqLitType) {
+
+               Graph g = getProducer().newInstance();
+
+               if (!reqLitType || g.getCapabilities().handlesLiteralTyping()) {
+                       graphWith(g, data);
+
+                       Node literal = NodeCreateUtils.create(search);
+                       //
+                       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);
+               }
+       }
+
+       @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);
+               testLiteralTypingBasedFind("a P 'simple'xsd:string", 1,
+                               "'simple'xsd:string", "'simple'xsd:string", 
false);
+//             testLiteralTypingBasedFind("a P 'simple'; a P 
'simple'xsd:string", 2,
+//                             "'simple'", "'simple' 'simple'xsd:string", 
true);
+//             testLiteralTypingBasedFind("a P 'simple'; a P 
'simple'xsd:string", 2,
+//                             "'simple'xsd:string", "'simple' 
'simple'xsd:string", 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 = getProducer().newInstance();
+               assertEquals(0, g.size());
+               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);
+               assertEquals(4, g.size());
+               txnBegin(g);
+               g.delete(s);
+               g.delete(p);
+               g.delete(o);
+               g.delete(t);
+               txnCommit(g);
+               assertEquals(0, g.size());
+       }
+
+       @ContractTest
+       public void testSizeAfterRemove() {
+               Graph g = graphWith(getProducer().newInstance(), "x p y");
+               if (g.getCapabilities().iteratorRemoveAllowed()) {
+                       try {
+                               ExtendedIterator<Triple> it = g.find(triple("x 
?? ??"));
+                               it.removeNext();
+                               assertEquals(0, g.size());
+                       } catch (UnsupportedOperationException e) {
+                               fail("Error attempting to remove nodes " + 
e.getMessage());
+                       }
+               }
+       }
+
+       @ContractTest
+       public void testSingletonStatisticsWithSingleTriple() {
+
+               Graph g = graphWith(getProducer().newInstance(), "a P b");
+               GraphStatisticsHandler h = g.getStatisticsHandler();
+               if (h != null) {
+                       assertEquals(1L, h.getStatistic(node("a"), Node.ANY, 
Node.ANY));
+                       assertEquals(0L, h.getStatistic(node("x"), Node.ANY, 
Node.ANY));
+                       //
+                       assertEquals(1L, h.getStatistic(Node.ANY, node("P"), 
Node.ANY));
+                       assertEquals(0L, h.getStatistic(Node.ANY, node("Q"), 
Node.ANY));
+                       //
+                       assertEquals(1L, h.getStatistic(Node.ANY, Node.ANY, 
node("b")));
+                       assertEquals(0L, h.getStatistic(Node.ANY, Node.ANY, 
node("y")));
+               }
+       }
+
+       @ContractTest
+       public void testSingletonStatisticsWithSeveralTriples() {
+
+               Graph g = graphWith(getProducer().newInstance(),
+                               "a P b; a P c; a Q b; x S y");
+               GraphStatisticsHandler h = g.getStatisticsHandler();
+               if (h != null) {
+                       assertEquals(3L, h.getStatistic(node("a"), Node.ANY, 
Node.ANY));
+                       assertEquals(1L, h.getStatistic(node("x"), Node.ANY, 
Node.ANY));
+                       assertEquals(0L, h.getStatistic(node("y"), Node.ANY, 
Node.ANY));
+                       //
+                       assertEquals(2L, h.getStatistic(Node.ANY, node("P"), 
Node.ANY));
+                       assertEquals(1L, h.getStatistic(Node.ANY, node("Q"), 
Node.ANY));
+                       assertEquals(0L, h.getStatistic(Node.ANY, node("R"), 
Node.ANY));
+                       //
+                       assertEquals(2L, h.getStatistic(Node.ANY, Node.ANY, 
node("b")));
+                       assertEquals(1L, h.getStatistic(Node.ANY, Node.ANY, 
node("c")));
+                       assertEquals(0L, h.getStatistic(Node.ANY, Node.ANY, 
node("d")));
+               }
+       }
+
+       @ContractTest
+       public void testDoubletonStatisticsWithTriples() {
+
+               Graph g = graphWith(getProducer().newInstance(),
+                               "a P b; a P c; a Q b; x S y");
+               GraphStatisticsHandler h = g.getStatisticsHandler();
+               if (h != null) {
+                       assertEquals(-1L, h.getStatistic(node("a"), node("P"), 
Node.ANY));
+                       assertEquals(-1L, h.getStatistic(Node.ANY, node("P"), 
node("b")));
+                       assertEquals(-1L, h.getStatistic(node("a"), Node.ANY, 
node("b")));
+                       //
+                       assertEquals(0L, h.getStatistic(node("no"), node("P"), 
Node.ANY));
+               }
+       }
+
+       @ContractTest
+       public void testStatisticsWithOnlyVariables() {
+               testStatsWithAllVariables("");
+               testStatsWithAllVariables("a P b");
+               testStatsWithAllVariables("a P b; a P c");
+               testStatsWithAllVariables("a P b; a P c; a Q b; x S y");
+       }
+
+       private void testStatsWithAllVariables(String triples) {
+               Graph g = graphWith(getProducer().newInstance(), triples);
+               GraphStatisticsHandler h = g.getStatisticsHandler();
+               if (h != null) {
+                       assertEquals(g.size(), h.getStatistic(Node.ANY, 
Node.ANY, Node.ANY));
+               }
+       }
+
+       @ContractTest
+       public void testStatsWithConcreteTriple() {
+               testStatsWithConcreteTriple(0, "x P y", "");
+       }
+
+       private void testStatsWithConcreteTriple(int expect, String triple,
+                       String graph) {
+               Graph g = graphWith(getProducer().newInstance(), graph);
+               GraphStatisticsHandler h = g.getStatisticsHandler();
+               if (h != null) {
+                       Triple t = triple(triple);
+                       assertEquals(
+                                       expect,
+                                       h.getStatistic(t.getSubject(), 
t.getPredicate(),
+                                                       t.getObject()));
+               }
+       }
+
+       @ContractTest
+       public void testBrokenIndexes() {
+               Graph g = graphWith(getProducer().newInstance(), "x R y; x S 
z");
+               if (g.getCapabilities().iteratorRemoveAllowed()) {
+                       try {
+                               ExtendedIterator<Triple> it = g.find(Node.ANY, 
Node.ANY,
+                                               Node.ANY);
+                               it.removeNext();
+                               it.removeNext();
+                               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());
+                       } catch (UnsupportedOperationException e) {
+                               fail("Error attempting to remove nodes " + 
e.getMessage());
+                       }
+               }
+       }
+
+       @ContractTest
+       public void testBrokenSubject() {
+               Graph g = graphWith(getProducer().newInstance(), "x 
brokenSubject y");
+               if (g.getCapabilities().iteratorRemoveAllowed()) {
+                       try {
+                               ExtendedIterator<Triple> it = g.find(node("x"), 
Node.ANY,
+                                               Node.ANY);
+                               it.removeNext();
+                               assertFalse(g.find(Node.ANY, Node.ANY, 
Node.ANY).hasNext());
+                       } catch (UnsupportedOperationException e) {
+                               fail("Error attempting to remove nodes " + 
e.getMessage());
+                       }
+               }
+       }
+
+       @ContractTest
+       public void testBrokenPredicate() {
+               Graph g = graphWith(getProducer().newInstance(), "x 
brokenPredicate y");
+               if (g.getCapabilities().iteratorRemoveAllowed()) {
+                       try {
+                               ExtendedIterator<Triple> it = g.find(Node.ANY,
+                                               node("brokenPredicate"), 
Node.ANY);
+                               it.removeNext();
+                               assertFalse(g.find(Node.ANY, Node.ANY, 
Node.ANY).hasNext());
+                       } catch (UnsupportedOperationException e) {
+                               fail("Error attempting to remove nodes " + 
e.getMessage());
+                       }
+               }
+       }
+
+       @ContractTest
+       public void testBrokenObject() {
+               Graph g = graphWith(getProducer().newInstance(), "x 
brokenObject y");
+               if (g.getCapabilities().iteratorRemoveAllowed()) {
+                       try {
+                               ExtendedIterator<Triple> it = g.find(Node.ANY, 
Node.ANY,
+                                               node("y"));
+                               it.removeNext();
+                               assertFalse(g.find(Node.ANY, Node.ANY, 
Node.ANY).hasNext());
+
+                       } catch (UnsupportedOperationException e) {
+                               fail("Error attempting to remove nodes " + 
e.getMessage());
+                       }
+               }
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/src/test/java/org/apache/jena/graph/GraphEventManagerContractTest.java
----------------------------------------------------------------------
diff --git 
a/jena-core/src/test/java/org/apache/jena/graph/GraphEventManagerContractTest.java
 
b/jena-core/src/test/java/org/apache/jena/graph/GraphEventManagerContractTest.java
new file mode 100644
index 0000000..426002d
--- /dev/null
+++ 
b/jena-core/src/test/java/org/apache/jena/graph/GraphEventManagerContractTest.java
@@ -0,0 +1,514 @@
+/*
+ * 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 java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Before;
+import org.mockito.Mockito;
+import org.xenei.junit.contract.Contract;
+import org.xenei.junit.contract.ContractTest;
+
+import static org.junit.Assert.*;
+
+import org.apache.jena.graph.Graph;
+import org.apache.jena.graph.GraphEventManager;
+import org.apache.jena.graph.Triple;
+import org.apache.jena.graph.Factory;
+import org.apache.jena.testing_framework.ContractTemplate;
+import org.apache.jena.testing_framework.GraphHelper;
+import org.xenei.junit.contract.IProducer;
+import org.apache.jena.testing_framework.NodeCreateUtils;
+
+import static org.apache.jena.testing_framework.GraphHelper.*;
+
+/**
+ * An abstract test that tests EventManager implementations to ensure they
+ * comply with the EventManager contract.
+ * 
+ * Subclasses of this class must implement the getEventManagerProducer() method
+ * to create a new instance of the EventManager for testing.
+ */
+
+@Contract(GraphEventManager.class)
+public class GraphEventManagerContractTest<T extends GraphEventManager> extends
+               ContractTemplate<IProducer<T>> {
+
+       protected static final Triple[] tripleArray = tripleArray("S P O; Foo R 
B; X Q Y");
+
+       // the graph that is used as the source of the events.
+       private Graph mockGraph;
+       // The event manager we are working with.
+       private GraphEventManager gem;
+
+       public GraphEventManagerContractTest() {
+//             setProducer(new IProducer<T>() {
+//
+//                     @SuppressWarnings("unchecked")
+//                     @Override
+//                     public T newInstance() {
+//                             return (T) 
Factory.createGraphMem().getEventManager();
+//                     }
+//
+//                     @Override
+//                     public void cleanUp() {
+//                     }
+//             });
+
+       }
+
+       @Contract.Inject
+       public final void setGraphEventManagerContractTestProducer(
+                       IProducer<T> producer) {
+               super.setProducer(producer);
+       }
+
+       @After
+       public final void afterGraphEventManagerContractTest() {
+               getProducer().cleanUp();
+       }
+
+       @Before
+       public final void beforeGraphEventManagerContractTest() {
+               mockGraph = Mockito.mock(Graph.class);
+               gem = getProducer().newInstance();
+               L = new RecordingGraphListener();
+       }
+
+       /**
+        * Test that when a listener is registered the same EventManager is
+        * returned.
+        */
+       @ContractTest
+       public void testEventRegister() {
+               assertSame(gem, gem.register(new RecordingGraphListener()));
+       }
+
+       /**
+        * Test that we can safely unregister a listener that isn't registered.
+        */
+       @ContractTest
+       public void testEventUnregister() {
+               assertSame(gem, gem.unregister(L));
+       }
+
+       /**
+        * Handy triple for test purposes.
+        */
+       protected Triple SPO = NodeCreateUtils.createTriple("S P O");
+
+       /**
+        * The RecordingListener that reports all the events sent from the
+        * EventManager.
+        */
+       protected RecordingGraphListener L;
+
+       /**
+        * Test that adding a triple is reported.
+        */
+       @ContractTest
+       public void testAddTriple() {
+               gem.register(L);
+               gem.notifyAddTriple(mockGraph, SPO);
+               L.assertHas(new Object[] { "add", mockGraph, SPO });
+       }
+
+       /**
+        * Test that deleting a triple is reported.
+        */
+       @ContractTest
+       public void testDeleteTriple() {
+               gem.register(L);
+               gem.notifyDeleteTriple(mockGraph, SPO);
+               L.assertHas(new Object[] { "delete", mockGraph, SPO });
+       }
+
+       /**
+        * Test that when 2 listeners are added both receive events.
+        */
+       @ContractTest
+       public void testTwoListeners() {
+               RecordingGraphListener L1 = new RecordingGraphListener();
+               RecordingGraphListener L2 = new RecordingGraphListener();
+               gem.register(L1).register(L2);
+               gem.notifyAddTriple(mockGraph, SPO);
+               L2.assertHas(new Object[] { "add", mockGraph, SPO });
+               L1.assertHas(new Object[] { "add", mockGraph, SPO });
+       }
+
+       /**
+        * Test that unregistering a listener after registering it results in 
it not
+        * receiving messages.
+        */
+       @ContractTest
+       public void testUnregisterWorks() {
+               gem.register(L).unregister(L);
+               gem.notifyAddTriple(mockGraph, SPO);
+               L.assertHas(new Object[] {});
+       }
+
+       /**
+        * Test that registering a listener twice results in the listener 
receiving
+        * the events twice.
+        */
+       @ContractTest
+       public void testRegisterTwice() {
+               gem.register(L).register(L);
+               gem.notifyAddTriple(mockGraph, SPO);
+               L.assertHas(new Object[] { "add", mockGraph, SPO, "add", 
mockGraph, SPO });
+       }
+
+       /**
+        * Test that registering a listener twice and unregistering it once will
+        * result in the listener receiving each event one time.
+        */
+       @ContractTest
+       public void testUnregisterOnce() {
+               gem.register(L).register(L).unregister(L);
+               gem.notifyDeleteTriple(mockGraph, SPO);
+               L.assertHas(new Object[] { "delete", mockGraph, SPO });
+       }
+
+       /**
+        * Test that adding an array is reported as adding an array.
+        */
+       @ContractTest
+       public void testAddArray() {
+               gem.register(L);
+               gem.notifyAddArray(mockGraph, tripleArray);
+               L.assertHas(new Object[] { "add[]", mockGraph, tripleArray });
+       }
+
+       /**
+        * Test that adding a list is reported as adding a list
+        */
+       @ContractTest
+       public void testAddList() {
+               gem.register(L);
+               List<Triple> elems = Arrays.asList(tripleArray);
+               gem.notifyAddList(mockGraph, elems);
+               L.assertHas(new Object[] { "addList", mockGraph, elems });
+       }
+
+       /**
+        * Test that deleting an array is reported as deleting an array.
+        */
+       @ContractTest
+       public void testDeleteArray() {
+               gem.register(L);
+               gem.notifyDeleteArray(mockGraph, tripleArray);
+               L.assertHas(new Object[] { "delete[]", mockGraph, tripleArray 
});
+       }
+
+       /**
+        * Test that deleting a list is reported as deleting a list.
+        */
+       @ContractTest
+       public void testDeleteList() {
+               gem.register(L);
+               List<Triple> elems = Arrays.asList(tripleArray);
+               gem.notifyDeleteList(mockGraph, elems);
+               L.assertHas(new Object[] { "deleteList", mockGraph, elems });
+       }
+
+       /**
+        * Test that adding a list as an iterator is reported as an add 
iterator.
+        */
+       @ContractTest
+       public void testAddListAsIterator() {
+               gem.register(L);
+               List<Triple> elems = Arrays.asList(tripleArray);
+               gem.notifyAddIterator(mockGraph, elems);
+               L.assertHas(new Object[] { "addIterator", mockGraph, elems });
+       }
+
+       /**
+        * Test that adding an iterator is reported as adding an iterator.
+        */
+       @ContractTest
+       public void testAddIterator() {
+               gem.register(L);
+               List<Triple> elems = Arrays.asList(tripleArray);
+               gem.notifyAddIterator(mockGraph, elems.iterator());
+               L.assertHas(new Object[] { "addIterator", mockGraph, elems });
+       }
+
+       /**
+        * Test that deleting an iterator is reported as a deleting an iterator.
+        */
+       @ContractTest
+       public void testDeleteIterator() {
+               gem.register(L);
+               List<Triple> elems = Arrays.asList(tripleArray);
+               gem.notifyDeleteIterator(mockGraph, elems.iterator());
+               L.assertHas(new Object[] { "deleteIterator", mockGraph, elems 
});
+       }
+
+       /**
+        * Test that deleting a list as an iterator is reported as deleting an
+        * iterator.
+        */
+       @ContractTest
+       public void testDeleteListAsIterator() {
+               gem.register(L);
+               List<Triple> elems = Arrays.asList(tripleArray);
+               gem.notifyDeleteIterator(mockGraph, elems);
+               L.assertHas(new Object[] { "deleteIterator", mockGraph, elems 
});
+       }
+
+       /**
+        * Test that adding a graph is reported as adding a graph.
+        */
+       @ContractTest
+       public void testAddGraph() {
+               gem.register(L);
+               Graph other = Mockito.mock(Graph.class);
+               gem.notifyAddGraph(mockGraph, other);
+               L.assertHas(new Object[] { "addGraph", mockGraph, other });
+       }
+
+       /**
+        * Test that deleting a graph is reported as deleting a graph.
+        */
+       @ContractTest
+       public void testDeleteGraph() {
+               gem.register(L);
+               Graph other = Mockito.mock(Graph.class);
+               gem.notifyDeleteGraph(mockGraph, other);
+               L.assertHas(new Object[] { "deleteGraph", mockGraph, other });
+       }
+
+       /**
+        * Test that sending a general event is reported as an event and the 
value
+        * is saved.
+        */
+       @ContractTest
+       public void testGeneralEvent() {
+               gem.register(L);
+               Object value = new int[] {};
+               gem.notifyEvent(mockGraph, value);
+               L.assertHas(new Object[] { "someEvent", mockGraph, value });
+       }
+
+       @ContractTest
+       public void testListening() {
+               assertFalse("Should not be listening", gem.listening());
+               gem.register(L);
+               assertTrue("Should be listening", gem.listening());
+               gem.unregister(L);
+               assertFalse("Should not be listening", gem.listening());
+       }
+
+       //
+       // Foo series of tests to check modifying the manger in mid notification
+       //
+
+       private ComeAndGoListener all[];
+
+       abstract private static class ComeAndGoListener implements 
GraphListener {
+
+               // Was I registered when start() was called, and have not been
+               // unregistered.
+               boolean inPlay = false;
+               // currently registered or not.
+               boolean registered = false;
+               boolean notified = false;
+
+               void register(GraphEventManager gem) {
+                       registered = true;
+                       gem.register(this);
+               }
+
+               void unregister(GraphEventManager gem) {
+                       registered = false;
+                       inPlay = false;
+                       gem.unregister(this);
+               }
+
+               void start() {
+                       if (registered)
+                               inPlay = true;
+               }
+
+               void check() {
+                       if (inPlay && !notified)
+                               fail("listener that was in-play was not 
notified of adding triple.");
+               }
+
+               @Override
+               final public void notifyAddTriple(Graph g, Triple t) {
+                       notified = true;
+                       doSomeDamage();
+               }
+
+               abstract void doSomeDamage();
+
+               @Override
+               public void notifyAddArray(Graph g, Triple[] triples) {
+               }
+
+               @Override
+               public void notifyAddGraph(Graph g, Graph added) {
+               }
+
+               @Override
+               public void notifyAddIterator(Graph g, Iterator<Triple> it) {
+               }
+
+               @Override
+               public void notifyAddList(Graph g, List<Triple> triples) {
+               }
+
+               @Override
+               public void notifyDeleteArray(Graph g, Triple[] triples) {
+               }
+
+               @Override
+               public void notifyDeleteGraph(Graph g, Graph removed) {
+               }
+
+               @Override
+               public void notifyDeleteIterator(Graph g, Iterator<Triple> it) {
+               }
+
+               @Override
+               public void notifyDeleteList(Graph g, List<Triple> L) {
+               }
+
+               @Override
+               public void notifyDeleteTriple(Graph g, Triple t) {
+               }
+
+               @Override
+               public void notifyEvent(Graph source, Object value) {
+               }
+
+       }
+
+       /**
+        * ComeAndGoListener implementation that does no damage
+        * 
+        */
+       private static final class SimpleListener extends ComeAndGoListener {
+               @Override
+               void doSomeDamage() {
+               }
+       }
+
+       /**
+        * Test adding a triple to trigger event.
+        * 
+        * @param registerTo
+        *            Number of listeners to register.
+        * @param allx
+        */
+       private void testAddingTriple(int registerTo, ComeAndGoListener... 
allx) {
+               all = allx;
+               // register addMe
+               for (int i = 0; i < registerTo; i++) {
+                       all[i].register(gem);
+               }
+
+               // start them all
+               for (ComeAndGoListener l : all) {
+                       l.start();
+               }
+               // send the notification.
+               gem.notifyAddTriple(mockGraph, GraphHelper.triple("make a 
change"));
+               // check them
+               for (ComeAndGoListener l : all) {
+                       l.check();
+               }
+       }
+
+       /**
+        * Test that a listener added during event processing does not receive 
the
+        * event.
+        */
+       @ContractTest
+       public void testAddOne() {
+               testAddingTriple(2, new ComeAndGoListener() {
+                       @Override
+                       void doSomeDamage() {
+                               all[2].register(gem);
+                       }
+               }, new SimpleListener(), new SimpleListener());
+       }
+
+       /**
+        * Test that when a listener that has not yet been handled is removed 
during
+        * event processing it receive the event.
+        */
+       @ContractTest
+       public void testDelete2nd() {
+               testAddingTriple(3, new ComeAndGoListener() {
+                       @Override
+                       void doSomeDamage() {
+                               all[1].unregister(gem);
+                       }
+               }, new SimpleListener(), new SimpleListener());
+       }
+
+       /**
+        * Test that when a listener that has been handled is removed during 
event
+        * processing it receives the event.
+        */
+       @ContractTest
+       public void testDelete1st() {
+               testAddingTriple(3, new SimpleListener(), new 
ComeAndGoListener() {
+                       @Override
+                       void doSomeDamage() {
+                               all[0].unregister(gem);
+                       }
+               }, new SimpleListener());
+       }
+
+       /**
+        * Test that when a listener that removes itself during event 
processing it
+        * receives the event.
+        */
+       @ContractTest
+       public void testDeleteSelf() {
+               testAddingTriple(3, new ComeAndGoListener() {
+                       @Override
+                       void doSomeDamage() {
+                               unregister(gem);
+                       }
+               }, new SimpleListener(), new SimpleListener());
+       }
+
+       /**
+        * Test that when a listener that removes and adds itself during event
+        * processing it receives the event.
+        */
+       @ContractTest
+       public void testDeleteAndAddSelf() {
+               testAddingTriple(3, new ComeAndGoListener() {
+                       @Override
+                       void doSomeDamage() {
+                               unregister(gem);
+                               register(gem);
+                       }
+               }, new SimpleListener(), new SimpleListener());
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/src/test/java/org/apache/jena/graph/GraphMakerContractTest.java
----------------------------------------------------------------------
diff --git 
a/jena-core/src/test/java/org/apache/jena/graph/GraphMakerContractTest.java 
b/jena-core/src/test/java/org/apache/jena/graph/GraphMakerContractTest.java
new file mode 100644
index 0000000..5fbd9c2
--- /dev/null
+++ b/jena-core/src/test/java/org/apache/jena/graph/GraphMakerContractTest.java
@@ -0,0 +1,314 @@
+/*
+ * 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.junit.Assert.*;
+import java.util.Set;
+
+import org.junit.After;
+import org.junit.Before;
+import org.xenei.junit.contract.Contract;
+import org.xenei.junit.contract.ContractTest;
+
+import org.apache.jena.graph.Graph;
+import org.apache.jena.graph.GraphMaker;
+import org.apache.jena.graph.Node;
+import org.apache.jena.graph.Triple;
+import org.apache.jena.graph.impl.SimpleGraphMaker;
+import org.apache.jena.shared.AlreadyExistsException;
+import org.apache.jena.shared.DoesNotExistException;
+import org.apache.jena.testing_framework.GraphHelper;
+import org.xenei.junit.contract.IProducer;
+import org.apache.jena.testing_framework.TestUtils;
+
+/**
+ * Abstract base class for testing graph factories. Subclasses define the 
method
+ * <code>getGraphFactory()</code> which supplies a new graph factory to be
+ * tested: ATGF invokes that during <code>setUp</code> and closes it in
+ * <code>tearDown</code>.
+ * <p>
+ * This bunch of tests is not remotely exhaustive, but it was sufficent to 
drive
+ * the development of the first full graph factory. (Although at the time it
+ * wasn't abstract.)
+ */
+@Contract(GraphMaker.class)
+public class GraphMakerContractTest {
+
+       private IProducer<GraphMaker> producer;
+
+       private GraphMaker graphMaker;
+
+       public GraphMakerContractTest() {
+//             producer = new IProducer<GraphMaker>() {
+//
+//                     @Override
+//                     public GraphMaker newInstance() {
+//                             return new SimpleGraphMaker();
+//                     }
+//
+//                     @Override
+//                     public void cleanUp() {
+//
+//                     }
+//             };
+       }
+
+       @Contract.Inject
+       public final void setGraphMaker(IProducer<GraphMaker> producer) {
+               this.producer = producer;
+       }
+
+       protected final IProducer<GraphMaker> getGraphMakerProducer() {
+               return producer;
+       }
+
+       @After
+       public final void afterGraphMakerContractTest() {
+               producer.cleanUp();
+       }
+
+       @Before
+       public final void beforeGraphMakerContractTest() {
+               graphMaker = producer.newInstance();
+       }
+
+       @After
+       public void tearDown() {
+               graphMaker.close();
+               getGraphMakerProducer().cleanUp();
+       }
+
+       /**
+        * Foo trivial test that getGraph delivers a proper graph, not cheating 
with
+        * null, and that getGraph() "always" delivers the same Graph.
+        */
+       @ContractTest
+       public void testGetGraph() {
+               Graph g1 = graphMaker.getGraph();
+               assertFalse("should deliver a Graph", g1 == null);
+               assertSame(g1, graphMaker.getGraph());
+               g1.close();
+       }
+
+       @ContractTest
+       public void testCreateGraph() {
+               TestUtils.assertDiffer("each created graph must differ",
+                               graphMaker.createGraph(), 
graphMaker.createGraph());
+       }
+
+       @ContractTest
+       public void testAnyName() {
+               graphMaker.createGraph("plain").close();
+               graphMaker.createGraph("with.dot").close();
+               
graphMaker.createGraph("http://electric-hedgehog.net/topic#marker";)
+                               .close();
+       }
+
+       /**
+        * Test that we can't create a graph with the same name twice.
+        */
+       @ContractTest
+       public void testCannotCreateTwice() {
+               String name = jName("bonsai");
+               graphMaker.createGraph(name, true);
+               try {
+                       graphMaker.createGraph(name, true);
+                       fail("should not be able to create " + name + " twice");
+               } catch (AlreadyExistsException e) {
+               }
+       }
+
+       private String jName(String name) {
+               return "jena-test-AbstractTestGraphMaker-" + name;
+       }
+
+       @ContractTest
+       public void testCanCreateTwice() {
+               String name = jName("bridge");
+               Graph g1 = graphMaker.createGraph(name, true);
+               Graph g2 = graphMaker.createGraph(name, false);
+               assertTrue("graphs should be the same", sameGraph(g1, g2));
+               Graph g3 = graphMaker.createGraph(name);
+               assertTrue("graphs should be the same", sameGraph(g1, g3));
+       }
+
+       /**
+        * Test that we cannot open a graph that does not exist.
+        */
+       @ContractTest
+       public void testCannotOpenUncreated() {
+               String name = jName("noSuchGraph");
+               try {
+                       graphMaker.openGraph(name, true);
+                       fail(name + " should not exist");
+               } catch (DoesNotExistException e) {
+               }
+       }
+
+       /**
+        * Test that we *can* open a graph that hasn't been created
+        */
+       @ContractTest
+       public void testCanOpenUncreated() {
+               String name = jName("willBeCreated");
+               Graph g1 = graphMaker.openGraph(name);
+               g1.close();
+               graphMaker.openGraph(name, true);
+       }
+
+       /**
+        * Utility - test that a graph with the given name exists.
+        */
+       private void testExists(String name) {
+               assertTrue(name + " should exist", graphMaker.hasGraph(name));
+       }
+
+       /**
+        * Utility - test that no graph with the given name exists.
+        */
+       private void testDoesNotExist(String name) {
+               assertFalse(name + " should exist", graphMaker.hasGraph(name));
+       }
+
+       /**
+        * Test that we can find a graph once its been created. We need to know 
if
+        * two graphs are "the same" here: we have a temporary work-around but 
it is
+        * not sound.
+        * 
+        */
+       @ContractTest
+       public void testCanFindCreatedGraph() {
+               String alpha = jName("alpha"), beta = jName("beta");
+               Graph g1 = graphMaker.createGraph(alpha, true);
+               Graph h1 = graphMaker.createGraph(beta, true);
+               Graph g2 = graphMaker.openGraph(alpha, true);
+               Graph h2 = graphMaker.openGraph(beta, true);
+               assertTrue("should find alpha", sameGraph(g1, g2));
+               assertTrue("should find beta", sameGraph(h1, h2));
+       }
+
+       /**
+        * Weak test for "same graph": adding this to one is visible in t'other.
+        * Stopgap for use in testCanFindCreatedGraph. TODO: clean that test up
+        * (left over from RDB days)
+        */
+       private boolean sameGraph(Graph g1, Graph g2) {
+               Node S = GraphHelper.node("S"), P = GraphHelper.node("P"), O = 
GraphHelper
+                               .node("O");
+               g1.add(Triple.create(S, P, O));
+               g2.add(Triple.create(O, P, S));
+               return g2.contains(S, P, O) && g1.contains(O, P, S);
+       }
+
+       /**
+        * Test that we can remove a graph from the factory without disturbing
+        * another graph's binding.
+        */
+       @ContractTest
+       public void testCanRemoveGraph() {
+               String alpha = jName("bingo"), beta = jName("brillo");
+               graphMaker.createGraph(alpha, true);
+               graphMaker.createGraph(beta, true);
+               testExists(alpha);
+               testExists(beta);
+               graphMaker.removeGraph(alpha);
+               testExists(beta);
+               testDoesNotExist(alpha);
+       }
+
+       @ContractTest
+       public void testHasnt() {
+               assertFalse("no such graph", graphMaker.hasGraph("john"));
+               assertFalse("no such graph", graphMaker.hasGraph("paul"));
+               assertFalse("no such graph", graphMaker.hasGraph("george"));
+               /* */
+               graphMaker.createGraph("john", true);
+               assertTrue("john now exists", graphMaker.hasGraph("john"));
+               assertFalse("no such graph", graphMaker.hasGraph("paul"));
+               assertFalse("no such graph", graphMaker.hasGraph("george"));
+               /* */
+               graphMaker.createGraph("paul", true);
+               assertTrue("john still exists", graphMaker.hasGraph("john"));
+               assertTrue("paul now exists", graphMaker.hasGraph("paul"));
+               assertFalse("no such graph", graphMaker.hasGraph("george"));
+               /* */
+               graphMaker.removeGraph("john");
+               assertFalse("john has been removed", 
graphMaker.hasGraph("john"));
+               assertTrue("paul still exists", graphMaker.hasGraph("paul"));
+               assertFalse("no such graph", graphMaker.hasGraph("george"));
+       }
+
+       @ContractTest
+       public void testCarefulClose() {
+               Graph x = graphMaker.createGraph("x");
+               Graph y = graphMaker.openGraph("x");
+               x.add(GraphHelper.triple("a BB c"));
+               x.close();
+               y.add(GraphHelper.triple("p RR q"));
+               y.close();
+       }
+
+       /**
+        * Test that a maker with no graphs lists no names.
+        */
+       @ContractTest
+       public void testListNoGraphs() {
+               Set<String> s = graphMaker.listGraphs().toSet();
+               if (s.size() > 0)
+                       fail("found names from 'empty' graph maker: " + s);
+       }
+
+       /**
+        * Test that a maker with three graphs inserted lists those three 
grapsh; we
+        * don't mind what order they appear in. We also use funny names to 
ensure
+        * that the spelling that goes in is the one that comes out [should 
really
+        * be in a separate test].
+        */
+       @ContractTest
+       public void testListThreeGraphs() {
+               String x = "x", y = "y/sub", z = "z:boo";
+               Graph X = graphMaker.createGraph(x);
+               Graph Y = graphMaker.createGraph(y);
+               Graph Z = graphMaker.createGraph(z);
+               Set<String> wanted = TestUtils.setOfStrings(x + " " + y + " " + 
z);
+               assertEquals(wanted, 
GraphHelper.iteratorToSet(graphMaker.listGraphs()));
+               X.close();
+               Y.close();
+               Z.close();
+       }
+
+       /**
+        * Test that a maker with some things put in and then some removed gets 
the
+        * right things listed.
+        */
+       @ContractTest
+       public void testListAfterDelete() {
+               String x = "x_y", y = "y//zub", z = "a:b/c";
+               Graph X = graphMaker.createGraph(x);
+               Graph Y = graphMaker.createGraph(y);
+               Graph Z = graphMaker.createGraph(z);
+               graphMaker.removeGraph(x);
+               Set<String> s = 
GraphHelper.iteratorToSet(graphMaker.listGraphs());
+               assertEquals(TestUtils.setOfStrings(y + " " + z), s);
+               X.close();
+               Y.close();
+               Z.close();
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/src/test/java/org/apache/jena/graph/GraphWithPerformContractTest.java
----------------------------------------------------------------------
diff --git 
a/jena-core/src/test/java/org/apache/jena/graph/GraphWithPerformContractTest.java
 
b/jena-core/src/test/java/org/apache/jena/graph/GraphWithPerformContractTest.java
new file mode 100644
index 0000000..aaaa85a
--- /dev/null
+++ 
b/jena-core/src/test/java/org/apache/jena/graph/GraphWithPerformContractTest.java
@@ -0,0 +1,86 @@
+package org.apache.jena.graph;
+
+import static org.apache.jena.testing_framework.GraphHelper.graphWith;
+import static org.apache.jena.testing_framework.GraphHelper.triple;
+import static org.apache.jena.testing_framework.GraphHelper.txnBegin;
+import static org.apache.jena.testing_framework.GraphHelper.txnCommit;
+
+import static org.junit.Assert.*;
+
+import org.junit.After;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xenei.junit.contract.Contract;
+import org.xenei.junit.contract.ContractTest;
+
+import org.apache.jena.graph.impl.GraphWithPerform;
+import org.apache.jena.mem.GraphMem;
+import org.apache.jena.testing_framework.ContractTemplate;
+
+import org.xenei.junit.contract.IProducer;
+
+/**
+ * GraphWithPerform is an implementation interface that extends Graph with the
+ * performAdd and performDelete methods used by GraphBase to invoke
+ * non-notifying versions of add and delete.
+ */
+@Contract(GraphWithPerform.class)
+public class GraphWithPerformContractTest<T extends GraphWithPerform> extends
+               ContractTemplate<IProducer<T>> {
+       // Recording listener for tests
+       protected RecordingGraphListener GL = new RecordingGraphListener();
+
+       private static final Logger LOG = LoggerFactory
+                       .getLogger(GraphWithPerformContractTest.class);
+
+       @SuppressWarnings("unchecked")
+       public GraphWithPerformContractTest() {
+//             setProducer((IProducer<T>) new IProducer<GraphWithPerform>() {
+//
+//                     @Override
+//                     public GraphWithPerform newInstance() {
+//                             return new GraphMem();
+//                     }
+//
+//                     @Override
+//                     public void cleanUp() {
+//
+//                     }
+//             });
+       }
+
+       @Contract.Inject
+       public void setGraphWithPerformContractTestProducer(IProducer<T> 
producer) {
+               super.setProducer(producer);
+       }
+
+       @After
+       public final void afterGraphWithPerformContractTest() {
+               getProducer().cleanUp();
+       }
+
+       @ContractTest
+       public void testPerformAdd_Triple() {
+               GraphWithPerform g = (GraphWithPerform) graphWith(getProducer()
+                               .newInstance(), "S P O; S2 P2 O2");
+               g.getEventManager().register(GL);
+               txnBegin(g);
+               g.performAdd(triple("S3 P3 O3"));
+               txnCommit(g);
+               GL.assertEmpty();
+               assertTrue(g.contains(triple("S3 P3 O3")));
+       }
+
+       @ContractTest
+       public void testPerformDelete_Triple() {
+               GraphWithPerform g = (GraphWithPerform) graphWith(getProducer()
+                               .newInstance(), "S P O; S2 P2 O2");
+               g.getEventManager().register(GL);
+               txnBegin(g);
+               g.performDelete(triple("S2 P2 O2"));
+               txnCommit(g);
+               GL.assertEmpty();
+               assertFalse(g.contains(triple("S2 P2 O2")));
+       }
+
+}

Reply via email to