]> source.dussan.org Git - poi.git/commitdiff
Patch from Josh, which shows that various bugs are now fixed
authorNick Burch <nick@apache.org>
Sun, 16 Mar 2008 15:20:47 +0000 (15:20 +0000)
committerNick Burch <nick@apache.org>
Sun, 16 Mar 2008 15:20:47 +0000 (15:20 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@637593 13f79535-47bb-0310-9956-ffa450edef68

src/scratchpad/testcases/org/apache/poi/hssf/record/formula/eval/AllFormulaEvalTests.java
src/scratchpad/testcases/org/apache/poi/hssf/record/formula/eval/TestFormulaBugs.java [new file with mode: 0755]
src/testcases/org/apache/poi/hssf/data/27349-vlookupAcrossSheets.xls [new file with mode: 0755]

index 3260c371c62f9680bcd83f6c3d57f93e936de109..353fe57e74f688e848710eba99ab41631c780aaa 100755 (executable)
@@ -31,6 +31,7 @@ public class AllFormulaEvalTests {
                TestSuite result = new TestSuite("Tests for org.apache.poi.hssf.record.formula.eval");
                result.addTestSuite(TestCircularReferences.class);
                result.addTestSuite(TestExternalFunction.class);
+               result.addTestSuite(TestFormulaBugs.class);
                result.addTestSuite(TestFormulasFromSpreadsheet.class);
                result.addTestSuite(TestUnaryPlusEval.class);
                return result;
diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/eval/TestFormulaBugs.java b/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/eval/TestFormulaBugs.java
new file mode 100755 (executable)
index 0000000..617f5d0
--- /dev/null
@@ -0,0 +1,217 @@
+/* ====================================================================
+   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 java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
+
+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.hssf.usermodel.HSSFFormulaEvaluator.CellValue;
+
+/**
+ * Miscellaneous tests for bugzilla entries.<p/> The test name contains the
+ * bugzilla bug id.
+ * 
+ * 
+ * @author Josh Micich
+ */
+public final class TestFormulaBugs extends TestCase {
+
+       private static final String TEST_DATA_DIR_SYS_PROPERTY_NAME = "HSSF.testdata.path";
+
+       /**
+        * Opens a sample file from the standard HSSF test data directory
+        * 
+        * @return an open <tt>InputStream</tt> for the specified sample file
+        */
+       private static InputStream openSampleFileStream(String sampleFileName) {
+               // TODO - move this method somewhere common
+               String dataDirName = System
+                               .getProperty(TEST_DATA_DIR_SYS_PROPERTY_NAME);
+               if (dataDirName == null) {
+                       throw new RuntimeException("Must set system property '"
+                                       + TEST_DATA_DIR_SYS_PROPERTY_NAME
+                                       + "' before running tests");
+               }
+               File dataDir = new File(dataDirName);
+               if (!dataDir.exists()) {
+                       throw new RuntimeException("Data dir '" + dataDirName
+                                       + "' specified by system property '"
+                                       + TEST_DATA_DIR_SYS_PROPERTY_NAME + "' does not exist");
+               }
+               File f = new File(dataDir, sampleFileName);
+               if (!f.exists()) {
+                       throw new RuntimeException("Sample file '" + sampleFileName
+                                       + "' not found in data dir '" + dataDirName + "'");
+               }
+               InputStream is;
+               try {
+                       is = new FileInputStream(f);
+               } catch (FileNotFoundException e) {
+                       throw new RuntimeException(e);
+               }
+               return is;
+       }
+
+       /**
+        * Bug 27349 - VLOOKUP with reference to another sheet.<p/> This test was
+        * added <em>long</em> after the relevant functionality was fixed.
+        */
+       public void test27349() {
+               // 27349-vlookupAcrossSheets.xls is bugzilla/attachment.cgi?id=10622
+               InputStream is = openSampleFileStream("27349-vlookupAcrossSheets.xls");
+               HSSFWorkbook wb;
+               try {
+                       // original bug may have thrown exception here, or output warning to
+                       // stderr
+                       wb = new HSSFWorkbook(is);
+               } catch (IOException e) {
+                       throw new RuntimeException(e);
+               }
+
+               HSSFSheet sheet = wb.getSheetAt(0);
+               HSSFRow row = sheet.getRow(1);
+               HSSFCell cell = row.getCell(0);
+
+               // this definitely would have failed due to 27349
+               assertEquals("VLOOKUP(1,'DATA TABLE'!$A$8:'DATA TABLE'!$B$10,2)", cell
+                               .getCellFormula());
+
+               // We might as well evaluate the formula
+               HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb);
+               fe.setCurrentRow(row);
+               CellValue cv = fe.evaluate(cell);
+
+               assertEquals(HSSFCell.CELL_TYPE_NUMERIC, cv.getCellType());
+               assertEquals(3.0, cv.getNumberValue(), 0.0);
+       }
+
+       /**
+        * Bug 27405 - isnumber() formula always evaluates to false in if statement<p/>
+        * 
+        * seems to be a duplicate of 24925
+        */
+       public void test27405() {
+
+               HSSFWorkbook wb = new HSSFWorkbook();
+               HSSFSheet sheet = wb.createSheet("input");
+               // input row 0
+               HSSFRow row = sheet.createRow((short) 0);
+               HSSFCell cell = row.createCell((short) 0);
+               cell = row.createCell((short) 1);
+               cell.setCellValue(1); // B1
+               // input row 1
+               row = sheet.createRow((short) 1);
+               cell = row.createCell((short) 1);
+               cell.setCellValue(999); // B2
+
+               int rno = 4;
+               row = sheet.createRow(rno);
+               cell = row.createCell((short) 1); // B5
+               cell.setCellFormula("isnumber(b1)");
+               cell = row.createCell((short) 3); // D5
+               cell.setCellFormula("IF(ISNUMBER(b1),b1,b2)");
+
+               if (false) { // set true to check excel file manually
+                       // bug report mentions 'Editing the formula in excel "fixes" the problem.'
+                       try {
+                               FileOutputStream fileOut = new FileOutputStream("27405output.xls");
+                               wb.write(fileOut);
+                               fileOut.close();
+                       } catch (IOException e) {
+                               throw new RuntimeException(e);
+                       }
+               }
+               
+               // use POI's evaluator as an extra sanity check
+               HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb);
+               fe.setCurrentRow(row);
+               CellValue cv;
+               cv = fe.evaluate(cell);
+               assertEquals(HSSFCell.CELL_TYPE_NUMERIC, cv.getCellType());
+               assertEquals(1.0, cv.getNumberValue(), 0.0);
+               
+               cv = fe.evaluate(row.getCell(1));
+               assertEquals(HSSFCell.CELL_TYPE_BOOLEAN, cv.getCellType());
+               assertEquals(true, cv.getBooleanValue());
+       }
+
+       /**
+        * Bug 42448 - Can't parse SUMPRODUCT(A!C7:A!C67, B8:B68) / B69 <p/>
+        */
+       public void test42448() {
+               HSSFWorkbook wb = new HSSFWorkbook();
+               HSSFSheet sheet1 = wb.createSheet("Sheet1");
+
+               HSSFRow row = sheet1.createRow(0);
+               HSSFCell cell = row.createCell((short) 0);
+
+               // it's important to create the referenced sheet first
+               HSSFSheet sheet2 = wb.createSheet("A"); // note name 'A'
+               // TODO - POI crashes if the formula is added before this sheet
+               // RuntimeException("Zero length string is an invalid sheet name")
+               // Excel doesn't crash but the formula doesn't work until it is
+               // re-entered
+
+               String inputFormula = "SUMPRODUCT(A!C7:A!C67, B8:B68) / B69"; // as per bug report
+               try {
+                       cell.setCellFormula(inputFormula); 
+               } catch (StringIndexOutOfBoundsException e) {
+                       throw new AssertionFailedError("Identified bug 42448");
+               }
+
+               assertEquals("SUMPRODUCT(A!C7:C67,B8:B68)/B69", cell.getCellFormula());
+
+               // might as well evaluate the sucker...
+
+               addCell(sheet2, 5, 2, 3.0); // A!C6
+               addCell(sheet2, 6, 2, 4.0); // A!C7
+               addCell(sheet2, 66, 2, 5.0); // A!C67
+               addCell(sheet2, 67, 2, 6.0); // A!C68
+
+               addCell(sheet1, 6, 1, 7.0); // B7
+               addCell(sheet1, 7, 1, 8.0); // B8
+               addCell(sheet1, 67, 1, 9.0); // B68
+               addCell(sheet1, 68, 1, 10.0); // B69
+
+               double expectedResult = (4.0 * 8.0 + 5.0 * 9.0) / 10.0;
+
+               HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet1, wb);
+               fe.setCurrentRow(row);
+               CellValue cv = fe.evaluate(cell);
+
+               assertEquals(HSSFCell.CELL_TYPE_NUMERIC, cv.getCellType());
+               assertEquals(expectedResult, cv.getNumberValue(), 0.0);
+       }
+
+       private static void addCell(HSSFSheet sheet, int rowIx, int colIx,
+                       double value) {
+               sheet.createRow(rowIx).createCell((short) colIx).setCellValue(value);
+       }
+}
diff --git a/src/testcases/org/apache/poi/hssf/data/27349-vlookupAcrossSheets.xls b/src/testcases/org/apache/poi/hssf/data/27349-vlookupAcrossSheets.xls
new file mode 100755 (executable)
index 0000000..c21d434
Binary files /dev/null and b/src/testcases/org/apache/poi/hssf/data/27349-vlookupAcrossSheets.xls differ