44950 - fixed HSSFFormulaEvaluator.evaluateInCell() and Area3DEval.getValue() also added validation for number of elements in AreaEvals
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@654356 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
33a18267e1
commit
86746dde00
@ -37,6 +37,7 @@
|
|||||||
|
|
||||||
<!-- Don't forget to update status.xml too! -->
|
<!-- Don't forget to update status.xml too! -->
|
||||||
<release version="3.1-beta2" date="2008-05-??">
|
<release version="3.1-beta2" date="2008-05-??">
|
||||||
|
<action dev="POI-DEVELOPERS" type="fix">44950 - fixed HSSFFormulaEvaluator.evaluateInCell() and Area3DEval.getValue() also added validation for number of elements in AreaEvals</action>
|
||||||
<action dev="POI-DEVELOPERS" type="fix">42570 - fixed LabelRecord to use empty string instead of null when the length is zero.</action>
|
<action dev="POI-DEVELOPERS" type="fix">42570 - fixed LabelRecord to use empty string instead of null when the length is zero.</action>
|
||||||
<action dev="POI-DEVELOPERS" type="fix">42564 - fixed ArrayPtg to use ConstantValueParser. Fixed a few other ArrayPtg encoding issues.</action>
|
<action dev="POI-DEVELOPERS" type="fix">42564 - fixed ArrayPtg to use ConstantValueParser. Fixed a few other ArrayPtg encoding issues.</action>
|
||||||
<action dev="POI-DEVELOPERS" type="fix">Follow-on from 28754 - StringPtg.toFormulaString() should escape double quotes</action>
|
<action dev="POI-DEVELOPERS" type="fix">Follow-on from 28754 - StringPtg.toFormulaString() should escape double quotes</action>
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
<!-- Don't forget to update changes.xml too! -->
|
<!-- Don't forget to update changes.xml too! -->
|
||||||
<changes>
|
<changes>
|
||||||
<release version="3.1-beta2" date="2008-05-??">
|
<release version="3.1-beta2" date="2008-05-??">
|
||||||
|
<action dev="POI-DEVELOPERS" type="fix">44950 - fixed HSSFFormulaEvaluator.evaluateInCell() and Area3DEval.getValue() also added validation for number of elements in AreaEvals</action>
|
||||||
<action dev="POI-DEVELOPERS" type="fix">42570 - fixed LabelRecord to use empty string instead of null when the length is zero.</action>
|
<action dev="POI-DEVELOPERS" type="fix">42570 - fixed LabelRecord to use empty string instead of null when the length is zero.</action>
|
||||||
<action dev="POI-DEVELOPERS" type="fix">42564 - fixed ArrayPtg to use ConstantValueParser. Fixed a few other ArrayPtg encoding issues.</action>
|
<action dev="POI-DEVELOPERS" type="fix">42564 - fixed ArrayPtg to use ConstantValueParser. Fixed a few other ArrayPtg encoding issues.</action>
|
||||||
<action dev="POI-DEVELOPERS" type="fix">Follow-on from 28754 - StringPtg.toFormulaString() should escape double quotes</action>
|
<action dev="POI-DEVELOPERS" type="fix">Follow-on from 28754 - StringPtg.toFormulaString() should escape double quotes</action>
|
||||||
|
@ -24,77 +24,9 @@ import org.apache.poi.hssf.record.formula.Ptg;
|
|||||||
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
|
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public final class Area2DEval implements AreaEval {
|
public final class Area2DEval extends AreaEvalBase {
|
||||||
// TODO -refactor with Area3DEval
|
|
||||||
private final AreaPtg _delegate;
|
|
||||||
|
|
||||||
private final ValueEval[] _values;
|
|
||||||
|
|
||||||
public Area2DEval(Ptg ptg, ValueEval[] values) {
|
public Area2DEval(Ptg ptg, ValueEval[] values) {
|
||||||
if(ptg == null) {
|
super((AreaPtg) ptg, values);
|
||||||
throw new IllegalArgumentException("ptg must not be null");
|
|
||||||
}
|
|
||||||
if(values == null) {
|
|
||||||
throw new IllegalArgumentException("values must not be null");
|
|
||||||
}
|
|
||||||
for(int i=values.length-1; i>=0; i--) {
|
|
||||||
if(values[i] == null) {
|
|
||||||
throw new IllegalArgumentException("value array elements must not be null");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// TODO - check size of array vs size of AreaPtg
|
|
||||||
_delegate = (AreaPtg) ptg;
|
|
||||||
_values = values;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getFirstColumn() {
|
|
||||||
return _delegate.getFirstColumn();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getFirstRow() {
|
|
||||||
return _delegate.getFirstRow();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getLastColumn() {
|
|
||||||
return _delegate.getLastColumn();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getLastRow() {
|
|
||||||
return _delegate.getLastRow();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ValueEval[] getValues() {
|
|
||||||
return _values;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ValueEval getValueAt(int row, int col) {
|
|
||||||
ValueEval retval;
|
|
||||||
int index = ((row-getFirstRow())*(getLastColumn()-getFirstColumn()+1))+(col-getFirstColumn());
|
|
||||||
if (index <0 || index >= _values.length)
|
|
||||||
retval = ErrorEval.VALUE_INVALID;
|
|
||||||
else
|
|
||||||
retval = _values[index];
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean contains(int row, int col) {
|
|
||||||
return (getFirstRow() <= row) && (getLastRow() >= row)
|
|
||||||
&& (getFirstColumn() <= col) && (getLastColumn() >= col);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean containsRow(int row) {
|
|
||||||
return (getFirstRow() <= row) && (getLastRow() >= row);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean containsColumn(short col) {
|
|
||||||
return (getFirstColumn() <= col) && (getLastColumn() >= col);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isColumn() {
|
|
||||||
return _delegate.getFirstColumn() == _delegate.getLastColumn();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isRow() {
|
|
||||||
return _delegate.getFirstRow() == _delegate.getLastRow();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -24,82 +24,16 @@ import org.apache.poi.hssf.record.formula.Ptg;
|
|||||||
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
|
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public final class Area3DEval implements AreaEval {
|
public final class Area3DEval extends AreaEvalBase {
|
||||||
// TODO -refactor with Area3DEval
|
|
||||||
private final Area3DPtg _delegate;
|
|
||||||
|
|
||||||
private final ValueEval[] _values;
|
private final int _externSheetIndex;
|
||||||
|
|
||||||
public Area3DEval(Ptg ptg, ValueEval[] values) {
|
public Area3DEval(Ptg ptg, ValueEval[] values) {
|
||||||
if(ptg == null) {
|
super((Area3DPtg) ptg, values);
|
||||||
throw new IllegalArgumentException("ptg must not be null");
|
_externSheetIndex = ((Area3DPtg) ptg).getExternSheetIndex();
|
||||||
}
|
|
||||||
if(values == null) {
|
|
||||||
throw new IllegalArgumentException("values must not be null");
|
|
||||||
}
|
|
||||||
for(int i=values.length-1; i>=0; i--) {
|
|
||||||
if(values[i] == null) {
|
|
||||||
throw new IllegalArgumentException("value array elements must not be null");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// TODO - check size of array vs size of AreaPtg
|
|
||||||
_values = values;
|
|
||||||
_delegate = (Area3DPtg) ptg;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getFirstColumn() {
|
|
||||||
return _delegate.getFirstColumn();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getFirstRow() {
|
|
||||||
return _delegate.getFirstRow();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getLastColumn() {
|
|
||||||
return (short) _delegate.getLastColumn();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getLastRow() {
|
|
||||||
return _delegate.getLastRow();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ValueEval[] getValues() {
|
|
||||||
return _values;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ValueEval getValueAt(int row, int col) {
|
|
||||||
ValueEval retval;
|
|
||||||
int index = (row-getFirstRow())*(col-getFirstColumn());
|
|
||||||
if (index <0 || index >= _values.length)
|
|
||||||
retval = ErrorEval.VALUE_INVALID;
|
|
||||||
else
|
|
||||||
retval = _values[index];
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean contains(int row, int col) {
|
|
||||||
return (getFirstRow() <= row) && (getLastRow() >= row)
|
|
||||||
&& (getFirstColumn() <= col) && (getLastColumn() >= col);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean containsRow(int row) {
|
|
||||||
return (getFirstRow() <= row) && (getLastRow() >= row);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean containsColumn(short col) {
|
|
||||||
return (getFirstColumn() <= col) && (getLastColumn() >= col);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public boolean isColumn() {
|
|
||||||
return _delegate.getFirstColumn() == _delegate.getLastColumn();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isRow() {
|
|
||||||
return _delegate.getFirstRow() == _delegate.getLastRow();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getExternSheetIndex() {
|
public int getExternSheetIndex() {
|
||||||
return _delegate.getExternSheetIndex();
|
return _externSheetIndex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,122 @@
|
|||||||
|
/*
|
||||||
|
* 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.poi.hssf.record.formula.eval;
|
||||||
|
|
||||||
|
import org.apache.poi.hssf.record.formula.AreaI;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Josh Micich
|
||||||
|
*/
|
||||||
|
abstract class AreaEvalBase implements AreaEval {
|
||||||
|
|
||||||
|
private final int _firstColumn;
|
||||||
|
private final int _firstRow;
|
||||||
|
private final int _lastColumn;
|
||||||
|
private final int _lastRow;
|
||||||
|
private final ValueEval[] _values;
|
||||||
|
private final int _nColumns;
|
||||||
|
private final int _nRows;
|
||||||
|
|
||||||
|
protected AreaEvalBase(AreaI ptg, ValueEval[] values) {
|
||||||
|
if (values == null) {
|
||||||
|
throw new IllegalArgumentException("values must not be null");
|
||||||
|
}
|
||||||
|
_firstRow = ptg.getFirstRow();
|
||||||
|
_firstColumn = ptg.getFirstColumn();
|
||||||
|
_lastRow = ptg.getLastRow();
|
||||||
|
_lastColumn = ptg.getLastColumn();
|
||||||
|
|
||||||
|
_nColumns = _lastColumn - _firstColumn + 1;
|
||||||
|
_nRows = _lastRow - _firstRow + 1;
|
||||||
|
|
||||||
|
int expectedItemCount = _nRows * _nColumns;
|
||||||
|
if ((values.length != expectedItemCount)) {
|
||||||
|
// Note - this math may need alteration when POI starts to support full column or full row refs
|
||||||
|
throw new IllegalArgumentException("Array size should be (" + expectedItemCount
|
||||||
|
+ ") but was (" + values.length + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = values.length - 1; i >= 0; i--) {
|
||||||
|
if (values[i] == null) {
|
||||||
|
throw new IllegalArgumentException("value array elements must not be null");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_values = values;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final int getFirstColumn() {
|
||||||
|
return _firstColumn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final int getFirstRow() {
|
||||||
|
return _firstRow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final int getLastColumn() {
|
||||||
|
return _lastColumn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final int getLastRow() {
|
||||||
|
return _lastRow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final ValueEval[] getValues() {
|
||||||
|
// TODO - clone() - but some junits rely on not cloning at the moment
|
||||||
|
return _values;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final ValueEval getValueAt(int row, int col) {
|
||||||
|
int rowOffsetIx = row - _firstRow;
|
||||||
|
int colOffsetIx = col - _firstColumn;
|
||||||
|
|
||||||
|
if(rowOffsetIx < 0 || rowOffsetIx >= _nRows) {
|
||||||
|
throw new IllegalArgumentException("Specified row index (" + row
|
||||||
|
+ ") is outside the allowed range (" + _firstRow + ".." + _lastRow + ")");
|
||||||
|
}
|
||||||
|
if(colOffsetIx < 0 || colOffsetIx >= _nColumns) {
|
||||||
|
throw new IllegalArgumentException("Specified column index (" + col
|
||||||
|
+ ") is outside the allowed range (" + _firstColumn + ".." + col + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
int index = rowOffsetIx * _nColumns + colOffsetIx;
|
||||||
|
return _values[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
public final boolean contains(int row, int col) {
|
||||||
|
return _firstRow <= row && _lastRow >= row
|
||||||
|
&& _firstColumn <= col && _lastColumn >= col;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final boolean containsRow(int row) {
|
||||||
|
return (_firstRow <= row) && (_lastRow >= row);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final boolean containsColumn(short col) {
|
||||||
|
return (_firstColumn <= col) && (_lastColumn >= col);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final boolean isColumn() {
|
||||||
|
return _firstColumn == _lastColumn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final boolean isRow() {
|
||||||
|
return _firstRow == _lastRow;
|
||||||
|
}
|
||||||
|
}
|
@ -817,8 +817,7 @@ public class HSSFCell
|
|||||||
int row=record.getRow();
|
int row=record.getRow();
|
||||||
short col=record.getColumn();
|
short col=record.getColumn();
|
||||||
short styleIndex=record.getXFIndex();
|
short styleIndex=record.getXFIndex();
|
||||||
if ((cellType != CELL_TYPE_ERROR) && (cellType != CELL_TYPE_FORMULA))
|
if (cellType != CELL_TYPE_ERROR) {
|
||||||
{
|
|
||||||
setCellType(CELL_TYPE_ERROR, false, row, col, styleIndex);
|
setCellType(CELL_TYPE_ERROR, false, row, col, styleIndex);
|
||||||
}
|
}
|
||||||
(( BoolErrRecord ) record).setValue(value);
|
(( BoolErrRecord ) record).setValue(value);
|
||||||
|
@ -232,8 +232,7 @@ public class HSSFFormulaEvaluator {
|
|||||||
cell.setCellValue(cv.getBooleanValue());
|
cell.setCellValue(cv.getBooleanValue());
|
||||||
break;
|
break;
|
||||||
case HSSFCell.CELL_TYPE_ERROR:
|
case HSSFCell.CELL_TYPE_ERROR:
|
||||||
cell.setCellType(HSSFCell.CELL_TYPE_ERROR);
|
cell.setCellErrorValue(cv.getErrorValue());
|
||||||
cell.setCellValue(cv.getErrorValue());
|
|
||||||
break;
|
break;
|
||||||
case HSSFCell.CELL_TYPE_NUMERIC:
|
case HSSFCell.CELL_TYPE_NUMERIC:
|
||||||
cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC);
|
cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC);
|
||||||
|
@ -28,7 +28,8 @@ import junit.framework.TestSuite;
|
|||||||
public class AllFormulaEvalTests {
|
public class AllFormulaEvalTests {
|
||||||
|
|
||||||
public static Test suite() {
|
public static Test suite() {
|
||||||
TestSuite result = new TestSuite("Tests for org.apache.poi.hssf.record.formula.eval");
|
TestSuite result = new TestSuite(AllFormulaEvalTests.class.getName());
|
||||||
|
result.addTestSuite(TestAreaEval.class);
|
||||||
result.addTestSuite(TestCircularReferences.class);
|
result.addTestSuite(TestCircularReferences.class);
|
||||||
result.addTestSuite(TestExternalFunction.class);
|
result.addTestSuite(TestExternalFunction.class);
|
||||||
result.addTestSuite(TestFormulaBugs.class);
|
result.addTestSuite(TestFormulaBugs.class);
|
||||||
|
@ -0,0 +1,62 @@
|
|||||||
|
/* ====================================================================
|
||||||
|
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.poi.hssf.record.formula.eval;
|
||||||
|
|
||||||
|
import junit.framework.AssertionFailedError;
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
import org.apache.poi.hssf.record.formula.Area3DPtg;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for <tt>AreaEval</tt>
|
||||||
|
*
|
||||||
|
* @author Josh Micich
|
||||||
|
*/
|
||||||
|
public final class TestAreaEval extends TestCase {
|
||||||
|
|
||||||
|
public void testGetValue_bug44950() {
|
||||||
|
|
||||||
|
Area3DPtg ptg = new Area3DPtg("B2:D3", (short)0);
|
||||||
|
NumberEval one = new NumberEval(1);
|
||||||
|
ValueEval[] values = {
|
||||||
|
one,
|
||||||
|
new NumberEval(2),
|
||||||
|
new NumberEval(3),
|
||||||
|
new NumberEval(4),
|
||||||
|
new NumberEval(5),
|
||||||
|
new NumberEval(6),
|
||||||
|
};
|
||||||
|
AreaEval ae = new Area3DEval(ptg, values);
|
||||||
|
if (one == ae.getValueAt(1, 2)) {
|
||||||
|
throw new AssertionFailedError("Identified bug 44950 a");
|
||||||
|
}
|
||||||
|
confirm(1, ae, 1, 1);
|
||||||
|
confirm(2, ae, 1, 2);
|
||||||
|
confirm(3, ae, 1, 3);
|
||||||
|
confirm(4, ae, 2, 1);
|
||||||
|
confirm(5, ae, 2, 2);
|
||||||
|
confirm(6, ae, 2, 3);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void confirm(int expectedValue, AreaEval ae, int row, int col) {
|
||||||
|
NumberEval v = (NumberEval) ae.getValueAt(row, col);
|
||||||
|
assertEquals(expectedValue, v.getNumberValue(), 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -67,7 +67,7 @@ public final class TestCountFuncs extends TestCase {
|
|||||||
args = new Eval[] {
|
args = new Eval[] {
|
||||||
EvalFactory.createAreaEval("D1:F5", 3, 5), // 15
|
EvalFactory.createAreaEval("D1:F5", 3, 5), // 15
|
||||||
EvalFactory.createRefEval("A1"),
|
EvalFactory.createRefEval("A1"),
|
||||||
EvalFactory.createAreaEval("A1:F6", 7, 6), // 42
|
EvalFactory.createAreaEval("A1:G6", 7, 6), // 42
|
||||||
new NumberEval(0),
|
new NumberEval(0),
|
||||||
};
|
};
|
||||||
confirmCountA(59, args);
|
confirmCountA(59, args);
|
||||||
@ -87,7 +87,7 @@ public final class TestCountFuncs extends TestCase {
|
|||||||
BoolEval.TRUE,
|
BoolEval.TRUE,
|
||||||
BlankEval.INSTANCE,
|
BlankEval.INSTANCE,
|
||||||
};
|
};
|
||||||
range = createAreaEval("A1:B2", values);
|
range = createAreaEval("A1:B3", values);
|
||||||
confirmCountIf(2, range, BoolEval.TRUE);
|
confirmCountIf(2, range, BoolEval.TRUE);
|
||||||
|
|
||||||
// when criteria is numeric
|
// when criteria is numeric
|
||||||
@ -98,9 +98,8 @@ public final class TestCountFuncs extends TestCase {
|
|||||||
new NumberEval(2),
|
new NumberEval(2),
|
||||||
new NumberEval(2),
|
new NumberEval(2),
|
||||||
BoolEval.TRUE,
|
BoolEval.TRUE,
|
||||||
BlankEval.INSTANCE,
|
|
||||||
};
|
};
|
||||||
range = createAreaEval("A1:B2", values);
|
range = createAreaEval("A1:B3", values);
|
||||||
confirmCountIf(3, range, new NumberEval(2));
|
confirmCountIf(3, range, new NumberEval(2));
|
||||||
// note - same results when criteria is a string that parses as the number with the same value
|
// note - same results when criteria is a string that parses as the number with the same value
|
||||||
confirmCountIf(3, range, new StringEval("2.00"));
|
confirmCountIf(3, range, new StringEval("2.00"));
|
||||||
|
@ -44,7 +44,7 @@ public final class TestIndex extends TestCase {
|
|||||||
7, 8,
|
7, 8,
|
||||||
9, 10,
|
9, 10,
|
||||||
11, 12,
|
11, 12,
|
||||||
13, // excess array element. TODO - Area2DEval currently has no validation to ensure correct size of values array
|
// 13, // excess array element. TODO - Area2DEval currently has no validation to ensure correct size of values array
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,10 +38,12 @@ public class AllUserModelTests {
|
|||||||
result.addTestSuite(TestEscherGraphics2d.class);
|
result.addTestSuite(TestEscherGraphics2d.class);
|
||||||
result.addTestSuite(TestFontDetails.class);
|
result.addTestSuite(TestFontDetails.class);
|
||||||
result.addTestSuite(TestFormulas.class);
|
result.addTestSuite(TestFormulas.class);
|
||||||
|
result.addTestSuite(TestFormulaEvaluatorBugs.class);
|
||||||
|
result.addTestSuite(TestFormulaEvaluatorDocs.class);
|
||||||
result.addTestSuite(TestHSSFCell.class);
|
result.addTestSuite(TestHSSFCell.class);
|
||||||
result.addTestSuite(TestHSSFClientAnchor.class);
|
result.addTestSuite(TestHSSFClientAnchor.class);
|
||||||
result.addTestSuite(TestHSSFConditionalFormatting.class);
|
|
||||||
result.addTestSuite(TestHSSFComment.class);
|
result.addTestSuite(TestHSSFComment.class);
|
||||||
|
result.addTestSuite(TestHSSFConditionalFormatting.class);
|
||||||
result.addTestSuite(TestHSSFDateUtil.class);
|
result.addTestSuite(TestHSSFDateUtil.class);
|
||||||
result.addTestSuite(TestHSSFHeaderFooter.class);
|
result.addTestSuite(TestHSSFHeaderFooter.class);
|
||||||
result.addTestSuite(TestHSSFHyperlink.class);
|
result.addTestSuite(TestHSSFHyperlink.class);
|
||||||
@ -54,9 +56,11 @@ public class AllUserModelTests {
|
|||||||
result.addTestSuite(TestHSSFSheet.class);
|
result.addTestSuite(TestHSSFSheet.class);
|
||||||
result.addTestSuite(TestHSSFSheetOrder.class);
|
result.addTestSuite(TestHSSFSheetOrder.class);
|
||||||
result.addTestSuite(TestHSSFSheetSetOrder.class);
|
result.addTestSuite(TestHSSFSheetSetOrder.class);
|
||||||
|
result.addTestSuite(TestHSSFTextbox.class);
|
||||||
result.addTestSuite(TestHSSFWorkbook.class);
|
result.addTestSuite(TestHSSFWorkbook.class);
|
||||||
result.addTestSuite(TestNamedRange.class);
|
result.addTestSuite(TestNamedRange.class);
|
||||||
result.addTestSuite(TestOLE2Embeding.class);
|
result.addTestSuite(TestOLE2Embeding.class);
|
||||||
|
result.addTestSuite(TestPOIFSProperties.class);
|
||||||
result.addTestSuite(TestReadWriteChart.class);
|
result.addTestSuite(TestReadWriteChart.class);
|
||||||
result.addTestSuite(TestSanityChecker.class);
|
result.addTestSuite(TestSanityChecker.class);
|
||||||
result.addTestSuite(TestSheetHiding.class);
|
result.addTestSuite(TestSheetHiding.class);
|
||||||
|
@ -22,12 +22,14 @@ import java.io.FileOutputStream;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import junit.framework.AssertionFailedError;
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
import org.apache.poi.hssf.HSSFTestDataSamples;
|
import org.apache.poi.hssf.HSSFTestDataSamples;
|
||||||
import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate;
|
import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate;
|
||||||
import org.apache.poi.hssf.record.formula.AreaPtg;
|
import org.apache.poi.hssf.record.formula.AreaPtg;
|
||||||
import org.apache.poi.hssf.record.formula.FuncVarPtg;
|
import org.apache.poi.hssf.record.formula.FuncVarPtg;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -54,39 +56,38 @@ public final class TestFormulaEvaluatorBugs extends TestCase {
|
|||||||
// re-calculate
|
// re-calculate
|
||||||
|
|
||||||
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("44636.xls");
|
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("44636.xls");
|
||||||
HSSFSheet sheet = wb.getSheetAt (0);
|
HSSFSheet sheet = wb.getSheetAt(0);
|
||||||
HSSFRow row = sheet.getRow (0);
|
HSSFRow row = sheet.getRow(0);
|
||||||
|
|
||||||
row.getCell((short)0).setCellValue(4.2);
|
row.getCell((short) 0).setCellValue(4.2);
|
||||||
row.getCell((short)2).setCellValue(25);
|
row.getCell((short) 2).setCellValue(25);
|
||||||
|
|
||||||
HSSFFormulaEvaluator.evaluateAllFormulaCells(wb);
|
HSSFFormulaEvaluator.evaluateAllFormulaCells(wb);
|
||||||
assertEquals(4.2*25, row.getCell((short)3).getNumericCellValue(), 0.0001);
|
assertEquals(4.2 * 25, row.getCell((short) 3).getNumericCellValue(), 0.0001);
|
||||||
|
|
||||||
// Save
|
// Save
|
||||||
File existing = new File(tmpDirName,"44636-existing.xls");
|
File existing = new File(tmpDirName, "44636-existing.xls");
|
||||||
FileOutputStream out = new FileOutputStream(existing);
|
FileOutputStream out = new FileOutputStream(existing);
|
||||||
wb.write(out);
|
wb.write(out);
|
||||||
out.close();
|
out.close();
|
||||||
System.err.println("Existing file for bug #44636 written to " + existing.toString());
|
System.err.println("Existing file for bug #44636 written to " + existing.toString());
|
||||||
|
|
||||||
|
|
||||||
// Now, do a new file from scratch
|
// Now, do a new file from scratch
|
||||||
wb = new HSSFWorkbook();
|
wb = new HSSFWorkbook();
|
||||||
sheet = wb.createSheet();
|
sheet = wb.createSheet();
|
||||||
|
|
||||||
row = sheet.createRow(0);
|
row = sheet.createRow(0);
|
||||||
row.createCell((short)0).setCellValue(1.2);
|
row.createCell((short) 0).setCellValue(1.2);
|
||||||
row.createCell((short)1).setCellValue(4.2);
|
row.createCell((short) 1).setCellValue(4.2);
|
||||||
|
|
||||||
row = sheet.createRow(1);
|
row = sheet.createRow(1);
|
||||||
row.createCell((short)0).setCellFormula("SUM(A1:B1)");
|
row.createCell((short) 0).setCellFormula("SUM(A1:B1)");
|
||||||
|
|
||||||
HSSFFormulaEvaluator.evaluateAllFormulaCells(wb);
|
HSSFFormulaEvaluator.evaluateAllFormulaCells(wb);
|
||||||
assertEquals(5.4, row.getCell((short)0).getNumericCellValue(), 0.0001);
|
assertEquals(5.4, row.getCell((short) 0).getNumericCellValue(), 0.0001);
|
||||||
|
|
||||||
// Save
|
// Save
|
||||||
File scratch = new File(tmpDirName,"44636-scratch.xls");
|
File scratch = new File(tmpDirName, "44636-scratch.xls");
|
||||||
out = new FileOutputStream(scratch);
|
out = new FileOutputStream(scratch);
|
||||||
wb.write(out);
|
wb.write(out);
|
||||||
out.close();
|
out.close();
|
||||||
@ -112,55 +113,55 @@ public final class TestFormulaEvaluatorBugs extends TestCase {
|
|||||||
HSSFFormulaEvaluator eva = new HSSFFormulaEvaluator(sheet, wb);
|
HSSFFormulaEvaluator eva = new HSSFFormulaEvaluator(sheet, wb);
|
||||||
|
|
||||||
row = sheet.getRow(0);
|
row = sheet.getRow(0);
|
||||||
cell = row.getCell((short)0);
|
cell = row.getCell((short) 0);
|
||||||
assertEquals("31+46", cell.getCellFormula());
|
assertEquals("31+46", cell.getCellFormula());
|
||||||
eva.setCurrentRow(row);
|
eva.setCurrentRow(row);
|
||||||
assertEquals(77, eva.evaluate(cell).getNumberValue(), 0);
|
assertEquals(77, eva.evaluate(cell).getNumberValue(), 0);
|
||||||
|
|
||||||
row = sheet.getRow(1);
|
row = sheet.getRow(1);
|
||||||
cell = row.getCell((short)0);
|
cell = row.getCell((short) 0);
|
||||||
assertEquals("30+53", cell.getCellFormula());
|
assertEquals("30+53", cell.getCellFormula());
|
||||||
eva.setCurrentRow(row);
|
eva.setCurrentRow(row);
|
||||||
assertEquals(83, eva.evaluate(cell).getNumberValue(), 0);
|
assertEquals(83, eva.evaluate(cell).getNumberValue(), 0);
|
||||||
|
|
||||||
row = sheet.getRow(2);
|
row = sheet.getRow(2);
|
||||||
cell = row.getCell((short)0);
|
cell = row.getCell((short) 0);
|
||||||
assertEquals("SUM(A1:A2)", cell.getCellFormula());
|
assertEquals("SUM(A1:A2)", cell.getCellFormula());
|
||||||
eva.setCurrentRow(row);
|
eva.setCurrentRow(row);
|
||||||
assertEquals(160, eva.evaluate(cell).getNumberValue(), 0);
|
assertEquals(160, eva.evaluate(cell).getNumberValue(), 0);
|
||||||
|
|
||||||
row = sheet.getRow(4);
|
row = sheet.getRow(4);
|
||||||
cell = row.getCell((short)0);
|
cell = row.getCell((short) 0);
|
||||||
assertEquals("32767+32768", cell.getCellFormula());
|
assertEquals("32767+32768", cell.getCellFormula());
|
||||||
eva.setCurrentRow(row);
|
eva.setCurrentRow(row);
|
||||||
assertEquals(65535, eva.evaluate(cell).getNumberValue(), 0);
|
assertEquals(65535, eva.evaluate(cell).getNumberValue(), 0);
|
||||||
|
|
||||||
row = sheet.getRow(7);
|
row = sheet.getRow(7);
|
||||||
cell = row.getCell((short)0);
|
cell = row.getCell((short) 0);
|
||||||
assertEquals("32744+42333", cell.getCellFormula());
|
assertEquals("32744+42333", cell.getCellFormula());
|
||||||
eva.setCurrentRow(row);
|
eva.setCurrentRow(row);
|
||||||
assertEquals(75077, eva.evaluate(cell).getNumberValue(), 0);
|
assertEquals(75077, eva.evaluate(cell).getNumberValue(), 0);
|
||||||
|
|
||||||
row = sheet.getRow(8);
|
row = sheet.getRow(8);
|
||||||
cell = row.getCell((short)0);
|
cell = row.getCell((short) 0);
|
||||||
assertEquals("327680.0/32768", cell.getCellFormula());
|
assertEquals("327680.0/32768", cell.getCellFormula());
|
||||||
eva.setCurrentRow(row);
|
eva.setCurrentRow(row);
|
||||||
assertEquals(10, eva.evaluate(cell).getNumberValue(), 0);
|
assertEquals(10, eva.evaluate(cell).getNumberValue(), 0);
|
||||||
|
|
||||||
row = sheet.getRow(9);
|
row = sheet.getRow(9);
|
||||||
cell = row.getCell((short)0);
|
cell = row.getCell((short) 0);
|
||||||
assertEquals("32767+32769", cell.getCellFormula());
|
assertEquals("32767+32769", cell.getCellFormula());
|
||||||
eva.setCurrentRow(row);
|
eva.setCurrentRow(row);
|
||||||
assertEquals(65536, eva.evaluate(cell).getNumberValue(), 0);
|
assertEquals(65536, eva.evaluate(cell).getNumberValue(), 0);
|
||||||
|
|
||||||
row = sheet.getRow(10);
|
row = sheet.getRow(10);
|
||||||
cell = row.getCell((short)0);
|
cell = row.getCell((short) 0);
|
||||||
assertEquals("35000+36000", cell.getCellFormula());
|
assertEquals("35000+36000", cell.getCellFormula());
|
||||||
eva.setCurrentRow(row);
|
eva.setCurrentRow(row);
|
||||||
assertEquals(71000, eva.evaluate(cell).getNumberValue(), 0);
|
assertEquals(71000, eva.evaluate(cell).getNumberValue(), 0);
|
||||||
|
|
||||||
row = sheet.getRow(11);
|
row = sheet.getRow(11);
|
||||||
cell = row.getCell((short)0);
|
cell = row.getCell((short) 0);
|
||||||
assertEquals("-1000000.0-3000000.0", cell.getCellFormula());
|
assertEquals("-1000000.0-3000000.0", cell.getCellFormula());
|
||||||
eva.setCurrentRow(row);
|
eva.setCurrentRow(row);
|
||||||
assertEquals(-4000000, eva.evaluate(cell).getNumberValue(), 0);
|
assertEquals(-4000000, eva.evaluate(cell).getNumberValue(), 0);
|
||||||
@ -188,10 +189,9 @@ public final class TestFormulaEvaluatorBugs extends TestCase {
|
|||||||
HSSFRow rowSUM2D = sheet.getRow(5);
|
HSSFRow rowSUM2D = sheet.getRow(5);
|
||||||
|
|
||||||
// Test the sum
|
// Test the sum
|
||||||
HSSFCell cellSUM = rowSUM.getCell((short)0);
|
HSSFCell cellSUM = rowSUM.getCell((short) 0);
|
||||||
|
|
||||||
FormulaRecordAggregate frec =
|
FormulaRecordAggregate frec = (FormulaRecordAggregate) cellSUM.getCellValueRecord();
|
||||||
(FormulaRecordAggregate)cellSUM.getCellValueRecord();
|
|
||||||
List ops = frec.getFormulaRecord().getParsedExpression();
|
List ops = frec.getFormulaRecord().getParsedExpression();
|
||||||
assertEquals(2, ops.size());
|
assertEquals(2, ops.size());
|
||||||
assertEquals(AreaPtg.class, ops.get(0).getClass());
|
assertEquals(AreaPtg.class, ops.get(0).getClass());
|
||||||
@ -199,7 +199,7 @@ public final class TestFormulaEvaluatorBugs extends TestCase {
|
|||||||
|
|
||||||
// Actually stored as C1 to C65536
|
// Actually stored as C1 to C65536
|
||||||
// (last row is -1 === 65535)
|
// (last row is -1 === 65535)
|
||||||
AreaPtg ptg = (AreaPtg)ops.get(0);
|
AreaPtg ptg = (AreaPtg) ops.get(0);
|
||||||
assertEquals(2, ptg.getFirstColumn());
|
assertEquals(2, ptg.getFirstColumn());
|
||||||
assertEquals(2, ptg.getLastColumn());
|
assertEquals(2, ptg.getLastColumn());
|
||||||
assertEquals(0, ptg.getFirstRow());
|
assertEquals(0, ptg.getFirstRow());
|
||||||
@ -216,17 +216,16 @@ public final class TestFormulaEvaluatorBugs extends TestCase {
|
|||||||
// can do it properly
|
// can do it properly
|
||||||
assertEquals(6, eva.evaluate(cellSUM).getNumberValue(), 0);
|
assertEquals(6, eva.evaluate(cellSUM).getNumberValue(), 0);
|
||||||
|
|
||||||
|
|
||||||
// Test the index
|
// Test the index
|
||||||
// Again, the formula string will be right but
|
// Again, the formula string will be right but
|
||||||
// lacking row count, evaluated will be right
|
// lacking row count, evaluated will be right
|
||||||
HSSFCell cellIDX = rowIDX.getCell((short)0);
|
HSSFCell cellIDX = rowIDX.getCell((short) 0);
|
||||||
assertEquals("INDEX(C:C,2,1)", cellIDX.getCellFormula());
|
assertEquals("INDEX(C:C,2,1)", cellIDX.getCellFormula());
|
||||||
eva.setCurrentRow(rowIDX);
|
eva.setCurrentRow(rowIDX);
|
||||||
assertEquals(2, eva.evaluate(cellIDX).getNumberValue(), 0);
|
assertEquals(2, eva.evaluate(cellIDX).getNumberValue(), 0);
|
||||||
|
|
||||||
// Across two colums
|
// Across two colums
|
||||||
HSSFCell cellSUM2D = rowSUM2D.getCell((short)0);
|
HSSFCell cellSUM2D = rowSUM2D.getCell((short) 0);
|
||||||
assertEquals("SUM(C:D)", cellSUM2D.getCellFormula());
|
assertEquals("SUM(C:D)", cellSUM2D.getCellFormula());
|
||||||
eva.setCurrentRow(rowSUM2D);
|
eva.setCurrentRow(rowSUM2D);
|
||||||
assertEquals(66, eva.evaluate(cellSUM2D).getNumberValue(), 0);
|
assertEquals(66, eva.evaluate(cellSUM2D).getNumberValue(), 0);
|
||||||
@ -240,7 +239,7 @@ public final class TestFormulaEvaluatorBugs extends TestCase {
|
|||||||
HSSFSheet sheet = wb.createSheet();
|
HSSFSheet sheet = wb.createSheet();
|
||||||
wb.setSheetName(0, "Sheet1");
|
wb.setSheetName(0, "Sheet1");
|
||||||
HSSFRow row = sheet.createRow(0);
|
HSSFRow row = sheet.createRow(0);
|
||||||
HSSFCell cell = row.createCell((short)0);
|
HSSFCell cell = row.createCell((short) 0);
|
||||||
|
|
||||||
cell.setCellFormula("1=1");
|
cell.setCellFormula("1=1");
|
||||||
|
|
||||||
@ -255,27 +254,44 @@ public final class TestFormulaEvaluatorBugs extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testClassCast_bug44861() throws Exception {
|
public void testClassCast_bug44861() throws Exception {
|
||||||
HSSFWorkbook wb = HSSFTestDataSamples.
|
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("44861.xls");
|
||||||
openSampleWorkbook("44861.xls");
|
|
||||||
|
|
||||||
// Check direct
|
// Check direct
|
||||||
HSSFFormulaEvaluator.evaluateAllFormulaCells(wb);
|
HSSFFormulaEvaluator.evaluateAllFormulaCells(wb);
|
||||||
|
|
||||||
// And via calls
|
// And via calls
|
||||||
int numSheets = wb.getNumberOfSheets();
|
int numSheets = wb.getNumberOfSheets();
|
||||||
for(int i=0; i<numSheets; i++) {
|
for (int i = 0; i < numSheets; i++) {
|
||||||
HSSFSheet s = wb.getSheetAt(i);
|
HSSFSheet s = wb.getSheetAt(i);
|
||||||
HSSFFormulaEvaluator eval = new HSSFFormulaEvaluator(s,wb);
|
HSSFFormulaEvaluator eval = new HSSFFormulaEvaluator(s, wb);
|
||||||
|
|
||||||
for(Iterator rows = s.rowIterator(); rows.hasNext();) {
|
for (Iterator rows = s.rowIterator(); rows.hasNext();) {
|
||||||
HSSFRow r = (HSSFRow)rows.next();
|
HSSFRow r = (HSSFRow) rows.next();
|
||||||
eval.setCurrentRow(r);
|
eval.setCurrentRow(r);
|
||||||
|
|
||||||
for(Iterator cells = r.cellIterator(); cells.hasNext();) {
|
for (Iterator cells = r.cellIterator(); cells.hasNext();) {
|
||||||
HSSFCell c = (HSSFCell)cells.next();
|
HSSFCell c = (HSSFCell) cells.next();
|
||||||
eval.evaluateFormulaCell(c);
|
eval.evaluateFormulaCell(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testEvaluateInCellWithErrorCode_bug44950() {
|
||||||
|
HSSFWorkbook wb = new HSSFWorkbook();
|
||||||
|
HSSFSheet sheet = wb.createSheet("Sheet1");
|
||||||
|
HSSFRow row = sheet.createRow(1);
|
||||||
|
HSSFCell cell = row.createCell((short) 0);
|
||||||
|
cell.setCellFormula("na()"); // this formula evaluates to an Excel error code '#N/A'
|
||||||
|
HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb);
|
||||||
|
fe.setCurrentRow(row);
|
||||||
|
try {
|
||||||
|
fe.evaluateInCell(cell);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
if (e.getMessage().equals("You cannot get an error value from a non-error cell")) {
|
||||||
|
throw new AssertionFailedError("Identified bug 44950 b");
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user