diff --git a/src/resources/main/org/apache/poi/hssf/record/formula/function/functionMetadata.txt b/src/resources/main/org/apache/poi/hssf/record/formula/function/functionMetadata.txt index 237fbf094..590b455c4 100644 --- a/src/resources/main/org/apache/poi/hssf/record/formula/function/functionMetadata.txt +++ b/src/resources/main/org/apache/poi/hssf/record/formula/function/functionMetadata.txt @@ -143,8 +143,8 @@ 169 COUNTA 0 30 V R 183 PRODUCT 0 30 V R 184 FACT 1 1 V V +189 DPRODUCT 3 3 V R R R 190 ISNONTEXT 1 1 V V -191 DPRODUCT 3 3 V R R R 193 STDEVP 1 30 V R 194 VARP 1 30 V R 195 DSTDEVP 3 3 V R R R diff --git a/src/testcases/org/apache/poi/hssf/data/missingFuncs44675.xls b/src/testcases/org/apache/poi/hssf/data/missingFuncs44675.xls index 71f874370..4a6847245 100644 Binary files a/src/testcases/org/apache/poi/hssf/data/missingFuncs44675.xls and b/src/testcases/org/apache/poi/hssf/data/missingFuncs44675.xls differ diff --git a/src/testcases/org/apache/poi/hssf/record/formula/AllFormulaTests.java b/src/testcases/org/apache/poi/hssf/record/formula/AllFormulaTests.java index 645709bb6..3a7045022 100644 --- a/src/testcases/org/apache/poi/hssf/record/formula/AllFormulaTests.java +++ b/src/testcases/org/apache/poi/hssf/record/formula/AllFormulaTests.java @@ -29,7 +29,7 @@ import junit.framework.TestSuite; * * @author Josh Micich */ -public class AllFormulaTests { +public final class AllFormulaTests { public static Test suite() { TestSuite result = new TestSuite(AllFormulaTests.class.getName()); @@ -50,7 +50,6 @@ public class AllFormulaTests { result.addTestSuite(TestReferencePtg.class); result.addTestSuite(TestSheetNameFormatter.class); result.addTestSuite(TestUnionPtg.class); - result.addTest(AllFormulaFunctionTests.suite()); return result; } } diff --git a/src/testcases/org/apache/poi/hssf/record/formula/function/TestParseMissingBuiltInFuncs.java b/src/testcases/org/apache/poi/hssf/record/formula/function/TestParseMissingBuiltInFuncs.java index 3671d37c1..fdad5f44d 100644 --- a/src/testcases/org/apache/poi/hssf/record/formula/function/TestParseMissingBuiltInFuncs.java +++ b/src/testcases/org/apache/poi/hssf/record/formula/function/TestParseMissingBuiltInFuncs.java @@ -27,6 +27,9 @@ import org.apache.poi.hssf.record.formula.FuncPtg; import org.apache.poi.hssf.record.formula.FuncVarPtg; import org.apache.poi.hssf.record.formula.Ptg; /** + * Tests parsing of some built-in functions that were not properly + * registered in POI as bug #44675, #44733 (March/April 2008). + * * @author Josh Micich */ public final class TestParseMissingBuiltInFuncs extends TestCase { @@ -39,6 +42,7 @@ public final class TestParseMissingBuiltInFuncs extends TestCase { Ptg[] ptgs = parse(formula); Ptg ptgF = ptgs[ptgs.length-1]; // func is last RPN token in all these formulas + // Check critical things in the Ptg array encoding. if(!(ptgF instanceof AbstractFunctionPtg)) { throw new RuntimeException("function token missing"); } @@ -47,11 +51,15 @@ public final class TestParseMissingBuiltInFuncs extends TestCase { throw new AssertionFailedError("Failed to recognise built-in function in formula '" + formula + "'"); } - assertEquals(expPtgArraySize, ptgs.length); assertEquals(funcIx, func.getFunctionIndex()); Class expCls = isVarArgFunc ? FuncVarPtg.class : FuncPtg.class; assertEquals(expCls, ptgF.getClass()); + + // check that parsed Ptg array converts back to formula text OK + Workbook book = Workbook.createWorkbook(); + String reRenderedFormula = FormulaParser.toFormulaString(book, ptgs); + assertEquals(formula, reRenderedFormula); } public void testDatedif() { @@ -76,4 +84,7 @@ public final class TestParseMissingBuiltInFuncs extends TestCase { public void testIsnontext() { confirmFunc("ISNONTEXT(\"abc\")", 2, false, 190); } + public void testDproduct() { + confirmFunc("DPRODUCT(C1:E5,\"HarvestYield\",G1:H2)", 4, false, 189); + } } diff --git a/src/testcases/org/apache/poi/hssf/record/formula/function/TestReadMissingBuiltInFuncs.java b/src/testcases/org/apache/poi/hssf/record/formula/function/TestReadMissingBuiltInFuncs.java index f1e6bcfac..14799bd0a 100644 --- a/src/testcases/org/apache/poi/hssf/record/formula/function/TestReadMissingBuiltInFuncs.java +++ b/src/testcases/org/apache/poi/hssf/record/formula/function/TestReadMissingBuiltInFuncs.java @@ -21,7 +21,9 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; +import org.apache.poi.hssf.record.RecordFormatException; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; @@ -29,24 +31,31 @@ import junit.framework.AssertionFailedError; import junit.framework.TestCase; /** * Tests reading from a sample spreadsheet some built-in functions that were not properly - * registered in POI as bug #44675 (March 2008). + * registered in POI as bug #44675, #44733 (March/April 2008). * * @author Josh Micich */ public final class TestReadMissingBuiltInFuncs extends TestCase { - private HSSFSheet sht; + /** + * This spreadsheet has examples of calls to the interesting built-in functions in cells A1:A7 + */ + private static final String SAMPLE_SPREADSHEET_FILE_NAME = "missingFuncs44675.xls"; + private static HSSFSheet _sheet; - protected void setUp() { - String cwd = System.getProperty("HSSF.testdata.path"); - HSSFWorkbook wb; - try { - InputStream is = new FileInputStream(new File(cwd, "missingFuncs44675.xls")); - wb = new HSSFWorkbook(is); - } catch (IOException e) { - throw new RuntimeException(e); + private static HSSFSheet getSheet() { + if (_sheet == null) { + String cwd = System.getProperty("HSSF.testdata.path"); + HSSFWorkbook wb; + try { + InputStream is = new FileInputStream(new File(cwd, SAMPLE_SPREADSHEET_FILE_NAME)); + wb = new HSSFWorkbook(is); + } catch (IOException e) { + throw new RuntimeException(e); + } + _sheet = wb.getSheetAt(0); } - sht = wb.getSheetAt(0); + return _sheet; } public void testDatedif() { @@ -128,9 +137,30 @@ public final class TestReadMissingBuiltInFuncs extends TestCase { } assertEquals("ISNONTEXT(\"abc\")", formula); } + public void testDproduct() { + + String formula = getCellFormula(6); + assertEquals("DPRODUCT(C1:E5,\"HarvestYield\",G1:H2)", formula); + } private String getCellFormula(int rowIx) { - String result = sht.getRow(rowIx).getCell((short)0).getCellFormula(); + HSSFSheet sheet; + try { + sheet = getSheet(); + } catch (RecordFormatException e) { + if(e.getCause() instanceof InvocationTargetException) { + InvocationTargetException ite = (InvocationTargetException) e.getCause(); + if(ite.getTargetException() instanceof RuntimeException) { + RuntimeException re = (RuntimeException) ite.getTargetException(); + if(re.getMessage().equals("Invalid built-in function index (189)")) { + throw afe("DPRODUCT() registered with wrong index"); + } + } + } + // some other unexpected error + throw e; + } + String result = sheet.getRow(rowIx).getCell((short)0).getCellFormula(); if (false) { System.err.println(result); }