poi-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cen...@apache.org
Subject svn commit: r1649122 - in /poi/trunk/src: ooxml/testcases/org/apache/poi/ss/formula/eval/ ooxml/testcases/org/apache/poi/xssf/ testcases/org/apache/poi/hssf/ testcases/org/apache/poi/ss/ testcases/org/apache/poi/ss/formula/eval/
Date Fri, 02 Jan 2015 21:04:51 GMT
Author: centic
Date: Fri Jan  2 21:04:50 2015
New Revision: 1649122

URL: http://svn.apache.org/r1649122
Log:
Bug 46898: Convert unit tests for circular references to also run for XSSF

Added:
    poi/trunk/src/ooxml/testcases/org/apache/poi/ss/formula/eval/
    poi/trunk/src/ooxml/testcases/org/apache/poi/ss/formula/eval/TestXSSFCircularReferences.java
      - copied, changed from r1649107, poi/trunk/src/testcases/org/apache/poi/ss/formula/eval/AllFormulaEvalTests.java
    poi/trunk/src/testcases/org/apache/poi/ss/formula/eval/BaseTestCircularReferences.java
    poi/trunk/src/testcases/org/apache/poi/ss/formula/eval/TestHSSFCircularReferences.java
      - copied, changed from r1649107, poi/trunk/src/testcases/org/apache/poi/ss/formula/eval/AllFormulaEvalTests.java
Removed:
    poi/trunk/src/testcases/org/apache/poi/ss/formula/eval/TestCircularReferences.java
Modified:
    poi/trunk/src/ooxml/testcases/org/apache/poi/xssf/SXSSFITestDataProvider.java
    poi/trunk/src/ooxml/testcases/org/apache/poi/xssf/XSSFITestDataProvider.java
    poi/trunk/src/testcases/org/apache/poi/hssf/HSSFITestDataProvider.java
    poi/trunk/src/testcases/org/apache/poi/ss/ITestDataProvider.java
    poi/trunk/src/testcases/org/apache/poi/ss/formula/eval/AllFormulaEvalTests.java

Copied: poi/trunk/src/ooxml/testcases/org/apache/poi/ss/formula/eval/TestXSSFCircularReferences.java
(from r1649107, poi/trunk/src/testcases/org/apache/poi/ss/formula/eval/AllFormulaEvalTests.java)
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/testcases/org/apache/poi/ss/formula/eval/TestXSSFCircularReferences.java?p2=poi/trunk/src/ooxml/testcases/org/apache/poi/ss/formula/eval/TestXSSFCircularReferences.java&p1=poi/trunk/src/testcases/org/apache/poi/ss/formula/eval/AllFormulaEvalTests.java&r1=1649107&r2=1649122&rev=1649122&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/ss/formula/eval/AllFormulaEvalTests.java (original)
+++ poi/trunk/src/ooxml/testcases/org/apache/poi/ss/formula/eval/TestXSSFCircularReferences.java
Fri Jan  2 21:04:50 2015
@@ -17,30 +17,15 @@
 
 package org.apache.poi.ss.formula.eval;
 
-import junit.framework.Test;
-import junit.framework.TestSuite;
+import org.apache.poi.xssf.XSSFITestDataProvider;
 
 /**
- * Collects all tests the package <tt>org.apache.poi.hssf.record.formula.eval</tt>.
+ * Tests XSSFFormulaEvaluator for its handling of cell formula circular references.
  *
  * @author Josh Micich
  */
