/* ====================================================================
   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.ss.formula;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.IOException;

import org.apache.poi.hssf.HSSFTestDataSamples;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.formula.eval.BlankEval;
import org.apache.poi.ss.formula.eval.ErrorEval;
import org.apache.poi.ss.formula.eval.MissingArgEval;
import org.apache.poi.ss.formula.eval.NumberEval;
import org.apache.poi.ss.formula.eval.ValueEval;
import org.apache.poi.ss.formula.ptg.AreaErrPtg;
import org.apache.poi.ss.formula.ptg.AttrPtg;
import org.apache.poi.ss.formula.ptg.DeletedArea3DPtg;
import org.apache.poi.ss.formula.ptg.DeletedRef3DPtg;
import org.apache.poi.ss.formula.ptg.IntPtg;
import org.apache.poi.ss.formula.ptg.Ptg;
import org.apache.poi.ss.formula.ptg.RefErrorPtg;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.CellValue;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.apache.poi.ss.usermodel.Name;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.junit.Ignore;
import org.junit.Test;

/**
 * Tests {@link WorkbookEvaluator}.
 *
 * @author Josh Micich
 */
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);
    }

    /**
     * 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,
        };

        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() {

        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);
    }

    /**
     * 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,
        };

        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");

        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);

        HSSFCell cell;

        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);


        // 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);

        // 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]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 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(CellType.NUMERIC, cv.getCellTypeEnum());
        // 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(CellType.STRING, cv.getCellTypeEnum());
        // 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(CellType.STRING, cv.getCellTypeEnum());
        // 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(CellType.ERROR, cv.getCellTypeEnum());
            assertEquals(ErrorEval.VALUE_INVALID.getErrorCode(), cv.getErrorValue());

            // verify circular refs are still detected properly
            fe.clearAllCachedResultValues();
            cell.setCellFormula("OFFSET(A1,0,0)");
            cv = fe.evaluate(cell);
            assertEquals(CellType.ERROR, cv.getCellTypeEnum());
            assertEquals(ErrorEval.CIRCULAR_REF_ERROR.getErrorCode(), cv.getErrorValue());
        } finally {
            wb.close();
        }
    }


    /**
     * 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");

        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");

        
        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();
    }

    @Test
    public void testIgnoreMissingWorkbooks() {
        // TODO: update this test for meaningful functional behavior
        WorkbookEvaluator evaluator = new WorkbookEvaluator(null, null, null);
        assertFalse(evaluator.isIgnoreMissingWorkbooks());

        evaluator.setIgnoreMissingWorkbooks(true);
        assertTrue(evaluator.isIgnoreMissingWorkbooks());

        evaluator.setIgnoreMissingWorkbooks(false);
        assertFalse(evaluator.isIgnoreMissingWorkbooks());
    }

    @Test
    public void testDebugEvaluationOutputForNextEval() {
        // TODO: update this test for meaningful functional behavior
        WorkbookEvaluator evaluator = new WorkbookEvaluator(null, null, null);
        assertFalse(evaluator.isDebugEvaluationOutputForNextEval());

        evaluator.setDebugEvaluationOutputForNextEval(true);
        assertTrue(evaluator.isDebugEvaluationOutputForNextEval());

        evaluator.setDebugEvaluationOutputForNextEval(false);
        assertFalse(evaluator.isDebugEvaluationOutputForNextEval());
    }
    
// Test IF-Equals Formula Evaluation (bug 58591)
    
    private Workbook testIFEqualsFormulaEvaluation_setup(String formula, CellType a1CellType) {
        Workbook wb = new HSSFWorkbook();
        Sheet sheet = wb.createSheet("IFEquals");
        Row row = sheet.createRow(0);
        Cell A1 = row.createCell(0);
        Cell B1 = row.createCell(1);
        Cell C1 = row.createCell(2);
        Cell D1 = row.createCell(3);
        
        switch (a1CellType) {
            case NUMERIC:
                A1.setCellValue(1.0);
                // "A1=1" should return true
                break;
            case STRING:
                A1.setCellValue("1");
                // "A1=1" should return false
                // "A1=\"1\"" should return true
                break;
            case BOOLEAN:
                A1.setCellValue(true);
                // "A1=1" should return true
                break;
            case FORMULA:
                A1.setCellFormula("1");
                // "A1=1" should return true
                break;
            case BLANK:
                A1.setCellValue((String) null);
                // "A1=1" should return false
                break;
            default:
                throw new IllegalArgumentException("unexpected cell type: " + a1CellType);
        }
        B1.setCellValue(2.0);
        C1.setCellValue(3.0);
        D1.setCellFormula(formula);
        
        return wb;
    }
    
    private void testIFEqualsFormulaEvaluation_teardown(Workbook wb) {
        try {
            wb.close();
        } catch (final IOException e) {
            fail("Unable to close workbook");
        }
    }
    
    
    
    private void testIFEqualsFormulaEvaluation_evaluate(
        String formula, CellType cellType, String expectedFormula, double expectedResult) {
        Workbook wb = testIFEqualsFormulaEvaluation_setup(formula, cellType);
        Cell D1 = wb.getSheet("IFEquals").getRow(0).getCell(3);
        
        FormulaEvaluator eval = wb.getCreationHelper().createFormulaEvaluator();
        CellValue result = eval.evaluate(D1);
        
        // Call should not modify the contents
        assertEquals(CellType.FORMULA, D1.getCellTypeEnum());
        assertEquals(expectedFormula, D1.getCellFormula());
        
        assertEquals(CellType.NUMERIC, result.getCellTypeEnum());
        assertEquals(expectedResult, result.getNumberValue(), EPSILON);
        
        testIFEqualsFormulaEvaluation_teardown(wb);
    }
    
    private void testIFEqualsFormulaEvaluation_eval(
            final String formula, final CellType cellType, final String expectedFormula, final double expectedValue) {
        testIFEqualsFormulaEvaluation_evaluate(formula, cellType, expectedFormula, expectedValue);
        testIFEqualsFormulaEvaluation_evaluateFormulaCell(formula, cellType, expectedFormula, expectedValue);
        testIFEqualsFormulaEvaluation_evaluateInCell(formula, cellType, expectedFormula, expectedValue);
        testIFEqualsFormulaEvaluation_evaluateAll(formula, cellType, expectedFormula, expectedValue);
        testIFEqualsFormulaEvaluation_evaluateAllFormulaCells(formula, cellType, expectedFormula, expectedValue);
    }
    
    @Test
    public void testIFEqualsFormulaEvaluation_NumericLiteral() {
        final String formula = "IF(A1=1, 2, 3)";
        final CellType cellType = CellType.NUMERIC;
        final String expectedFormula = "IF(A1=1,2,3)";
        final double expectedValue = 2.0;
        testIFEqualsFormulaEvaluation_eval(formula, cellType, expectedFormula, expectedValue);
    }
    
    @Test
    public void testIFEqualsFormulaEvaluation_Numeric() {
        final String formula = "IF(A1=1, B1, C1)";
        final CellType cellType = CellType.NUMERIC;
        final String expectedFormula = "IF(A1=1,B1,C1)";
        final double expectedValue = 2.0;
        testIFEqualsFormulaEvaluation_eval(formula, cellType, expectedFormula, expectedValue);
    }
    
    @Test
    public void testIFEqualsFormulaEvaluation_NumericCoerceToString() {
        final String formula = "IF(A1&\"\"=\"1\", B1, C1)";
        final CellType cellType = CellType.NUMERIC;
        final String expectedFormula = "IF(A1&\"\"=\"1\",B1,C1)";
        final double expectedValue = 2.0;
        testIFEqualsFormulaEvaluation_eval(formula, cellType, expectedFormula, expectedValue);
    }
    
    @Test
    public void testIFEqualsFormulaEvaluation_String() {
        final String formula = "IF(A1=1, B1, C1)";
        final CellType cellType = CellType.STRING;
        final String expectedFormula = "IF(A1=1,B1,C1)";
        final double expectedValue = 3.0;
        testIFEqualsFormulaEvaluation_eval(formula, cellType, expectedFormula, expectedValue);
    }
    
    @Test
    public void testIFEqualsFormulaEvaluation_StringCompareToString() {
        final String formula = "IF(A1=\"1\", B1, C1)";
        final CellType cellType = CellType.STRING;
        final String expectedFormula = "IF(A1=\"1\",B1,C1)";
        final double expectedValue = 2.0;
        testIFEqualsFormulaEvaluation_eval(formula, cellType, expectedFormula, expectedValue);
    }
    
    @Test
    public void testIFEqualsFormulaEvaluation_StringCoerceToNumeric() {
        final String formula = "IF(A1+0=1, B1, C1)";
        final CellType cellType = CellType.STRING;
        final String expectedFormula = "IF(A1+0=1,B1,C1)";
        final double expectedValue = 2.0;
        testIFEqualsFormulaEvaluation_eval(formula, cellType, expectedFormula, expectedValue);
    }
    
    @Ignore("Bug 58591: this test currently fails")
    @Test
    public void testIFEqualsFormulaEvaluation_Boolean() {
        final String formula = "IF(A1=1, B1, C1)";
        final CellType cellType = CellType.BOOLEAN;
        final String expectedFormula = "IF(A1=1,B1,C1)";
        final double expectedValue = 2.0;
        testIFEqualsFormulaEvaluation_eval(formula, cellType, expectedFormula, expectedValue);
    }
    
    @Ignore("Bug 58591: this test currently fails")
    @Test
    public void testIFEqualsFormulaEvaluation_BooleanSimple() {
        final String formula = "3-(A1=1)";
        final CellType cellType = CellType.BOOLEAN;
        final String expectedFormula = "3-(A1=1)";
        final double expectedValue = 2.0;
        testIFEqualsFormulaEvaluation_eval(formula, cellType, expectedFormula, expectedValue);
    }
    
    @Test
    public void testIFEqualsFormulaEvaluation_Formula() {
        final String formula = "IF(A1=1, B1, C1)";
        final CellType cellType = CellType.FORMULA;
        final String expectedFormula = "IF(A1=1,B1,C1)";
        final double expectedValue = 2.0;
        testIFEqualsFormulaEvaluation_eval(formula, cellType, expectedFormula, expectedValue);
    }
    
    @Test
    public void testIFEqualsFormulaEvaluation_Blank() {
        final String formula = "IF(A1=1, B1, C1)";
        final CellType cellType = CellType.BLANK;
        final String expectedFormula = "IF(A1=1,B1,C1)";
        final double expectedValue = 3.0;
        testIFEqualsFormulaEvaluation_eval(formula, cellType, expectedFormula, expectedValue);
    }
    
    @Test
    public void testIFEqualsFormulaEvaluation_BlankCompareToZero() {
        final String formula = "IF(A1=0, B1, C1)";
        final CellType cellType = CellType.BLANK;
        final String expectedFormula = "IF(A1=0,B1,C1)";
        final double expectedValue = 2.0;
        testIFEqualsFormulaEvaluation_eval(formula, cellType, expectedFormula, expectedValue);
    }
    
    @Ignore("Bug 58591: this test currently fails")
    @Test
    public void testIFEqualsFormulaEvaluation_BlankInverted() {
        final String formula = "IF(NOT(A1)=1, B1, C1)";
        final CellType cellType = CellType.BLANK;
        final String expectedFormula = "IF(NOT(A1)=1,B1,C1)";
        final double expectedValue = 2.0;
        testIFEqualsFormulaEvaluation_eval(formula, cellType, expectedFormula, expectedValue);
    }
    
    @Ignore("Bug 58591: this test currently fails")
    @Test
    public void testIFEqualsFormulaEvaluation_BlankInvertedSimple() {
        final String formula = "3-(NOT(A1)=1)";
        final CellType cellType = CellType.BLANK;
        final String expectedFormula = "3-(NOT(A1)=1)";
        final double expectedValue = 2.0;
        testIFEqualsFormulaEvaluation_eval(formula, cellType, expectedFormula, expectedValue);
    }
    
    
    private void testIFEqualsFormulaEvaluation_evaluateFormulaCell(
            String formula, CellType cellType, String expectedFormula, double expectedResult) {
        Workbook wb = testIFEqualsFormulaEvaluation_setup(formula, cellType);
        Cell D1 = wb.getSheet("IFEquals").getRow(0).getCell(3);
        
        FormulaEvaluator eval = wb.getCreationHelper().createFormulaEvaluator();
        CellType resultCellType = eval.evaluateFormulaCellEnum(D1);
        
        // Call should modify the contents, but leave the formula intact
        assertEquals(CellType.FORMULA, D1.getCellTypeEnum());
        assertEquals(expectedFormula, D1.getCellFormula());
        assertEquals(CellType.NUMERIC, resultCellType);
        assertEquals(CellType.NUMERIC, D1.getCachedFormulaResultTypeEnum());
        assertEquals(expectedResult, D1.getNumericCellValue(), EPSILON);
        
        testIFEqualsFormulaEvaluation_teardown(wb);
    }
    
    private void testIFEqualsFormulaEvaluation_evaluateInCell(
            String formula, CellType cellType, String expectedFormula, double expectedResult) {
        Workbook wb = testIFEqualsFormulaEvaluation_setup(formula, cellType);
        Cell D1 = wb.getSheet("IFEquals").getRow(0).getCell(3);
        
        FormulaEvaluator eval = wb.getCreationHelper().createFormulaEvaluator();
        Cell result = eval.evaluateInCell(D1);
        
        // Call should modify the contents and replace the formula with the result
        assertSame(D1, result); // returns the same cell that was provided as an argument so that calls can be chained.
        try {
            D1.getCellFormula();
            fail("cell formula should be overwritten with formula result");
        } catch (final IllegalStateException expected) { }
        assertEquals(CellType.NUMERIC, D1.getCellTypeEnum());
        assertEquals(expectedResult, D1.getNumericCellValue(), EPSILON);
        
        testIFEqualsFormulaEvaluation_teardown(wb);
    }
    
    private void testIFEqualsFormulaEvaluation_evaluateAll(
            String formula, CellType cellType, String expectedFormula, double expectedResult) {
        Workbook wb = testIFEqualsFormulaEvaluation_setup(formula, cellType);
        Cell D1 = wb.getSheet("IFEquals").getRow(0).getCell(3);
        
        FormulaEvaluator eval = wb.getCreationHelper().createFormulaEvaluator();
        eval.evaluateAll();
        
        // Call should modify the contents
        assertEquals(CellType.FORMULA, D1.getCellTypeEnum());
        assertEquals(expectedFormula, D1.getCellFormula());
        
        assertEquals(CellType.NUMERIC, D1.getCachedFormulaResultTypeEnum());
        assertEquals(expectedResult, D1.getNumericCellValue(), EPSILON);
        
        testIFEqualsFormulaEvaluation_teardown(wb);
    }
    
    private void testIFEqualsFormulaEvaluation_evaluateAllFormulaCells(
            String formula, CellType cellType, String expectedFormula, double expectedResult) {
        Workbook wb = testIFEqualsFormulaEvaluation_setup(formula, cellType);
        Cell D1 = wb.getSheet("IFEquals").getRow(0).getCell(3);
        
        HSSFFormulaEvaluator.evaluateAllFormulaCells(wb);
        
        // Call should modify the contents
        assertEquals(CellType.FORMULA, D1.getCellTypeEnum());
        // whitespace gets deleted because formula is parsed and re-rendered
        assertEquals(expectedFormula, D1.getCellFormula());
        
        assertEquals(CellType.NUMERIC, D1.getCachedFormulaResultTypeEnum());
        assertEquals(expectedResult, D1.getNumericCellValue(), EPSILON);
        
        testIFEqualsFormulaEvaluation_teardown(wb);
    }
}
