/*
* The contents of this file are subject to the Open Software License
* Version 3.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.opensource.org/licenses/osl-3.0.txt
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*/
package org.mulgara.store.tuples;
// Third party packages
import junit.framework.*; // JUnit
import org.apache.log4j.Logger; // Log4J
// Locally written packages
import org.mulgara.query.TuplesException;
import org.mulgara.query.Variable;
/**
* Test case for {@link Difference}.
*
* @created 2005-03-31
* @author <a href="mailto:pgearon@users.sourceforge.net">Paula Gearon</a>
* @copyright © 2003 <A href="http://www.topazproject.org/">The Topaz Project</A>
* @licence <a href="{@docRoot}/../../LICENCE">Open Software License v3.0</a>
*/
public class DifferenceUnitTest extends TestCase {
/** Logger. */
@SuppressWarnings("unused")
private static final Logger logger = Logger.getLogger(DifferenceUnitTest.class);
/** Test variable. */
final Variable x = new Variable("x");
/** Test variable. */
final Variable y = new Variable("y");
/** Test variable. */
final Variable z = new Variable("z");
/** Test variable. */
final Variable w = new Variable("w");
/** Test variable. */
final Variable u = new Variable("u");
/** Test variable. */
final Variable v = new Variable("v");
/**
* Constructs a new test with the given name.
*
* @param name the name of the test
*/
public DifferenceUnitTest(String name) {
super(name);
}
/**
* Hook for test runner to obtain a test suite from.
*
* @return The test suite
*/
public static Test suite() {
TestSuite testSuite = new TestSuite();
testSuite.addTest(new DifferenceUnitTest("testNoCommonVars"));
testSuite.addTest(new DifferenceUnitTest("testOneIntersectingVar"));
testSuite.addTest(new DifferenceUnitTest("testIntersectingVars"));
// The following test requires suffix matching with unbound prefixes, which is not working
// testSuite.addTest(new DifferenceUnitTest("testNullJoin"));
// testSuite.addTest(new DifferenceUnitTest("testNullPropagation"));
// testSuite.addTest(new DifferenceUnitTest("testLeadingPrefixNull"));
return testSuite;
}
/**
* Default text runner.
*
* @param args The command line arguments
*/
public static void main(String[] args) {
junit.textui.TestRunner.run(suite());
}
/**
* Create test instance.
*
* @throws Exception EXCEPTION TO DO
*/
public void setUp() throws Exception {
// null implementation
}
/**
* The teardown method for JUnit
*
* @throws Exception EXCEPTION TO DO
*/
public void tearDown() throws Exception {
// null implementation
}
//
// Test cases
//
/**
* Test {@link Difference}. When passed two arguments without common
* variables, an IllegalArgumentException should be thrown.
*
* @throws Exception if query fails when it should have succeeded
*/
public void testNoCommonVars() throws Exception {
Tuples lhs =
TuplesFactory.newInstance().newTuples(new MemoryTuples(x, 1).and(y, 2)
.or(x, 3).and(y,
4));
Tuples rhs =
TuplesFactory.newInstance().newTuples(new MemoryTuples(z, 5).and(w, 6)
.or(z, 7).and(w,
8));
try {
new Difference(lhs, rhs);
assertTrue(false);
} catch (IllegalArgumentException e) {
/* no-op */
}
TuplesTestingUtil.closeTuples(new Tuples[] { lhs, rhs });
}
/**
* Test {@link Difference}. When passed arguments with some common variables,
* the result should be the first argument, minus any matching rows from the second.
*
* @throws Exception if query fails when it should have succeeded
*/
public void testOneIntersectingVar() throws Exception {
String[] lvars = new String[] {"x", "y"};
String[] rvars = new String[] {"y", "z"};
LiteralTuples lhs = new LiteralTuples(lvars);
lhs.appendTuple(new long[] {1, 2});
lhs.appendTuple(new long[] {3, 4});
lhs.appendTuple(new long[] {5, 6});
lhs.appendTuple(new long[] {7, 8});
lhs.appendTuple(new long[] {9, 10});
LiteralTuples rhs = new LiteralTuples(rvars);
rhs.appendTuple(new long[] {4, 11});
rhs.appendTuple(new long[] {6, 12});
rhs.appendTuple(new long[] {11, 13});
Tuples diff = new Difference(lhs, rhs);
Tuples actual = TuplesOperations.sort(diff);
// check the variables
Variable[] variables = diff.getVariables();
assertEquals(2, variables.length);
assertEquals(x, variables[0]);
assertEquals(y, variables[1]);
variables = actual.getVariables();
assertEquals(2, variables.length);
assertEquals(x, variables[0]);
assertEquals(y, variables[1]);
// First, try a straightforward iteration through all rows
actual.beforeFirst();
TuplesTestingUtil.testTuplesRow(actual, new long[] {1, 2});
TuplesTestingUtil.testTuplesRow(actual, new long[] {7, 8});
TuplesTestingUtil.testTuplesRow(actual, new long[] {9, 10});
assertTrue(!actual.next());
// Second, try prefix searches
actual.beforeFirst(new long[] { 7 }, 0);
TuplesTestingUtil.testTuplesRow(actual, new long[] {7, 8 });
assertTrue(!actual.next());
// Third, try more prefix searches
actual.beforeFirst(new long[] { 9, 10 }, 0);
TuplesTestingUtil.testTuplesRow(actual, new long[] {9, 10 });
assertTrue(!actual.next());
actual.close();
// Try joining in the opposite order (RHS to LHS)
// first, re-order the lhs
lvars = new String[] {"y", "x"};
lhs = new LiteralTuples(lvars);
lhs.appendTuple(new long[] {2, 1});
lhs.appendTuple(new long[] {4, 3});
lhs.appendTuple(new long[] {6, 5});
lhs.appendTuple(new long[] {8, 7});
lhs.appendTuple(new long[] {10, 9});
actual = new Difference(rhs, lhs);
variables = actual.getVariables();
assertEquals(2, variables.length);
assertEquals(y, variables[0]);
assertEquals(z, variables[1]);
actual.beforeFirst();
TuplesTestingUtil.testTuplesRow(actual, new long[] {11, 13});
assertTrue(!actual.next());
TuplesTestingUtil.closeTuples(new Tuples[] {actual, lhs, rhs});
}
/**
* Test {@link Difference}. When passed arguments with some common variables,
* the result should be the first argument, minus any matching rows from the second.
*
* @throws Exception if query fails when it should have succeeded
*/
public void testIntersectingVars() throws Exception {
// lhs intersect rhs = rhs
String[] lvars = new String[] {"x", "y", "z"};
String[] rvars = new String[] {"y", "z"};
LiteralTuples lhs = new LiteralTuples(lvars);
lhs.appendTuple(new long[] {1, 2, 3});
lhs.appendTuple(new long[] {4, 5, 6});
lhs.appendTuple(new long[] {7, 5, 6});
lhs.appendTuple(new long[] {9, 10, 11});
lhs.appendTuple(new long[] {12, 13, 14});
lhs.appendTuple(new long[] {15, 16, 17});
lhs.appendTuple(new long[] {15, 7, 14});
LiteralTuples rhs = new LiteralTuples(rvars);
rhs.appendTuple(new long[] {5, 6});
rhs.appendTuple(new long[] {6, 14});
rhs.appendTuple(new long[] {7, 14});
rhs.appendTuple(new long[] {8, 9});
Tuples actual = TuplesOperations.sort(new Difference(lhs, rhs));
// check the variables
Variable[] variables = actual.getVariables();
assertEquals(3, variables.length);
assertEquals(x, variables[0]);
assertEquals(y, variables[1]);
assertEquals(z, variables[2]);
// First, try a straightforward iteration through all rows
actual.beforeFirst();
TuplesTestingUtil.testTuplesRow(actual, new long[] {1, 2, 3});
TuplesTestingUtil.testTuplesRow(actual, new long[] {9, 10, 11});
TuplesTestingUtil.testTuplesRow(actual, new long[] {12, 13, 14});
TuplesTestingUtil.testTuplesRow(actual, new long[] {15, 16, 17});
assertTrue(!actual.next());
assertEquals(actual.getRowCount(), 4);
// Second, try prefix searches
actual.beforeFirst(new long[] {9}, 0);
TuplesTestingUtil.testTuplesRow(actual, new long[] {9, 10, 11});
assertTrue(!actual.next());
// Third, try more prefix searches
actual.beforeFirst(new long[] {12, 13}, 0);
TuplesTestingUtil.testTuplesRow(actual, new long[] {12, 13, 14});
assertTrue(!actual.next());
// Now test the end
actual.beforeFirst(new long[] {15}, 0);
TuplesTestingUtil.testTuplesRow(actual, new long[] {15, 16, 17});
assertTrue(!actual.next());
actual.close();
// variables: lhs intersect rhs = lhs
// first, reorder the lhs
lvars = new String[] {"y", "z", "x"};
lhs = new LiteralTuples(lvars);
lhs.appendTuple(new long[] {2, 3, 1});
lhs.appendTuple(new long[] {5, 6, 4});
lhs.appendTuple(new long[] {5, 6, 7});
lhs.appendTuple(new long[] {10, 11, 9});
lhs.appendTuple(new long[] {13, 14, 12});
lhs.appendTuple(new long[] {16, 17, 15});
lhs.appendTuple(new long[] {7, 14, 15});
actual = TuplesOperations.sort(new Difference(rhs, lhs));
actual.beforeFirst();
TuplesTestingUtil.testTuplesRow(actual, new long[] {6, 14});
TuplesTestingUtil.testTuplesRow(actual, new long[] {8, 9});
assertTrue(!actual.next());
TuplesTestingUtil.closeTuples(new Tuples[] {actual, lhs, rhs});
// variables: rhs intersect lhs != rhs != lhs
rvars = new String[] {"y", "z", "a"};
rhs = new LiteralTuples(rvars);
rhs.appendTuple(new long[] {5, 6, 3});
rhs.appendTuple(new long[] {6, 14, 1});
rhs.appendTuple(new long[] {7, 14, 2});
rhs.appendTuple(new long[] {8, 9, 11});
actual = TuplesOperations.sort(new Difference(rhs, lhs));
actual.beforeFirst();
TuplesTestingUtil.testTuplesRow(actual, new long[] {6, 14, 1});
TuplesTestingUtil.testTuplesRow(actual, new long[] {8, 9, 11});
assertTrue(!actual.next());
TuplesTestingUtil.closeTuples(new Tuples[] {actual, lhs, rhs});
}
/**
* Test {@link Difference}.n the presence of unconstrained elements.
*/
public void testNullJoin() throws Exception {
String[] vars = new String[] {"x", "y"};
LiteralTuples lhs = new LiteralTuples(vars);
lhs.appendTuple(new long[] {1, 1});
lhs.appendTuple(new long[] {2, 2});
LiteralTuples rhs = new LiteralTuples(vars);
rhs.appendTuple(new long[] {Tuples.UNBOUND, 2});
rhs.appendTuple(new long[] {1, Tuples.UNBOUND});
Tuples actual = TuplesOperations.sort(new Difference(lhs, rhs));
actual.beforeFirst();
assertTrue(!actual.next());
TuplesTestingUtil.closeTuples(new Tuples[] { actual, lhs, rhs } );
}
/**
* Test {@link Difference}.n the presence of unconstrained elements.
* <pre>
* x y z x z x y z
* | 5 6 7 | | * 1 | | 5 6 7 |
* | 2 3 1 | - | 2 * | =
* | 2 4 * |
* </pre>
*/
public void testNullPropagation() throws Exception {
String[] lvars = new String[] { "x", "y", "z" };
final long[][] lhsValues = new long[][] {
new long[] { 5, 6, 7 },
new long[] { 2, 3, 1 },
new long[] { 2, 4, Tuples.UNBOUND } };
LiteralTuples lhs = LiteralTuples.create(lvars, lhsValues);
String[] rvars = new String[] { "x", "z" };
final long[][] rhsValues = new long[][] {
new long[] { Tuples.UNBOUND, 1 },
new long[] { 2, Tuples.UNBOUND } };
LiteralTuples rhs = LiteralTuples.create(rvars, rhsValues);
Tuples actual = TuplesOperations.sort(new Difference(lhs, rhs));
actual.beforeFirst();
TuplesTestingUtil.testTuplesRow(actual, new long[] { 5, 6, 7 } );
assertTrue(!actual.next());
TuplesTestingUtil.closeTuples(new Tuples[] { actual, lhs, rhs });
}
/**
* Test {@link Difference}.n the presence of unconstrained elements.
* <pre>
* x y x y x y
* | * 2 | | * 3 | =
* | 1 * | join | 4 * |
* </pre>
*/
public void testLeadingPrefixNull() throws Exception {
String[] vars = new String[] { "x", "y" };
final long[][] lhsValues = new long[][] {
new long[] { Tuples.UNBOUND, 2 },
new long[] { 1, Tuples.UNBOUND } };
final long[][] rhsValues = new long[][] {
new long[] { Tuples.UNBOUND, 3 },
new long[] { 4, Tuples.UNBOUND } };
LiteralTuples lhs = LiteralTuples.create(vars, lhsValues);
LiteralTuples rhs = LiteralTuples.create(vars, rhsValues);
Tuples actual = TuplesOperations.sort(new Difference(lhs, rhs));
actual.beforeFirst();
assertTrue(!actual.next());
TuplesTestingUtil.closeTuples(new Tuples[] { actual, lhs, rhs });
}
/**
* Internal method used during debugging. This method writes the contents of a tuples
* to STDOUT.
* @param t The tuples to dump
* @throws TuplesException If there was an exception accessing the tuples.
*/
@SuppressWarnings("unused")
private void dumpTuples(Tuples t) throws TuplesException {
Variable[] v = t.getVariables();
for (int i = 0; i < v.length; i++) {
System.out.print(v[i].getName() + " ");
}
System.out.println();
t.beforeFirst();
while (t.next()) {
String line = new String();
for (int i = 0; i < v.length; i++) {
line += t.getColumnValue(t.getColumnIndex(v[i])) + " ";
}
System.out.println(line);
}
}
}