-public class AllFormulaEvalTests {
-
-	public static Test suite() {
-		TestSuite result = new TestSuite(AllFormulaEvalTests.class.getName());
-		result.addTestSuite(TestAreaEval.class);
-		result.addTestSuite(TestCircularReferences.class);
-		result.addTestSuite(TestDivideEval.class);
-		result.addTestSuite(TestEqualEval.class);
-		result.addTestSuite(TestExternalFunction.class);
-		result.addTestSuite(TestFormulaBugs.class);
-		result.addTestSuite(TestFormulasFromSpreadsheet.class);
-		result.addTestSuite(TestMinusZeroResult.class);
-		result.addTestSuite(TestMissingArgEval.class);
-		result.addTestSuite(TestPercentEval.class);
-		result.addTestSuite(TestRangeEval.class);
-		result.addTestSuite(TestUnaryPlusEval.class);
-		return result;
-	}
+public final class TestXSSFCircularReferences extends BaseTestCircularReferences {
+	public TestXSSFCircularReferences() {
+        super(XSSFITestDataProvider.instance);
+    }
 }

Modified: poi/trunk/src/ooxml/testcases/org/apache/poi/xssf/SXSSFITestDataProvider.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/testcases/org/apache/poi/xssf/SXSSFITestDataProvider.java?rev=1649122&r1=1649121&r2=1649122&view=diff
==============================================================================
--- poi/trunk/src/ooxml/testcases/org/apache/poi/xssf/SXSSFITestDataProvider.java (original)
+++ poi/trunk/src/ooxml/testcases/org/apache/poi/xssf/SXSSFITestDataProvider.java Fri Jan
 2 21:04:50 2015
@@ -19,19 +19,21 @@
 
 package org.apache.poi.xssf;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+
 import org.apache.poi.POIDataSamples;
 import org.apache.poi.ss.ITestDataProvider;
 import org.apache.poi.ss.SpreadsheetVersion;
+import org.apache.poi.ss.usermodel.FormulaEvaluator;
 import org.apache.poi.ss.usermodel.Workbook;
 import org.apache.poi.xssf.streaming.SXSSFWorkbook;
+import org.apache.poi.xssf.usermodel.XSSFFormulaEvaluator;
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-
 /**
  * @author Yegor Kozlov
  */
@@ -43,6 +45,7 @@ public final class SXSSFITestDataProvide
     private SXSSFITestDataProvider() {
         // enforce singleton
     }
+
     public Workbook openSampleWorkbook(String sampleFileName) {
     	XSSFWorkbook xssfWorkbook = XSSFITestDataProvider.instance.openSampleWorkbook(sampleFileName);
         SXSSFWorkbook swb = new SXSSFWorkbook(xssfWorkbook);
@@ -66,17 +69,25 @@ public final class SXSSFITestDataProvide
         }
         return result;
     }
+
     public SXSSFWorkbook createWorkbook(){
         SXSSFWorkbook wb = new SXSSFWorkbook();
         instances.add(wb);
         return wb;
     }
+    
+    public FormulaEvaluator createFormulaEvaluator(Workbook wb) {
+        return new XSSFFormulaEvaluator(((SXSSFWorkbook) wb).getXSSFWorkbook());
+    }
+
     public byte[] getTestDataFileContent(String fileName) {
         return POIDataSamples.getSpreadSheetInstance().readFile(fileName);
     }
+
     public SpreadsheetVersion getSpreadsheetVersion(){
         return SpreadsheetVersion.EXCEL2007;
     }
+
     public String getStandardFileNameExtension() {
         return "xlsx";
     }

Modified: poi/trunk/src/ooxml/testcases/org/apache/poi/xssf/XSSFITestDataProvider.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/testcases/org/apache/poi/xssf/XSSFITestDataProvider.java?rev=1649122&r1=1649121&r2=1649122&view=diff
==============================================================================
--- poi/trunk/src/ooxml/testcases/org/apache/poi/xssf/XSSFITestDataProvider.java (original)
+++ poi/trunk/src/ooxml/testcases/org/apache/poi/xssf/XSSFITestDataProvider.java Fri Jan 
2 21:04:50 2015
@@ -20,7 +20,9 @@ package org.apache.poi.xssf;
 import org.apache.poi.POIDataSamples;
 import org.apache.poi.ss.ITestDataProvider;
 import org.apache.poi.ss.SpreadsheetVersion;
