/***************************************************************** * 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.cayenne.exp; import static org.junit.Assert.assertEquals; import java.io.IOException; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.apache.cayenne.ObjectId; import org.apache.cayenne.exp.parser.SimpleNode; import org.apache.cayenne.testdo.testmap.Artist; import org.junit.Test; public class ExpressionTest { @Test public void testToEJBQL_numericType_integer() throws IOException { Expression e = ExpressionFactory.matchExp("consignment.parts", new Integer(123)); assertEquals("x.consignment.parts = 123", e.toEJBQL("x")); } @Test public void testToEJBQL_numericType_long() throws IOException { Expression e = ExpressionFactory.matchExp("consignment.parts", new Long(1418342400)); assertEquals("x.consignment.parts = 1418342400", e.toEJBQL("x")); } @Test public void testToEJBQL_numericType_float() throws IOException { Expression e = ExpressionFactory.greaterOrEqualExp("consignment.parts", new Float("3.145")); assertEquals("x.consignment.parts >= 3.145", e.toEJBQL("x")); } @Test public void testToEJBQL_numericType_double() throws IOException { Expression e = ExpressionFactory.greaterOrEqualExp("consignment.parts", new Double(3.14)); assertEquals("x.consignment.parts >= 3.14", e.toEJBQL("x")); } @Test public void testAppendAsEJBQL_Timestamp_ParameterCapture() throws IOException { Date now = new Date(); Expression e = ExpressionFactory.greaterOrEqualExp("dateOfBirth", now); StringBuilder buffer = new StringBuilder(); List<Object> parametersAccumulator = new ArrayList<Object>(); e.appendAsEJBQL(parametersAccumulator, buffer, "x"); String ejbql = buffer.toString(); assertEquals("x.dateOfBirth >= ?1", ejbql); assertEquals(parametersAccumulator.size(), 1); assertEquals(parametersAccumulator.get(0), now); } @Test public void testAppendAsEJBQL_in_EncodeListOfParameters_ParameterCapture() throws IOException { Expression e = ExpressionFactory.inExp("artistName", "a", "b", "c"); StringBuilder buffer = new StringBuilder(); List<Object> parametersAccumulator = new ArrayList<Object>(); e.appendAsEJBQL(parametersAccumulator, buffer, "x"); String ejbql = buffer.toString(); assertEquals("x.artistName in (?1, ?2, ?3)", ejbql); assertEquals(parametersAccumulator.size(), 3); assertEquals(parametersAccumulator.get(0), "a"); assertEquals(parametersAccumulator.get(1), "b"); assertEquals(parametersAccumulator.get(2), "c"); } @Test public void testAppendAsEJBQL_in_EncodeListOfParameters() throws IOException { Expression e = ExpressionFactory.inExp("artistName", "a", "b", "c"); StringBuilder buffer = new StringBuilder(); e.appendAsEJBQL(buffer, "x"); String ejbql = buffer.toString(); assertEquals("x.artistName in ('a', 'b', 'c')", ejbql); } @Test public void testAppendAsEJBQL_PersistentParamater() throws IOException { Artist a = new Artist(); ObjectId aId = new ObjectId("Artist", Artist.ARTIST_ID_PK_COLUMN, 1); a.setObjectId(aId); Expression e = ExpressionFactory.matchExp("artist", a); StringBuilder buffer = new StringBuilder(); e.appendAsEJBQL(buffer, "x"); String ejbql = buffer.toString(); assertEquals("x.artist = 1", ejbql); } @Test public void testAppendAsEJBQLNotEquals() throws IOException { Expression e = ExpressionFactory.exp("artistName != 'bla'"); StringBuilder buffer = new StringBuilder(); e.appendAsEJBQL(buffer, "x"); String ejbql = buffer.toString(); assertEquals("x.artistName <> 'bla'", ejbql); } @Test public void testIsNotNullEx() { Expression e = Artist.ARTIST_NAME.isNotNull(); String ejbql = e.toEJBQL("x"); assertEquals("not (x.artistName is null)", ejbql); } @Test public void testAndExp() { Expression e1 = ExpressionFactory.matchExp("name", "Picasso"); Expression e2 = ExpressionFactory.matchExp("age", 30); Expression exp = e1.andExp(e2); assertEquals(exp.getType(), Expression.AND); assertEquals(2, ((SimpleNode) exp).jjtGetNumChildren()); } @Test public void testOrExp() { Expression e1 = ExpressionFactory.matchExp("name", "Picasso"); Expression e2 = ExpressionFactory.matchExp("age", 30); Expression exp = e1.orExp(e2); assertEquals(exp.getType(), Expression.OR); assertEquals(2, ((SimpleNode) exp).jjtGetNumChildren()); } @Test public void testAndExpVarArgs() { Expression e1 = ExpressionFactory.matchExp("name", "Picasso"); Expression e2 = ExpressionFactory.matchExp("age", 30); Expression e3 = ExpressionFactory.matchExp("height", 5.5); Expression e4 = ExpressionFactory.matchExp("numEars", 1); Expression exp = e1.andExp(e2, e3, e4); assertEquals(exp.getType(), Expression.AND); assertEquals(4, ((SimpleNode) exp).jjtGetNumChildren()); } @Test public void testOrExpVarArgs() { Expression e1 = ExpressionFactory.matchExp("name", "Picasso"); Expression e2 = ExpressionFactory.matchExp("age", 30); Expression e3 = ExpressionFactory.matchExp("height", 5.5); Expression e4 = ExpressionFactory.matchExp("numEars", 1); Expression exp = e1.orExp(e2, e3, e4); assertEquals(exp.getType(), Expression.OR); assertEquals(4, ((SimpleNode) exp).jjtGetNumChildren()); } @Test public void testBitwiseNegate() { Expression exp = ExpressionFactory.exp("~7"); assertEquals(Expression.BITWISE_NOT, exp.getType()); assertEquals(1, ((SimpleNode) exp).jjtGetNumChildren()); assertEquals(new Long(-8), exp.evaluate(new Object())); // ~7 = -8 in // digital world } @Test public void testBitwiseAnd() { Expression exp = ExpressionFactory.exp("1 & 0"); assertEquals(Expression.BITWISE_AND, exp.getType()); assertEquals(2, ((SimpleNode) exp).jjtGetNumChildren()); assertEquals(new Long(0), exp.evaluate(new Object())); } @Test public void testBitwiseOr() { Expression exp = ExpressionFactory.exp("1 | 0"); assertEquals(Expression.BITWISE_OR, exp.getType()); assertEquals(2, ((SimpleNode) exp).jjtGetNumChildren()); assertEquals(new Long(1), exp.evaluate(new Object())); } @Test public void testBitwiseXor() { Expression exp = ExpressionFactory.exp("1 ^ 0"); assertEquals(Expression.BITWISE_XOR, exp.getType()); assertEquals(2, ((SimpleNode) exp).jjtGetNumChildren()); assertEquals(new Long(1), exp.evaluate(new Object())); } @Test public void testBitwiseLeftShift() { Expression exp = ExpressionFactory.exp("7 << 2"); assertEquals(Expression.BITWISE_LEFT_SHIFT, exp.getType()); assertEquals(2, ((SimpleNode) exp).jjtGetNumChildren()); assertEquals(new Long(28), exp.evaluate(new Object())); } @Test public void testBitwiseRightShift() { Expression exp = ExpressionFactory.exp("7 >> 2"); assertEquals(Expression.BITWISE_RIGHT_SHIFT, exp.getType()); assertEquals(2, ((SimpleNode) exp).jjtGetNumChildren()); assertEquals(new Long(1), exp.evaluate(new Object())); } /** * (a | b) | c = a | (b | c) */ @Test public void testBitwiseAssociativity() { Expression e1 = ExpressionFactory.exp("(3010 | 2012) | 4095"); Expression e2 = ExpressionFactory.exp("3010 | (2012 | 4095)"); assertEquals(e1.evaluate(new Object()), e2.evaluate(new Object())); } /** * a | b = b | a */ @Test public void testBitwiseCommutativity() { Expression e1 = ExpressionFactory.exp("3010 | 4095"); Expression e2 = ExpressionFactory.exp("4095 | 3010"); assertEquals(e1.evaluate(new Object()), e2.evaluate(new Object())); } /** * a | (a & b) = a */ @Test public void testBitwiseAbsorption() { Expression e1 = ExpressionFactory.exp("2012 | (2012 & 3010)"); Expression e2 = ExpressionFactory.exp("2012L"); // scalar becomes Long // object assertEquals(e1.evaluate(new Object()), e2.evaluate(new Object())); } /** * a | (b & c) = (a | b) & (a | c) */ @Test public void testBitwiseDistributivity() { Expression e1 = ExpressionFactory.exp("4095 | (7777 & 8888)"); Expression e2 = ExpressionFactory.exp("(4095 | 7777) & (4095 | 8888)"); assertEquals(e1.evaluate(new Object()), e2.evaluate(new Object())); } /** * a | ~a = 1 But in Java computed result is -1 because of JVM represents * negative numbers as positive ones: ~2 = -3; For instance, there are only * 4 bits and that is why -3 means '1101' and 3 means '0011' because of * '1101' + '0011' = (1)'0000' what is zero; but the same time '1101' is 13. */ @Test public void testBitwiseComplements() { Expression e1 = ExpressionFactory.exp("5555 | ~5555"); Expression e2 = ExpressionFactory.exp("9999 & ~9999"); assertEquals(new Long(-1), e1.evaluate(new Object())); // ~0 = -1 that // is the way // how // robots kill // humans what // means x | ~x // = // 1 in boolean // algebra // against java // digital // bitwise // operations // logics assertEquals(new Long(0), e2.evaluate(new Object())); } /** * Huntington equation n(n(x) + y) + n(n(x) + n(y)) = x where is 'n' is * negotation (may be any other unary operation) and '+' is disjunction (OR * operation, i.e. '|' bitwise operation). */ @Test public void testBitwiseHuntingtonEquation() { Expression theHuntingEquation = ExpressionFactory.exp("~(~3748 | 4095) | ~(~3748 | ~4095)"); assertEquals(new Long(3748), theHuntingEquation.evaluate(new Object())); } /** * Robbins equation n(n(x + y) + n(x + n(y))) = x where is 'n' is negotation * and '+' is disjunction (OR operation, i.e. '|' bitwise operation). Every * Robbins algebra is a Boolean algebra according to automated reasoning * program EQP. */ @Test public void testBitwiseRobbinsEquation() { Expression theRobbinsEquation = ExpressionFactory.exp("~(~(5111 | 4095) | ~(5111 | ~4095))"); assertEquals(new Long(5111), theRobbinsEquation.evaluate(new Object())); } /** * Bitwise and math operations are ruled by precedence. */ @Test public void testBitwisePrecedence() { Expression e1 = ExpressionFactory.exp("1 << 1 & 2"); // 1 << 1 = 2 and // after that 2 // & 2 // = 2; Expression e2 = ExpressionFactory.exp("0 | 1 & ~(3 | ~3)"); // by java // math // precedence // that // means 0 | // (1 & (~(3 // | (~3)))) Expression e3 = ExpressionFactory.exp("3 | ~(-3) + 2"); // JVM ~(-3) = 2 // and then 2 + // 2 is 4 what // bitwise is // 100, then 011 // | 100 = 111 // what means 3 // + 4 = 7 Expression e4 = ExpressionFactory.exp("2 * 2 | 2"); // (2 * 2) | 2 = 4 | // 2 = '100' | '10' // = '110' = 6 Expression e5 = ExpressionFactory.exp("6 / 2 & 3"); // (6 / 2) & 3 = 3 & // 3 = 3 assertEquals(new Long(2), e1.evaluate(new Object())); assertEquals(new Long(0), e2.evaluate(new Object())); assertEquals(new Long(7), e3.evaluate(new Object())); assertEquals(new Long(6), e4.evaluate(new Object())); assertEquals(new Long(3), e5.evaluate(new Object())); } @Test public void testAppendAsEJBQL_NotEquals_ParameterCapture() throws IOException { Expression e = ExpressionFactory.exp("artistName != 'bla'"); StringBuilder buffer = new StringBuilder(); List<Object> parametersAccumulator = new ArrayList<Object>(); e.appendAsEJBQL(parametersAccumulator, buffer, "x"); String ejbql = buffer.toString(); assertEquals("x.artistName <> ?1", ejbql); assertEquals(parametersAccumulator.size(), 1); assertEquals(parametersAccumulator.get(0), "bla"); } @Test public void testAppendAsEJBQL_Enum() throws IOException { Expression e = ExpressionFactory.exp("a = enum:org.apache.cayenne.exp.ExpEnum1.THREE"); StringBuilder buffer = new StringBuilder(); e.appendAsEJBQL(buffer, "x"); String ejbql = buffer.toString(); assertEquals("x.a = enum:org.apache.cayenne.exp.ExpEnum1.THREE", ejbql); } @Test public void testAppendAsString_StringLiteral() throws IOException { Expression e1 = ExpressionFactory.exp("a = 'abc'"); StringBuilder buffer = new StringBuilder(); e1.appendAsString(buffer); assertEquals("a = \"abc\"", buffer.toString()); } @Test public void testAppendAsString_Enum() throws IOException { Expression e1 = ExpressionFactory.exp("a = enum:org.apache.cayenne.exp.ExpEnum1.TWO"); StringBuilder buffer = new StringBuilder(); e1.appendAsString(buffer); assertEquals("a = enum:org.apache.cayenne.exp.ExpEnum1.TWO", buffer.toString()); } }