You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commonsrdf.apache.org by wi...@apache.org on 2015/03/27 19:44:44 UTC

[2/7] incubator-commonsrdf git commit: COMMONSRDF-2: refactorized api java packages

http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/blob/fa5321e4/api/src/test/java/com/github/commonsrdf/api/AbstractGraphTest.java
----------------------------------------------------------------------
diff --git a/api/src/test/java/com/github/commonsrdf/api/AbstractGraphTest.java b/api/src/test/java/com/github/commonsrdf/api/AbstractGraphTest.java
deleted file mode 100644
index be7dfe4..0000000
--- a/api/src/test/java/com/github/commonsrdf/api/AbstractGraphTest.java
+++ /dev/null
@@ -1,275 +0,0 @@
-/**
- * Licensed 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 com.github.commonsrdf.api;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import java.util.Optional;
-
-import org.junit.Assume;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Test Graph implementation
- * <p>
- * To add to your implementation's tests, create a subclass with a name ending
- * in <code>Test</code> and provide {@link #createFactory()} which minimally
- * must support {@link RDFTermFactory#createGraph()} and
- * {@link RDFTermFactory#createIRI(String)}, but ideally support all operations.
- *
- * @see Graph
- * @see RDFTermFactory
- * @see com.github.commonsrdf.simple.SimpleGraphTest
- */
-public abstract class AbstractGraphTest {
-
-	private RDFTermFactory factory;
-	private Graph graph;
-	private IRI alice;
-	private IRI bob;
-	private IRI name;
-	private IRI knows;
-	private IRI member;
-	private BlankNode org1;
-	private BlankNode org2;
-	private Literal aliceName;
-	private Literal bobName;
-	private Literal secretClubName;
-	private Literal companyName;
-	private Triple bobNameTriple;
-
-	public abstract RDFTermFactory createFactory();
-
-	@Before
-	public void createGraphAndAdd() {
-		factory = createFactory();
-		graph = factory.createGraph();
-		assertEquals(0, graph.size());
-
-		alice = factory.createIRI("http://example.com/alice");
-		bob = factory.createIRI("http://example.com/bob");
-		name = factory.createIRI("http://xmlns.com/foaf/0.1/name");
-		knows = factory.createIRI("http://xmlns.com/foaf/0.1/knows");
-		member = factory.createIRI("http://xmlns.com/foaf/0.1/member");
-		try {
-			org1 = factory.createBlankNode("org1");
-			org2 = factory.createBlankNode("org2");
-		} catch (UnsupportedOperationException ex) {
-			// leave as null
-		}
-
-		try {
-			secretClubName = factory.createLiteral("The Secret Club");
-			companyName = factory.createLiteral("A company");
-			aliceName = factory.createLiteral("Alice");
-			bobName = factory.createLiteral("Bob", "en-US");
-		} catch (UnsupportedOperationException ex) {
-			// leave as null
-		}
-
-		if (aliceName != null) {
-			graph.add(alice, name, aliceName);
-		}
-		graph.add(alice, knows, bob);
-
-		if (org1 != null) {
-			graph.add(alice, member, org1);
-		}
-
-		if (bobName != null) {
-			try {
-				bobNameTriple = factory.createTriple(bob, name, bobName);
-			} catch (UnsupportedOperationException ex) {
-				// leave as null
-			}
-			if (bobNameTriple != null) {
-				graph.add(bobNameTriple);
-			}
-		}
-		if (org1 != null) {
-			graph.add(factory.createTriple(bob, member, org1));
-			graph.add(factory.createTriple(bob, member, org2));
-			if (secretClubName != null) {
-				graph.add(org1, name, secretClubName);
-				graph.add(org2, name, companyName);
-			}
-		}
-	}
-
-	@Test
-	public void graphToString() {
-		Assume.assumeNotNull(aliceName, companyName);
-		System.out.println(graph);
-		assertTrue(graph
-				.toString()
-				.startsWith(
-						"<http://example.com/alice> <http://xmlns.com/foaf/0.1/name> \"Alice\" ."));
-		assertTrue(graph.toString().endsWith(
-				"_:org2 <http://xmlns.com/foaf/0.1/name> \"A company\" ."));
-
-	}
-
-	@Test
-	public void size() throws Exception {
-		assertTrue(graph.size() > 0);
-		Assume.assumeNotNull(org1, org2, aliceName, bobName, secretClubName,
-				companyName, bobNameTriple);
-		// Can only reliably predict size if we could create all triples
-		assertEquals(8, graph.size());
-	}
-
-	@Test
-	public void contains() throws Exception {
-		assertFalse(graph.contains(bob, knows, alice)); // or so he claims..
-
-		assertTrue(graph.contains(alice, knows, bob));
-
-		Optional<? extends Triple> first = graph.getTriples().skip(4)
-				.findFirst();
-		Assume.assumeTrue(first.isPresent());
-		Triple existingTriple = first.get();
-		assertTrue(graph.contains(existingTriple));
-
-		Triple nonExistingTriple = factory.createTriple(bob, knows, alice);
-		assertFalse(graph.contains(nonExistingTriple));
-
-		Triple triple = null;
-		try {
-			triple = factory.createTriple(alice, knows, bob);
-		} catch (UnsupportedOperationException ex) {
-		}
-		if (triple != null) {
-			// FIXME: Should not this always be true?
-			// assertTrue(graph.contains(triple));
-		}
-	}
-
-	@Test
-	public void remove() throws Exception {
-		long fullSize = graph.size();
-		graph.remove(alice, knows, bob);
-		long shrunkSize = graph.size();
-		assertEquals(1, fullSize - shrunkSize);
-
-		graph.remove(alice, knows, bob);
-		assertEquals(shrunkSize, graph.size()); // unchanged
-
-		graph.add(alice, knows, bob);
-		graph.add(alice, knows, bob);
-		graph.add(alice, knows, bob);
-		// Undetermined size at this point -- but at least it
-		// should be bigger
-		assertTrue(graph.size() > shrunkSize);
-
-		// and after a single remove they should all be gone
-		graph.remove(alice, knows, bob);
-		assertEquals(shrunkSize, graph.size());
-
-		Optional<? extends Triple> anyTriple = graph.getTriples().findAny();
-		Assume.assumeTrue(anyTriple.isPresent());
-
-		Triple otherTriple = anyTriple.get();
-		graph.remove(otherTriple);
-		assertEquals(shrunkSize - 1, graph.size());
-		graph.remove(otherTriple);
-		assertEquals(shrunkSize - 1, graph.size()); // no change
-		graph.add(otherTriple);
-		assertEquals(shrunkSize, graph.size());
-	}
-
-	@Test
-	public void clear() throws Exception {
-		graph.clear();
-		assertFalse(graph.contains(alice, knows, bob));
-		assertEquals(0, graph.size());
-		graph.clear(); // no-op
-		assertEquals(0, graph.size());
-	}
-
-	@Test
-	public void getTriples() throws Exception {
-
-		long tripleCount = graph.getTriples().count();
-		assertTrue(tripleCount > 0);
-		assertTrue(graph.getTriples().allMatch(t -> graph.contains(t)));
-		// Check exact count
-		Assume.assumeNotNull(org1, org2, aliceName, bobName, secretClubName,
-				companyName, bobNameTriple);
-		assertEquals(8, tripleCount);
-	}
-
-	@Test
-	public void getTriplesQuery() throws Exception {
-
-		long aliceCount = graph.getTriples(alice, null, null).count();
-		assertTrue(aliceCount > 0);
-		Assume.assumeNotNull(aliceName);
-		assertEquals(3, aliceCount);
-
-		Assume.assumeNotNull(org1, org2, bobName, companyName, secretClubName);
-		assertEquals(4, graph.getTriples(null, name, null).count());
-		Assume.assumeNotNull(org1);
-		assertEquals(2, graph.getTriples(null, member, org1).count());
-	}
-
-	/**
-	 * An attempt to use the Java 8 streams to look up a more complicated query.
-	 * 
-	 * FYI, the equivalent SPARQL version (untested):
-	 * 
-	 * <pre>
-	 * 	SELECT ?orgName WHERE { 
-	 * 			?org foaf:name ?orgName .
-	 * 			?alice foaf:member ?org .
-	 * 			?bob foaf:member ?org .
-	 * 			?alice foaf:knows ?bob .
-	 * 		  FILTER NOT EXIST { ?bob foaf:knows ?alice }
-	 * 	}
-	 * </pre>
-	 * 
-	 * @throws Exception
-	 */
-	@Test
-	public void whyJavaStreamsMightNotTakeOverFromSparql() throws Exception {
-		Assume.assumeNotNull(org1, org2, secretClubName);
-		// Find a secret organizations
-		assertEquals(
-				"\"The Secret Club\"",
-				graph.getTriples(null, knows, null)
-						// Find One-way "knows"
-						.filter(t -> !graph.contains(
-								(BlankNodeOrIRI) t.getObject(), knows,
-								t.getSubject()))
-						.map(knowsTriple -> graph
-								// and those they know, what are they member of?
-								.getTriples(
-										(BlankNodeOrIRI) knowsTriple
-												.getObject(), member, null)
-								// keep those which first-guy is a member of
-								.filter(memberTriple -> graph.contains(
-										knowsTriple.getSubject(), member,
-										// First hit is good enough
-										memberTriple.getObject())).findFirst()
-								.get().getObject())
-						// then look up the name of that org
-						.map(org -> graph
-								.getTriples((BlankNodeOrIRI) org, name, null)
-								.findFirst().get().getObject().ntriplesString())
-						.findFirst().get());
-
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/blob/fa5321e4/api/src/test/java/com/github/commonsrdf/api/AbstractRDFTermFactoryTest.java
----------------------------------------------------------------------
diff --git a/api/src/test/java/com/github/commonsrdf/api/AbstractRDFTermFactoryTest.java b/api/src/test/java/com/github/commonsrdf/api/AbstractRDFTermFactoryTest.java
deleted file mode 100644
index 36b2cb8..0000000
--- a/api/src/test/java/com/github/commonsrdf/api/AbstractRDFTermFactoryTest.java
+++ /dev/null
@@ -1,401 +0,0 @@
-/**
- * Licensed 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 com.github.commonsrdf.api;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotSame;
-
-import org.junit.Assume;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Test RDFTermFactory implementation (and thus its RDFTerm implementations)
- * <p>
- * To add to your implementation's tests, create a subclass with a name ending
- * in <code>Test</code> and provide {@link #createFactory()} which minimally
- * supports one of the operations, but ideally supports all operations.
- * 
- * @see RDFTermFactory
- * @see com.github.commonsrdf.simple.SimpleRDFTermFactoryTest
- */
-public abstract class AbstractRDFTermFactoryTest {
-
-	private RDFTermFactory factory;
-
-	@Test
-	public void createBlankNode() throws Exception {
-		BlankNode bnode;
-		try {
-			bnode = factory.createBlankNode();
-		} catch (UnsupportedOperationException ex) {
-			Assume.assumeNoException(ex);
-			return;
-		}
-
-		BlankNode bnode2 = factory.createBlankNode();
-		assertNotEquals(
-				"Second blank node has not got a unique internal identifier",
-				bnode.internalIdentifier(), bnode2.internalIdentifier());
-	}
-
-	@Test
-	public void createBlankNodeIdentifierEmpty() throws Exception {
-		try {
-			factory.createBlankNode("");
-		} catch (UnsupportedOperationException e) {
-			Assume.assumeNoException(e);
-		} catch (IllegalArgumentException e) {
-			// Expected exception
-		}
-	}
-
-	@Test
-	public void createBlankNodeIdentifier() throws Exception {
-		BlankNode bnode;
-		try {
-			bnode = factory.createBlankNode("example1");
-		} catch (UnsupportedOperationException ex) {
-			Assume.assumeNoException(ex);
-			return;
-		}
-		assertEquals("example1", bnode.internalIdentifier());
-		// .. but we can't assume the internal identifier leaks into
-		// ntriplesString
-		// assertEquals("_:example1", bnode.ntriplesString());
-	}
-
-	@Test
-	public void createBlankNodeIdentifierTwice() throws Exception {
-		BlankNode bnode1, bnode2, bnode3;
-		try {
-			bnode1 = factory.createBlankNode("example1");
-			bnode2 = factory.createBlankNode("example1");
-			bnode3 = factory.createBlankNode("differ");
-		} catch (UnsupportedOperationException ex) {
-			Assume.assumeNoException(ex);
-			return;
-		}
-		assertEquals(bnode1.internalIdentifier(), bnode2.internalIdentifier());
-		// We don't know what the ntriplesString is, but it MUST be the same
-		assertEquals(bnode1.ntriplesString(), bnode2.ntriplesString());
-		// and here it MUST differ
-		assertNotEquals(bnode1.ntriplesString(), bnode3.ntriplesString());
-	}
-
-	public abstract RDFTermFactory createFactory();
-
-	@Test
-	public void createGraph() {
-		Graph graph;
-		try {
-			graph = factory.createGraph();
-		} catch (UnsupportedOperationException ex) {
-			Assume.assumeNoException(ex);
-			return;
-		}
-
-		assertEquals("Graph was not empty", 0, graph.size());
-		graph.add(factory.createBlankNode(),
-				factory.createIRI("http://example.com/"),
-				factory.createBlankNode());
-
-		Graph graph2 = factory.createGraph();
-		assertNotSame(graph, graph2);
-		assertEquals("Graph was empty after adding", 1, graph.size());
-		assertEquals("New graph was not empty", 0, graph2.size());
-	}
-
-	@Test
-	public void createIRI() throws Exception {
-		IRI example;
-		try {
-			example = factory.createIRI("http://example.com/");
-		} catch (UnsupportedOperationException ex) {
-			Assume.assumeNoException("createIRI not supported", ex);
-			return;
-		}
-
-		assertEquals("http://example.com/", example.getIRIString());
-		assertEquals("<http://example.com/>", example.ntriplesString());
-
-		IRI term = factory.createIRI("http://example.com/vocab#term");
-		assertEquals("http://example.com/vocab#term", term.getIRIString());
-		assertEquals("<http://example.com/vocab#term>", term.ntriplesString());
-
-		// and now for the international fun!
-
-		IRI latin1 = factory.createIRI("http://accént.example.com/première");
-		assertEquals("http://accént.example.com/première",
-				latin1.getIRIString());
-		assertEquals("<http://accént.example.com/première>",
-				latin1.ntriplesString());
-
-		IRI cyrillic = factory.createIRI("http://example.испытание/Кириллица");
-		assertEquals("http://example.испытание/Кириллица",
-				cyrillic.getIRIString());
-		assertEquals("<http://example.испытание/Кириллица>",
-				cyrillic.ntriplesString());
-
-		IRI deseret = factory.createIRI("http://𐐀.example.com/𐐀");
-		assertEquals("http://𐐀.example.com/𐐀", deseret.getIRIString());
-		assertEquals("<http://𐐀.example.com/𐐀>", deseret.ntriplesString());
-	}
-
-	@Test
-	public void createIRIRelative() throws Exception {
-		// Although relative IRIs are defined in
-		// http://www.w3.org/TR/rdf11-concepts/#section-IRIs
-		// it is not a requirement for an implementation to support
-		// it (all instances of an relative IRI should eventually
-		// be possible to resolve to an absolute IRI)
-		try {
-			factory.createIRI("../relative");
-		} catch (UnsupportedOperationException | IllegalArgumentException ex) {
-			Assume.assumeNoException(ex);
-			return;
-		}
-		IRI relative = factory.createIRI("../relative");
-		assertEquals("../relative", relative.getIRIString());
-		assertEquals("<../relative>", relative.ntriplesString());
-
-		IRI relativeTerm = factory.createIRI("../relative#term");
-		assertEquals("../relative#term", relativeTerm.getIRIString());
-		assertEquals("<../relative#term>", relativeTerm.ntriplesString());
-
-		IRI emptyRelative = factory.createIRI(""); // <> equals the base URI
-		assertEquals("", emptyRelative.getIRIString());
-		assertEquals("<>", emptyRelative.ntriplesString());
-	}
-
-	@Test
-	public void createLiteral() throws Exception {
-		Literal example;
-		try {
-			example = factory.createLiteral("Example");
-		} catch (UnsupportedOperationException ex) {
-			Assume.assumeNoException(ex);
-			return;
-		}
-
-		assertEquals("Example", example.getLexicalForm());
-		assertFalse(example.getLanguageTag().isPresent());
-		assertEquals("http://www.w3.org/2001/XMLSchema#string", example
-				.getDatatype().getIRIString());
-		// http://lists.w3.org/Archives/Public/public-rdf-comments/2014Dec/0004.html
-		assertEquals("\"Example\"", example.ntriplesString());
-	}
-
-	@Test
-	public void createLiteralDateTime() throws Exception {
-		Literal dateTime;
-		try {
-			dateTime = factory
-					.createLiteral(
-							"2014-12-27T00:50:00T-0600",
-							factory.createIRI("http://www.w3.org/2001/XMLSchema#dateTime"));
-		} catch (UnsupportedOperationException ex) {
-			Assume.assumeNoException(ex);
-			return;
-		}
-		assertEquals("2014-12-27T00:50:00T-0600", dateTime.getLexicalForm());
-		assertFalse(dateTime.getLanguageTag().isPresent());
-		assertEquals("http://www.w3.org/2001/XMLSchema#dateTime", dateTime
-				.getDatatype().getIRIString());
-		assertEquals(
-				"\"2014-12-27T00:50:00T-0600\"^^<http://www.w3.org/2001/XMLSchema#dateTime>",
-				dateTime.ntriplesString());
-	}
-
-	@Test
-	public void createLiteralLang() throws Exception {
-		Literal example;
-		try {
-			example = factory.createLiteral("Example", "en");
-		} catch (UnsupportedOperationException ex) {
-			Assume.assumeNoException(ex);
-			return;
-		}
-
-		assertEquals("Example", example.getLexicalForm());
-		assertEquals("en", example.getLanguageTag().get());
-		assertEquals("http://www.w3.org/1999/02/22-rdf-syntax-ns#langString",
-				example.getDatatype().getIRIString());
-		assertEquals("\"Example\"@en", example.ntriplesString());
-	}
-
-	@Test
-	public void createLiteralLangISO693_3() throws Exception {
-		// see https://issues.apache.org/jira/browse/JENA-827
-		Literal vls;
-		try {
-			vls = factory.createLiteral("Herbert Van de Sompel", "vls"); // JENA-827
-																			// reference
-		} catch (UnsupportedOperationException ex) {
-			Assume.assumeNoException(ex);
-			return;
-		}
-
-		assertEquals("vls", vls.getLanguageTag().get());
-		assertEquals("http://www.w3.org/1999/02/22-rdf-syntax-ns#langString",
-				vls.getDatatype().getIRIString());
-		assertEquals("\"Herbert Van de Sompel\"@vls", vls.ntriplesString());
-	}
-
-	@Test
-	public void createLiteralString() throws Exception {
-		Literal example;
-		try {
-			example = factory.createLiteral("Example", factory
-					.createIRI("http://www.w3.org/2001/XMLSchema#string"));
-		} catch (UnsupportedOperationException ex) {
-			Assume.assumeNoException(ex);
-			return;
-		}
-		assertEquals("Example", example.getLexicalForm());
-		assertFalse(example.getLanguageTag().isPresent());
-		assertEquals("http://www.w3.org/2001/XMLSchema#string", example
-				.getDatatype().getIRIString());
-		// http://lists.w3.org/Archives/Public/public-rdf-comments/2014Dec/0004.html
-		assertEquals("\"Example\"", example.ntriplesString());
-	}
-
-	@Test
-	public void createTripleBnodeBnode() {
-		BlankNode subject;
-		IRI predicate;
-		BlankNode object;
-		Triple triple;
-		try {
-			subject = factory.createBlankNode("b1");
-			predicate = factory.createIRI("http://example.com/pred");
-			object = factory.createBlankNode("b2");
-			triple = factory.createTriple(subject, predicate, object);
-		} catch (UnsupportedOperationException ex) {
-			Assume.assumeNoException(ex);
-			return;
-		}
-
-		// bnode equivalence should be OK as we used the same
-		// factory and have not yet inserted Triple into a Graph
-		assertEquals(subject, triple.getSubject());
-		assertEquals(predicate, triple.getPredicate());
-		assertEquals(object, triple.getObject());
-	}
-
-	@Test
-	public void createTripleBnodeIRI() {
-		BlankNode subject;
-		IRI predicate;
-		IRI object;
-		Triple triple;
-		try {
-			subject = factory.createBlankNode("b1");
-			predicate = factory.createIRI("http://example.com/pred");
-			object = factory.createIRI("http://example.com/obj");
-			triple = factory.createTriple(subject, predicate, object);
-		} catch (UnsupportedOperationException ex) {
-			Assume.assumeNoException(ex);
-			return;
-		}
-
-		// bnode equivalence should be OK as we used the same
-		// factory and have not yet inserted Triple into a Graph
-		assertEquals(subject, triple.getSubject());
-		assertEquals(predicate, triple.getPredicate());
-		assertEquals(object, triple.getObject());
-	}
-
-	@Test
-	public void createTripleBnodeTriple() {
-		BlankNode subject;
-		IRI predicate;
-		Literal object;
-		Triple triple;
-		try {
-			subject = factory.createBlankNode();
-			predicate = factory.createIRI("http://example.com/pred");
-			object = factory.createLiteral("Example", "en");
-			triple = factory.createTriple(subject, predicate, object);
-		} catch (UnsupportedOperationException ex) {
-			Assume.assumeNoException(ex);
-			return;
-		}
-
-		// bnode equivalence should be OK as we used the same
-		// factory and have not yet inserted Triple into a Graph
-		assertEquals(subject, triple.getSubject());
-		assertEquals(predicate, triple.getPredicate());
-		assertEquals(object, triple.getObject());
-	}
-
-	@Before
-	public void getFactory() {
-		factory = createFactory();
-	}
-
-	@Test
-	public void possiblyInvalidBlankNode() throws Exception {
-		BlankNode withColon;
-		try {
-			withColon = factory.createBlankNode("with:colon");
-		} catch (UnsupportedOperationException ex) {
-			Assume.assumeNoException("createBlankNode(String) not supported",
-					ex);
-			return;
-		} catch (IllegalArgumentException ex) {
-			// Good!
-			return;
-		}
-		// Factory allows :colon, which is OK as long as it's not causing an
-		// invalid ntriplesString
-		assertFalse(withColon.ntriplesString().contains("with:colon"));
-
-		// and creating it twice gets the same ntriplesString
-		assertEquals(withColon.ntriplesString(),
-				factory.createBlankNode("with:colon").ntriplesString());
-	}
-
-	@Test(expected = IllegalArgumentException.class)
-	public void invalidIRI() throws Exception {
-		try {
-			factory.createIRI("<no_brackets>");
-		} catch (UnsupportedOperationException ex) {
-			Assume.assumeNoException("createIRI not supported", ex);
-			return;
-		}
-	}
-
-	@Test(expected = IllegalArgumentException.class)
-	public void invalidLiteralLang() throws Exception {
-		try {
-			factory.createLiteral("Example", "with space");
-		} catch (UnsupportedOperationException ex) {
-			Assume.assumeNoException(
-					"createLiteral(String,String) not supported", ex);
-			return;
-		}
-	}
-
-	@Test(expected = Exception.class)
-	public void invalidTriplePredicate() {
-		BlankNode subject = factory.createBlankNode("b1");
-		BlankNode predicate = factory.createBlankNode("b2");
-		BlankNode object = factory.createBlankNode("b3");
-		factory.createTriple(subject, (IRI) predicate, object);
-	}
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/blob/fa5321e4/api/src/test/java/com/github/commonsrdf/api/DefaultRDFTermFactoryTest.java
----------------------------------------------------------------------
diff --git a/api/src/test/java/com/github/commonsrdf/api/DefaultRDFTermFactoryTest.java b/api/src/test/java/com/github/commonsrdf/api/DefaultRDFTermFactoryTest.java
deleted file mode 100644
index e314968..0000000
--- a/api/src/test/java/com/github/commonsrdf/api/DefaultRDFTermFactoryTest.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- * Licensed 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 com.github.commonsrdf.api;
-
-import com.github.commonsrdf.api.RDFTermFactory;
-
-/**
- * The default RDFTermFactory might be useless (every method throws
- * UnsupportedOperationException), but this test ensures that
- * AbstractRDFTermFactoryTest does not fall over on unsupported operations.
- *
- */
-public class DefaultRDFTermFactoryTest extends AbstractRDFTermFactoryTest {
-
-	@Override
-	public RDFTermFactory createFactory() {
-		return new RDFTermFactory() {
-		};
-	}
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/blob/fa5321e4/api/src/test/java/org/apache/commons/rdf/api/AbstractBlankNodeTest.java
----------------------------------------------------------------------
diff --git a/api/src/test/java/org/apache/commons/rdf/api/AbstractBlankNodeTest.java b/api/src/test/java/org/apache/commons/rdf/api/AbstractBlankNodeTest.java
new file mode 100644
index 0000000..2377d89
--- /dev/null
+++ b/api/src/test/java/org/apache/commons/rdf/api/AbstractBlankNodeTest.java
@@ -0,0 +1,222 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.rdf.api;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+/**
+ * Abstract test class for the BlankNode interface.
+ * 
+ * @author Peter Ansell p_ansell@yahoo.com
+ */
+public abstract class AbstractBlankNodeTest {
+
+	protected abstract BlankNode getBlankNode();
+
+	/**
+	 * Gets a new blank node object based on the given identifier.
+	 * <p>
+	 * Subsequent calls to this method during a single test with the same
+	 * identifier must return BlankNode objects that are equals and have the
+	 * same hashCode. The objects returned from successive calls during a single
+	 * test may be the same object, or they may be different objects.
+	 * </p>
+	 * 
+	 * @param identifier
+	 *            The identifier to use as the reference for creating the blank
+	 *            node that is returned.
+	 * @return A new blank node based on the
+	 */
+	protected abstract BlankNode getBlankNode(String identifier);
+
+	/**
+	 * Test method for
+	 * {@link BlankNode#internalIdentifier()}.
+	 */
+	@Test
+	public final void testInternalIdentifier() {
+		BlankNode testNull = new BlankNode() {
+			@Override
+			public String ntriplesString() {
+				return null;
+			}
+
+			@Override
+			public String internalIdentifier() {
+				return null;
+			}
+		};
+		BlankNode testAutomatic1 = getBlankNode();
+		BlankNode testAutomatic2 = getBlankNode();
+		BlankNode testManual3a = getBlankNode("3");
+		BlankNode testManual3b = getBlankNode("3");
+		BlankNode testManual4 = getBlankNode("4");
+
+		// Test against our fake stub
+		assertNotEquals(testNull.internalIdentifier(),
+				testAutomatic1.internalIdentifier());
+		assertNotEquals(testAutomatic1.internalIdentifier(),
+				testNull.internalIdentifier());
+		assertNotEquals(testNull.internalIdentifier(),
+				testManual3a.internalIdentifier());
+		assertNotEquals(testManual3a.internalIdentifier(),
+				testNull.internalIdentifier());
+
+		// Test the two imported instances against each other
+		assertEquals(testAutomatic1.internalIdentifier(),
+				testAutomatic1.internalIdentifier());
+		assertEquals(testAutomatic2.internalIdentifier(),
+				testAutomatic2.internalIdentifier());
+		assertNotEquals(testAutomatic1.internalIdentifier(),
+				testAutomatic2.internalIdentifier());
+		assertNotEquals(testAutomatic2.internalIdentifier(),
+				testAutomatic1.internalIdentifier());
+		assertNotEquals(testAutomatic1.internalIdentifier(),
+				testManual3a.internalIdentifier());
+		assertEquals(testManual3b.internalIdentifier(),
+				testManual3a.internalIdentifier());
+		assertNotEquals(testManual3a.internalIdentifier(),
+				testManual4.internalIdentifier());
+	}
+
+	/**
+	 * Test method for
+	 * {@link BlankNode#equals(java.lang.Object)}.
+	 */
+	@Test
+	public final void testEquals() {
+		BlankNode testNull = new BlankNode() {
+			@Override
+			public String ntriplesString() {
+				return null;
+			}
+
+			@Override
+			public String internalIdentifier() {
+				return null;
+			}
+		};
+		BlankNode testAutomatic1 = getBlankNode();
+		BlankNode testAutomatic2 = getBlankNode();
+		BlankNode testManual3a = getBlankNode("3");
+		BlankNode testManual3b = getBlankNode("3");
+		BlankNode testManual4 = getBlankNode("4");
+
+		// Test against our fake stub
+		assertNotEquals(testNull, testAutomatic1);
+		assertNotEquals(testAutomatic1, testNull);
+		assertNotEquals(testNull, testManual3a);
+		assertNotEquals(testManual3a, testNull);
+
+		// Test the two imported instances against each other
+		assertEquals(testAutomatic1, testAutomatic1);
+		assertEquals(testAutomatic2, testAutomatic2);
+		assertNotEquals(testAutomatic1, testAutomatic2);
+		assertNotEquals(testAutomatic2, testAutomatic1);
+		assertNotEquals(testAutomatic1, testManual3a);
+		assertEquals(testManual3b, testManual3a);
+		assertNotEquals(testManual3a, testManual4);
+	}
+
+	/**
+	 * Test method for {@link BlankNode#hashCode()}.
+	 */
+	@Test
+	public final void testHashCode() {
+		BlankNode testNull = new BlankNode() {
+			@Override
+			public String ntriplesString() {
+				return null;
+			}
+
+			@Override
+			public String internalIdentifier() {
+				return null;
+			}
+		};
+		BlankNode testAutomatic1 = getBlankNode();
+		BlankNode testAutomatic2 = getBlankNode();
+		BlankNode testManual3a = getBlankNode("3");
+		BlankNode testManual3b = getBlankNode("3");
+		BlankNode testManual4 = getBlankNode("4");
+
+		// Test against our fake stub
+		assertNotEquals(testNull.hashCode(), testAutomatic1.hashCode());
+		assertNotEquals(testAutomatic1.hashCode(), testNull.hashCode());
+		assertNotEquals(testNull.hashCode(), testManual3a.hashCode());
+		assertNotEquals(testManual3a.hashCode(), testNull.hashCode());
+
+		// Test the two imported instances against each other
+		assertEquals(testAutomatic1.hashCode(), testAutomatic1.hashCode());
+		assertEquals(testAutomatic2.hashCode(), testAutomatic2.hashCode());
+		assertNotEquals(testAutomatic1.hashCode(), testAutomatic2.hashCode());
+		assertNotEquals(testAutomatic2.hashCode(), testAutomatic1.hashCode());
+		assertNotEquals(testAutomatic1.hashCode(), testManual3a.hashCode());
+		assertEquals(testManual3b.hashCode(), testManual3a.hashCode());
+		assertNotEquals(testManual3a.hashCode(), testManual4.hashCode());
+	}
+
+	/**
+	 * Test method for
+	 * {@link RDFTerm#ntriplesString()}.
+	 */
+	@Test
+	public final void testNtriplesString() {
+		BlankNode testNull = new BlankNode() {
+			@Override
+			public String ntriplesString() {
+				return null;
+			}
+
+			@Override
+			public String internalIdentifier() {
+				return null;
+			}
+		};
+		BlankNode testAutomatic1 = getBlankNode();
+		BlankNode testAutomatic2 = getBlankNode();
+		BlankNode testManual3a = getBlankNode("3");
+		BlankNode testManual3b = getBlankNode("3");
+		BlankNode testManual4 = getBlankNode("4");
+
+		// Test against our fake stub
+		assertNotEquals(testNull.ntriplesString(),
+				testAutomatic1.ntriplesString());
+		assertNotEquals(testAutomatic1.ntriplesString(),
+				testNull.ntriplesString());
+		assertNotEquals(testNull.ntriplesString(),
+				testManual3a.ntriplesString());
+		assertNotEquals(testManual3a.ntriplesString(),
+				testNull.ntriplesString());
+
+		// Test the two imported instances against each other
+		assertEquals(testAutomatic1.ntriplesString(),
+				testAutomatic1.ntriplesString());
+		assertEquals(testAutomatic2.ntriplesString(),
+				testAutomatic2.ntriplesString());
+		assertNotEquals(testAutomatic1.ntriplesString(),
+				testAutomatic2.ntriplesString());
+		assertNotEquals(testAutomatic2.ntriplesString(),
+				testAutomatic1.ntriplesString());
+		assertNotEquals(testAutomatic1.ntriplesString(),
+				testManual3a.ntriplesString());
+		assertEquals(testManual3b.ntriplesString(),
+				testManual3a.ntriplesString());
+		assertNotEquals(testManual3a.ntriplesString(),
+				testManual4.ntriplesString());
+	}
+
+}

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

http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/blob/fa5321e4/api/src/test/java/org/apache/commons/rdf/api/AbstractRDFTermFactoryTest.java
----------------------------------------------------------------------
diff --git a/api/src/test/java/org/apache/commons/rdf/api/AbstractRDFTermFactoryTest.java b/api/src/test/java/org/apache/commons/rdf/api/AbstractRDFTermFactoryTest.java
new file mode 100644
index 0000000..7e1d545
--- /dev/null
+++ b/api/src/test/java/org/apache/commons/rdf/api/AbstractRDFTermFactoryTest.java
@@ -0,0 +1,401 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.rdf.api;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotSame;
+
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Test RDFTermFactory implementation (and thus its RDFTerm implementations)
+ * <p>
+ * To add to your implementation's tests, create a subclass with a name ending
+ * in <code>Test</code> and provide {@link #createFactory()} which minimally
+ * supports one of the operations, but ideally supports all operations.
+ * 
+ * @see RDFTermFactory
+ * @see com.github.commonsrdf.simple.SimpleRDFTermFactoryTest
+ */
+public abstract class AbstractRDFTermFactoryTest {
+
+	private RDFTermFactory factory;
+
+	@Test
+	public void createBlankNode() throws Exception {
+		BlankNode bnode;
+		try {
+			bnode = factory.createBlankNode();
+		} catch (UnsupportedOperationException ex) {
+			Assume.assumeNoException(ex);
+			return;
+		}
+
+		BlankNode bnode2 = factory.createBlankNode();
+		assertNotEquals(
+				"Second blank node has not got a unique internal identifier",
+				bnode.internalIdentifier(), bnode2.internalIdentifier());
+	}
+
+	@Test
+	public void createBlankNodeIdentifierEmpty() throws Exception {
+		try {
+			factory.createBlankNode("");
+		} catch (UnsupportedOperationException e) {
+			Assume.assumeNoException(e);
+		} catch (IllegalArgumentException e) {
+			// Expected exception
+		}
+	}
+
+	@Test
+	public void createBlankNodeIdentifier() throws Exception {
+		BlankNode bnode;
+		try {
+			bnode = factory.createBlankNode("example1");
+		} catch (UnsupportedOperationException ex) {
+			Assume.assumeNoException(ex);
+			return;
+		}
+		assertEquals("example1", bnode.internalIdentifier());
+		// .. but we can't assume the internal identifier leaks into
+		// ntriplesString
+		// assertEquals("_:example1", bnode.ntriplesString());
+	}
+
+	@Test
+	public void createBlankNodeIdentifierTwice() throws Exception {
+		BlankNode bnode1, bnode2, bnode3;
+		try {
+			bnode1 = factory.createBlankNode("example1");
+			bnode2 = factory.createBlankNode("example1");
+			bnode3 = factory.createBlankNode("differ");
+		} catch (UnsupportedOperationException ex) {
+			Assume.assumeNoException(ex);
+			return;
+		}
+		assertEquals(bnode1.internalIdentifier(), bnode2.internalIdentifier());
+		// We don't know what the ntriplesString is, but it MUST be the same
+		assertEquals(bnode1.ntriplesString(), bnode2.ntriplesString());
+		// and here it MUST differ
+		assertNotEquals(bnode1.ntriplesString(), bnode3.ntriplesString());
+	}
+
+	public abstract RDFTermFactory createFactory();
+
+	@Test
+	public void createGraph() {
+		Graph graph;
+		try {
+			graph = factory.createGraph();
+		} catch (UnsupportedOperationException ex) {
+			Assume.assumeNoException(ex);
+			return;
+		}
+
+		assertEquals("Graph was not empty", 0, graph.size());
+		graph.add(factory.createBlankNode(),
+				factory.createIRI("http://example.com/"),
+				factory.createBlankNode());
+
+		Graph graph2 = factory.createGraph();
+		assertNotSame(graph, graph2);
+		assertEquals("Graph was empty after adding", 1, graph.size());
+		assertEquals("New graph was not empty", 0, graph2.size());
+	}
+
+	@Test
+	public void createIRI() throws Exception {
+		IRI example;
+		try {
+			example = factory.createIRI("http://example.com/");
+		} catch (UnsupportedOperationException ex) {
+			Assume.assumeNoException("createIRI not supported", ex);
+			return;
+		}
+
+		assertEquals("http://example.com/", example.getIRIString());
+		assertEquals("<http://example.com/>", example.ntriplesString());
+
+		IRI term = factory.createIRI("http://example.com/vocab#term");
+		assertEquals("http://example.com/vocab#term", term.getIRIString());
+		assertEquals("<http://example.com/vocab#term>", term.ntriplesString());
+
+		// and now for the international fun!
+
+		IRI latin1 = factory.createIRI("http://accént.example.com/première");
+		assertEquals("http://accént.example.com/première",
+				latin1.getIRIString());
+		assertEquals("<http://accént.example.com/première>",
+				latin1.ntriplesString());
+
+		IRI cyrillic = factory.createIRI("http://example.испытание/Кириллица");
+		assertEquals("http://example.испытание/Кириллица",
+				cyrillic.getIRIString());
+		assertEquals("<http://example.испытание/Кириллица>",
+				cyrillic.ntriplesString());
+
+		IRI deseret = factory.createIRI("http://𐐀.example.com/𐐀");
+		assertEquals("http://𐐀.example.com/𐐀", deseret.getIRIString());
+		assertEquals("<http://𐐀.example.com/𐐀>", deseret.ntriplesString());
+	}
+
+	@Test
+	public void createIRIRelative() throws Exception {
+		// Although relative IRIs are defined in
+		// http://www.w3.org/TR/rdf11-concepts/#section-IRIs
+		// it is not a requirement for an implementation to support
+		// it (all instances of an relative IRI should eventually
+		// be possible to resolve to an absolute IRI)
+		try {
+			factory.createIRI("../relative");
+		} catch (UnsupportedOperationException | IllegalArgumentException ex) {
+			Assume.assumeNoException(ex);
+			return;
+		}
+		IRI relative = factory.createIRI("../relative");
+		assertEquals("../relative", relative.getIRIString());
+		assertEquals("<../relative>", relative.ntriplesString());
+
+		IRI relativeTerm = factory.createIRI("../relative#term");
+		assertEquals("../relative#term", relativeTerm.getIRIString());
+		assertEquals("<../relative#term>", relativeTerm.ntriplesString());
+
+		IRI emptyRelative = factory.createIRI(""); // <> equals the base URI
+		assertEquals("", emptyRelative.getIRIString());
+		assertEquals("<>", emptyRelative.ntriplesString());
+	}
+
+	@Test
+	public void createLiteral() throws Exception {
+		Literal example;
+		try {
+			example = factory.createLiteral("Example");
+		} catch (UnsupportedOperationException ex) {
+			Assume.assumeNoException(ex);
+			return;
+		}
+
+		assertEquals("Example", example.getLexicalForm());
+		assertFalse(example.getLanguageTag().isPresent());
+		assertEquals("http://www.w3.org/2001/XMLSchema#string", example
+				.getDatatype().getIRIString());
+		// http://lists.w3.org/Archives/Public/public-rdf-comments/2014Dec/0004.html
+		assertEquals("\"Example\"", example.ntriplesString());
+	}
+
+	@Test
+	public void createLiteralDateTime() throws Exception {
+		Literal dateTime;
+		try {
+			dateTime = factory
+					.createLiteral(
+							"2014-12-27T00:50:00T-0600",
+							factory.createIRI("http://www.w3.org/2001/XMLSchema#dateTime"));
+		} catch (UnsupportedOperationException ex) {
+			Assume.assumeNoException(ex);
+			return;
+		}
+		assertEquals("2014-12-27T00:50:00T-0600", dateTime.getLexicalForm());
+		assertFalse(dateTime.getLanguageTag().isPresent());
+		assertEquals("http://www.w3.org/2001/XMLSchema#dateTime", dateTime
+				.getDatatype().getIRIString());
+		assertEquals(
+				"\"2014-12-27T00:50:00T-0600\"^^<http://www.w3.org/2001/XMLSchema#dateTime>",
+				dateTime.ntriplesString());
+	}
+
+	@Test
+	public void createLiteralLang() throws Exception {
+		Literal example;
+		try {
+			example = factory.createLiteral("Example", "en");
+		} catch (UnsupportedOperationException ex) {
+			Assume.assumeNoException(ex);
+			return;
+		}
+
+		assertEquals("Example", example.getLexicalForm());
+		assertEquals("en", example.getLanguageTag().get());
+		assertEquals("http://www.w3.org/1999/02/22-rdf-syntax-ns#langString",
+				example.getDatatype().getIRIString());
+		assertEquals("\"Example\"@en", example.ntriplesString());
+	}
+
+	@Test
+	public void createLiteralLangISO693_3() throws Exception {
+		// see https://issues.apache.org/jira/browse/JENA-827
+		Literal vls;
+		try {
+			vls = factory.createLiteral("Herbert Van de Sompel", "vls"); // JENA-827
+																			// reference
+		} catch (UnsupportedOperationException ex) {
+			Assume.assumeNoException(ex);
+			return;
+		}
+
+		assertEquals("vls", vls.getLanguageTag().get());
+		assertEquals("http://www.w3.org/1999/02/22-rdf-syntax-ns#langString",
+				vls.getDatatype().getIRIString());
+		assertEquals("\"Herbert Van de Sompel\"@vls", vls.ntriplesString());
+	}
+
+	@Test
+	public void createLiteralString() throws Exception {
+		Literal example;
+		try {
+			example = factory.createLiteral("Example", factory
+					.createIRI("http://www.w3.org/2001/XMLSchema#string"));
+		} catch (UnsupportedOperationException ex) {
+			Assume.assumeNoException(ex);
+			return;
+		}
+		assertEquals("Example", example.getLexicalForm());
+		assertFalse(example.getLanguageTag().isPresent());
+		assertEquals("http://www.w3.org/2001/XMLSchema#string", example
+				.getDatatype().getIRIString());
+		// http://lists.w3.org/Archives/Public/public-rdf-comments/2014Dec/0004.html
+		assertEquals("\"Example\"", example.ntriplesString());
+	}
+
+	@Test
+	public void createTripleBnodeBnode() {
+		BlankNode subject;
+		IRI predicate;
+		BlankNode object;
+		Triple triple;
+		try {
+			subject = factory.createBlankNode("b1");
+			predicate = factory.createIRI("http://example.com/pred");
+			object = factory.createBlankNode("b2");
+			triple = factory.createTriple(subject, predicate, object);
+		} catch (UnsupportedOperationException ex) {
+			Assume.assumeNoException(ex);
+			return;
+		}
+
+		// bnode equivalence should be OK as we used the same
+		// factory and have not yet inserted Triple into a Graph
+		assertEquals(subject, triple.getSubject());
+		assertEquals(predicate, triple.getPredicate());
+		assertEquals(object, triple.getObject());
+	}
+
+	@Test
+	public void createTripleBnodeIRI() {
+		BlankNode subject;
+		IRI predicate;
+		IRI object;
+		Triple triple;
+		try {
+			subject = factory.createBlankNode("b1");
+			predicate = factory.createIRI("http://example.com/pred");
+			object = factory.createIRI("http://example.com/obj");
+			triple = factory.createTriple(subject, predicate, object);
+		} catch (UnsupportedOperationException ex) {
+			Assume.assumeNoException(ex);
+			return;
+		}
+
+		// bnode equivalence should be OK as we used the same
+		// factory and have not yet inserted Triple into a Graph
+		assertEquals(subject, triple.getSubject());
+		assertEquals(predicate, triple.getPredicate());
+		assertEquals(object, triple.getObject());
+	}
+
+	@Test
+	public void createTripleBnodeTriple() {
+		BlankNode subject;
+		IRI predicate;
+		Literal object;
+		Triple triple;
+		try {
+			subject = factory.createBlankNode();
+			predicate = factory.createIRI("http://example.com/pred");
+			object = factory.createLiteral("Example", "en");
+			triple = factory.createTriple(subject, predicate, object);
+		} catch (UnsupportedOperationException ex) {
+			Assume.assumeNoException(ex);
+			return;
+		}
+
+		// bnode equivalence should be OK as we used the same
+		// factory and have not yet inserted Triple into a Graph
+		assertEquals(subject, triple.getSubject());
+		assertEquals(predicate, triple.getPredicate());
+		assertEquals(object, triple.getObject());
+	}
+
+	@Before
+	public void getFactory() {
+		factory = createFactory();
+	}
+
+	@Test
+	public void possiblyInvalidBlankNode() throws Exception {
+		BlankNode withColon;
+		try {
+			withColon = factory.createBlankNode("with:colon");
+		} catch (UnsupportedOperationException ex) {
+			Assume.assumeNoException("createBlankNode(String) not supported",
+					ex);
+			return;
+		} catch (IllegalArgumentException ex) {
+			// Good!
+			return;
+		}
+		// Factory allows :colon, which is OK as long as it's not causing an
+		// invalid ntriplesString
+		assertFalse(withColon.ntriplesString().contains("with:colon"));
+
+		// and creating it twice gets the same ntriplesString
+		assertEquals(withColon.ntriplesString(),
+				factory.createBlankNode("with:colon").ntriplesString());
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void invalidIRI() throws Exception {
+		try {
+			factory.createIRI("<no_brackets>");
+		} catch (UnsupportedOperationException ex) {
+			Assume.assumeNoException("createIRI not supported", ex);
+			return;
+		}
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void invalidLiteralLang() throws Exception {
+		try {
+			factory.createLiteral("Example", "with space");
+		} catch (UnsupportedOperationException ex) {
+			Assume.assumeNoException(
+					"createLiteral(String,String) not supported", ex);
+			return;
+		}
+	}
+
+	@Test(expected = Exception.class)
+	public void invalidTriplePredicate() {
+		BlankNode subject = factory.createBlankNode("b1");
+		BlankNode predicate = factory.createBlankNode("b2");
+		BlankNode object = factory.createBlankNode("b3");
+		factory.createTriple(subject, (IRI) predicate, object);
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-commonsrdf/blob/fa5321e4/api/src/test/java/org/apache/commons/rdf/api/DefaultRDFTermFactoryTest.java
----------------------------------------------------------------------
diff --git a/api/src/test/java/org/apache/commons/rdf/api/DefaultRDFTermFactoryTest.java b/api/src/test/java/org/apache/commons/rdf/api/DefaultRDFTermFactoryTest.java
new file mode 100644
index 0000000..b2f9697
--- /dev/null
+++ b/api/src/test/java/org/apache/commons/rdf/api/DefaultRDFTermFactoryTest.java
@@ -0,0 +1,30 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.rdf.api;
+
+/**
+ * The default RDFTermFactory might be useless (every method throws
+ * UnsupportedOperationException), but this test ensures that
+ * AbstractRDFTermFactoryTest does not fall over on unsupported operations.
+ *
+ */
+public class DefaultRDFTermFactoryTest extends AbstractRDFTermFactoryTest {
+
+	@Override
+	public RDFTermFactory createFactory() {
+		return new RDFTermFactory() {
+		};
+	}
+
+}