package com.temenos.interaction.odataext.odataparser;
/*
* Test class for the oData parser/printer filter operators.
*/
/*
* #%L
* interaction-odata4j-ext
* %%
* Copyright (C) 2012 - 2013 Temenos Holdings N.V.
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.List;
import org.junit.Ignore;
import org.junit.Test;
import org.odata4j.expression.BoolCommonExpression;
import org.odata4j.expression.Expression;
import com.temenos.interaction.odataext.odataparser.data.Relation;
import com.temenos.interaction.odataext.odataparser.data.RowFilter;
import com.temenos.interaction.odataext.odataparser.data.RowFilters;
public class ODataParserOperatorFilterTest extends AbstractODataParserFilterTest {
/**
* Test a simple filter
*/
@Test
public void testSimpleFilter() {
testValid("a eq b");
}
/**
* Test binary string filters
*/
@Test
public void testStringFilters() {
for (Relation rel : Relation.values()) {
if (!rel.isNumeric() && !rel.isBoolean() && (2 == rel.getExpectedArgumentCount()) && !rel.isFunctionCall()) {
String str = "a " + rel.getoDataString() + " b";
testValid(str);
}
}
}
/**
* Test binary numeric filters.
*/
@Test
public void testNumericFilters() {
// Test all binary relations
for (Relation rel : Relation.values()) {
if (rel.isNumeric() && !rel.isFunctionCall()) {
testValid("a eq 1 " + rel.getoDataString() + " 2");
testValid("1 " + rel.getoDataString() + " 2 eq b");
}
}
}
/**
* Test binary decimal numeric filters.
*/
@Test
public void testDecimalFilters() {
// Test all binary relations
for (Relation rel : Relation.values()) {
if (rel.isNumeric() && !rel.isFunctionCall()) {
testValid("a eq 123.456M " + rel.getoDataString() + " -234.567M");
// Since we print 'M' in upper case only that is 'valid'. But
// check the lower case version also parses.
try {
ODataParser.parseFilters("123.456m " + rel.getoDataString() + " -234.567m eq b");
} catch (Exception e) {
fail();
}
}
}
}
/**
* Test binary decimal numeric filters with missing 'm'.
*/
@Test
public void testDecimalNoMFilters() {
// Test all binary relations
for (Relation rel : Relation.values()) {
if (rel.isNumeric() && !rel.isFunctionCall()) {
// Invalid syntax. Should throw.
testInvalid("a eq 123.456 " + rel.getoDataString() + " 234.567");
}
}
}
/**
* Test binary long numeric filters.
*/
@Test
public void testLongFilters() {
// Test all binary relations
for (Relation rel : Relation.values()) {
if (rel.isNumeric() && !rel.isFunctionCall()) {
testValid("a eq 123L " + rel.getoDataString() + " -234L");
}
}
}
/**
* Test binary floating numeric filters.
*/
@Test
public void testFloatFilters() {
// Test all binary relations
for (Relation rel : Relation.values()) {
if (rel.isNumeric() && !rel.isFunctionCall()) {
// Looks like oData4j treats these as normal literals. Just
// check that they parse.
try {
ODataParser.parseFilters("a eq 123.456f " + rel.getoDataString() + " -234.567f");
} catch (Exception e) {
fail();
}
}
}
}
/**
* Test binary double numeric filters.
*/
@Test
public void testDoubleFilters() {
// Test all binary relations
for (Relation rel : Relation.values()) {
if (rel.isNumeric() && !rel.isFunctionCall()) {
testValid("a eq 123.456d " + rel.getoDataString() + " -234.567d");
// Looks like oData4j does not support following format.
// testValid("a eq 1E+10d " + rel.getoDataString() + " -2E+3d");
}
}
}
/**
* Test boolean unary filters.
*/
@Test
public void testBooleanUnaryFilters() {
for (Relation rel : Relation.values()) {
if (rel.isBoolean() && (1 == rel.getExpectedArgumentCount()) && !rel.isFunctionCall()) {
testValid(rel.getoDataString() + " false");
}
}
}
/**
* Test boolean binary filters.
*/
@Test
public void testBooleanBinaryFilters() {
for (Relation rel : Relation.values()) {
if (rel.isBoolean() && (2 == rel.getExpectedArgumentCount()) && (!rel.isFunctionCall())) {
String str = "true " + rel.getoDataString() + " false";
testValid(str);
}
}
}
/**
* Test bracketed operations.
*/
@Test
public void testBracketFilter() {
testValid("(a eq 1) and (b ne 2)");
testValid("(1 add 2) ne (3 div 4)");
testValid("((1 add 2)) ne (3 div 4)");
}
// TODO add tests for functions
@Test
public void testBinaryFunctionsFilter() {
testValid("a eq substringof('a', b)");
}
@Test
public void testUnaryFunctionsFilter() {
testValid("b eq tolower('TeSt')");
}
/**
* Test gel Sql symbol
*/
@Test
public void testGetSqlSymbolFilter() {
List<RowFilter> filter = null;
try {
filter = ODataParser.parseFilter("a eq b");
} catch (Exception e) {
fail();
}
assertEquals("=", filter.get(0).getRelation().getSqlSymbol());
}
/**
* Test empty filters.
*/
@Test
public void testEmptyFilter() {
testValid("");
}
/*
* Test filter containing multiple terms
*/
@Test
public void testMultipleFilter() {
testValid("a eq b and bb eq cc");
}
/*
* Test filter containing quoted space elements.
*/
@Test
public void testQuotesSpaceFilter() {
testValid("'a b' eq 'b c'");
}
/*
* Test filter containing quoted dot elements.
*/
@Test
public void testQuotesDotFilter() {
testValid("'a.b' eq 'b.c'");
}
/*
* Test filter containing Time elements.
*
* Currently this does not appear to parse.
*/
@Test
@Ignore
public void testTimeFilter() {
testValid("a eq 13:20:00");
}
/*
* Test filter containing DateTime elements.
*/
@Test
public void testDateTimeFilter() {
testValid("a eq datetime'2000-12-12T12:00'");
}
/*
* Test filter containing DateTime offset elements.
*
* Currently this does not appear to parse.
*/
@Test
@Ignore
public void testDateTimeOffsetFilter() {
testValid("a eq 2002-10-10T17:00:00Z");
}
/**
* Test invalid filters throw.
*/
@Test
public void testBadFilter() {
// Bad condition
testInvalid("a xx b");
// Can't parse a null string.
testInvalid(null);
// Wrong number of element
testInvalid("a");
testInvalid("a b");
testInvalid("a b c");
}
/**
* Test null intermediate filter.
*/
@Test
public void testNullFilter() {
String actual = null;
boolean threw = false;
try {
actual = ODataParser.toFilters(null);
} catch (Exception e) {
threw = true;
}
assertTrue("Didn't throw. Expected \"" + null + "\"Actual is \"" + actual + "\"", threw);
}
/**
* Test 'block all' filter.
*/
@Test
public void testBlockAllFilter() {
String actual = null;
boolean threw = false;
// Create a non-null, 'block all', filter.
RowFilters filter = new RowFilters();
filter.addFilters((RowFilters)null);
assertTrue(filter.isBlockAll());
try {
actual = ODataParser.toFilters(filter);
} catch (Exception e) {
threw = true;
}
assertTrue("Didn't throw. Expected \"" + null + "\"Actual is \"" + actual + "\"", threw);
}
/**
* Test parsing a OData4j expression
*/
@Test
@Deprecated
public void testExpressionFilter() {
List<RowFilter> actual = null;
BoolCommonExpression expr = (BoolCommonExpression) Expression.parse("a eq b");
try {
actual = ODataParser.parseFilter(expr);
} catch (Exception e) {
fail("Failed with " + e);
}
assertFalse(null == actual);
assertEquals(1, actual.size());
assertEquals("a", actual.get(0).getFieldName().getName());
assertEquals(Relation.EQ, actual.get(0).getRelation());
assertEquals("b", actual.get(0).getValue());
}
/**
* Test old style filter.
*/
@Test
@Deprecated
public void testOldFilter() {
// Just do a representative one
testOldValid("a eq b and c ne 'd' and e gt 1");
}
}