+import org.apache.poi.ss.usermodel.FormulaEvaluator;
 import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.xssf.usermodel.XSSFFormulaEvaluator;
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 
 /**
@@ -32,24 +34,34 @@ public final class XSSFITestDataProvider
     private XSSFITestDataProvider() {
         // enforce singleton
     }
+
     public XSSFWorkbook openSampleWorkbook(String sampleFileName) {
         return XSSFTestDataSamples.openSampleWorkbook(sampleFileName);
     }
+
     public XSSFWorkbook writeOutAndReadBack(Workbook original) {
         if(!(original instanceof XSSFWorkbook)) {
             throw new IllegalArgumentException("Expected an instance of XSSFWorkbook");
         }
         return XSSFTestDataSamples.writeOutAndReadBack((XSSFWorkbook)original);
     }
+
     public XSSFWorkbook createWorkbook(){
         return new XSSFWorkbook();
     }
+    
+    public FormulaEvaluator createFormulaEvaluator(Workbook wb) {
+        return new XSSFFormulaEvaluator((XSSFWorkbook) wb);
+    }
+
     public byte[] getTestDataFileContent(String fileName) {
         return POIDataSamples.getSpreadSheetInstance().readFile(fileName);
     }
+
     public SpreadsheetVersion getSpreadsheetVersion(){
         return SpreadsheetVersion.EXCEL2007;
     }
+
     public String getStandardFileNameExtension() {
         return "xlsx";
     }

Modified: poi/trunk/src/testcases/org/apache/poi/hssf/HSSFITestDataProvider.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/HSSFITestDataProvider.java?rev=1649122&r1=1649121&r2=1649122&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/hssf/HSSFITestDataProvider.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/hssf/HSSFITestDataProvider.java Fri Jan  2 21:04:50
2015
@@ -18,9 +18,11 @@
 package org.apache.poi.hssf;
 
 import org.apache.poi.POIDataSamples;
+import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.apache.poi.ss.ITestDataProvider;
 import org.apache.poi.ss.SpreadsheetVersion;
+import org.apache.poi.ss.usermodel.FormulaEvaluator;
 import org.apache.poi.ss.usermodel.Workbook;
 
 /**
@@ -32,24 +34,34 @@ public final class HSSFITestDataProvider
     private HSSFITestDataProvider(){
         // enforce singleton
     }
+    
     public HSSFWorkbook openSampleWorkbook(String sampleFileName) {
         return HSSFTestDataSamples.openSampleWorkbook(sampleFileName);
     }
+    
     public HSSFWorkbook writeOutAndReadBack(Workbook original) {
         if(!(original instanceof HSSFWorkbook)) {
             throw new IllegalArgumentException("Expected an instance of HSSFWorkbook");
         }
         return HSSFTestDataSamples.writeOutAndReadBack((HSSFWorkbook)original);
     }
+    
     public HSSFWorkbook createWorkbook(){
         return new HSSFWorkbook();
     }
+    
+    public FormulaEvaluator createFormulaEvaluator(Workbook wb) {
+        return new HSSFFormulaEvaluator((HSSFWorkbook) wb);
+    }
+
     public byte[] getTestDataFileContent(String fileName) {
         return POIDataSamples.getSpreadSheetInstance().readFile(fileName);
     }
+    
     public SpreadsheetVersion getSpreadsheetVersion(){
         return SpreadsheetVersion.EXCEL97;
     }
+    
     public String getStandardFileNameExtension() {
         return "xls";
     }

Modified: poi/trunk/src/testcases/org/apache/poi/ss/ITestDataProvider.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/ss/ITestDataProvider.java?rev=1649122&r1=1649121&r2=1649122&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/ss/ITestDataProvider.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/ss/ITestDataProvider.java Fri Jan  2 21:04:50 2015
@@ -17,6 +17,7 @@
 
 package org.apache.poi.ss;
 
+import org.apache.poi.ss.usermodel.FormulaEvaluator;
 import org.apache.poi.ss.usermodel.Workbook;
 
 /**
@@ -46,6 +47,15 @@ public interface ITestDataProvider {
     Workbook createWorkbook();
 
     /**
+     * Creates the corresponding {@link FormulaEvaluator} for the
+     * type of Workbook handled by this Provider. 
+     *
+     * @param wb The workbook to base the formula evaluator on.
+     * @return A new instance of a matching type of formula evaluator. 
+     */
+    FormulaEvaluator createFormulaEvaluator(Workbook wb);
+
+    /**
      * Opens a sample file from the standard HSSF test data directory
      *
      * @return an open <tt>InputStream</tt> for the specified sample file

Modified: poi/trunk/src/testcases/org/apache/poi/ss/formula/eval/AllFormulaEvalTests.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/ss/formula/eval/AllFormulaEvalTests.java?rev=1649122&r1=1649121&r2=1649122&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/ss/formula/eval/AllFormulaEvalTests.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/ss/formula/eval/AllFormulaEvalTests.java Fri Jan
 2 21:04:50 2015
@@ -30,7 +30,7 @@ public class AllFormulaEvalTests {
 	public static Test suite() {
 		TestSuite result = new TestSuite(AllFormulaEvalTests.class.getName());
 		result.addTestSuite(TestAreaEval.class);
-		result.addTestSuite(TestCircularReferences.class);
+		result.addTestSuite(TestHSSFCircularReferences.class);
 		result.addTestSuite(TestDivideEval.class);
 		result.addTestSuite(TestEqualEval.class);
 		result.addTestSuite(TestExternalFunction.class);

Added: poi/trunk/src/testcases/org/apache/poi/ss/formula/eval/BaseTestCircularReferences.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/ss/formula/eval/BaseTestCircularReferences.java?rev=1649122&view=auto
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/ss/formula/eval/BaseTestCircularReferences.java
(added)
+++ poi/trunk/src/testcases/org/apache/poi/ss/formula/eval/BaseTestCircularReferences.java
Fri Jan  2 21:04:50 2015
@@ -0,0 +1,161 @@
+package org.apache.poi.ss.formula.eval;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
+
+import org.apache.poi.ss.ITestDataProvider;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.CellValue;
+import org.apache.poi.ss.usermodel.FormulaEvaluator;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
+
+/**
+ * Common superclass for testing cases of circular references
+ * both for HSSF and XSSF
+ */
+public abstract class BaseTestCircularReferences extends TestCase {
+
+    protected final ITestDataProvider _testDataProvider;
+
+    /**
+     * @param testDataProvider an object that provides test data in HSSF / XSSF specific
way
+     */
+    protected BaseTestCircularReferences(ITestDataProvider testDataProvider) {
+        _testDataProvider = testDataProvider;
+    }
+
+
+    /**
+     * Translates StackOverflowError into AssertionFailedError
+     */
+    private CellValue evaluateWithCycles(Workbook wb, Cell testCell)
+            throws AssertionFailedError {
+        FormulaEvaluator evaluator = _testDataProvider.createFormulaEvaluator(wb);
+        try {
+            return evaluator.evaluate(testCell);
+        } catch (StackOverflowError e) {
+            throw new AssertionFailedError( "circular reference caused stack overflow error");
+        }
+    }
+    /**
+     * Makes sure that the specified evaluated cell value represents a circular reference
error.
+     */
+    private static void confirmCycleErrorCode(CellValue cellValue) {
+        assertTrue(cellValue.getCellType() == Cell.CELL_TYPE_ERROR);
+        assertEquals(ErrorEval.CIRCULAR_REF_ERROR.getErrorCode(), cellValue.getErrorValue());
+    }
+
+
+    /**
+     * ASF Bugzilla Bug 44413
+     * "INDEX() formula cannot contain its own location in the data array range"
+     */
+    public void testIndexFormula() {
+
+        Workbook wb = _testDataProvider.createWorkbook();
+        Sheet sheet = wb.createSheet("Sheet1");
+
+        int colB = 1;
+        sheet.createRow(0).createCell(colB).setCellValue(1);
+        sheet.createRow(1).createCell(colB).setCellValue(2);
+        sheet.createRow(2).createCell(colB).setCellValue(3);
+        Row row4 = sheet.createRow(3);
+        Cell testCell = row4.createCell(0);
+        // This formula should evaluate to the contents of B2,
+        testCell.setCellFormula("INDEX(A1:B4,2,2)");
+        // However the range A1:B4 also includes the current cell A4.  If the other parameters
+        // were 4 and 1, this would represent a circular reference.  Prior to v3.2 POI would
+        // 'fully' evaluate ref arguments before invoking operators, which raised the possibility
of
+        // cycles / StackOverflowErrors.
+
+
+        CellValue cellValue = evaluateWithCycles(wb, testCell);
+
+        assertTrue(cellValue.getCellType() == Cell.CELL_TYPE_NUMERIC);
+        assertEquals(2, cellValue.getNumberValue(), 0);
+    }
+
+    /**
+     * Cell A1 has formula "=A1"
+     */
+    public void testSimpleCircularReference() {
+
+        Workbook wb = _testDataProvider.createWorkbook();
+        Sheet sheet = wb.createSheet("Sheet1");
+
+        Row row = sheet.createRow(0);
+        Cell testCell = row.createCell(0);
+        testCell.setCellFormula("A1");
+
+        CellValue cellValue = evaluateWithCycles(wb, testCell);
+
+        confirmCycleErrorCode(cellValue);
+    }
+
+    /**
+     * A1=B1, B1=C1, C1=D1, D1=A1
+     */
+    public void testMultiLevelCircularReference() {
+
+        Workbook wb = _testDataProvider.createWorkbook();
+        Sheet sheet = wb.createSheet("Sheet1");
+
+        Row row = sheet.createRow(0);
+        row.createCell(0).setCellFormula("B1");
+        row.createCell(1).setCellFormula("C1");
+        row.createCell(2).setCellFormula("D1");
+        Cell testCell = row.createCell(3);
+        testCell.setCellFormula("A1");
+
+        CellValue cellValue = evaluateWithCycles(wb, testCell);
+
+        confirmCycleErrorCode(cellValue);
+    }
+
+    public void testIntermediateCircularReferenceResults_bug46898() {
+        Workbook wb = _testDataProvider.createWorkbook();
+        Sheet sheet = wb.createSheet("Sheet1");
+
+        Row row = sheet.createRow(0);
+
+        Cell cellA1 = row.createCell(0);
+        Cell cellB1 = row.createCell(1);
+        Cell cellC1 = row.createCell(2);
+        Cell cellD1 = row.createCell(3);
+        Cell cellE1 = row.createCell(4);
+
+        cellA1.setCellFormula("IF(FALSE, 1+B1, 42)");
+        cellB1.setCellFormula("1+C1");
+        cellC1.setCellFormula("1+D1");
+        cellD1.setCellFormula("1+E1");
+        cellE1.setCellFormula("1+A1");
+
+        FormulaEvaluator fe = _testDataProvider.createFormulaEvaluator(wb);
+        CellValue cv;
+
+        // Happy day flow - evaluate A1 first
+        cv = fe.evaluate(cellA1);
+        assertEquals(Cell.CELL_TYPE_NUMERIC, cv.getCellType());
+        assertEquals(42.0, cv.getNumberValue(), 0.0);
+        cv = fe.evaluate(cellB1); // no circ-ref-error because A1 result is cached
+        assertEquals(Cell.CELL_TYPE_NUMERIC, cv.getCellType());
+        assertEquals(46.0, cv.getNumberValue(), 0.0);
+
+        // Show the bug - evaluate another cell from the loop first
+        fe.clearAllCachedResultValues();
+        cv = fe.evaluate(cellB1);
+        if (cv.getCellType() == ErrorEval.CIRCULAR_REF_ERROR.getErrorCode()) {
+            throw new AssertionFailedError("Identified bug 46898");
+        }
+        assertEquals(Cell.CELL_TYPE_NUMERIC, cv.getCellType());
+        assertEquals(46.0, cv.getNumberValue(), 0.0);
+
+        // start evaluation on another cell
+        fe.clearAllCachedResultValues();
+        cv = fe.evaluate(cellE1);
+        assertEquals(Cell.CELL_TYPE_NUMERIC, cv.getCellType());
+        assertEquals(43.0, cv.getNumberValue(), 0.0);
+    }
+}

