From: Josh Micich Date: Tue, 8 Dec 2009 20:08:59 +0000 (+0000) Subject: Refactored some code in OFFSET implementation. Added test cases showing comparisons... X-Git-Tag: REL_3_7_BETA1~225 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=9d377f8a917965c28c23f1985492a33fc968f87e;p=poi.git Refactored some code in OFFSET implementation. Added test cases showing comparisons with BoolEval. git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@888555 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Offset.java b/src/java/org/apache/poi/hssf/record/formula/functions/Offset.java index 92b583bcb7..be4a33e680 100644 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Offset.java +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Offset.java @@ -18,13 +18,10 @@ package org.apache.poi.hssf.record.formula.functions; import org.apache.poi.hssf.record.formula.eval.AreaEval; -import org.apache.poi.hssf.record.formula.eval.BoolEval; import org.apache.poi.hssf.record.formula.eval.ErrorEval; import org.apache.poi.hssf.record.formula.eval.EvaluationException; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; import org.apache.poi.hssf.record.formula.eval.OperandResolver; import org.apache.poi.hssf.record.formula.eval.RefEval; -import org.apache.poi.hssf.record.formula.eval.StringEval; import org.apache.poi.hssf.record.formula.eval.ValueEval; /** * Implementation for Excel function OFFSET()

@@ -223,43 +220,8 @@ public final class Offset implements Function { /** * OFFSET's numeric arguments (2..5) have similar processing rules */ - private static int evaluateIntArg(ValueEval eval, int srcCellRow, int srcCellCol) throws EvaluationException { - - double d = evaluateDoubleArg(eval, srcCellRow, srcCellCol); - return convertDoubleToInt(d); - } - - /** - * Fractional values are silently truncated by Excel. - * Truncation is toward negative infinity. - */ - /* package */ static int convertDoubleToInt(double d) { - // Note - the standard java type conversion from double to int truncates toward zero. - // but Math.floor() truncates toward negative infinity - return (int)Math.floor(d); - } - - private static double evaluateDoubleArg(ValueEval eval, int srcCellRow, int srcCellCol) throws EvaluationException { + static int evaluateIntArg(ValueEval eval, int srcCellRow, int srcCellCol) throws EvaluationException { ValueEval ve = OperandResolver.getSingleValue(eval, srcCellRow, srcCellCol); - - if (ve instanceof NumericValueEval) { - return ((NumericValueEval) ve).getNumberValue(); - } - if (ve instanceof StringEval) { - StringEval se = (StringEval) ve; - Double d = OperandResolver.parseDouble(se.getStringValue()); - if(d == null) { - throw new EvaluationException(ErrorEval.VALUE_INVALID); - } - return d.doubleValue(); - } - if (ve instanceof BoolEval) { - // in the context of OFFSET, booleans resolve to 0 and 1. - if(((BoolEval) ve).getBooleanValue()) { - return 1; - } - return 0; - } - throw new RuntimeException("Unexpected eval type (" + ve.getClass().getName() + ")"); + return OperandResolver.coerceValueToInt(ve); } } diff --git a/src/testcases/org/apache/poi/hssf/record/formula/eval/TestEqualEval.java b/src/testcases/org/apache/poi/hssf/record/formula/eval/TestEqualEval.java index 7e465b60de..739b32cc7e 100644 --- a/src/testcases/org/apache/poi/hssf/record/formula/eval/TestEqualEval.java +++ b/src/testcases/org/apache/poi/hssf/record/formula/eval/TestEqualEval.java @@ -95,6 +95,37 @@ public final class TestEqualEval extends TestCase { return be.getBooleanValue(); } + public void testBooleanCompares() { + confirmCompares(BoolEval.TRUE, new StringEval("TRUE"), +1); + confirmCompares(BoolEval.TRUE, new NumberEval(1.0), +1); + confirmCompares(BoolEval.TRUE, BoolEval.TRUE, 0); + confirmCompares(BoolEval.TRUE, BoolEval.FALSE, +1); + + confirmCompares(BoolEval.FALSE, new StringEval("TRUE"), +1); + confirmCompares(BoolEval.FALSE, new StringEval("FALSE"), +1); + confirmCompares(BoolEval.FALSE, new NumberEval(0.0), +1); + confirmCompares(BoolEval.FALSE, BoolEval.FALSE, 0); + } + private static void confirmCompares(ValueEval a, ValueEval b, int expRes) { + confirm(a, b, expRes>0, EI.GreaterThan); + confirm(a, b, expRes>=0, EI.GreaterEqual); + confirm(a, b, expRes==0, EI.Equal); + confirm(a, b, expRes<=0, EI.LessEqual); + confirm(a, b, expRes<0, EI.LessThan); + + confirm(b, a, expRes<0, EI.GreaterThan); + confirm(b, a, expRes<=0, EI.GreaterEqual); + confirm(b, a, expRes==0, EI.Equal); + confirm(b, a, expRes>=0, EI.LessEqual); + confirm(b, a, expRes>0, EI.LessThan); + } + private static void confirm(ValueEval a, ValueEval b, boolean expectedResult, Function cmpOp) { + ValueEval[] args = { a, b, }; + ValueEval result = evaluate(cmpOp, args, 10, 20); + assertEquals(BoolEval.class, result.getClass()); + assertEquals(expectedResult, ((BoolEval) result).getBooleanValue()); + } + /** * Bug 47198 involved a formula "-A1=0" where cell A1 was 0.0. * Excel evaluates "-A1=0" to TRUE, not because it thinks -0.0==0.0 diff --git a/src/testcases/org/apache/poi/hssf/record/formula/functions/TestOffset.java b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestOffset.java index f114662985..49cc6d597d 100644 --- a/src/testcases/org/apache/poi/hssf/record/formula/functions/TestOffset.java +++ b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestOffset.java @@ -17,32 +17,41 @@ package org.apache.poi.hssf.record.formula.functions; +import junit.framework.AssertionFailedError; import junit.framework.TestCase; +import org.apache.poi.hssf.record.formula.eval.EvaluationException; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; import org.apache.poi.hssf.record.formula.functions.Offset.LinearOffsetRange; /** * Tests for OFFSET function implementation - * + * * @author Josh Micich */ public final class TestOffset extends TestCase { - private static void confirmDoubleConvert(double doubleVal, int expected) { - assertEquals(expected, Offset.convertDoubleToInt(doubleVal)); + try { + assertEquals(expected, Offset.evaluateIntArg(new NumberEval(doubleVal), -1, -1)); + } catch (EvaluationException e) { + throw new AssertionFailedError("Unexpected error '" + e.getErrorEval().toString() + "'."); + } } /** * Excel's double to int conversion (for function 'OFFSET()') behaves more like Math.floor(). * Note - negative values are not symmetrical + * Fractional values are silently truncated. + * Truncation is toward negative infinity. */ public void testDoubleConversion() { - + confirmDoubleConvert(100.09, 100); confirmDoubleConvert(100.01, 100); confirmDoubleConvert(100.00, 100); confirmDoubleConvert(99.99, 99); - + confirmDoubleConvert(+2.01, +2); confirmDoubleConvert(+2.00, +2); confirmDoubleConvert(+1.99, +1); @@ -62,25 +71,25 @@ public final class TestOffset extends TestCase { public void testLinearOffsetRange() { LinearOffsetRange lor; - + lor = new LinearOffsetRange(3, 2); assertEquals(3, lor.getFirstIndex()); assertEquals(4, lor.getLastIndex()); lor = lor.normaliseAndTranslate(0); // expected no change assertEquals(3, lor.getFirstIndex()); assertEquals(4, lor.getLastIndex()); - + lor = lor.normaliseAndTranslate(5); assertEquals(8, lor.getFirstIndex()); assertEquals(9, lor.getLastIndex()); - + // negative length - + lor = new LinearOffsetRange(6, -4).normaliseAndTranslate(0); assertEquals(3, lor.getFirstIndex()); assertEquals(6, lor.getLastIndex()); - - + + // bounds checking lor = new LinearOffsetRange(0, 100); assertFalse(lor.isOutOfBounds(0, 16383)); @@ -88,5 +97,4 @@ public final class TestOffset extends TestCase { assertTrue(lor.isOutOfBounds(0, 16383)); assertFalse(lor.isOutOfBounds(0, 65535)); } - }