You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by cl...@apache.org on 2015/05/23 08:58:19 UTC
[09/25] jena git commit: Added initial contract tests added
testing_framework
http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/src/test/java/org/apache/jena/testing_framework/GraphHelper.java
----------------------------------------------------------------------
diff --git a/jena-core/src/test/java/org/apache/jena/testing_framework/GraphHelper.java b/jena-core/src/test/java/org/apache/jena/testing_framework/GraphHelper.java
new file mode 100644
index 0000000..c208e8d
--- /dev/null
+++ b/jena-core/src/test/java/org/apache/jena/testing_framework/GraphHelper.java
@@ -0,0 +1,508 @@
+/*
+ * 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.testing_framework;
+
+/**
+ * Foo set of static test helpers. Generally included as a static.
+ */
+
+import static org.junit.Assert.*;
+
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import org.apache.jena.graph.Factory;
+import org.apache.jena.graph.Graph;
+import org.apache.jena.graph.GraphUtil;
+import org.apache.jena.graph.Node;
+import org.apache.jena.graph.Triple;
+import org.apache.jena.shared.JenaException;
+import org.apache.jena.shared.PrefixMapping;
+import org.apache.jena.util.CollectionFactory;
+import org.apache.jena.util.IteratorCollection;
+import org.apache.jena.util.iterator.ExtendedIterator;
+
+public class GraphHelper extends TestUtils {
+
+ /**
+ * Answer a Node as described by <code>x</code>; a shorthand for
+ * <code>Node.create(x)</code>, which see.
+ */
+ public static Node node(String x) {
+ return NodeCreateUtils.create(x);
+ }
+
+ /**
+ * Answer a set containing the elements from the iterator <code>it</code>; a
+ * shorthand for <code>IteratorCollection.iteratorToSet(it)</code>, which
+ * see.
+ */
+ public static <T> Set<T> iteratorToSet(Iterator<? extends T> it) {
+ return IteratorCollection.iteratorToSet(it);
+ }
+
+ /**
+ * Answer a list containing the elements from the iterator <code>it</code>,
+ * in order; a shorthand for
+ * <code>IteratorCollection.iteratorToList(it)</code>, which see.
+ */
+ public static <T> List<T> iteratorToList(Iterator<? extends T> it) {
+ return IteratorCollection.iteratorToList(it);
+ }
+
+ /**
+ * Answer a set of the nodes described (as per <code>node()</code>) by the
+ * space-separated substrings of <code>nodes</code>.
+ */
+ public static Set<Node> nodeSet(String nodes) {
+ Set<Node> result = CollectionFactory.createHashedSet();
+ StringTokenizer st = new StringTokenizer(nodes);
+ while (st.hasMoreTokens())
+ result.add(node(st.nextToken()));
+ return result;
+ }
+
+ /**
+ * Answer a set of the elements of <code>Foo</code>.
+ */
+ public static <T> Set<T> arrayToSet(T[] A) {
+ return CollectionFactory.createHashedSet(Arrays.asList(A));
+ }
+
+ /**
+ * Answer a triple described by the three space-separated node descriptions
+ * in <code>fact</code>; a shorthand for <code>Triple.create(fact)</code>,
+ * which see.
+ */
+ public static Triple triple(String fact) {
+ return NodeCreateUtils.createTriple(fact);
+ }
+
+ /**
+ * Answer a triple described by the three space-separated node descriptions
+ * in <code>fact</code>, using prefix-mappings from <code>pm</code>; a
+ * shorthand for <code>Triple.create(pm, fact)</code>, which see.
+ */
+ public static Triple triple(PrefixMapping pm, String fact) {
+ return NodeCreateUtils.createTriple(pm, fact);
+ }
+
+ /**
+ * Answer an array of triples; each triple is described by one of the
+ * semi-separated substrings of <code>facts</code>, as per
+ * <code>triple</code> with prefix-mapping <code>Extended</code>.
+ */
+ public static Triple[] tripleArray(String facts) {
+ ArrayList<Triple> al = new ArrayList<Triple>();
+ StringTokenizer semis = new StringTokenizer(facts, ";");
+ while (semis.hasMoreTokens())
+ al.add(triple(PrefixMapping.Extended, semis.nextToken()));
+ return al.toArray(new Triple[al.size()]);
+ }
+
+ /**
+ * Answer a set of triples where the elements are described by the
+ * semi-separated substrings of <code>facts</code>, as per
+ * <code>triple</code>.
+ */
+ public static Set<Triple> tripleSet(String facts) {
+ Set<Triple> result = new HashSet<Triple>();
+ StringTokenizer semis = new StringTokenizer(facts, ";");
+ while (semis.hasMoreTokens())
+ result.add(triple(semis.nextToken()));
+ return result;
+ }
+
+ /**
+ * Answer a list of nodes, where the nodes are described by the
+ * space-separated substrings of <code>items</code> as per
+ * <code>node()</code>.
+ */
+ public static List<Node> nodeList(String items) {
+ ArrayList<Node> nl = new ArrayList<Node>();
+ StringTokenizer nodes = new StringTokenizer(items);
+ while (nodes.hasMoreTokens())
+ nl.add(node(nodes.nextToken()));
+ return nl;
+ }
+
+ /**
+ * Answer an array of nodes, where the nodes are described by the
+ * space-separated substrings of <code>items</code> as per
+ */
+ public static Node[] nodeArray(String items) {
+ List<Node> nl = nodeList(items);
+ return nl.toArray(new Node[nl.size()]);
+ }
+
+ /**
+ * Answer the graph <code>g</code> after adding to it every triple encoded
+ * in <code>s</code> in the fashion of <code>tripleArray</code>, a
+ * semi-separated sequence of space-separated node descriptions.
+ */
+ public static Graph graphAdd(Graph g, String s) {
+ StringTokenizer semis = new StringTokenizer(s, ";");
+ while (semis.hasMoreTokens())
+ g.add(triple(PrefixMapping.Extended, semis.nextToken()));
+ return g;
+ }
+
+ /**
+ * Like graphAdd but does it within a transaction if supported
+ *
+ * @param g
+ * The graph to add to
+ * @param s
+ * The string describing the graph
+ * @return The populated graph.
+ */
+ public static Graph graphAddTxn(Graph g, String s) {
+ txnBegin(g);
+ StringTokenizer semis = new StringTokenizer(s, ";");
+ while (semis.hasMoreTokens())
+ g.add(triple(PrefixMapping.Extended, semis.nextToken()));
+ txnCommit(g);
+ return g;
+ }
+
+ /**
+ * Used to create a graph with values.
+ *
+ * @param g
+ * The newly created graph
+ * @param s
+ * The string representing the graph data.
+ * @return The populated graph
+ */
+ public static Graph graphWith(Graph g, String s) {
+ return graphAddTxn(g, s);
+ }
+
+ /**
+ * Answer a new memory-based graph with Extended prefixes.
+ */
+ public static Graph memGraph() {
+ Graph result = Factory.createGraphMem();
+ result.getPrefixMapping().setNsPrefixes(PrefixMapping.Extended);
+ return result;
+ }
+
+ /**
+ * Answer a new memory-based graph with initial contents as described by
+ * <code>s</code> in the fashion of <code>graphAdd()</code>. Not
+ * over-ridable; do not use for abstraction.
+ */
+ public static Graph graphWith(String s) {
+ return graphWith(memGraph(), s);
+ }
+
+ /**
+ * Assert that the graph <code>g</code> is isomorphic to the graph described
+ * by <code>template</code> in the fashion of <code>graphWith</code>.
+ */
+ public static void assertEqualsTemplate(String title, Graph g,
+ String template) {
+ assertIsomorphic(title, graphWith(template), g);
+ }
+
+ /**
+ * Assert that the supplied graph <code>got</code> is isomorphic with the
+ * the desired graph <code>expected</code>; if not, display a readable
+ * description of both graphs.
+ */
+ public static void assertIsomorphic(String title, Graph expected, Graph got) {
+ if (!expected.isIsomorphicWith(got)) {
+ Map<Node, Object> map = CollectionFactory.createHashedMap();
+ fail(title + ": wanted " + nice(expected, map) + "\nbut got "
+ + nice(got, map));
+ }
+ }
+
+ /**
+ * Answer a string which is a newline-separated list of triples (as produced
+ * by niceTriple) in the graph <code>g</code>. The map <code>bnodes</code>
+ * maps already-seen bnodes to their "nice" strings.
+ */
+ public static String nice(Graph g, Map<Node, Object> bnodes) {
+ StringBuffer b = new StringBuffer(g.size() * 100);
+ ExtendedIterator<Triple> it = GraphUtil.findAll(g);
+ while (it.hasNext())
+ niceTriple(b, bnodes, it.next());
+ return b.toString();
+ }
+
+ /**
+ * Append to the string buffer <code>b</code> a "nice" representation of the
+ * triple <code>t</code> on a new line, using (and updating)
+ * <code>bnodes</code> to supply "nice" strings for any blank nodes.
+ */
+ protected static void niceTriple(StringBuffer b, Map<Node, Object> bnodes,
+ Triple t) {
+ b.append("\n ");
+ appendNode(b, bnodes, t.getSubject());
+ appendNode(b, bnodes, t.getPredicate());
+ appendNode(b, bnodes, t.getObject());
+ }
+
+ /**
+ * Foo counter for new bnode strings; it starts at 1000 so as to make the
+ * bnode strings more uniform (at least for the first 9000 bnodes).
+ */
+ protected static int bnc = 1000;
+
+ /**
+ * Append to the string buffer <code>b</code> a space followed by the "nice"
+ * representation of the node <code>n</code>. If <code>n</code> is a bnode,
+ * re-use any existing string for it from <code>bnodes</code> or make a new
+ * one of the form <i>_bNNNN</i> with NNNN a new integer.
+ */
+ protected static void appendNode(StringBuffer b, Map<Node, Object> bnodes,
+ Node n) {
+ b.append(' ');
+ if (n.isBlank()) {
+ Object already = bnodes.get(n);
+ if (already == null)
+ bnodes.put(n, already = "_b" + bnc++);
+ b.append(already);
+ } else
+ b.append(nice(n));
+ }
+
+ // protected static Graph graphWithTxn(IProducer<? extends Graph> producer,
+ // String s) {
+ // Graph g = producer.newInstance();
+ // txnBegin(g);
+ // try {
+ // graphAdd(g, s);
+ // txnCommit(g);
+ // } catch (Exception e) {
+ // txnRollback(g);
+ // fail(e.getMessage());
+ // }
+ // return g;
+ // }
+
+ /**
+ * Answer the "nice" representation of this node, the string returned by
+ * <code>n.toString(PrefixMapping.Extended,true)</code>.
+ */
+ protected static String nice(Node n) {
+ return n.toString(PrefixMapping.Extended, true);
+ }
+
+ /**
+ * Assert that the computed graph <code>got</code> is isomorphic with the
+ * desired graph <code>expected</code>; if not, fail with a default message
+ * (and pretty output of the graphs).
+ */
+ public static void assertIsomorphic(Graph expected, Graph got) {
+ assertIsomorphic("graphs must be isomorphic", expected, got);
+ }
+
+ /**
+ * Assert that the graph <code>g</code> must contain the triple described by
+ * <code>s</code>; if not, fail with pretty output of both graphs and a
+ * message containing <code>name</code>.
+ */
+ public static void assertContains(String name, String s, Graph g) {
+ assertTrue(name + " must contain " + s, g.contains(triple(s)));
+ }
+
+ /**
+ * Assert that the graph <code>g</code> contains all the triples described
+ * by the string <code>s</code; if not, fail with a message containing
+ * <code>name</code>.
+ */
+ public static void assertContainsAll(String name, Graph g, String s) {
+ StringTokenizer semis = new StringTokenizer(s, ";");
+ while (semis.hasMoreTokens())
+ assertContains(name, semis.nextToken(), g);
+ }
+
+ /**
+ * Assert that the graph <code>g</code> does not contain the triple
+ * described by <code>s<code>; if it does, fail with a message containing
+ <code>name</code>.
+ */
+ public static void assertOmits(String name, Graph g, String s) {
+ assertFalse(name + " must not contain " + s, g.contains(triple(s)));
+ }
+
+ /**
+ * Assert that the graph <code>g</code> contains none of the triples
+ * described by <code>s</code> in the usual way; otherwise, fail with a
+ * message containing <code>name</code>.
+ */
+ public static void assertOmitsAll(String name, Graph g, String s) {
+ StringTokenizer semis = new StringTokenizer(s, ";");
+ while (semis.hasMoreTokens())
+ assertOmits(name, g, semis.nextToken());
+ }
+
+ /**
+ * Assert that <code>g</code> contains the triple described by
+ * <code>fact</code> in the usual way.
+ */
+ public static boolean contains(Graph g, String fact) {
+ return g.contains(triple(fact));
+ }
+
+ /**
+ * Assert that <code>g</code> contains every triple in <code>triples</code>.
+ */
+ public static void testContains(Graph g, Triple[] triples) {
+ for (int i = 0; i < triples.length; i += 1)
+ assertTrue("contains " + triples[i], g.contains(triples[i]));
+ }
+
+ /**
+ * Assert that <code>g</code> contains every triple in <code>triples</code>.
+ */
+ public static void testContains(Graph g, List<Triple> triples) {
+ for (int i = 0; i < triples.size(); i += 1)
+ assertTrue(g.contains(triples.get(i)));
+ }
+
+ /**
+ * Assert that <code>g</code> contains every triple in <code>it</code>.
+ */
+ public static void testContains(Graph g, Iterator<Triple> it) {
+ while (it.hasNext())
+ assertTrue(g.contains(it.next()));
+ }
+
+ /**
+ * Assert that <code>g</code> contains every triple in <code>other</code>.
+ */
+ public static void testContains(Graph g, Graph other) {
+ testContains(g, GraphUtil.findAll(other));
+ }
+
+ /**
+ * Assert that <code>g</code> contains none of the triples in
+ * <code>triples</code>.
+ */
+ public static void testOmits(Graph g, Triple[] triples) {
+ for (int i = 0; i < triples.length; i += 1)
+ assertFalse("", g.contains(triples[i]));
+ }
+
+ /**
+ * Assert that <code>g</code> contains none of the triples in
+ * <code>triples</code>.
+ */
+ public static void testOmits(Graph g, List<Triple> triples) {
+ for (int i = 0; i < triples.size(); i += 1)
+ assertFalse("", g.contains(triples.get(i)));
+ }
+
+ /**
+ * Assert that <code>g</code> contains none of the triples in
+ * <code>it</code>.
+ */
+ public static void testOmits(Graph g, Iterator<Triple> it) {
+ while (it.hasNext())
+ assertFalse("", g.contains(it.next()));
+ }
+
+ /**
+ * Assert that <code>g</code> contains none of the triples in
+ * <code>other</code>.
+ */
+ public static void testOmits(Graph g, Graph other) {
+ testOmits(g, GraphUtil.findAll(other));
+ }
+
+ /**
+ * Answer an instance of <code>graphClass</code>. If <code>graphClass</code>
+ * has a constructor that takes a <code>ReificationStyle</code> argument,
+ * then that constructor is run on <code>style</code> to get the instance.
+ * Otherwise, if it has a # constructor that takes an argument of
+ * <code>wrap</code>'s class before the <code>ReificationStyle</code>, that
+ * constructor is used; this allows non-static inner classes to be used for
+ * <code>graphClass</code>, with <code>wrap</code> being the outer class
+ * instance. If no suitable constructor exists, a JenaException is thrown.
+ *
+ * @param wrap
+ * the outer class instance if graphClass is an inner class
+ * @param graphClass
+ * a class implementing Graph
+ * @return an instance of graphClass with the given style
+ * @throws RuntimeException
+ * or JenaException if construction fails
+ */
+ public static Graph getGraph(Object wrap, Class<? extends Graph> graphClass) {
+ try {
+ Constructor<?> cons = getConstructor(graphClass, new Class[] {});
+ if (cons != null)
+ return (Graph) cons.newInstance(new Object[] {});
+ Constructor<?> cons2 = getConstructor(graphClass,
+ new Class[] { wrap.getClass() });
+ if (cons2 != null)
+ return (Graph) cons2.newInstance(new Object[] { wrap });
+ throw new JenaException("no suitable graph constructor found for "
+ + graphClass);
+ } catch (RuntimeException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new JenaException(e);
+ }
+ }
+
+ /**
+ * Begin a transaction on the graph if transactions are supported.
+ *
+ * @param g
+ */
+ public static void txnBegin(Graph g) {
+ if (g.getTransactionHandler().transactionsSupported()) {
+ g.getTransactionHandler().begin();
+ }
+ }
+
+ /**
+ * Commit the transaction on the graph if transactions are supported.
+ *
+ * @param g
+ */
+ public static void txnCommit(Graph g) {
+ if (g.getTransactionHandler().transactionsSupported()) {
+ g.getTransactionHandler().commit();
+ }
+ }
+
+ /**
+ * Rollback (abort) the transaction on the graph if transactions are
+ * supported.
+ *
+ * @param g
+ */
+ public static void txnRollback(Graph g) {
+ if (g.getTransactionHandler().transactionsSupported()) {
+ g.getTransactionHandler().abort();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/src/test/java/org/apache/jena/testing_framework/GraphProducerInterface.java
----------------------------------------------------------------------
diff --git a/jena-core/src/test/java/org/apache/jena/testing_framework/GraphProducerInterface.java b/jena-core/src/test/java/org/apache/jena/testing_framework/GraphProducerInterface.java
new file mode 100644
index 0000000..8c33eb1
--- /dev/null
+++ b/jena-core/src/test/java/org/apache/jena/testing_framework/GraphProducerInterface.java
@@ -0,0 +1,41 @@
+/*
+ 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.testing_framework;
+
+/**
+ * Creates the graph for testing. Implementations must track the creation of
+ * graphs created with newGraph and close them when closeGraphs is called.
+ *
+ */
+//public interface GraphProducerInterface<T> {
+//
+// /**
+// * Returns a new Graph to take part in the test.
+// *
+// * @return The graph implementation to test.
+// */
+// public abstract Graph newGraph();
+//
+// /**
+// * provides a hook to close down graphs. When called all graphs created by
+// * the newGraph() method should be closed. Note that some graphs may have
+// * been closed during the test, so graphs should be tested for being closed
+// * prior to closing.
+// */
+// public abstract void closeGraphs();
+// }
http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/src/test/java/org/apache/jena/testing_framework/IContainerProducer.java
----------------------------------------------------------------------
diff --git a/jena-core/src/test/java/org/apache/jena/testing_framework/IContainerProducer.java b/jena-core/src/test/java/org/apache/jena/testing_framework/IContainerProducer.java
new file mode 100644
index 0000000..41bc6df
--- /dev/null
+++ b/jena-core/src/test/java/org/apache/jena/testing_framework/IContainerProducer.java
@@ -0,0 +1,19 @@
+package org.apache.jena.testing_framework;
+
+import org.apache.jena.rdf.model.Container;
+import org.apache.jena.rdf.model.Resource;
+
+public interface IContainerProducer<T extends Container> extends
+ IResourceProducer<T> {
+
+ /**
+ * The Resource identifying the continer type. e.g. RDF.seq
+ */
+ Resource getContainerType();
+
+ /**
+ * The class of the continaer. e.g. Seq.class
+ */
+ Class<? extends Container> getContainerClass();
+
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/src/test/java/org/apache/jena/testing_framework/IIteratorProducer.java
----------------------------------------------------------------------
diff --git a/jena-core/src/test/java/org/apache/jena/testing_framework/IIteratorProducer.java b/jena-core/src/test/java/org/apache/jena/testing_framework/IIteratorProducer.java
new file mode 100644
index 0000000..3178692
--- /dev/null
+++ b/jena-core/src/test/java/org/apache/jena/testing_framework/IIteratorProducer.java
@@ -0,0 +1,42 @@
+package org.apache.jena.testing_framework;
+
+import java.util.List;
+
+import org.apache.jena.util.iterator.ExtendedIterator;
+
+public interface IIteratorProducer<T> {
+
+ /**
+ * Get a new instance of the iterator.
+ *
+ * @return
+ */
+ public ExtendedIterator<T> newInstance();
+
+ /**
+ * Clean up after a test
+ */
+ public void cleanUp();
+
+ /**
+ * The list of items found in the iterator. Does not have to be in order.
+ *
+ * @return
+ */
+ public List<T> getList();
+
+ /**
+ * True if delete is supported by the iterator
+ *
+ * @return
+ */
+ public boolean supportsDelete();
+
+ /**
+ * True if this is an iterator on a copy so that delete works but getting a
+ * new copy for the iterator test will return the original list.
+ *
+ * @return
+ */
+ public boolean isCopy();
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/src/test/java/org/apache/jena/testing_framework/INodeProducer.java
----------------------------------------------------------------------
diff --git a/jena-core/src/test/java/org/apache/jena/testing_framework/INodeProducer.java b/jena-core/src/test/java/org/apache/jena/testing_framework/INodeProducer.java
new file mode 100644
index 0000000..2532c32
--- /dev/null
+++ b/jena-core/src/test/java/org/apache/jena/testing_framework/INodeProducer.java
@@ -0,0 +1,39 @@
+/*
+ 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.testing_framework;
+
+import org.xenei.junit.contract.IProducer;
+
+import org.apache.jena.rdf.model.Model;
+import org.apache.jena.rdf.model.RDFNode;
+
+/**
+ * An abstract implementation of the IProducer<RDFNode> interface.
+ *
+ * This class handles tracking of the created graphs and closing them. It also
+ * provides a callback for the implementing class to perform extra cleanup when
+ * the graph is closed.
+ *
+ */
+public interface INodeProducer<T extends RDFNode> extends IProducer<T> {
+
+ abstract public T newInstance(String uri);
+
+ abstract public Model getModel();
+
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/src/test/java/org/apache/jena/testing_framework/IResourceProducer.java
----------------------------------------------------------------------
diff --git a/jena-core/src/test/java/org/apache/jena/testing_framework/IResourceProducer.java b/jena-core/src/test/java/org/apache/jena/testing_framework/IResourceProducer.java
new file mode 100644
index 0000000..ef9eead
--- /dev/null
+++ b/jena-core/src/test/java/org/apache/jena/testing_framework/IResourceProducer.java
@@ -0,0 +1,10 @@
+package org.apache.jena.testing_framework;
+
+import org.apache.jena.rdf.model.Resource;
+
+public interface IResourceProducer<X extends Resource> extends INodeProducer<X> {
+ /**
+ * Returns true if the Resource implementation supports non URI values
+ */
+ boolean supportsAnonymous();
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/src/test/java/org/apache/jena/testing_framework/IStatementProducer.java
----------------------------------------------------------------------
diff --git a/jena-core/src/test/java/org/apache/jena/testing_framework/IStatementProducer.java b/jena-core/src/test/java/org/apache/jena/testing_framework/IStatementProducer.java
new file mode 100644
index 0000000..8830948
--- /dev/null
+++ b/jena-core/src/test/java/org/apache/jena/testing_framework/IStatementProducer.java
@@ -0,0 +1,45 @@
+/*
+ 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.testing_framework;
+
+import org.apache.jena.rdf.model.Model;
+import org.apache.jena.rdf.model.Property;
+import org.apache.jena.rdf.model.RDFNode;
+import org.apache.jena.rdf.model.Resource;
+import org.apache.jena.rdf.model.Statement;
+
+/**
+ * An abstract implementation of the IProducer<RDFNode> interface.
+ *
+ * This class handles tracking of the created graphs and closing them. It also
+ * provides a callback for the implementing class to perform extra cleanup when
+ * the graph is closed.
+ *
+ */
+public interface IStatementProducer<T extends Statement> {
+
+ abstract public T newInstance(String fact);
+
+ abstract public T newInstance(Resource s, Property p, RDFNode o);
+
+ abstract public Model getModel();
+
+ abstract public void cleanUp();
+
+ abstract public AbstractModelProducer<Model> getModelProducer();
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/src/test/java/org/apache/jena/testing_framework/ITripleStoreProducer.java
----------------------------------------------------------------------
diff --git a/jena-core/src/test/java/org/apache/jena/testing_framework/ITripleStoreProducer.java b/jena-core/src/test/java/org/apache/jena/testing_framework/ITripleStoreProducer.java
new file mode 100644
index 0000000..fe4e25d
--- /dev/null
+++ b/jena-core/src/test/java/org/apache/jena/testing_framework/ITripleStoreProducer.java
@@ -0,0 +1,35 @@
+/*
+ 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.testing_framework;
+
+import org.apache.jena.graph.impl.TripleStore;
+
+/**
+ * Creates the graph for testing
+ *
+ */
+public interface ITripleStoreProducer {
+
+ /**
+ * Returns a TripleStore to take part in the test. Must be overridden in a
+ * subclass.
+ *
+ * @return The TripleStore implementation to test.
+ */
+ public abstract TripleStore newTripleStore();
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/src/test/java/org/apache/jena/testing_framework/ModelHelper.java
----------------------------------------------------------------------
diff --git a/jena-core/src/test/java/org/apache/jena/testing_framework/ModelHelper.java b/jena-core/src/test/java/org/apache/jena/testing_framework/ModelHelper.java
new file mode 100644
index 0000000..2f35203
--- /dev/null
+++ b/jena-core/src/test/java/org/apache/jena/testing_framework/ModelHelper.java
@@ -0,0 +1,409 @@
+/*
+ * 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.testing_framework;
+
+import org.apache.jena.graph.Node;
+import org.apache.jena.rdf.model.Literal;
+import org.apache.jena.rdf.model.Model;
+import org.apache.jena.rdf.model.ModelFactory;
+import org.apache.jena.rdf.model.Property;
+import org.apache.jena.rdf.model.RDFNode;
+import org.apache.jena.rdf.model.Resource;
+import org.apache.jena.rdf.model.ResourceFactory;
+import org.apache.jena.rdf.model.Statement;
+import org.apache.jena.rdf.model.StmtIterator;
+import org.apache.jena.shared.PrefixMapping;
+import org.apache.jena.util.CollectionFactory;
+
+import static org.junit.Assert.*;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import org.junit.Assert;
+import org.xenei.junit.contract.IProducer;
+
+/**
+ * provides useful functionality for testing models, eg building small models
+ * from strings, testing equality, etc.
+ *
+ * Currently this class extends GraphHelper and thus TestCase.
+ */
+public class ModelHelper extends GraphHelper {
+
+ private static Model builderModel;
+
+ static {
+ builderModel = ModelFactory.createDefaultModel();
+ builderModel.setNsPrefixes(PrefixMapping.Extended);
+ }
+
+ protected static final Model empty = ModelFactory.createDefaultModel();
+
+ protected static Model extendedModel(IProducer<Model> producer) {
+ Model result = producer.newInstance();
+ result.setNsPrefixes(PrefixMapping.Extended);
+ return result;
+ }
+
+ protected static String nice(RDFNode n) {
+ return nice(n.asNode());
+ }
+
+ public static Statement statement(String fact) {
+ StringTokenizer st = new StringTokenizer(fact);
+ Resource sub = resource(st.nextToken());
+ Property pred = property(st.nextToken());
+ RDFNode obj = rdfNode(st.nextToken());
+ return builderModel.createStatement(sub, pred, obj);
+ }
+
+ public static Statement statement(Resource s, Property p, RDFNode o) {
+ return builderModel.createStatement(s, p, o);
+ }
+
+ public static RDFNode rdfNode(Model m, String s) {
+ return m.asRDFNode(NodeCreateUtils.create(s));
+ }
+
+ public static RDFNode rdfNode(String s) {
+ return rdfNode(builderModel, s);
+ }
+
+ public static <T extends RDFNode> T rdfNode(String s, Class<T> c) {
+ return rdfNode(s).as(c);
+ }
+
+ public static Resource resource() {
+ return ResourceFactory.createResource();
+ }
+
+ public static Resource resource(String s) {
+ return (Resource) rdfNode(s);
+ }
+
+ // public static Resource resource(Model m, String s) {
+ // return (Resource) rdfNode(m, s);
+ // }
+
+ public static Property property(String s) {
+ return rdfNode(s).as(Property.class);
+ }
+
+ public static Property property(Model m, String s) {
+ return rdfNode(m, s).as(Property.class);
+ }
+
+ public static Literal literal(String s, String lang) {
+ return builderModel.createLiteral(s, lang);
+ }
+
+ public static Literal literal(String s) {
+ return rdfNode(s).as(Literal.class);
+ }
+
+ // /**
+ // * Create an array of Statements parsed from a semi-separated string.
+ // *
+ // * @param lockModel
+ // * a model to serve as a statement factory
+ // * @param facts
+ // * a sequence of semicolon-separated "S P O" facts
+ // * @return a Statement[] of the (S P O) statements from the string
+ // */
+ // public static Statement[] statements(Model m, String facts) {
+ // ArrayList<Statement> sl = new ArrayList<Statement>();
+ // StringTokenizer st = new StringTokenizer(facts, ";");
+ // while (st.hasMoreTokens())
+ // sl.add(statement(m, st.nextToken()));
+ // return sl.toArray(new Statement[sl.size()]);
+ // }
+
+ /**
+ * Create an array of Statements parsed from a semi-separated string.
+ *
+ * @param lockModel
+ * a model to serve as a statement factory
+ * @param facts
+ * a sequence of semicolon-separated "S P O" facts
+ * @return a Statement[] of the (S P O) statements from the string
+ */
+ public static Statement[] statements(String facts) {
+ ArrayList<Statement> sl = new ArrayList<Statement>();
+ StringTokenizer st = new StringTokenizer(facts, ";");
+ while (st.hasMoreTokens())
+ sl.add(statement(st.nextToken()));
+ return sl.toArray(new Statement[sl.size()]);
+ }
+
+ /**
+ * Create an array of Resources from a whitespace-separated string
+ *
+ * @param items
+ * a whitespace-separated sequence to feed to resource
+ * @return a Resource[] of the parsed resources
+ */
+ public static Resource[] resources(String items) {
+ ArrayList<Resource> rl = new ArrayList<Resource>();
+ StringTokenizer st = new StringTokenizer(items);
+ while (st.hasMoreTokens())
+ rl.add(resource(st.nextToken()));
+ return rl.toArray(new Resource[rl.size()]);
+ }
+
+ /**
+ * Answer the set of resources given by the space-separated
+ * <code>items</code> string. Each resource specification is interpreted as
+ * per <code>resource</code>.
+ */
+ public static Set<Resource> resourceSet(String items) {
+ Set<Resource> result = new HashSet<Resource>();
+ StringTokenizer st = new StringTokenizer(items);
+ while (st.hasMoreTokens())
+ result.add(resource(st.nextToken()));
+ return result;
+ }
+
+ /**
+ * add to a model all the statements expressed by a string.
+ *
+ * Does not do any transaction manipulation.
+ *
+ * @param m
+ * the model to be updated
+ * @param facts
+ * a sequence of semicolon-separated "S P O" facts
+ * @return the updated model
+ */
+ public static Model modelAdd(Model m, String facts) {
+ StringTokenizer semis = new StringTokenizer(facts, ";");
+
+ while (semis.hasMoreTokens()) {
+ StringTokenizer st = new StringTokenizer(semis.nextToken());
+ Resource sub = resource(st.nextToken());
+ Property pred = property(st.nextToken());
+ RDFNode obj = rdfNode(st.nextToken());
+ m.add(sub, pred, obj);
+ }
+
+ return m;
+ }
+
+ /**
+ * create a memory based model with extended prefixes and initialises it
+ * with statements parsed from a string.
+ *
+ * does all insertions in a transaction.
+ *
+ * @param facts
+ * @return
+ */
+ public static Model memModel(String facts) {
+ Model model = ModelFactory.createMemModelMaker().createFreshModel();
+ model.setNsPrefixes(PrefixMapping.Extended);
+ txnBegin(model);
+ modelAdd(model, facts);
+ txnCommit(model);
+ return model;
+ }
+
+ /**
+ * Creates a model with extended prefixes and initialises it with statements
+ * parsed from a string.
+ *
+ * does all insertions in a transaction.
+ *
+ * @param facts
+ * a string in semicolon-separated "S P O" format
+ * @return a model containing those facts
+ */
+ public static Model modelWithStatements(
+ IProducer<? extends Model> producer, String facts) {
+ Model m = createModel(producer);
+ txnBegin(m);
+ modelAdd(m, facts);
+ txnCommit(m);
+ return m;
+ }
+
+ /**
+ * Creates a model with extended prefixes and initialises it with statements
+ * parsed from the statement iterator.
+ *
+ * does all insertions in a transaction.
+ *
+ * @param facts
+ * a string in semicolon-separated "S P O" format
+ * @return a model containing those facts
+ */
+ public static Model modelWithStatements(
+ IProducer<? extends Model> producer, final StmtIterator it) {
+ Model m = createModel(producer);
+ txnBegin(m);
+ while (it.hasNext()) {
+ m.add(it.nextStatement());
+ }
+ txnCommit(m);
+ return m;
+ }
+
+ /**
+ * make a model and give it Extended prefixes
+ */
+ public static Model createModel(IProducer<? extends Model> producer) {
+ Model result = producer.newInstance();
+ result.setNsPrefixes(PrefixMapping.Extended);
+ return result;
+ }
+
+ /**
+ * test that two models are isomorphic and fail if they are not.
+ *
+ * @param title
+ * a String appearing at the beginning of the failure message
+ * @param wanted
+ * the model value that is expected
+ * @param got
+ * the model value to check
+ * @exception if
+ * the models are not isomorphic
+ */
+ public static void assertIsoModels(String title, Model wanted, Model got) {
+ if (wanted.isIsomorphicWith(got) == false) {
+ Map<Node, Object> map = CollectionFactory.createHashedMap();
+ fail(title + ": expected " + nice(wanted.getGraph(), map)
+ + "\n but had " + nice(got.getGraph(), map));
+ }
+ }
+
+ public static void assertContainsAll(final Model model, final Model model2) {
+ for (final StmtIterator s = model2.listStatements(); s.hasNext();) {
+ Assert.assertTrue(model.contains(s.nextStatement()));
+ }
+ }
+
+ public static void assertSameStatements(final Model model,
+ final Model model2) {
+ assertContainsAll(model, model2);
+ assertContainsAll(model2, model);
+ }
+
+ public static Property prop(final String uri) {
+ return ResourceFactory.createProperty("eh:/" + uri);
+ }
+
+ public static Resource res(final String uri) {
+ return ResourceFactory.createResource("eh:/" + uri);
+ }
+
+ /**
+ * Fail if the two models are not isomorphic. See
+ * assertIsoModels(String,Model,Model).
+ */
+ public static void assertIsoModels(Model wanted, Model got) {
+ assertIsoModels("models must be isomorphic", wanted, got);
+ }
+
+ public static final boolean tvBoolean = true;
+ public static final byte tvByte = 1;
+ public static final short tvShort = 2;
+ public static final int tvInt = -1;
+ public static final long tvLong = -2;
+ public static final char tvChar = '!';
+ public static final float tvFloat = (float) 123.456;
+ public static final double tvDouble = -123.456;
+ public static final String tvString = "test 12 string";
+ public static final double dDelta = 0.000000005;
+
+ public static final float fDelta = 0.000005f;
+
+ public static final Object tvLitObj = new LitTestObj(1234);
+ public static final LitTestObj tvObject = new LitTestObj(12345);
+
+ public static class LitTestObj {
+ protected long content;
+
+ public LitTestObj(final long l) {
+ content = l;
+ }
+
+ public LitTestObj(final String s) {
+ content = Long.parseLong(s.substring(1, s.length() - 1));
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ return (o instanceof LitTestObj)
+ && (content == ((LitTestObj) o).content);
+ }
+
+ @Override
+ public int hashCode() {
+ return (int) (content ^ (content >> 32));
+ }
+
+ @Override
+ public String toString() {
+ return "[" + Long.toString(content) + "]";
+ }
+
+ public long getContent() {
+ return content;
+ }
+ }
+
+ /**
+ * Begin a transaction on the model if transactions are supported.
+ *
+ * @param m
+ */
+ public static Model txnBegin(Model m) {
+ if (m.supportsTransactions()) {
+ return m.begin();
+ }
+ return m;
+ }
+
+ /**
+ * Commit the transaction on the model if transactions are supported.
+ *
+ * @param m
+ */
+ public static Model txnCommit(Model m) {
+ if (m.supportsTransactions()) {
+ return m.commit();
+ }
+ return m;
+ }
+
+ /**
+ * Rollback (abort) the transaction on the model if transactions are
+ * supported.
+ *
+ * @param m
+ */
+ public static Model txnRollback(Model m) {
+ if (m.supportsTransactions()) {
+ return m.abort();
+ }
+ return m;
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/src/test/java/org/apache/jena/testing_framework/NodeCreateUtils.java
----------------------------------------------------------------------
diff --git a/jena-core/src/test/java/org/apache/jena/testing_framework/NodeCreateUtils.java b/jena-core/src/test/java/org/apache/jena/testing_framework/NodeCreateUtils.java
new file mode 100644
index 0000000..83d42eb
--- /dev/null
+++ b/jena-core/src/test/java/org/apache/jena/testing_framework/NodeCreateUtils.java
@@ -0,0 +1,177 @@
+/*
+ * 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.testing_framework;
+
+import java.util.StringTokenizer;
+
+import org.apache.jena.datatypes.xsd.XSDDatatype;
+import org.apache.jena.graph.Node;
+import org.apache.jena.graph.NodeFactory;
+import org.apache.jena.graph.Triple;
+import org.apache.jena.graph.impl.LiteralLabel;
+import org.apache.jena.graph.impl.LiteralLabelFactory;
+import org.apache.jena.rdf.model.AnonId;
+import org.apache.jena.shared.*;
+
+/**
+ * Creating nodes from string specifications.
+ */
+public class NodeCreateUtils {
+ /**
+ * Returns a Node described by the string, primarily for testing purposes.
+ * The string represents a URI, a numeric literal, a string literal, a bnode
+ * label, or a variable.
+ * <ul>
+ * <li>'some text' :: a string literal with that text
+ * <li>'some text'someLanguage:: a string literal with that text and
+ * language
+ * <li>'some text'someURI:: a typed literal with that text and datatype
+ * <li>digits :: a literal [OF WHAT TYPE] with that [numeric] value
+ * <li>_XXX :: a bnode with an AnonId built from _XXX
+ * <li>?VVV :: a variable with name VVV
+ * <li>&PPP :: to be done
+ * <li>name:stuff :: the URI; name may be expanded using the Extended map
+ * </ul>
+ *
+ * @param x
+ * the string describing the node
+ * @return a node of the appropriate type with the appropriate label
+ */
+ public static Node create(String x) {
+ return create(PrefixMapping.Extended, x);
+ }
+
+ /**
+ * Returns a Node described by the string, primarily for testing purposes.
+ * The string represents a URI, a numeric literal, a string literal, a bnode
+ * label, or a variable.
+ * <ul>
+ * <li>'some text' :: a string literal with that text
+ * <li>'some text'someLanguage:: a string literal with that text and
+ * language
+ * <li>'some text'someURI:: a typed literal with that text and datatype
+ * <li>digits :: a literal [OF WHAT TYPE] with that [numeric] value
+ * <li>_XXX :: a bnode with an AnonId built from _XXX
+ * <li>?VVV :: a variable with name VVV
+ * <li>&PPP :: to be done
+ * <li>name:stuff :: the URI; name may be expanded using the Extended map
+ * </ul>
+ *
+ * @param pm
+ * the PrefixMapping for translating pre:X strings
+ * @param x
+ * the string encoding the node to create
+ * @return a node with the appropriate type and label
+ */
+ public static Node create(PrefixMapping pm, String x) {
+ if (x.equals(""))
+ throw new JenaException(
+ "Node.create does not accept an empty string as argument");
+ char first = x.charAt(0);
+ if (first == '\'' || first == '\"')
+ return NodeFactory.createLiteral(newString(pm, first, x));
+ if (Character.isDigit(first))
+ return NodeFactory.createLiteral(x, "", XSDDatatype.XSDinteger);
+ if (first == '_')
+ return NodeFactory.createAnon(new AnonId(x));
+ if (x.equals("??"))
+ return Node.ANY;
+ if (first == '?')
+ return NodeFactory.createVariable(x.substring(1));
+ if (first == '&')
+ return NodeFactory.createURI("q:" + x.substring(1));
+ int colon = x.indexOf(':');
+ String d = pm.getNsPrefixURI("");
+ return colon < 0 ? NodeFactory.createURI((d == null ? "eh:/" : d) + x)
+ : NodeFactory.createURI(pm.expandPrefix(x));
+ }
+
+ public static String unEscape(String spelling) {
+ if (spelling.indexOf('\\') < 0)
+ return spelling;
+ StringBuffer result = new StringBuffer(spelling.length());
+ int start = 0;
+ while (true) {
+ int b = spelling.indexOf('\\', start);
+ if (b < 0)
+ break;
+ result.append(spelling.substring(start, b));
+ result.append(unEscape(spelling.charAt(b + 1)));
+ start = b + 2;
+ }
+ result.append(spelling.substring(start));
+ return result.toString();
+ }
+
+ public static char unEscape(char ch) {
+ switch (ch) {
+ case '\\':
+ case '\"':
+ case '\'':
+ return ch;
+ case 'n':
+ return '\n';
+ case 's':
+ return ' ';
+ case 't':
+ return '\t';
+ default:
+ return 'Z';
+ }
+ }
+
+ public static LiteralLabel literal(PrefixMapping pm, String spelling,
+ String langOrType) {
+ String content = unEscape(spelling);
+ int colon = langOrType.indexOf(':');
+ return colon < 0 ? LiteralLabelFactory.create(content, langOrType,
+ false) : LiteralLabelFactory.createLiteralLabel(content, "",
+ NodeFactory.getType(pm.expandPrefix(langOrType)));
+ }
+
+ public static LiteralLabel newString(PrefixMapping pm, char quote,
+ String nodeString) {
+ int close = nodeString.lastIndexOf(quote);
+ return literal(pm, nodeString.substring(1, close),
+ nodeString.substring(close + 1));
+ }
+
+ /**
+ * Utility factory as for create(String), but allowing the PrefixMapping to
+ * be specified explicitly.
+ */
+ public static Triple createTriple(PrefixMapping pm, String fact) {
+ StringTokenizer st = new StringTokenizer(fact);
+ Node sub = create(pm, st.nextToken());
+ Node pred = create(pm, st.nextToken());
+ Node obj = create(pm, st.nextToken());
+ return Triple.create(sub, pred, obj);
+ }
+
+ /**
+ * Utility factory method for creating a triple based on the content of an
+ * "S P O" string. The S, P, O are processed by Node.create, see which for
+ * details of the supported syntax. This method exists to support test code.
+ * Nodes are interpreted using the Standard prefix mapping.
+ */
+
+ public static Triple createTriple(String fact) {
+ return createTriple(PrefixMapping.Standard, fact);
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/src/test/java/org/apache/jena/testing_framework/NodeProducerInterface.java
----------------------------------------------------------------------
diff --git a/jena-core/src/test/java/org/apache/jena/testing_framework/NodeProducerInterface.java b/jena-core/src/test/java/org/apache/jena/testing_framework/NodeProducerInterface.java
new file mode 100644
index 0000000..c80d3f4
--- /dev/null
+++ b/jena-core/src/test/java/org/apache/jena/testing_framework/NodeProducerInterface.java
@@ -0,0 +1,32 @@
+/*
+ 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.testing_framework;
+
+/**
+ * Creates the graph for testing. Implementations must track the creation of
+ * graphs created with newGraph and close them when closeGraphs is called.
+ *
+ */
+//public interface NodeProducerInterface {
+//
+// /**
+// * Returns a new anonymous RDFNode in an model.
+// */
+// public abstract RDFNode newRDFNode();
+//
+// }
http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/src/test/java/org/apache/jena/testing_framework/TestFileData.java
----------------------------------------------------------------------
diff --git a/jena-core/src/test/java/org/apache/jena/testing_framework/TestFileData.java b/jena-core/src/test/java/org/apache/jena/testing_framework/TestFileData.java
new file mode 100644
index 0000000..7b46366
--- /dev/null
+++ b/jena-core/src/test/java/org/apache/jena/testing_framework/TestFileData.java
@@ -0,0 +1,380 @@
+package org.apache.jena.testing_framework;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.Assert.assertTrue;
+import org.junit.Test;
+
+import org.apache.jena.graph.Graph;
+import org.apache.jena.graph.NodeFactory;
+import org.apache.jena.graph.Triple;
+import org.apache.jena.rdf.model.AnonId;
+import org.apache.jena.rdf.model.Model;
+import org.apache.jena.rdf.model.ModelFactory;
+import org.apache.jena.graph.Factory;
+
+/**
+ * Class that produces RDF and TTL data, a Graph and a Model that all contain
+ * the same data. This is used for various tests where files are read/written
+ *
+ */
+public class TestFileData {
+
+ public static final String NS = "uri:urn:x-rdf:test#";
+
+ private static Map<String, String[]> rdfData = new HashMap<String, String[]>();
+ private static Map<String, String[]> ttlData = new HashMap<String, String[]>();
+
+ static {
+ rdfData.put(
+ "", // default set must be equiv to TTL default
+ new String[] {
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>",
+ "<rdf:RDF",
+ " xmlns:u=\"uri:\"",
+ " xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"",
+ String.format(" xmlns:ex=\"%s\">", NS),
+ String.format(
+ " <rdf:Description rdf:about=\"%ssubject\">",
+ NS),
+ String.format(
+ " <ex:predicate rdf:resource=\"%sobject\"/>",
+ NS), " </rdf:Description>",
+ " <rdf:Description rdf:about=\"uri:e\">",
+ " <u:p5>verify base works</u:p5>",
+ " </rdf:Description>", "</rdf:RDF>" });
+ rdfData.put(
+ "realtiveURI", // has relative URI in description rdf:about
+ new String[] {
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>",
+ "<rdf:RDF",
+ " xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"",
+ " xmlns:ex=\"http://example.com/\">",
+ " <rdf:Description rdf:about=\"http://example.com/subject\">",
+ " <ex:predicate rdf:resource=\"http://example.com/object\"/>",
+ " </rdf:Description>",
+ " <rdf:Description rdf:about=\"e\">",
+ " <ex:p5>verify base works</ex:p5>",
+ " </rdf:Description>", "</rdf:RDF>" });
+ rdfData.put(
+ "OntologyList0",
+ new String[] {
+ "<?xml version='1.0' encoding='ISO-8859-1'?>",
+ "<!DOCTYPE rdf:RDF [",
+ " <!ENTITY rdf 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'>",
+ " <!ENTITY rdfs 'http://www.w3.org/2000/01/rdf-schema#'>",
+ "]>",
+ "<rdf:RDF",
+ " xmlns:rdf =\"&rdf;\"",
+ " xmlns:rdfs =\"&rdfs;\"",
+ String.format(" xml:base =\"%s\"",
+ NS.substring(0, NS.length() - 1)),
+ String.format(" xmlns =\"%s\"", NS), ">",
+ "<rdf:Description rdf:ID=\"root\">",
+ " <p rdf:parseType=\"Collection\">", " </p>",
+ "</rdf:Description>", "</rdf:RDF>" });
+ rdfData.put(
+ "OntologyList1",
+ new String[] {
+ "<?xml version='1.0' encoding='ISO-8859-1'?>",
+ "<!DOCTYPE rdf:RDF [",
+ " <!ENTITY rdf 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'>",
+ " <!ENTITY rdfs 'http://www.w3.org/2000/01/rdf-schema#'>",
+ "]>",
+ "<rdf:RDF",
+ " xmlns:rdf =\"&rdf;\"",
+ " xmlns:rdfs =\"&rdfs;\"",
+ String.format(" xml:base =\"%s\"",
+ NS.substring(0, NS.length() - 1)),
+ String.format(" xmlns =\"%s\"", NS), ">",
+ "<rdf:Description rdf:ID=\"root\">",
+ " <p rdf:parseType=\"Collection\">",
+ " <rdf:Description rdf:ID=\"a\" />", " </p>",
+ "</rdf:Description>", "</rdf:RDF>" });
+ rdfData.put(
+ "OntologyList2",
+ new String[] {
+ "<?xml version='1.0' encoding='ISO-8859-1'?>",
+ "<!DOCTYPE rdf:RDF [",
+ " <!ENTITY rdf 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'>",
+ " <!ENTITY rdfs 'http://www.w3.org/2000/01/rdf-schema#'>",
+ "]>",
+ "<rdf:RDF",
+ " xmlns:rdf =\"&rdf;\"",
+ " xmlns:rdfs =\"&rdfs;\"",
+ String.format(" xml:base =\"%s\"",
+ NS.substring(0, NS.length() - 1)),
+ String.format(" xmlns =\"%s\"", NS), ">",
+ "<rdf:Description rdf:ID=\"root\">",
+ " <p rdf:parseType=\"Collection\">",
+ " <rdf:Description rdf:ID=\"a\" />",
+ " <rdf:Description rdf:ID=\"b\" />", " </p>",
+ "</rdf:Description>", "</rdf:RDF>" });
+ rdfData.put(
+ "OntologyList3",
+ new String[] {
+ "<?xml version='1.0' encoding='ISO-8859-1'?>",
+ "<!DOCTYPE rdf:RDF [",
+ " <!ENTITY rdf 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'>",
+ " <!ENTITY rdfs 'http://www.w3.org/2000/01/rdf-schema#'>",
+ "]>",
+ "<rdf:RDF",
+ " xmlns:rdf =\"&rdf;\"",
+ " xmlns:rdfs =\"&rdfs;\"",
+ String.format(" xml:base =\"%s\"",
+ NS.substring(0, NS.length() - 1)),
+ String.format(" xmlns =\"%s\"", NS), ">",
+ "<rdf:Description rdf:ID=\"root\">",
+ " <p rdf:parseType=\"Collection\">",
+ " <rdf:Description rdf:ID=\"a\" />",
+ " <rdf:Description rdf:ID=\"b\" />",
+ " <rdf:Description rdf:ID=\"c\" />", " </p>",
+ "</rdf:Description>", "</rdf:RDF>" });
+ rdfData.put(
+ "OntologyList4",
+ new String[] {
+ "<?xml version='1.0' encoding='ISO-8859-1'?>",
+ "<!DOCTYPE rdf:RDF [",
+ " <!ENTITY rdf 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'>",
+ " <!ENTITY rdfs 'http://www.w3.org/2000/01/rdf-schema#'>",
+ "]>",
+ "<rdf:RDF",
+ " xmlns:rdf =\"&rdf;\"",
+ " xmlns:rdfs =\"&rdfs;\"",
+ String.format(" xml:base =\"%s\"",
+ NS.substring(0, NS.length() - 1)),
+ String.format(" xmlns =\"%s\"", NS), ">",
+ "<rdf:Description rdf:ID=\"root\">",
+ " <p rdf:parseType=\"Collection\">",
+ " <rdf:Description rdf:ID=\"a\" />",
+ " <rdf:Description rdf:ID=\"b\" />",
+ " <rdf:Description rdf:ID=\"c\" />",
+ " <rdf:Description rdf:ID=\"d\" />", " </p>",
+ "</rdf:Description>", "</rdf:RDF>" });
+ rdfData.put(
+ "OntologyList5",
+ new String[] {
+ "<?xml version='1.0' encoding='ISO-8859-1'?>",
+ "<!DOCTYPE rdf:RDF [",
+ " <!ENTITY rdf 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'>",
+ " <!ENTITY rdfs 'http://www.w3.org/2000/01/rdf-schema#'>",
+ "]>",
+ "<rdf:RDF",
+ " xmlns:rdf =\"&rdf;\"",
+ " xmlns:rdfs =\"&rdfs;\"",
+ String.format(" xml:base =\"%s\"",
+ NS.substring(0, NS.length() - 1)),
+ String.format(" xmlns =\"%s\"", NS), ">",
+ "<rdf:Description rdf:ID=\"root\">",
+ " <p rdf:parseType=\"Collection\">",
+ " <rdf:Description rdf:ID=\"a\" />",
+ " <rdf:Description rdf:ID=\"b\" />",
+ " <rdf:Description rdf:ID=\"c\" />",
+ " <rdf:Description rdf:ID=\"d\" />",
+ " <rdf:Description rdf:ID=\"e\" />", " </p>",
+ "</rdf:Description>", "</rdf:RDF>" });
+
+ ttlData.put(
+ "", // default set must be equiv to RDF default and must be
+ // parsable as N-TRIPLE
+ new String[] {
+ String.format("<%ssubject> <%spredicate> <%sobject> .",
+ NS, NS, NS), "<e> <p5> \"verify base works\" ." });
+
+ }
+
+ private static String toDataString(String[] lines) {
+ String eol = System.getProperty("line.separator");
+ StringBuilder sb = new StringBuilder();
+ for (String l : lines) {
+ sb.append(l).append(eol);
+ }
+ return sb.toString();
+ }
+
+ public static Graph getGraph() {
+
+ Graph g = Factory.createGraphMem();
+
+ g.add(new Triple(NodeFactory.createURI("http://example.com/subject"),
+ NodeFactory.createURI("http://example.com/predicate"),
+ NodeFactory.createURI("http://example.com/object")));
+
+ g.add(new Triple(NodeFactory.createAnon(AnonId.create("a")),
+ NodeFactory.createURI("http://example.com/p1"), NodeFactory
+ .createAnon(AnonId.create("b"))));
+
+ g.add(new Triple(NodeFactory.createAnon(AnonId.create("b")),
+ NodeFactory.createURI("http://example.com/p2"), NodeFactory
+ .createLiteral("foo")));
+
+ g.add(new Triple(NodeFactory.createURI("http://example.com/ns/e"),
+ NodeFactory.createURI("http://example.com/ns/p5"), NodeFactory
+ .createLiteral("verify base works")));
+
+ return g;
+ }
+
+ public static Model getModel() {
+ return ModelFactory.createModelForGraph(getGraph());
+ }
+
+ public static Model populateRDFModel(Model model, String name)
+ throws IOException {
+ ModelHelper.txnBegin(model);
+ model.read(getRDFInput(name), "http://example.com/test/");
+ ModelHelper.txnCommit(model);
+ return model;
+ }
+
+ public static Model getRDFModel(String name) throws IOException {
+ return populateRDFModel(ModelFactory.createDefaultModel(), name);
+ }
+
+ private static String[] getRDFData(String name) throws IOException {
+ String[] data = rdfData.get(name);
+ if (data == null) {
+ throw new IOException("Can not find RDF data " + name);
+ }
+ return data;
+ }
+
+ public static InputStream getRDFInput(String name) throws IOException {
+ return new ByteArrayInputStream(toDataString(getRDFData(name))
+ .getBytes());
+ }
+
+ public static InputStream getRDFInput() throws IOException {
+ return getRDFInput("");
+ }
+
+ private static String[] getTTLData(String name) throws IOException {
+ String[] data = ttlData.get(name);
+ if (data == null) {
+ throw new IOException("Can not find TTL data " + name);
+ }
+ return data;
+ }
+
+ public static InputStream getTTLInput(String name) throws IOException {
+ return new ByteArrayInputStream(toDataString(getTTLData(name))
+ .getBytes());
+ }
+
+ public static InputStream getTTLInput() throws IOException {
+ return getTTLInput("");
+ }
+
+ public static Reader getRDFReader(String name) throws IOException {
+
+ return new StringReader(toDataString(getRDFData(name)));
+ }
+
+ public static Reader getRDFReader() throws IOException {
+
+ return getRDFReader("");
+ }
+
+ public static Reader getTTLReader() throws IOException {
+ return getTTLReader("");
+ }
+
+ public static Reader getTTLReader(String name) throws IOException {
+ return new StringReader(toDataString(getTTLData(name)));
+ }
+
+ public static String getRDFName(String name) throws IOException {
+ return createFile(toDataString(getRDFData(name)), ".rdf");
+ }
+
+ public static String getRDFName() throws IOException {
+ return getRDFName("");
+ }
+
+ private static String createFile(String data, String extension)
+ throws IOException {
+ File f = File.createTempFile("tfd", extension);
+ f.deleteOnExit();
+ FileOutputStream fos = new FileOutputStream(f);
+ // fos.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>".getBytes());
+ // fos.write(System.getProperty("line.separator").getBytes());
+ fos.write(data.getBytes());
+ fos.close();
+ return f.toURI().toURL().toExternalForm();
+ }
+
+ public static String getTTLName() throws IOException {
+ return getTTLName("");
+ }
+
+ public static String getTTLName(String name) throws IOException {
+ return createFile(toDataString(getTTLData(name)), ".ttl");
+ }
+
+ @Test
+ public void testEquality() throws Exception {
+ Model ttl = ModelFactory.createDefaultModel().read(getTTLInput(), NS,
+ "TTL");
+ Model rdf = ModelFactory.createDefaultModel().read(getRDFInput(), NS,
+ "RDF/XML-ABBREV");
+
+ assertTrue(ttl.isIsomorphicWith(rdf));
+ assertTrue(rdf.isIsomorphicWith(ttl));
+ }
+
+ public static void main(String... argv) throws Exception {
+ // //Model model = ModelFactory.createDefaultModel() ;
+ // //String x = "<s> <p> 'verify it works' ." ;
+ //
+ //
+ // //Reader sr = getTTLReader();
+ // //model.read(sr, "http://example/", "TTL") ;
+ // //model.read(sr, "", "TTL") ;
+ // //model.read( getRDFInput() );
+ // Model ttl = ModelFactory.createDefaultModel().read( getTTLInput(),
+ // "", "TTL");
+ // Model rdf = ModelFactory.createDefaultModel().read( getRDFInput(),
+ // "", "RDF/XML-ABBREV");
+ //
+ // ttl.write(System.out, "RDF/XML-ABBREV") ;
+ // System.out.println("-----") ;
+ // // model.setNsPrefix("ex", "http://example/") ;
+ // rdf.write(System.out, "N-TRIPLES") ;
+ // System.out.println("-----") ;
+ // System.out.println( getTTLName() );
+ // System.out.println( "ttl iso rdf: "+ttl.isIsomorphicWith(rdf));
+ //
+ // System.out.println( getRDFName() );
+ // System.out.println( "rdf iso ttl: "+rdf.isIsomorphicWith(ttl));
+
+ String[] lines = { "<rdf:RDF",
+ " xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">",
+ " <rdf:Description rdf:about=\"e\">",
+ " <p5>verify base works</p5>", " </rdf:Description>",
+ "</rdf:RDF>" };
+
+ String eol = System.getProperty("line.separator");
+ StringBuilder sb = new StringBuilder();
+ for (String l : lines) {
+ sb.append(l).append(eol);
+ }
+
+ Model model = ModelFactory.createDefaultModel();
+
+ StringReader sr = new StringReader(sb.toString());
+ model.read(sr, "http://example/");
+ model.write(System.out, "N-TRIPLES");
+ System.out.println("-----");
+ model.setNsPrefix("ex", "http://example/");
+ model.write(System.out, "RDF/XML-ABBREV", "http://another/");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/src/test/java/org/apache/jena/testing_framework/TestUtils.java
----------------------------------------------------------------------
diff --git a/jena-core/src/test/java/org/apache/jena/testing_framework/TestUtils.java b/jena-core/src/test/java/org/apache/jena/testing_framework/TestUtils.java
new file mode 100644
index 0000000..78d4bab
--- /dev/null
+++ b/jena-core/src/test/java/org/apache/jena/testing_framework/TestUtils.java
@@ -0,0 +1,320 @@
+/*
+ * 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.testing_framework;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Constructor;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import org.slf4j.LoggerFactory;
+
+import static org.junit.Assert.*;
+
+import org.apache.jena.util.CollectionFactory;
+import org.apache.jena.util.iterator.ExtendedIterator;
+import org.apache.jena.util.iterator.WrappedIterator;
+
+/**
+ * Foo basis for Jena test cases which provides assertFalse and assertDiffer.
+ * Often the logic of the names is clearer than using a negation.
+ */
+public class TestUtils {
+ // do not instantiate
+ protected TestUtils() {
+ throw new UnsupportedOperationException("Do not instantiate TestUtils");
+ };
+
+ /**
+ * assert that the two objects must be unequal according to .equals().
+ *
+ * @param title
+ * a labelling string for the assertion failure text
+ * @param x
+ * an object to test; the subject of a .equals()
+ * @param y
+ * the other object; the argument of the .equals()
+ */
+ public static void assertDiffer(String title, Object x, Object y) {
+ if (x == null ? y == null : x.equals(y))
+ fail((title == null ? "objects should be different, but both were: "
+ : title)
+ + x);
+ }
+
+ /**
+ * assert that the two objects must be unequal according to .equals().
+ *
+ * @param x
+ * an object to test; the subject of a .equals()
+ * @param y
+ * the other object; the argument of the .equals()
+ */
+ public static void assertDiffer(Object x, Object y) {
+ assertDiffer(null, x, y);
+ }
+
+ /**
+ * assert that the object <code>x</code> must be of the class
+ * <code>expected</code>.
+ */
+ public static void assertInstanceOf(Class<?> expected, Object x) {
+ if (x == null)
+ fail("expected instance of " + expected + ", but had null");
+ if (!expected.isInstance(x))
+ fail("expected instance of " + expected + ", but had instance of "
+ + x.getClass());
+ }
+
+ /**
+ * Answer a Set formed from the elements of the List <code>L</code>.
+ */
+ public static <T> Set<T> listToSet(List<T> L) {
+ return CollectionFactory.createHashedSet(L);
+ }
+
+ /**
+ * Answer a List of the substrings of <code>s</code> that are separated by
+ * spaces.
+ */
+ public static List<String> listOfStrings(String s) {
+ List<String> result = new ArrayList<String>();
+ StringTokenizer st = new StringTokenizer(s);
+ while (st.hasMoreTokens())
+ result.add(st.nextToken());
+ return result;
+ }
+
+ /**
+ * Answer a Set of the substrings of <code>s</code> that are separated by
+ * spaces.
+ */
+ public static Set<String> setOfStrings(String s) {
+ Set<String> result = new HashSet<String>();
+ StringTokenizer st = new StringTokenizer(s);
+ while (st.hasMoreTokens())
+ result.add(st.nextToken());
+ return result;
+ }
+
+ /**
+ * Answer a list containing the single object <code>x</code>.
+ */
+ public static <T> List<T> listOfOne(T x) {
+ List<T> result = new ArrayList<T>();
+ result.add(x);
+ return result;
+ }
+
+ /**
+ * Answer a Set containing the single object <code>x</code>.
+ */
+ public static <T> Set<T> setOfOne(T x) {
+ Set<T> result = new HashSet<T>();
+ result.add(x);
+ return result;
+ }
+
+ /**
+ * Answer a fresh list which is the concatenation of <code>L</code> then
+ * <code>R</code>. Neither <code>L</code> nor <code>R</code> is updated.
+ */
+ public static <T> List<T> append(List<? extends T> L, List<? extends T> R) {
+ List<T> result = new ArrayList<T>(L);
+ result.addAll(R);
+ return result;
+ }
+
+ /**
+ * Answer an iterator over the space-separated substrings of <code>s</code>.
+ */
+ protected static ExtendedIterator<String> iteratorOfStrings(String s) {
+ return WrappedIterator.create(listOfStrings(s).iterator());
+ }
+
+ /**
+ * Answer the constructor of the class <code>c</code> which takes arguments
+ * of the type(s) in <code>args</code>, or <code>null</code> if there isn't
+ * one.
+ */
+ public static Constructor<?> getConstructor(Class<?> c, Class<?>[] args) {
+ try {
+ return c.getConstructor(args);
+ } catch (NoSuchMethodException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Answer true iff <code>subClass</code> is the same class as
+ * <code>superClass</code>, if its superclass <i>is</i>
+ * <code>superClass</code>, or if one of its interfaces hasAsInterface that
+ * class.
+ */
+ public static boolean hasAsParent(Class<?> subClass, Class<?> superClass) {
+ if (subClass == superClass || subClass.getSuperclass() == superClass)
+ return true;
+ Class<?>[] is = subClass.getInterfaces();
+ for (int i = 0; i < is.length; i += 1)
+ if (hasAsParent(is[i], superClass))
+ return true;
+ return false;
+ }
+
+ /**
+ * Fail unless <code>subClass</code> has <code>superClass</code> as a
+ * parent, either a superclass or an implemented (directly or not)
+ * interface.
+ */
+ public static void assertHasParent(Class<?> subClass, Class<?> superClass) {
+ if (hasAsParent(subClass, superClass) == false)
+ fail("" + subClass + " should have " + superClass + " as a parent");
+ }
+
+ /**
+ * Tests o1.equals( o2 ) && o2.equals(o1) && o1.hashCode() == o2.hashCode()
+ *
+ * @param o1
+ * @param o2
+ */
+ public static void assertEquivalent(Object o1, Object o2) {
+ assertEquals(o1, o2);
+ assertEquals(o2, o1);
+ assertEquals(o1.hashCode(), o2.hashCode());
+ }
+
+ /**
+ * Tests o1.equals( o2 ) && o2.equals(o1) && o1.hashCode() == o2.hashCode()
+ *
+ * @param o1
+ * @param o2
+ */
+ public static void assertEquivalent(String msg, Object o1, Object o2) {
+ assertEquals(msg, o1, o2);
+ assertEquals(msg, o2, o1);
+ assertEquals(msg, o1.hashCode(), o2.hashCode());
+ }
+
+ /**
+ * Tests o1.equals( o2 ) && o2.equals(o1) && o1.hashCode() == o2.hashCode()
+ *
+ * @param o1
+ * @param o2
+ */
+ public static void assertNotEquivalent(String msg, Object o1, Object o2) {
+ assertNotEquals(msg, o1, o2);
+ assertNotEquals(msg, o2, o1);
+ }
+
+ private static URL getURL(String fn) {
+ URL u = TestUtils.class.getClassLoader().getResource(fn);
+ if (u == null) {
+ throw new RuntimeException(new FileNotFoundException(fn));
+ }
+ return u;
+ }
+
+ public static String getFileName(String fn) {
+
+ try {
+ return getURL(fn).toURI().toString();
+ } catch (URISyntaxException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static InputStream getInputStream(String fn) throws IOException {
+ return getURL(fn).openStream();
+ }
+
+ // FIXME this is to be removed when testing is complete
+ public static void logAssertEquals(Class<?> clazz, String msg, Object obj1,
+ Object obj2) {
+ if (obj1 == null && obj2 == null) {
+ return;
+ }
+
+ if (obj1 != null) {
+ if (obj1 == obj2) {
+ return;
+ }
+ if (obj1.equals(obj2)) {
+ return;
+ }
+ }
+ LoggerFactory.getLogger(clazz).warn(
+ String.format("%s expected: %s got: %s", msg, obj1, obj2));
+ System.out.println(String.format("[%sWARNING] %s expected: %s got: %s",
+ clazz, msg, obj1, obj2));
+ }
+
+ // FIXME this is to be removed when testing is complete
+ public static void logAssertTrue(Class<?> clazz, String msg, boolean value) {
+ if (value) {
+ return;
+ }
+
+ LoggerFactory.getLogger(clazz).warn(String.format("%s", msg));
+ System.out.println(String.format("[%s WARNING] %s ", clazz, msg));
+ }
+
+ // FIXME this is to be removed when testing is complete
+ public static void logAssertFalse(Class<?> clazz, String msg, boolean value) {
+ if (!value) {
+ return;
+ }
+
+ LoggerFactory.getLogger(clazz).warn(String.format("%s", msg));
+ System.out.println(String.format("[%s WARNING] %s ", clazz, msg));
+ }
+
+ // FIXME this is to be removed when testing is complete
+ public static void logAssertSame(Class<?> clazz, String msg, Object obj1,
+ Object obj2) {
+ if (obj1 == null && obj2 == null) {
+ return;
+ }
+
+ if (obj1 != null) {
+ if (obj1 == obj2) {
+ return;
+ }
+ }
+ LoggerFactory.getLogger(clazz).warn(
+ String.format("%s expected: %s got: %s", msg, obj1, obj2));
+ System.out
+ .println(String.format("[%s WARNING] %s expected: %s got: %s",
+ clazz, msg, obj1, obj2));
+ }
+
+ public static String safeName(String s) {
+ // Safe from Eclipse
+ s = s.replace('(', '[');
+ s = s.replace(')', ']');
+ return s;
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/src/test/java/org/apache/jena/testing_framework/manifest/Manifest.java
----------------------------------------------------------------------
diff --git a/jena-core/src/test/java/org/apache/jena/testing_framework/manifest/Manifest.java b/jena-core/src/test/java/org/apache/jena/testing_framework/manifest/Manifest.java
new file mode 100644
index 0000000..79d2fce
--- /dev/null
+++ b/jena-core/src/test/java/org/apache/jena/testing_framework/manifest/Manifest.java
@@ -0,0 +1,228 @@
+/*
+ * 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.testing_framework.manifest;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.jena.n3.IRIResolver;
+import org.apache.jena.rdf.model.*;
+import org.apache.jena.util.FileManager;
+import org.apache.jena.vocabulary.RDF;
+import org.apache.jena.vocabulary.RDFS;
+import org.apache.jena.vocabulary.TestManifest;
+import org.apache.jena.vocabulary.TestManifestX;
+
+/**
+ * A test manifest for a single manifest file.
+ */
+
+public class Manifest {
+ // This class does not know about JUnit.
+ private static Logger log = LoggerFactory.getLogger(Manifest.class);
+ private Model manifest;
+ private String manifestName;
+ private String filename;
+ private List<String> includedFiles = new ArrayList<String>();
+ private Resource manifestRes = null;
+
+ public Manifest(String fn) {
+ log.debug("Manifest = " + fn);
+ filename = IRIResolver.resolveGlobal(fn);
+ log.debug(" = " + filename);
+ manifest = FileManager.get().loadModel(filename);
+ parseIncludes();
+ parseManifest();
+ }
+
+ public String getName() {
+ return manifestName;
+ }
+
+ public Iterator<String> includedManifests() {
+ return includedFiles.iterator();
+ }
+
+ private void parseManifest() {
+ StmtIterator manifestStmts = manifest.listStatements(null, RDF.type,
+ TestManifest.Manifest);
+ if (!manifestStmts.hasNext()) {
+ log.warn("No manifest in manifest file: " + filename);
+ return;
+ }
+
+ Statement manifestItemStmt = manifestStmts.nextStatement();
+ if (manifestStmts.hasNext()) {
+ log.warn("Multiple manifests in manifest file: " + filename);
+ return;
+ }
+
+ manifestRes = manifestItemStmt.getSubject();
+ manifestName = getLiteral(manifestRes, RDFS.label);
+ if (manifestName == null)
+ manifestName = getLiteral(manifestRes, RDFS.comment);
+ manifestStmts.close();
+ }
+
+ // For every test item (does not recurse)
+ public void apply(ManifestItemHandler gen) {
+
+ StmtIterator manifestStmts = manifest.listStatements(null, RDF.type,
+ TestManifest.Manifest);
+
+ for (; manifestStmts.hasNext();) {
+ Statement manifestItemStmt = manifestStmts.nextStatement();
+ Resource manifestRes = manifestItemStmt.getSubject();
+
+ // For each item in this manifest
+ StmtIterator listIter = manifestRes
+ .listProperties(TestManifest.entries);
+ for (; listIter.hasNext();) {
+ // List head
+ Resource listItem = listIter.nextStatement().getResource();
+ for (; !listItem.equals(RDF.nil);) {
+ ManifestItem item = new ManifestItem(listItem
+ .getRequiredProperty(RDF.first).getResource());
+ gen.processManifestItem(item);
+ // Move to next list item
+ listItem = listItem.getRequiredProperty(RDF.rest)
+ .getResource();
+ }
+ }
+ listIter.close();
+ }
+ manifestStmts.close();
+ }
+
+ // -------- included manifests
+ private void parseIncludes() {
+ parseIncludes(TestManifest.include);
+ parseIncludes(TestManifestX.include);
+ }
+
+ private void parseIncludes(Property property) {
+ StmtIterator includeStmts = manifest.listStatements(null, property,
+ (RDFNode) null);
+
+ for (; includeStmts.hasNext();) {
+ Statement s = includeStmts.nextStatement();
+ if (!(s.getObject() instanceof Resource)) {
+ log.warn("Include: not a Resource" + s);
+ continue;
+ }
+ Resource r = s.getResource();
+ parseOneIncludesList(r);
+ }
+ includeStmts.close();
+ }
+
+ private void parseOneIncludesList(Resource r) {
+ if (r == null)
+ return;
+
+ if (r.equals(RDF.nil))
+ return;
+
+ if (!r.isAnon()) {
+ String uri = r.getURI();
+ if (includedFiles.contains(uri))
+ return;
+ includedFiles.add(r.getURI());
+ return;
+ }
+
+ // BNnode => list
+ Resource listItem = r;
+ while (!listItem.equals(RDF.nil)) {
+ r = listItem.getRequiredProperty(RDF.first).getResource();
+ parseOneIncludesList(r);
+ // Move on
+ listItem = listItem.getRequiredProperty(RDF.rest).getResource();
+ }
+ }
+
+ public static Resource getResource(Resource r, Property p) {
+ if (r == null)
+ return null;
+ if (!r.hasProperty(p))
+ return null;
+
+ RDFNode n = r.getProperty(p).getObject();
+ if (n instanceof Resource)
+ return (Resource) n;
+
+ throw new ManifestException("Manifest problem (not a Resource): " + n
+ + " => " + p);
+ }
+
+ public static Collection<Resource> listResources(Resource r, Property p) {
+ if (r == null)
+ return null;
+ List<Resource> x = new ArrayList<Resource>();
+ StmtIterator sIter = r.listProperties(p);
+ for (; sIter.hasNext();) {
+ RDFNode n = sIter.next().getObject();
+ if (!(n instanceof Resource))
+ throw new ManifestException(
+ "Manifest problem (not a Resource): " + n + " => " + p);
+ x.add((Resource) n);
+ }
+ return x;
+ }
+
+ public static String getLiteral(Resource r, Property p) {
+ if (r == null)
+ return null;
+ if (!r.hasProperty(p))
+ return null;
+
+ RDFNode n = r.getProperty(p).getObject();
+ if (n instanceof Literal)
+ return ((Literal) n).getLexicalForm();
+
+ throw new ManifestException("Manifest problem (not a Literal): " + n
+ + " => " + p);
+ }
+
+ public static String getLiteralOrURI(Resource r, Property p) {
+ if (r == null)
+ return null;
+
+ if (!r.hasProperty(p))
+ return null;
+
+ RDFNode n = r.getProperty(p).getObject();
+ if (n instanceof Literal)
+ return ((Literal) n).getLexicalForm();
+
+ if (n instanceof Resource) {
+ Resource r2 = (Resource) n;
+ if (!r2.isAnon())
+ return r2.getURI();
+ }
+
+ throw new ManifestException("Manifest problem: " + n + " => " + p);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/src/test/java/org/apache/jena/testing_framework/manifest/ManifestException.java
----------------------------------------------------------------------
diff --git a/jena-core/src/test/java/org/apache/jena/testing_framework/manifest/ManifestException.java b/jena-core/src/test/java/org/apache/jena/testing_framework/manifest/ManifestException.java
new file mode 100644
index 0000000..14a3d44
--- /dev/null
+++ b/jena-core/src/test/java/org/apache/jena/testing_framework/manifest/ManifestException.java
@@ -0,0 +1,48 @@
+/*
+ * 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.testing_framework.manifest;
+
+/**
+ * TestException a root exception for all (intentional) exceptions in tests
+ * setup, not a failure of the test itself (e.g. manifest problems)
+ */
+
+public class ManifestException extends RuntimeException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 5601201233175898449L;
+
+ public ManifestException() {
+ super();
+ }
+
+ public ManifestException(Throwable cause) {
+ super(cause);
+ }
+
+ public ManifestException(String msg) {
+ super(msg);
+ }
+
+ public ManifestException(String msg, Throwable cause) {
+ super(msg, cause);
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/src/test/java/org/apache/jena/testing_framework/manifest/ManifestFile.java
----------------------------------------------------------------------
diff --git a/jena-core/src/test/java/org/apache/jena/testing_framework/manifest/ManifestFile.java b/jena-core/src/test/java/org/apache/jena/testing_framework/manifest/ManifestFile.java
new file mode 100644
index 0000000..d7493bb
--- /dev/null
+++ b/jena-core/src/test/java/org/apache/jena/testing_framework/manifest/ManifestFile.java
@@ -0,0 +1,38 @@
+/*
+ * 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.testing_framework.manifest;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation to declare the manifest file for the test.
+ *
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ManifestFile {
+ /**
+ * The file that the annotated class should read
+ */
+ String value();
+
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/src/test/java/org/apache/jena/testing_framework/manifest/ManifestItem.java
----------------------------------------------------------------------
diff --git a/jena-core/src/test/java/org/apache/jena/testing_framework/manifest/ManifestItem.java b/jena-core/src/test/java/org/apache/jena/testing_framework/manifest/ManifestItem.java
new file mode 100644
index 0000000..81999bd
--- /dev/null
+++ b/jena-core/src/test/java/org/apache/jena/testing_framework/manifest/ManifestItem.java
@@ -0,0 +1,53 @@
+package org.apache.jena.testing_framework.manifest;
+
+import org.apache.jena.n3.turtle.TurtleTestVocab;
+import org.apache.jena.rdf.model.Resource;
+import org.apache.jena.vocabulary.RDF;
+import org.apache.jena.vocabulary.TestManifest;
+
+public class ManifestItem {
+ private Resource entry;
+
+ public ManifestItem(Resource entry) {
+ this.entry = entry;
+ }
+
+ public Resource getEntry() {
+ return entry;
+ }
+
+ public String getTestName() {
+ return Manifest.getLiteral(entry, TestManifest.name);
+ }
+
+ public Resource getAction() {
+ return Manifest.getResource(entry, TestManifest.action);
+ }
+
+ public Resource getResult() {
+ return Manifest.getResource(entry, TestManifest.result);
+ }
+
+ public Resource getType() {
+ return Manifest.getResource(entry, RDF.type);
+ }
+
+ public Resource getOutput() {
+ Resource result = getResult();
+ return result == null ? null : Manifest.getResource(result,
+ TurtleTestVocab.output);
+ }
+
+ public Resource getInput() {
+ Resource action = getAction();
+ return action == null ? null : Manifest.getResource(action,
+ TurtleTestVocab.input);
+ }
+
+ public String getUriString() {
+ Resource action = getAction();
+ Resource inputIRIr = action == null ? null : Manifest.getResource(
+ action, TurtleTestVocab.inputIRI);
+ return (inputIRIr == null) ? null : inputIRIr.getURI();
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/src/test/java/org/apache/jena/testing_framework/manifest/ManifestItemHandler.java
----------------------------------------------------------------------
diff --git a/jena-core/src/test/java/org/apache/jena/testing_framework/manifest/ManifestItemHandler.java b/jena-core/src/test/java/org/apache/jena/testing_framework/manifest/ManifestItemHandler.java
new file mode 100644
index 0000000..08ce69f
--- /dev/null
+++ b/jena-core/src/test/java/org/apache/jena/testing_framework/manifest/ManifestItemHandler.java
@@ -0,0 +1,35 @@
+/*
+ * 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.testing_framework.manifest;
+
+import java.util.List;
+
+import org.junit.runner.Runner;
+import org.junit.runners.model.InitializationError;
+
+public interface ManifestItemHandler {
+ /**
+ * Handle an item in a manifest
+ *
+ * @throws InitializationError
+ */
+ public void processManifestItem(ManifestItem item);
+
+ public void setTestRunnerList(List<Runner> runners);
+}