Copied: poi/trunk/src/testcases/org/apache/poi/ss/formula/eval/TestHSSFCircularReferences.java
(from r1649107, poi/trunk/src/testcases/org/apache/poi/ss/formula/eval/AllFormulaEvalTests.java)
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/ss/formula/eval/TestHSSFCircularReferences.java?p2=poi/trunk/src/testcases/org/apache/poi/ss/formula/eval/TestHSSFCircularReferences.java&p1=poi/trunk/src/testcases/org/apache/poi/ss/formula/eval/AllFormulaEvalTests.java&r1=1649107&r2=1649122&rev=1649122&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/ss/formula/eval/AllFormulaEvalTests.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/ss/formula/eval/TestHSSFCircularReferences.java
Fri Jan  2 21:04:50 2015
@@ -17,30 +17,15 @@
 
 package org.apache.poi.ss.formula.eval;
 
-import junit.framework.Test;
-import junit.framework.TestSuite;
+import org.apache.poi.hssf.HSSFITestDataProvider;
 
 /**
- * Collects all tests the package <tt>org.apache.poi.hssf.record.formula.eval</tt>.
+ * Tests HSSFFormulaEvaluator for its handling of cell formula circular references.
  *
  * @author Josh Micich
  */
-public class AllFormulaEvalTests {
-
-	public static Test suite() {
-		TestSuite result = new TestSuite(AllFormulaEvalTests.class.getName());
-		result.addTestSuite(TestAreaEval.class);
-		result.addTestSuite(TestCircularReferences.class);
-		result.addTestSuite(TestDivideEval.class);
-		result.addTestSuite(TestEqualEval.class);
-		result.addTestSuite(TestExternalFunction.class);
-		result.addTestSuite(TestFormulaBugs.class);
-		result.addTestSuite(TestFormulasFromSpreadsheet.class);
-		result.addTestSuite(TestMinusZeroResult.class);
-		result.addTestSuite(TestMissingArgEval.class);
-		result.addTestSuite(TestPercentEval.class);
-		result.addTestSuite(TestRangeEval.class);
-		result.addTestSuite(TestUnaryPlusEval.class);
-		return result;
-	}
+public final class TestHSSFCircularReferences extends BaseTestCircularReferences {
+	public TestHSSFCircularReferences() {
+        super(HSSFITestDataProvider.instance);
+    }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org


Mime
View raw message