whitespace

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1712909 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Javen O'Neal 2015-11-06 04:45:25 +00:00
parent 42c1296ef6
commit 663c64ff44

View File

@ -60,246 +60,245 @@ public class TestWorkbookEvaluator {
private static final double EPSILON = 0.0000001;
private static ValueEval evaluateFormula(Ptg[] ptgs) {
OperationEvaluationContext ec = new OperationEvaluationContext(null, null, 0, 0, 0, null);
return new WorkbookEvaluator(null, null, null).evaluateFormula(ec, ptgs);
}
private static ValueEval evaluateFormula(Ptg[] ptgs) {
OperationEvaluationContext ec = new OperationEvaluationContext(null, null, 0, 0, 0, null);
return new WorkbookEvaluator(null, null, null).evaluateFormula(ec, ptgs);
}
/**
* Make sure that the evaluator can directly handle tAttrSum (instead of relying on re-parsing
* the whole formula which converts tAttrSum to tFuncVar("SUM") )
*/
@Test
public void testAttrSum() {
/**
* Make sure that the evaluator can directly handle tAttrSum (instead of relying on re-parsing
* the whole formula which converts tAttrSum to tFuncVar("SUM") )
*/
@Test
public void testAttrSum() {
Ptg[] ptgs = {
new IntPtg(42),
AttrPtg.SUM,
};
Ptg[] ptgs = {
new IntPtg(42),
AttrPtg.SUM,
};
ValueEval result = evaluateFormula(ptgs);
assertEquals(42, ((NumberEval)result).getNumberValue(), 0.0);
}
ValueEval result = evaluateFormula(ptgs);
assertEquals(42, ((NumberEval)result).getNumberValue(), 0.0);
}
/**
* Make sure that the evaluator can directly handle (deleted) ref error tokens
* (instead of relying on re-parsing the whole formula which converts these
* to the error constant #REF! )
*/
@Test
public void testRefErr() {
/**
* Make sure that the evaluator can directly handle (deleted) ref error tokens
* (instead of relying on re-parsing the whole formula which converts these
* to the error constant #REF! )
*/
@Test
public void testRefErr() {
confirmRefErr(new RefErrorPtg());
confirmRefErr(new AreaErrPtg());
confirmRefErr(new DeletedRef3DPtg(0));
confirmRefErr(new DeletedArea3DPtg(0));
}
private static void confirmRefErr(Ptg ptg) {
Ptg[] ptgs = {
ptg,
};
confirmRefErr(new RefErrorPtg());
confirmRefErr(new AreaErrPtg());
confirmRefErr(new DeletedRef3DPtg(0));
confirmRefErr(new DeletedArea3DPtg(0));
}
private static void confirmRefErr(Ptg ptg) {
Ptg[] ptgs = {
ptg,
};
ValueEval result = evaluateFormula(ptgs);
assertEquals(ErrorEval.REF_INVALID, result);
}
ValueEval result = evaluateFormula(ptgs);
assertEquals(ErrorEval.REF_INVALID, result);
}
/**
* Make sure that the evaluator can directly handle tAttrSum (instead of relying on re-parsing
* the whole formula which converts tAttrSum to tFuncVar("SUM") )
*/
@Test
public void testMemFunc() {
/**
* Make sure that the evaluator can directly handle tAttrSum (instead of relying on re-parsing
* the whole formula which converts tAttrSum to tFuncVar("SUM") )
*/
@Test
public void testMemFunc() {
Ptg[] ptgs = {
new IntPtg(42),
AttrPtg.SUM,
};
Ptg[] ptgs = {
new IntPtg(42),
AttrPtg.SUM,
};
ValueEval result = evaluateFormula(ptgs);
assertEquals(42, ((NumberEval)result).getNumberValue(), 0.0);
}
ValueEval result = evaluateFormula(ptgs);
assertEquals(42, ((NumberEval)result).getNumberValue(), 0.0);
}
@Test
public void testEvaluateMultipleWorkbooks() {
HSSFWorkbook wbA = HSSFTestDataSamples.openSampleWorkbook("multibookFormulaA.xls");
HSSFWorkbook wbB = HSSFTestDataSamples.openSampleWorkbook("multibookFormulaB.xls");
@Test
public void testEvaluateMultipleWorkbooks() {
HSSFWorkbook wbA = HSSFTestDataSamples.openSampleWorkbook("multibookFormulaA.xls");
HSSFWorkbook wbB = HSSFTestDataSamples.openSampleWorkbook("multibookFormulaB.xls");
HSSFFormulaEvaluator evaluatorA = new HSSFFormulaEvaluator(wbA);
HSSFFormulaEvaluator evaluatorB = new HSSFFormulaEvaluator(wbB);
HSSFFormulaEvaluator evaluatorA = new HSSFFormulaEvaluator(wbA);
HSSFFormulaEvaluator evaluatorB = new HSSFFormulaEvaluator(wbB);
// Hook up the workbook evaluators to enable evaluation of formulas across books
String[] bookNames = { "multibookFormulaA.xls", "multibookFormulaB.xls", };
HSSFFormulaEvaluator[] evaluators = { evaluatorA, evaluatorB, };
HSSFFormulaEvaluator.setupEnvironment(bookNames, evaluators);
// Hook up the workbook evaluators to enable evaluation of formulas across books
String[] bookNames = { "multibookFormulaA.xls", "multibookFormulaB.xls", };
HSSFFormulaEvaluator[] evaluators = { evaluatorA, evaluatorB, };
HSSFFormulaEvaluator.setupEnvironment(bookNames, evaluators);
HSSFCell cell;
HSSFCell cell;
HSSFSheet aSheet1 = wbA.getSheetAt(0);
HSSFSheet bSheet1 = wbB.getSheetAt(0);
HSSFSheet aSheet1 = wbA.getSheetAt(0);
HSSFSheet bSheet1 = wbB.getSheetAt(0);
// Simple case - single link from wbA to wbB
confirmFormula(wbA, 0, 0, 0, "[multibookFormulaB.xls]BSheet1!B1");
cell = aSheet1.getRow(0).getCell(0);
confirmEvaluation(35, evaluatorA, cell);
// Simple case - single link from wbA to wbB
confirmFormula(wbA, 0, 0, 0, "[multibookFormulaB.xls]BSheet1!B1");
cell = aSheet1.getRow(0).getCell(0);
confirmEvaluation(35, evaluatorA, cell);
// more complex case - back link into wbA
// [wbA]ASheet1!A2 references (among other things) [wbB]BSheet1!B2
confirmFormula(wbA, 0, 1, 0, "[multibookFormulaB.xls]BSheet1!$B$2+2*A3");
// [wbB]BSheet1!B2 references (among other things) [wbA]AnotherSheet!A1:B2
confirmFormula(wbB, 0, 1, 1, "SUM([multibookFormulaA.xls]AnotherSheet!$A$1:$B$2)+B3");
// more complex case - back link into wbA
// [wbA]ASheet1!A2 references (among other things) [wbB]BSheet1!B2
confirmFormula(wbA, 0, 1, 0, "[multibookFormulaB.xls]BSheet1!$B$2+2*A3");
// [wbB]BSheet1!B2 references (among other things) [wbA]AnotherSheet!A1:B2
confirmFormula(wbB, 0, 1, 1, "SUM([multibookFormulaA.xls]AnotherSheet!$A$1:$B$2)+B3");
cell = aSheet1.getRow(1).getCell(0);
confirmEvaluation(264, evaluatorA, cell);
cell = aSheet1.getRow(1).getCell(0);
confirmEvaluation(264, evaluatorA, cell);
// change [wbB]BSheet1!B3 (from 50 to 60)
HSSFCell cellB3 = bSheet1.getRow(2).getCell(1);
cellB3.setCellValue(60);
evaluatorB.notifyUpdateCell(cellB3);
confirmEvaluation(274, evaluatorA, cell);
// change [wbB]BSheet1!B3 (from 50 to 60)
HSSFCell cellB3 = bSheet1.getRow(2).getCell(1);
cellB3.setCellValue(60);
evaluatorB.notifyUpdateCell(cellB3);
confirmEvaluation(274, evaluatorA, cell);
// change [wbA]ASheet1!A3 (from 100 to 80)
HSSFCell cellA3 = aSheet1.getRow(2).getCell(0);
cellA3.setCellValue(80);
evaluatorA.notifyUpdateCell(cellA3);
confirmEvaluation(234, evaluatorA, cell);
// change [wbA]ASheet1!A3 (from 100 to 80)
HSSFCell cellA3 = aSheet1.getRow(2).getCell(0);
cellA3.setCellValue(80);
evaluatorA.notifyUpdateCell(cellA3);
confirmEvaluation(234, evaluatorA, cell);
// change [wbA]AnotherSheet!A1 (from 2 to 3)
HSSFCell cellA1 = wbA.getSheetAt(1).getRow(0).getCell(0);
cellA1.setCellValue(3);
evaluatorA.notifyUpdateCell(cellA1);
confirmEvaluation(235, evaluatorA, cell);
}
// change [wbA]AnotherSheet!A1 (from 2 to 3)
HSSFCell cellA1 = wbA.getSheetAt(1).getRow(0).getCell(0);
cellA1.setCellValue(3);
evaluatorA.notifyUpdateCell(cellA1);
confirmEvaluation(235, evaluatorA, cell);
}
private static void confirmEvaluation(double expectedValue, HSSFFormulaEvaluator fe, HSSFCell cell) {
assertEquals(expectedValue, fe.evaluate(cell).getNumberValue(), 0.0);
}
private static void confirmEvaluation(double expectedValue, HSSFFormulaEvaluator fe, HSSFCell cell) {
assertEquals(expectedValue, fe.evaluate(cell).getNumberValue(), 0.0);
}
private static void confirmFormula(HSSFWorkbook wb, int sheetIndex, int rowIndex, int columnIndex,
String expectedFormula) {
HSSFCell cell = wb.getSheetAt(sheetIndex).getRow(rowIndex).getCell(columnIndex);
assertEquals(expectedFormula, cell.getCellFormula());
}
private static void confirmFormula(HSSFWorkbook wb, int sheetIndex, int rowIndex, int columnIndex,
String expectedFormula) {
HSSFCell cell = wb.getSheetAt(sheetIndex).getRow(rowIndex).getCell(columnIndex);
assertEquals(expectedFormula, cell.getCellFormula());
}
/**
* This test makes sure that any {@link MissingArgEval} that propagates to
* the result of a function gets translated to {@link BlankEval}.
*/
@Test
public void testMissingArg() {
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("Sheet1");
HSSFRow row = sheet.createRow(0);
HSSFCell cell = row.createCell(0);
cell.setCellFormula("1+IF(1,,)");
HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
CellValue cv = null;
try {
cv = fe.evaluate(cell);
} catch (RuntimeException e) {
fail("Missing arg result not being handled correctly.");
}
assertEquals(HSSFCell.CELL_TYPE_NUMERIC, cv.getCellType());
// adding blank to 1.0 gives 1.0
assertEquals(1.0, cv.getNumberValue(), 0.0);
/**
* This test makes sure that any {@link MissingArgEval} that propagates to
* the result of a function gets translated to {@link BlankEval}.
*/
@Test
public void testMissingArg() {
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("Sheet1");
HSSFRow row = sheet.createRow(0);
HSSFCell cell = row.createCell(0);
cell.setCellFormula("1+IF(1,,)");
HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
CellValue cv = null;
try {
cv = fe.evaluate(cell);
} catch (RuntimeException e) {
fail("Missing arg result not being handled correctly.");
}
assertEquals(HSSFCell.CELL_TYPE_NUMERIC, cv.getCellType());
// adding blank to 1.0 gives 1.0
assertEquals(1.0, cv.getNumberValue(), 0.0);
// check with string operand
cell.setCellFormula("\"abc\"&IF(1,,)");
fe.notifySetFormula(cell);
cv = fe.evaluate(cell);
assertEquals(HSSFCell.CELL_TYPE_STRING, cv.getCellType());
// adding blank to "abc" gives "abc"
assertEquals("abc", cv.getStringValue());
// check with string operand
cell.setCellFormula("\"abc\"&IF(1,,)");
fe.notifySetFormula(cell);
cv = fe.evaluate(cell);
assertEquals(HSSFCell.CELL_TYPE_STRING, cv.getCellType());
// adding blank to "abc" gives "abc"
assertEquals("abc", cv.getStringValue());
// check CHOOSE()
cell.setCellFormula("\"abc\"&CHOOSE(2,5,,9)");
fe.notifySetFormula(cell);
cv = fe.evaluate(cell);
assertEquals(HSSFCell.CELL_TYPE_STRING, cv.getCellType());
// adding blank to "abc" gives "abc"
assertEquals("abc", cv.getStringValue());
}
// check CHOOSE()
cell.setCellFormula("\"abc\"&CHOOSE(2,5,,9)");
fe.notifySetFormula(cell);
cv = fe.evaluate(cell);
assertEquals(HSSFCell.CELL_TYPE_STRING, cv.getCellType());
// adding blank to "abc" gives "abc"
assertEquals("abc", cv.getStringValue());
}
/**
* Functions like IF, INDIRECT, INDEX, OFFSET etc can return AreaEvals which
* should be dereferenced by the evaluator
* @throws IOException
*/
@Test
public void testResultOutsideRange() throws IOException {
Workbook wb = new HSSFWorkbook();
try {
Cell cell = wb.createSheet("Sheet1").createRow(0).createCell(0);
cell.setCellFormula("D2:D5"); // IF(TRUE,D2:D5,D2) or OFFSET(D2:D5,0,0) would work too
FormulaEvaluator fe = wb.getCreationHelper().createFormulaEvaluator();
CellValue cv;
try {
cv = fe.evaluate(cell);
} catch (IllegalArgumentException e) {
if ("Specified row index (0) is outside the allowed range (1..4)".equals(e.getMessage())) {
fail("Identified bug in result dereferencing");
}
throw new RuntimeException(e);
}
assertEquals(Cell.CELL_TYPE_ERROR, cv.getCellType());
assertEquals(ErrorConstants.ERROR_VALUE, cv.getErrorValue());
// verify circular refs are still detected properly
fe.clearAllCachedResultValues();
cell.setCellFormula("OFFSET(A1,0,0)");
cv = fe.evaluate(cell);
assertEquals(Cell.CELL_TYPE_ERROR, cv.getCellType());
assertEquals(ErrorEval.CIRCULAR_REF_ERROR.getErrorCode(), cv.getErrorValue());
} finally {
wb.close();
}
}
/**
* Functions like IF, INDIRECT, INDEX, OFFSET etc can return AreaEvals which
* should be dereferenced by the evaluator
* @throws IOException
*/
@Test
public void testResultOutsideRange() throws IOException {
Workbook wb = new HSSFWorkbook();
try {
Cell cell = wb.createSheet("Sheet1").createRow(0).createCell(0);
cell.setCellFormula("D2:D5"); // IF(TRUE,D2:D5,D2) or OFFSET(D2:D5,0,0) would work too
FormulaEvaluator fe = wb.getCreationHelper().createFormulaEvaluator();
CellValue cv;
try {
cv = fe.evaluate(cell);
} catch (IllegalArgumentException e) {
if ("Specified row index (0) is outside the allowed range (1..4)".equals(e.getMessage())) {
fail("Identified bug in result dereferencing");
}
throw new RuntimeException(e);
}
assertEquals(Cell.CELL_TYPE_ERROR, cv.getCellType());
assertEquals(ErrorConstants.ERROR_VALUE, cv.getErrorValue());
/**
* formulas with defined names.
* @throws IOException
*/
@Test
public void testNamesInFormulas() throws IOException {
Workbook wb = new HSSFWorkbook();
Sheet sheet = wb.createSheet("Sheet1");
Name name1 = wb.createName();
name1.setNameName("aConstant");
name1.setRefersToFormula("3.14");
// verify circular refs are still detected properly
fe.clearAllCachedResultValues();
cell.setCellFormula("OFFSET(A1,0,0)");
cv = fe.evaluate(cell);
assertEquals(Cell.CELL_TYPE_ERROR, cv.getCellType());
assertEquals(ErrorEval.CIRCULAR_REF_ERROR.getErrorCode(), cv.getErrorValue());
} finally {
wb.close();
}
}
Name name2 = wb.createName();
name2.setNameName("aFormula");
name2.setRefersToFormula("SUM(Sheet1!$A$1:$A$3)");
Name name3 = wb.createName();
name3.setNameName("aSet");
name3.setRefersToFormula("Sheet1!$A$2:$A$4");
/**
* formulas with defined names.
* @throws IOException
*/
@Test
public void testNamesInFormulas() throws IOException {
Workbook wb = new HSSFWorkbook();
Sheet sheet = wb.createSheet("Sheet1");
Name name1 = wb.createName();
name1.setNameName("aConstant");
name1.setRefersToFormula("3.14");
Row row0 = sheet.createRow(0);
Row row1 = sheet.createRow(1);
Row row2 = sheet.createRow(2);
Row row3 = sheet.createRow(3);
row0.createCell(0).setCellValue(2);
row1.createCell(0).setCellValue(5);
row2.createCell(0).setCellValue(3);
row3.createCell(0).setCellValue(7);
row0.createCell(2).setCellFormula("aConstant");
row1.createCell(2).setCellFormula("aFormula");
row2.createCell(2).setCellFormula("SUM(aSet)");
row3.createCell(2).setCellFormula("aConstant+aFormula+SUM(aSet)");
Name name2 = wb.createName();
name2.setNameName("aFormula");
name2.setRefersToFormula("SUM(Sheet1!$A$1:$A$3)");
FormulaEvaluator fe = wb.getCreationHelper().createFormulaEvaluator();
assertEquals(3.14, fe.evaluate(row0.getCell(2)).getNumberValue(), EPSILON);
assertEquals(10.0, fe.evaluate(row1.getCell(2)).getNumberValue(), EPSILON);
assertEquals(15.0, fe.evaluate(row2.getCell(2)).getNumberValue(), EPSILON);
assertEquals(28.14, fe.evaluate(row3.getCell(2)).getNumberValue(), EPSILON);
wb.close();
}
Name name3 = wb.createName();
name3.setNameName("aSet");
name3.setRefersToFormula("Sheet1!$A$2:$A$4");
Row row0 = sheet.createRow(0);
Row row1 = sheet.createRow(1);
Row row2 = sheet.createRow(2);
Row row3 = sheet.createRow(3);
row0.createCell(0).setCellValue(2);
row1.createCell(0).setCellValue(5);
row2.createCell(0).setCellValue(3);
row3.createCell(0).setCellValue(7);
row0.createCell(2).setCellFormula("aConstant");
row1.createCell(2).setCellFormula("aFormula");
row2.createCell(2).setCellFormula("SUM(aSet)");
row3.createCell(2).setCellFormula("aConstant+aFormula+SUM(aSet)");
FormulaEvaluator fe = wb.getCreationHelper().createFormulaEvaluator();
assertEquals(3.14, fe.evaluate(row0.getCell(2)).getNumberValue(), EPSILON);
assertEquals(10.0, fe.evaluate(row1.getCell(2)).getNumberValue(), EPSILON);
assertEquals(15.0, fe.evaluate(row2.getCell(2)).getNumberValue(), EPSILON);
assertEquals(28.14, fe.evaluate(row3.getCell(2)).getNumberValue(), EPSILON);
wb.close();
}
}