/** * 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.query.filter; import java.net.URI; import java.util.Date; import org.jrdf.graph.Literal; import org.jrdf.graph.Node; import org.mulgara.query.QueryException; import org.mulgara.query.filter.TestContext; import org.mulgara.query.filter.TestContextOwner; import org.mulgara.query.rdf.LiteralImpl; import org.mulgara.query.filter.value.Bool; import org.mulgara.query.filter.value.ComparableExpression; import org.mulgara.query.filter.value.DateTime; import org.mulgara.query.filter.value.TypedLiteral; import org.mulgara.query.filter.value.Var; import static org.mulgara.query.rdf.XSD.*; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** * Tests the < and > functions. * * @created Apr 15, 2008 * @author Paula Gearon * @copyright © 2008 <a href="http://www.topazproject.org/">The Topaz Project</a> * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a> */ public class InequalityComparisonUnitTest extends TestCase { protected URI xsdInt = INT_URI; protected URI xsdFloat = FLOAT_URI; protected URI xsdString = STRING_URI; Bool t = Bool.TRUE; Bool f = Bool.FALSE; /** * Build the unit test. * @param name The name of the test */ public InequalityComparisonUnitTest(String name) { super(name); } /** * Hook for test runner to obtain a test suite from. * @return The test suite */ public static Test suite() { TestSuite suite = new TestSuite(); suite.addTest(new InequalityComparisonUnitTest("testLT")); suite.addTest(new InequalityComparisonUnitTest("testLTE")); suite.addTest(new InequalityComparisonUnitTest("testGT")); suite.addTest(new InequalityComparisonUnitTest("testGTE")); suite.addTest(new InequalityComparisonUnitTest("testVar")); return suite; } private void fnTst(BinaryComparisonFilter fn, Bool expected) throws QueryException { assertTrue(expected.equals(fn)); assertTrue(fn.equals(expected)); } public void testLT() throws Exception { // compares two equal literals fnTst(new LessThan(t, t), f); fnTst(new LessThan(f, f), f); fnTst(new LessThan(f, t), t); fnTst(new LessThan(t, f), f); ComparableExpression lhs = TypedLiteral.newLiteral(7); ComparableExpression rhs = TypedLiteral.newLiteral(7.0); fnTst(new LessThan(lhs, lhs), f); fnTst(new LessThan(lhs, rhs), f); fnTst(new LessThan(rhs, lhs), f); rhs = TypedLiteral.newLiteral(8.0); fnTst(new LessThan(lhs, rhs), t); fnTst(new LessThan(rhs, lhs), f); // compare unequal literal strings lhs = TypedLiteral.newLiteral("foo", null, null); rhs = TypedLiteral.newLiteral("fool", null, null); fnTst(new LessThan(lhs, rhs), t); fnTst(new LessThan(rhs, lhs), f); // compare unequal literals types rhs = TypedLiteral.newLiteral("foo", xsdString, null); try { assertTrue(f.equals(new LessThan(lhs, rhs))); fail("Unequal literals should throw an exception when compared for inequality"); } catch (QueryException qe) { assertTrue(qe.getMessage().startsWith("Type Error")); } Date date = new Date(); lhs = new DateTime(date); rhs = new DateTime(new Date(date.getTime() + 1000)); fnTst(new LessThan(lhs, rhs), t); fnTst(new LessThan(rhs, lhs), f); } public void testGT() throws Exception { // compares two equal literals fnTst(new GreaterThan(t, t), f); fnTst(new GreaterThan(f, f), f); fnTst(new GreaterThan(f, t), f); fnTst(new GreaterThan(t, f), t); ComparableExpression lhs = TypedLiteral.newLiteral(7); ComparableExpression rhs = TypedLiteral.newLiteral(7.0); fnTst(new GreaterThan(lhs, lhs), f); fnTst(new GreaterThan(lhs, rhs), f); fnTst(new GreaterThan(rhs, lhs), f); rhs = TypedLiteral.newLiteral(8.0); fnTst(new GreaterThan(lhs, rhs), f); fnTst(new GreaterThan(rhs, lhs), t); // compare unequal literal strings lhs = TypedLiteral.newLiteral("foo", null, null); rhs = TypedLiteral.newLiteral("foo", null, null); fnTst(new GreaterThan(lhs, rhs), f); fnTst(new GreaterThan(rhs, lhs), f); rhs = TypedLiteral.newLiteral("fool", null, null); fnTst(new GreaterThan(lhs, rhs), f); fnTst(new GreaterThan(rhs, lhs), t); // compare unequal literals types rhs = TypedLiteral.newLiteral("foo", xsdString, null); try { assertTrue(f.equals(new GreaterThan(lhs, rhs))); fail("Unequal literals should throw an exception when compared for inequality"); } catch (QueryException qe) { assertTrue(qe.getMessage().startsWith("Type Error")); } Date date = new Date(); lhs = new DateTime(date); rhs = new DateTime(new Date(date.getTime() + 1000)); fnTst(new GreaterThan(lhs, rhs), f); fnTst(new GreaterThan(rhs, lhs), t); } public void testLTE() throws Exception { // compares two equal literals fnTst(new LessThanEqualTo(t, t), t); fnTst(new LessThanEqualTo(f, f), t); fnTst(new LessThanEqualTo(f, t), t); fnTst(new LessThanEqualTo(t, f), f); ComparableExpression lhs = TypedLiteral.newLiteral(7); ComparableExpression rhs = TypedLiteral.newLiteral(7.0); fnTst(new LessThanEqualTo(lhs, lhs), t); fnTst(new LessThanEqualTo(lhs, rhs), t); fnTst(new LessThanEqualTo(rhs, lhs), t); rhs = TypedLiteral.newLiteral(8.0); fnTst(new LessThanEqualTo(lhs, rhs), t); fnTst(new LessThanEqualTo(rhs, lhs), f); // compare unequal literal strings lhs = TypedLiteral.newLiteral("foo", null, null); rhs = TypedLiteral.newLiteral("foo", null, null); fnTst(new LessThanEqualTo(lhs, rhs), t); fnTst(new LessThanEqualTo(rhs, lhs), t); rhs = TypedLiteral.newLiteral("fool", null, null); fnTst(new LessThanEqualTo(lhs, rhs), t); fnTst(new LessThanEqualTo(rhs, lhs), f); // compare unequal literals types rhs = TypedLiteral.newLiteral("foo", xsdString, null); try { assertTrue(f.equals(new LessThanEqualTo(lhs, rhs))); fail("Unequal literals should throw an exception when compared for inequality"); } catch (QueryException qe) { assertTrue(qe.getMessage().startsWith("Type Error")); } Date date = new Date(); lhs = new DateTime(date); rhs = new DateTime(new Date(date.getTime() + 1000)); fnTst(new LessThanEqualTo(lhs, rhs), t); fnTst(new LessThanEqualTo(rhs, lhs), f); } public void testGTE() throws Exception { // compares two equal literals fnTst(new GreaterThanEqualTo(t, t), t); fnTst(new GreaterThanEqualTo(f, f), t); fnTst(new GreaterThanEqualTo(f, t), f); fnTst(new GreaterThanEqualTo(t, f), t); ComparableExpression lhs = TypedLiteral.newLiteral(7); ComparableExpression rhs = TypedLiteral.newLiteral(7.0); fnTst(new GreaterThanEqualTo(lhs, lhs), t); fnTst(new GreaterThanEqualTo(lhs, rhs), t); fnTst(new GreaterThanEqualTo(rhs, lhs), t); rhs = TypedLiteral.newLiteral(8.0); fnTst(new GreaterThanEqualTo(lhs, rhs), f); fnTst(new GreaterThanEqualTo(rhs, lhs), t); // compare unequal literal strings lhs = TypedLiteral.newLiteral("foo", null, null); rhs = TypedLiteral.newLiteral("foo", null, null); fnTst(new GreaterThanEqualTo(lhs, rhs), t); fnTst(new GreaterThanEqualTo(rhs, lhs), t); rhs = TypedLiteral.newLiteral("fool", null, null); fnTst(new GreaterThan(lhs, rhs), f); fnTst(new GreaterThan(rhs, lhs), t); // compare unequal literals types rhs = TypedLiteral.newLiteral("foo", xsdString, null); try { assertTrue(f.equals(new GreaterThanEqualTo(lhs, rhs))); fail("Unequal literals should throw an exception when compared for inequality"); } catch (QueryException qe) { assertTrue(qe.getMessage().startsWith("Type Error")); } Date date = new Date(); lhs = new DateTime(date); rhs = new DateTime(new Date(date.getTime() + 1000)); fnTst(new GreaterThanEqualTo(lhs, rhs), f); fnTst(new GreaterThanEqualTo(rhs, lhs), t); } public void testVar() throws Exception { Var x = new Var("x"); Var y = new Var("y"); AbstractFilterValue lt = new LessThan(x, y); AbstractFilterValue lte = new LessThanEqualTo(x, y); AbstractFilterValue gt = new GreaterThan(x, y); AbstractFilterValue gte = new GreaterThanEqualTo(x, y); Literal seven = new LiteralImpl("7", xsdInt); Literal sevenF = new LiteralImpl("7.0", xsdFloat); Literal eight = new LiteralImpl("8", xsdInt); Literal eightF = new LiteralImpl("8.0", xsdFloat); Literal simple = new LiteralImpl("foo"); Literal simpleLarge = new LiteralImpl("goo"); Literal str = new LiteralImpl("foo", xsdString); Literal strLarge = new LiteralImpl("goo", xsdString); Node[][] rows = { new Node[] {seven, seven}, new Node[] {seven, sevenF}, new Node[] {seven, eight}, new Node[] {seven, eightF}, new Node[] {simple, simple}, new Node[] {simple, simpleLarge}, new Node[] {simple, str}, new Node[] {seven, str}, new Node[] {sevenF, str}, new Node[] {str, seven}, new Node[] {str, sevenF}, new Node[] {str, str}, new Node[] {str, strLarge}, new Node[] {null, str}, }; TestContext c = new TestContext(new String[] {"x", "y"}, rows); c.beforeFirst(); lt.setContextOwner(new TestContextOwner(c)); lte.setContextOwner(new TestContextOwner(c)); gt.setContextOwner(new TestContextOwner(c)); gte.setContextOwner(new TestContextOwner(c)); // check the context setting lt.setCurrentContext(c); lte.setCurrentContext(c); gt.setCurrentContext(c); gte.setCurrentContext(c); // 0123 456 7890 12 3 String results = "eell elx xxxx el n"; runTests(c, lt, lte, gt, gte, results); } private void runTests(TestContext c, AbstractFilterValue lt, AbstractFilterValue lte, AbstractFilterValue gt, AbstractFilterValue gte, String results) throws Exception { c.beforeFirst(); int i = 0; for (char result: results.toCharArray()) { if (result == ' ') continue; String it = "iteration: " + i++; assertTrue(c.next()); switch (result) { case 'e': // equal assertTrue(it, f.equals(lt)); assertTrue(it, t.equals(lte)); assertTrue(it, f.equals(gt)); assertTrue(it, t.equals(gte)); break; case 'l': // less than assertTrue(it, t.equals(lt)); assertTrue(it, t.equals(lte)); assertTrue(it, f.equals(gt)); assertTrue(it, f.equals(gte)); break; case 'x': // Type error try { assertTrue(it, t.equals(lt)); fail("Unequal literals should throw an exception when compared for less than: " + i); } catch (QueryException qe) { assertTrue(qe.getMessage().startsWith("Type Error")); } try { assertTrue(it, t.equals(lte)); fail("Unequal literals should throw an exception when compared for less than or equal: " + i); } catch (QueryException qe) { assertTrue(qe.getMessage().startsWith("Type Error")); } try { assertTrue(it, t.equals(gt)); fail("Unequal literals should throw an exception when compared for greater than: " + i); } catch (QueryException qe) { assertTrue(qe.getMessage().startsWith("Type Error")); } try { assertTrue(it, t.equals(gte)); fail("Unequal literals should throw an exception when compared for greater than or equal: " + i); } catch (QueryException qe) { assertTrue(qe.getMessage().startsWith("Type Error")); } break; case 'n': // exception due to unbound try { assertTrue(it, f.equals(lt)); fail("No exception when testing an unbound value for equality: " + i); } catch (QueryException qe) { assertTrue(qe.getMessage().startsWith("Unbound column")); } try { assertTrue(it, f.equals(lte)); fail("No exception when testing an unbound value for equivalency: " + i); } catch (QueryException qe) { assertTrue(qe.getMessage().startsWith("Unbound column")); } try { assertTrue(it, f.equals(gt)); fail("No exception when testing an unbound value for inequality: " + i); } catch (QueryException qe) { assertTrue(qe.getMessage().startsWith("Unbound column")); } try { assertTrue(it, f.equals(gte)); fail("No exception when testing an unbound value for inequality: " + i); } catch (QueryException qe) { assertTrue(qe.getMessage().startsWith("Unbound column")); } break; default: fail("Bad test data"); } } assertFalse(c.next()); } }