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); +}
