From b677a332621e8935d8af2e923e2da4bad6e1f396 Mon Sep 17 00:00:00 2001 From: James Ahlborn Date: Sun, 18 Dec 2016 21:08:18 +0000 Subject: [PATCH] start testing simple math exprs git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/branches/exprs@1072 f203690c-595d-4dc9-a70b-905162fa7fd2 --- .../impl/expr/ExpressionTokenizer.java | 10 ++- .../jackcess/impl/expr/Expressionator.java | 4 + .../impl/expr/ExpressionatorTest.java | 77 ++++++++++++++++++- 3 files changed, 87 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/expr/ExpressionTokenizer.java b/src/main/java/com/healthmarketscience/jackcess/impl/expr/ExpressionTokenizer.java index 570823a..8ed9351 100644 --- a/src/main/java/com/healthmarketscience/jackcess/impl/expr/ExpressionTokenizer.java +++ b/src/main/java/com/healthmarketscience/jackcess/impl/expr/ExpressionTokenizer.java @@ -366,6 +366,7 @@ class ExpressionTokenizer int startPos = buf.curPos(); boolean foundNum = false; + boolean hasDecimal = false; try { @@ -376,6 +377,7 @@ class ExpressionTokenizer sb.append((char)c); buf.next(); } else if(c == '.') { + hasDecimal = true; sb.append((char)c); buf.next(); } else if(isSpecialChar((char)c)) { @@ -394,9 +396,13 @@ class ExpressionTokenizer String numStr = sb.toString(); try { // what number type to use here? - BigDecimal num = new BigDecimal(numStr); + // BigDecimal num = new BigDecimal(numStr); + Object num = (hasDecimal ? + (Number)Double.valueOf(numStr) : + (Number)Long.valueOf(numStr)); foundNum = true; - return new Token(TokenType.LITERAL, num, numStr, Value.Type.BIG_DEC); + return new Token(TokenType.LITERAL, num, numStr, + (hasDecimal ? Value.Type.DOUBLE : Value.Type.LONG)); } catch(NumberFormatException ne) { throw new IllegalArgumentException( "Invalid number literal " + numStr + " " + buf, ne); diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/expr/Expressionator.java b/src/main/java/com/healthmarketscience/jackcess/impl/expr/Expressionator.java index 263e7ff..d1d5968 100644 --- a/src/main/java/com/healthmarketscience/jackcess/impl/expr/Expressionator.java +++ b/src/main/java/com/healthmarketscience/jackcess/impl/expr/Expressionator.java @@ -1274,6 +1274,10 @@ public class Expressionator return new TimeValue((Date)value, sdf); case DATE_TIME: return new DateTimeValue((Date)value, sdf); + case LONG: + return new LongValue((Long)value); + case DOUBLE: + return new DoubleValue((Double)value); case BIG_DEC: return new BigDecimalValue((BigDecimal)value); default: diff --git a/src/test/java/com/healthmarketscience/jackcess/impl/expr/ExpressionatorTest.java b/src/test/java/com/healthmarketscience/jackcess/impl/expr/ExpressionatorTest.java index c7d2edc..b74063a 100644 --- a/src/test/java/com/healthmarketscience/jackcess/impl/expr/ExpressionatorTest.java +++ b/src/test/java/com/healthmarketscience/jackcess/impl/expr/ExpressionatorTest.java @@ -16,9 +16,15 @@ limitations under the License. package com.healthmarketscience.jackcess.impl.expr; -import junit.framework.TestCase; +import java.lang.reflect.Type; +import java.text.SimpleDateFormat; +import com.healthmarketscience.jackcess.DatabaseBuilder; +import com.healthmarketscience.jackcess.TestUtil; import com.healthmarketscience.jackcess.expr.Expression; +import com.healthmarketscience.jackcess.expr.Function; +import com.healthmarketscience.jackcess.expr.Value; +import junit.framework.TestCase; /** * @@ -26,7 +32,6 @@ import com.healthmarketscience.jackcess.expr.Expression; */ public class ExpressionatorTest extends TestCase { - public ExpressionatorTest(String name) { super(name); } @@ -114,6 +119,55 @@ public class ExpressionatorTest extends TestCase "{{\"A\"} + {{({{\"B\"} Not Between {{37} - {15}} And {52}})} / {4}}}"); + } + + public void testSimpleMathExpressions() throws Exception + { + for(int i = -10; i < 10; ++i) { + assertEquals((long)-i, eval("=-(" + i + ")")); + } + + for(int i = -10; i < 10; ++i) { + for(int j = -10; j < 10; ++j) { + assertEquals((long)(i + j), eval("=" + i + " + " + j)); + } + } + + for(int i = -10; i < 10; ++i) { + for(int j = -10; j < 10; ++j) { + assertEquals((long)(i - j), eval("=" + i + " - " + j)); + } + } + + for(int i = -10; i < 10; ++i) { + for(int j = -10; j < 10; ++j) { + assertEquals((long)(i * j), eval("=" + i + " * " + j)); + } + } + + for(int i = -10; i < 10; ++i) { + for(int j = -10; j < 10; ++j) { + try { + assertEquals((long)(i / j), eval("=" + i + " \\ " + j)); + if(j == 0) { + fail("ArithmeticException should have been thrown"); + } + } catch(ArithmeticException ae) { + if(j != 0) { + throw ae; + } + } + } + } + + // for(int i = -10; i < 10; ++i) { + // for(int j = -10; j < 10; ++j) { + // System.out.println("FOO " + i + " " + j); + // assertEquals((long)(Math.pow(i, j)), eval("=" + i + " ^ " + j)); + // } + // } + + } private static void validateExpr(String exprStr, String debugStr) { @@ -127,4 +181,23 @@ public class ExpressionatorTest extends TestCase assertEquals(debugStr, expr.toDebugString()); assertEquals(cleanStr, expr.toString()); } + + private static Object eval(String exprStr) { + Expression expr = Expressionator.parse( + Expressionator.Type.DEFAULT_VALUE, exprStr, new TestContext()); + return expr.evalDefault(); + } + + private static final class TestContext implements Expressionator.ParseContext + { + public SimpleDateFormat createDateFormat(String formatStr) { + SimpleDateFormat sdf = DatabaseBuilder.createDateFormat(formatStr); + sdf.setTimeZone(TestUtil.TEST_TZ); + return sdf; + } + + public Function getExpressionFunction(String name) { + return null; + } + } } -- 2.39.5