diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java index cb0a4b27e..42c70e8c8 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java @@ -22,7 +22,7 @@ import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; -import org.apache.poi.hssf.record.formula.Ptg; +import org.apache.poi.ss.formula.ptg.Ptg; import org.apache.poi.ss.formula.SharedFormula; import org.apache.poi.ss.formula.eval.ErrorEval; import org.apache.poi.ss.SpreadsheetVersion; diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFEvaluationWorkbook.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFEvaluationWorkbook.java index b2c71fee2..7813092a5 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFEvaluationWorkbook.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFEvaluationWorkbook.java @@ -17,9 +17,9 @@ package org.apache.poi.xssf.usermodel; -import org.apache.poi.hssf.record.formula.NamePtg; -import org.apache.poi.hssf.record.formula.NameXPtg; -import org.apache.poi.hssf.record.formula.Ptg; +import org.apache.poi.ss.formula.ptg.NamePtg; +import org.apache.poi.ss.formula.ptg.NameXPtg; +import org.apache.poi.ss.formula.ptg.Ptg; import org.apache.poi.ss.SpreadsheetVersion; import org.apache.poi.ss.formula.EvaluationCell; import org.apache.poi.ss.formula.EvaluationName; @@ -29,7 +29,6 @@ import org.apache.poi.ss.formula.FormulaParser; import org.apache.poi.ss.formula.FormulaParsingWorkbook; import org.apache.poi.ss.formula.FormulaRenderingWorkbook; import org.apache.poi.ss.formula.FormulaType; -import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalName; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDefinedName; /** diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFName.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFName.java index 2cb64cc27..1c06f8d27 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFName.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFName.java @@ -16,7 +16,7 @@ ==================================================================== */ package org.apache.poi.xssf.usermodel; -import org.apache.poi.hssf.record.formula.Ptg; +import org.apache.poi.ss.formula.ptg.Ptg; import org.apache.poi.ss.formula.FormulaParser; import org.apache.poi.ss.formula.FormulaType; import org.apache.poi.ss.usermodel.Name; diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRichTextString.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRichTextString.java index d58da0e09..d8416c9d6 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRichTextString.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRichTextString.java @@ -480,6 +480,7 @@ public class XSSFRichTextString implements RichTextString { return buf.toString(); } + @SuppressWarnings("deprecation") void applyFont(TreeMap formats, int startIndex, int endIndex, CTRPrElt fmt) { // delete format runs that fit between startIndex and endIndex // runs intersecting startIndex and endIndex remain diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFRowShifter.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFRowShifter.java index 682ba9c1f..166dcc369 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFRowShifter.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFRowShifter.java @@ -25,7 +25,7 @@ import org.apache.poi.ss.formula.FormulaRenderer; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.formula.FormulaShifter; -import org.apache.poi.hssf.record.formula.Ptg; +import org.apache.poi.ss.formula.ptg.Ptg; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCell; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellFormula; diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFFormulaParser.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFFormulaParser.java index f75abbc14..9b9010200 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFFormulaParser.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFFormulaParser.java @@ -19,10 +19,10 @@ package org.apache.poi.xssf.usermodel; import junit.framework.TestCase; -import org.apache.poi.hssf.record.formula.Ptg; -import org.apache.poi.hssf.record.formula.RefPtg; -import org.apache.poi.hssf.record.formula.IntPtg; -import org.apache.poi.hssf.record.formula.FuncPtg; +import org.apache.poi.ss.formula.ptg.Ptg; +import org.apache.poi.ss.formula.ptg.RefPtg; +import org.apache.poi.ss.formula.ptg.IntPtg; +import org.apache.poi.ss.formula.ptg.FuncPtg; import org.apache.poi.ss.formula.FormulaParseException; import org.apache.poi.ss.formula.FormulaParser; import org.apache.poi.ss.formula.FormulaType; diff --git a/src/scratchpad/src/org/apache/poi/hssf/usermodel/HSSFChart.java b/src/scratchpad/src/org/apache/poi/hssf/usermodel/HSSFChart.java index b1a26f798..c5b51aff5 100644 --- a/src/scratchpad/src/org/apache/poi/hssf/usermodel/HSSFChart.java +++ b/src/scratchpad/src/org/apache/poi/hssf/usermodel/HSSFChart.java @@ -35,9 +35,9 @@ import org.apache.poi.hssf.record.RecordBase; import org.apache.poi.hssf.record.SCLRecord; import org.apache.poi.hssf.record.UnknownRecord; import org.apache.poi.hssf.record.VCenterRecord; -import org.apache.poi.hssf.record.formula.Area3DPtg; -import org.apache.poi.hssf.record.formula.AreaPtgBase; -import org.apache.poi.hssf.record.formula.Ptg; +import org.apache.poi.ss.formula.ptg.Area3DPtg; +import org.apache.poi.ss.formula.ptg.AreaPtgBase; +import org.apache.poi.ss.formula.ptg.Ptg; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.ss.util.CellRangeAddressBase; diff --git a/src/testcases/org/apache/poi/ss/formula/TestEvaluationCache.java b/src/testcases/org/apache/poi/ss/formula/TestEvaluationCache.java index 87788ef8e..6edd5d13d 100644 --- a/src/testcases/org/apache/poi/ss/formula/TestEvaluationCache.java +++ b/src/testcases/org/apache/poi/ss/formula/TestEvaluationCache.java @@ -29,7 +29,7 @@ import junit.framework.AssertionFailedError; import junit.framework.TestCase; import org.apache.poi.hssf.model.HSSFFormulaParser; -import org.apache.poi.hssf.record.formula.Ptg; +import org.apache.poi.ss.formula.ptg.Ptg; import org.apache.poi.ss.formula.eval.BlankEval; import org.apache.poi.ss.formula.eval.BoolEval; import org.apache.poi.ss.formula.eval.ErrorEval; diff --git a/src/testcases/org/apache/poi/ss/formula/TestFormulaShifter.java b/src/testcases/org/apache/poi/ss/formula/TestFormulaShifter.java index 9f840e12a..79e42c2c5 100644 --- a/src/testcases/org/apache/poi/ss/formula/TestFormulaShifter.java +++ b/src/testcases/org/apache/poi/ss/formula/TestFormulaShifter.java @@ -18,10 +18,9 @@ package org.apache.poi.ss.formula; import junit.framework.TestCase; -import org.apache.poi.hssf.record.formula.AreaErrPtg; -import org.apache.poi.hssf.record.formula.AreaPtg; -import org.apache.poi.hssf.record.formula.Ptg; -import org.apache.poi.ss.formula.FormulaShifter; +import org.apache.poi.ss.formula.ptg.AreaErrPtg; +import org.apache.poi.ss.formula.ptg.AreaPtg; +import org.apache.poi.ss.formula.ptg.Ptg; /** * Tests for {@link FormulaShifter}. diff --git a/src/testcases/org/apache/poi/ss/formula/TestWorkbookEvaluator.java b/src/testcases/org/apache/poi/ss/formula/TestWorkbookEvaluator.java index 8dac906ec..8303e0860 100644 --- a/src/testcases/org/apache/poi/ss/formula/TestWorkbookEvaluator.java +++ b/src/testcases/org/apache/poi/ss/formula/TestWorkbookEvaluator.java @@ -21,13 +21,13 @@ import junit.framework.AssertionFailedError; import junit.framework.TestCase; import org.apache.poi.hssf.HSSFTestDataSamples; -import org.apache.poi.hssf.record.formula.AreaErrPtg; -import org.apache.poi.hssf.record.formula.AttrPtg; -import org.apache.poi.hssf.record.formula.DeletedArea3DPtg; -import org.apache.poi.hssf.record.formula.DeletedRef3DPtg; -import org.apache.poi.hssf.record.formula.IntPtg; -import org.apache.poi.hssf.record.formula.Ptg; -import org.apache.poi.hssf.record.formula.RefErrorPtg; +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.formula.eval.BlankEval; import org.apache.poi.ss.formula.eval.ErrorEval; import org.apache.poi.ss.formula.eval.MissingArgEval; diff --git a/src/testcases/org/apache/poi/ss/formula/constant/TestConstantValueParser.java b/src/testcases/org/apache/poi/ss/formula/constant/TestConstantValueParser.java new file mode 100644 index 000000000..80287e46a --- /dev/null +++ b/src/testcases/org/apache/poi/ss/formula/constant/TestConstantValueParser.java @@ -0,0 +1,78 @@ +/* ==================================================================== + 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.constant; + +import java.util.Arrays; + +import junit.framework.TestCase; + +import org.apache.poi.hssf.record.TestcaseRecordInputStream; +import org.apache.poi.hssf.usermodel.HSSFErrorConstants; +import org.apache.poi.util.HexRead; +import org.apache.poi.util.LittleEndianByteArrayOutputStream; +import org.apache.poi.util.LittleEndianInput; +/** + * + * @author Josh Micich + */ +public final class TestConstantValueParser extends TestCase { + private static final Object[] SAMPLE_VALUES = { + Boolean.TRUE, + null, + new Double(1.1), + "Sample text", + ErrorConstant.valueOf(HSSFErrorConstants.ERROR_DIV_0), + }; + private static final byte[] SAMPLE_ENCODING = HexRead.readFromString( + "04 01 00 00 00 00 00 00 00 " + + "00 00 00 00 00 00 00 00 00 " + + "01 9A 99 99 99 99 99 F1 3F " + + "02 0B 00 00 53 61 6D 70 6C 65 20 74 65 78 74 " + + "10 07 00 00 00 00 00 00 00"); + + public void testGetEncodedSize() { + int actual = ConstantValueParser.getEncodedSize(SAMPLE_VALUES); + assertEquals(51, actual); + } + public void testEncode() { + int size = ConstantValueParser.getEncodedSize(SAMPLE_VALUES); + byte[] data = new byte[size]; + + ConstantValueParser.encode(new LittleEndianByteArrayOutputStream(data, 0), SAMPLE_VALUES); + + if (!Arrays.equals(data, SAMPLE_ENCODING)) { + fail("Encoding differs"); + } + } + public void testDecode() { + LittleEndianInput in = TestcaseRecordInputStream.createLittleEndian(SAMPLE_ENCODING); + + Object[] values = ConstantValueParser.parse(in, 4); + for (int i = 0; i < values.length; i++) { + if(!isEqual(SAMPLE_VALUES[i], values[i])) { + fail("Decoded result differs"); + } + } + } + private static boolean isEqual(Object a, Object b) { + if (a == null) { + return b == null; + } + return a.equals(b); + } +} diff --git a/src/testcases/org/apache/poi/ss/formula/eval/TestAreaEval.java b/src/testcases/org/apache/poi/ss/formula/eval/TestAreaEval.java index 3965766cd..a3ace443d 100644 --- a/src/testcases/org/apache/poi/ss/formula/eval/TestAreaEval.java +++ b/src/testcases/org/apache/poi/ss/formula/eval/TestAreaEval.java @@ -20,7 +20,7 @@ package org.apache.poi.ss.formula.eval; import junit.framework.AssertionFailedError; import junit.framework.TestCase; -import org.apache.poi.hssf.record.formula.AreaPtg; +import org.apache.poi.ss.formula.ptg.AreaPtg; import org.apache.poi.ss.formula.functions.EvalFactory; /** diff --git a/src/testcases/org/apache/poi/ss/formula/eval/TestRangeEval.java b/src/testcases/org/apache/poi/ss/formula/eval/TestRangeEval.java index 439d642dc..fe28f1cd2 100644 --- a/src/testcases/org/apache/poi/ss/formula/eval/TestRangeEval.java +++ b/src/testcases/org/apache/poi/ss/formula/eval/TestRangeEval.java @@ -20,8 +20,8 @@ package org.apache.poi.ss.formula.eval; import junit.framework.AssertionFailedError; import junit.framework.TestCase; -import org.apache.poi.hssf.record.formula.AreaI; -import org.apache.poi.hssf.record.formula.AreaI.OffsetArea; +import org.apache.poi.ss.formula.ptg.AreaI; +import org.apache.poi.ss.formula.ptg.AreaI.OffsetArea; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator; import org.apache.poi.hssf.usermodel.HSSFRow; diff --git a/src/testcases/org/apache/poi/ss/formula/eval/TestUnaryPlusEval.java b/src/testcases/org/apache/poi/ss/formula/eval/TestUnaryPlusEval.java index 33022ad44..c4a39fc14 100644 --- a/src/testcases/org/apache/poi/ss/formula/eval/TestUnaryPlusEval.java +++ b/src/testcases/org/apache/poi/ss/formula/eval/TestUnaryPlusEval.java @@ -19,7 +19,7 @@ package org.apache.poi.ss.formula.eval; import junit.framework.TestCase; -import org.apache.poi.hssf.record.formula.AreaPtg; +import org.apache.poi.ss.formula.ptg.AreaPtg; import org.apache.poi.ss.formula.functions.EvalFactory; import org.apache.poi.ss.formula.functions.NumericFunctionInvoker; diff --git a/src/testcases/org/apache/poi/ss/formula/function/TestParseMissingBuiltInFuncs.java b/src/testcases/org/apache/poi/ss/formula/function/TestParseMissingBuiltInFuncs.java index a6872e5f2..6a18bd9e1 100644 --- a/src/testcases/org/apache/poi/ss/formula/function/TestParseMissingBuiltInFuncs.java +++ b/src/testcases/org/apache/poi/ss/formula/function/TestParseMissingBuiltInFuncs.java @@ -21,10 +21,10 @@ import junit.framework.AssertionFailedError; import junit.framework.TestCase; import org.apache.poi.hssf.model.HSSFFormulaParser; -import org.apache.poi.hssf.record.formula.AbstractFunctionPtg; -import org.apache.poi.hssf.record.formula.FuncPtg; -import org.apache.poi.hssf.record.formula.FuncVarPtg; -import org.apache.poi.hssf.record.formula.Ptg; +import org.apache.poi.ss.formula.ptg.AbstractFunctionPtg; +import org.apache.poi.ss.formula.ptg.FuncPtg; +import org.apache.poi.ss.formula.ptg.FuncVarPtg; +import org.apache.poi.ss.formula.ptg.Ptg; import org.apache.poi.hssf.usermodel.HSSFWorkbook; /** * Tests parsing of some built-in functions that were not properly diff --git a/src/testcases/org/apache/poi/ss/formula/functions/EvalFactory.java b/src/testcases/org/apache/poi/ss/formula/functions/EvalFactory.java index 7eee5627b..31d525070 100644 --- a/src/testcases/org/apache/poi/ss/formula/functions/EvalFactory.java +++ b/src/testcases/org/apache/poi/ss/formula/functions/EvalFactory.java @@ -17,10 +17,10 @@ package org.apache.poi.ss.formula.functions; -import org.apache.poi.hssf.record.formula.AreaI; -import org.apache.poi.hssf.record.formula.AreaPtg; -import org.apache.poi.hssf.record.formula.Ref3DPtg; -import org.apache.poi.hssf.record.formula.RefPtg; +import org.apache.poi.ss.formula.ptg.AreaI; +import org.apache.poi.ss.formula.ptg.AreaPtg; +import org.apache.poi.ss.formula.ptg.Ref3DPtg; +import org.apache.poi.ss.formula.ptg.RefPtg; import org.apache.poi.ss.formula.eval.AreaEval; import org.apache.poi.ss.formula.eval.AreaEvalBase; import org.apache.poi.ss.formula.eval.NumberEval; diff --git a/src/testcases/org/apache/poi/ss/formula/ptg/AbstractPtgTestCase.java b/src/testcases/org/apache/poi/ss/formula/ptg/AbstractPtgTestCase.java new file mode 100644 index 000000000..202a9e06c --- /dev/null +++ b/src/testcases/org/apache/poi/ss/formula/ptg/AbstractPtgTestCase.java @@ -0,0 +1,51 @@ +/* ==================================================================== + 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.ptg; + +import junit.framework.TestCase; + +import org.apache.poi.hssf.HSSFTestDataSamples; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; + +/** + * Convenient abstract class to reduce the amount of boilerplate code needed + * in ptg-related unit tests. + * + * @author Daniel Noll (daniel at nuix dot com dot au) + */ +public abstract class AbstractPtgTestCase extends TestCase { + + /** + * Loads a workbook from the given filename in the test data dir. + * + * @param sampleFileName the filename. + * @return the loaded workbook. + */ + protected static final HSSFWorkbook loadWorkbook(String sampleFileName) { + return HSSFTestDataSamples.openSampleWorkbook(sampleFileName); + } + + /** + * Creates a new Workbook and adds one sheet with the specified name + */ + protected static final HSSFWorkbook createWorkbookWithSheet(String sheetName) { + HSSFWorkbook book = new HSSFWorkbook(); + book.createSheet(sheetName); + return book; + } +} diff --git a/src/testcases/org/apache/poi/ss/formula/ptg/AllFormulaTests.java b/src/testcases/org/apache/poi/ss/formula/ptg/AllFormulaTests.java new file mode 100644 index 000000000..1881a4d64 --- /dev/null +++ b/src/testcases/org/apache/poi/ss/formula/ptg/AllFormulaTests.java @@ -0,0 +1,61 @@ +/* ==================================================================== + 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.ptg; + +import org.apache.poi.ss.formula.TestFormulaShifter; +import org.apache.poi.ss.formula.TestSheetNameFormatter; +import org.apache.poi.ss.formula.eval.AllFormulaEvalTests; +import org.apache.poi.ss.formula.function.AllFormulaFunctionTests; +import org.apache.poi.ss.formula.functions.AllIndividualFunctionEvaluationTests; + +import junit.framework.Test; +import junit.framework.TestSuite; + +/** + * Collects all tests for org.apache.poi.hssf.record.formula. + * + * @author Josh Micich + */ +public final class AllFormulaTests { + + public static Test suite() { + TestSuite result = new TestSuite(AllFormulaTests.class.getName()); + result.addTest(AllFormulaEvalTests.suite()); + result.addTest(AllFormulaFunctionTests.suite()); + result.addTest(AllIndividualFunctionEvaluationTests.suite()); + + result.addTestSuite(TestArea3DPtg.class); + result.addTestSuite(TestAreaErrPtg.class); + result.addTestSuite(TestAreaPtg.class); + result.addTestSuite(TestArrayPtg.class); + result.addTestSuite(TestAttrPtg.class); + result.addTestSuite(TestErrPtg.class); + result.addTestSuite(TestExternalFunctionFormulas.class); + result.addTestSuite(TestFormulaShifter.class); + result.addTestSuite(TestFuncPtg.class); + result.addTestSuite(TestFuncVarPtg.class); + result.addTestSuite(TestIntersectionPtg.class); + result.addTestSuite(TestPercentPtg.class); + result.addTestSuite(TestRangePtg.class); + result.addTestSuite(TestRef3DPtg.class); + result.addTestSuite(TestReferencePtg.class); + result.addTestSuite(TestSheetNameFormatter.class); + result.addTestSuite(TestUnionPtg.class); + return result; + } +} diff --git a/src/testcases/org/apache/poi/ss/formula/ptg/TestArea3DPtg.java b/src/testcases/org/apache/poi/ss/formula/ptg/TestArea3DPtg.java new file mode 100644 index 000000000..bb11807e5 --- /dev/null +++ b/src/testcases/org/apache/poi/ss/formula/ptg/TestArea3DPtg.java @@ -0,0 +1,48 @@ +/* ==================================================================== + 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.ptg; + +import org.apache.poi.hssf.usermodel.HSSFEvaluationWorkbook; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; + +/** + * Tests for Area3DPtg + * + * @author Josh Micich + */ +public final class TestArea3DPtg extends AbstractPtgTestCase { + + /** + * confirms that sheet names get properly escaped + */ + public void testToFormulaString() { + + Area3DPtg target = new Area3DPtg("A1:B1", (short)0); + + String sheetName = "my sheet"; + HSSFWorkbook wb = createWorkbookWithSheet(sheetName); + HSSFEvaluationWorkbook book = HSSFEvaluationWorkbook.create(wb); + assertEquals("'my sheet'!A1:B1", target.toFormulaString(book)); + + wb.setSheetName(0, "Sheet1"); + assertEquals("Sheet1!A1:B1", target.toFormulaString(book)); + + wb.setSheetName(0, "C64"); + assertEquals("'C64'!A1:B1", target.toFormulaString(book)); + } +} diff --git a/src/testcases/org/apache/poi/ss/formula/ptg/TestAreaErrPtg.java b/src/testcases/org/apache/poi/ss/formula/ptg/TestAreaErrPtg.java new file mode 100644 index 000000000..e8032cb23 --- /dev/null +++ b/src/testcases/org/apache/poi/ss/formula/ptg/TestAreaErrPtg.java @@ -0,0 +1,36 @@ +/* ==================================================================== + 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.ptg; + +import org.apache.poi.hssf.usermodel.HSSFWorkbook; + +/** + * Tests for {@link AreaErrPtg}. + * + * @author Daniel Noll (daniel at nuix dot com dot au) + */ +public final class TestAreaErrPtg extends AbstractPtgTestCase { + /** + * Tests reading a file containing this ptg. + */ + public void testReading() { + HSSFWorkbook workbook = loadWorkbook("AreaErrPtg.xls"); + assertEquals("Wrong formula string for area error", "SUM(#REF!)", + workbook.getSheetAt(0).getRow(0).getCell(2).getCellFormula()); + } +} diff --git a/src/testcases/org/apache/poi/ss/formula/ptg/TestAreaPtg.java b/src/testcases/org/apache/poi/ss/formula/ptg/TestAreaPtg.java new file mode 100644 index 000000000..0dd72661f --- /dev/null +++ b/src/testcases/org/apache/poi/ss/formula/ptg/TestAreaPtg.java @@ -0,0 +1,104 @@ + +/* ==================================================================== + 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.ptg; + +import junit.framework.TestCase; + +import org.apache.poi.hssf.model.HSSFFormulaParser; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; + +/** + * Tests for {@link AreaPtg}. + * + * @author Dmitriy Kumshayev + */ +public final class TestAreaPtg extends TestCase { + + AreaPtg relative; + AreaPtg absolute; + + protected void setUp() { + short firstRow=5; + short lastRow=13; + short firstCol=7; + short lastCol=17; + relative = new AreaPtg(firstRow,lastRow,firstCol,lastCol,true,true,true,true); + absolute = new AreaPtg(firstRow,lastRow,firstCol,lastCol,false,false,false,false); + } + + public void testSetColumnsAbsolute() + { + resetColumns(absolute); + validateReference(true, absolute); + } + public void testSetColumnsRelative() + { + resetColumns(relative); + validateReference(false, relative); + } + + private void validateReference(boolean abs, AreaPtg ref) + { + assertEquals("First column reference is not "+(abs?"absolute":"relative"),abs,!ref.isFirstColRelative()); + assertEquals("Last column reference is not "+(abs?"absolute":"relative"),abs,!ref.isLastColRelative()); + assertEquals("First row reference is not "+(abs?"absolute":"relative"),abs,!ref.isFirstRowRelative()); + assertEquals("Last row reference is not "+(abs?"absolute":"relative"),abs,!ref.isLastRowRelative()); + } + + + private static void resetColumns(AreaPtg aptg) { + int fc = aptg.getFirstColumn(); + int lc = aptg.getLastColumn(); + aptg.setFirstColumn(fc); + aptg.setLastColumn(lc); + assertEquals(fc , aptg.getFirstColumn() ); + assertEquals(lc , aptg.getLastColumn() ); + } + + public void testFormulaParser() + { + String formula1="SUM($E$5:$E$6)"; + String expectedFormula1="SUM($F$5:$F$6)"; + String newFormula1 = shiftAllColumnsBy1(formula1); + assertEquals("Absolute references changed", expectedFormula1, newFormula1); + + String formula2="SUM(E5:E6)"; + String expectedFormula2="SUM(F5:F6)"; + String newFormula2 = shiftAllColumnsBy1(formula2); + assertEquals("Relative references changed", expectedFormula2, newFormula2); + } + + private static String shiftAllColumnsBy1(String formula) { + int letUsShiftColumn1By1Column=1; + HSSFWorkbook wb = null; + Ptg[] ptgs = HSSFFormulaParser.parse(formula, wb); + for(int i=0; iArrayPtg + * + * @author Josh Micich + */ +public final class TestArrayPtg extends TestCase { + + private static final byte[] ENCODED_PTG_DATA = { + 0x40, + 0, 0, 0, 0, 0, 0, 0, + }; + private static final byte[] ENCODED_CONSTANT_DATA = { + 2, // 3 columns + 1, 0, // 2 rows + 4, 1, 0, 0, 0, 0, 0, 0, 0, // TRUE + 2, 4, 0, 0, 65, 66, 67, 68, // "ABCD" + 2, 1, 0, 0, 69, // "E" + 1, 0, 0, 0, 0, 0, 0, 0, 0, // 0 + 4, 0, 0, 0, 0, 0, 0, 0, 0, // FALSE + 2, 2, 0, 0, 70, 71, // "FG" + }; + + private static ArrayPtg create(byte[] initialData, byte[] constantData) { + ArrayPtg.Initial ptgInit = new ArrayPtg.Initial(TestcaseRecordInputStream.createLittleEndian(initialData)); + return ptgInit.finishReading(TestcaseRecordInputStream.createLittleEndian(constantData)); + } + + /** + * Lots of problems with ArrayPtg's decoding and encoding of the element value data + */ + public void testReadWriteTokenValueBytes() { + ArrayPtg ptg = create(ENCODED_PTG_DATA, ENCODED_CONSTANT_DATA); + assertEquals(3, ptg.getColumnCount()); + assertEquals(2, ptg.getRowCount()); + Object[][] values = ptg.getTokenArrayValues(); + assertEquals(2, values.length); + + + assertEquals(Boolean.TRUE, values[0][0]); + assertEquals("ABCD", values[0][1]); + assertEquals(new Double(0), values[1][0]); + assertEquals(Boolean.FALSE, values[1][1]); + assertEquals("FG", values[1][2]); + + byte[] outBuf = new byte[ENCODED_CONSTANT_DATA.length]; + ptg.writeTokenValueBytes(new LittleEndianByteArrayOutputStream(outBuf, 0)); + + if(outBuf[0] == 4) { + throw new AssertionFailedError("Identified bug 42564b"); + } + assertTrue(Arrays.equals(ENCODED_CONSTANT_DATA, outBuf)); + } + + + /** + * Excel stores array elements column by column. This test makes sure POI does the same. + */ + public void testElementOrdering() { + ArrayPtg ptg = create(ENCODED_PTG_DATA, ENCODED_CONSTANT_DATA); + assertEquals(3, ptg.getColumnCount()); + assertEquals(2, ptg.getRowCount()); + + assertEquals(0, ptg.getValueIndex(0, 0)); + assertEquals(1, ptg.getValueIndex(1, 0)); + assertEquals(2, ptg.getValueIndex(2, 0)); + assertEquals(3, ptg.getValueIndex(0, 1)); + assertEquals(4, ptg.getValueIndex(1, 1)); + assertEquals(5, ptg.getValueIndex(2, 1)); + } + + /** + * Test for a bug which was temporarily introduced by the fix for bug 42564. + * A spreadsheet was added to make the ordering clearer. + */ + public void testElementOrderingInSpreadsheet() { + HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("ex42564-elementOrder.xls"); + + // The formula has an array with 3 rows and 5 columns + String formula = wb.getSheetAt(0).getRow(0).getCell(0).getCellFormula(); + + if (formula.equals("SUM({1,6,11;2,7,12;3,8,13;4,9,14;5,10,15})")) { + throw new AssertionFailedError("Identified bug 42564 b"); + } + assertEquals("SUM({1,2,3,4,5;6,7,8,9,10;11,12,13,14,15})", formula); + } + + public void testToFormulaString() { + ArrayPtg ptg = create(ENCODED_PTG_DATA, ENCODED_CONSTANT_DATA); + String actualFormula; + try { + actualFormula = ptg.toFormulaString(); + } catch (IllegalArgumentException e) { + if (e.getMessage().equals("Unexpected constant class (java.lang.Boolean)")) { + throw new AssertionFailedError("Identified bug 45380"); + } + throw e; + } + assertEquals("{TRUE,\"ABCD\",\"E\";0,FALSE,\"FG\"}", actualFormula); + } + + /** + * worth checking since AttrPtg.sid=0x20 and Ptg.CLASS_* = (0x00, 0x20, and 0x40) + */ + public void testOperandClassDecoding() { + confirmOperandClassDecoding(Ptg.CLASS_REF); + confirmOperandClassDecoding(Ptg.CLASS_VALUE); + confirmOperandClassDecoding(Ptg.CLASS_ARRAY); + } + + private static void confirmOperandClassDecoding(byte operandClass) { + byte[] fullData = concat(ENCODED_PTG_DATA, ENCODED_CONSTANT_DATA); + + // Force encoded operand class for tArray + fullData[0] = (byte) (ArrayPtg.sid + operandClass); + + LittleEndianInput in = TestcaseRecordInputStream.createLittleEndian(fullData); + + Ptg[] ptgs = Ptg.readTokens(ENCODED_PTG_DATA.length, in); + assertEquals(1, ptgs.length); + ArrayPtg aPtg = (ArrayPtg) ptgs[0]; + assertEquals(operandClass, aPtg.getPtgClass()); + } + + private static byte[] concat(byte[] a, byte[] b) { + byte[] result = new byte[a.length + b.length]; + System.arraycopy(a, 0, result, 0, a.length); + System.arraycopy(b, 0, result, a.length, b.length); + return result; + } +} diff --git a/src/testcases/org/apache/poi/ss/formula/ptg/TestAttrPtg.java b/src/testcases/org/apache/poi/ss/formula/ptg/TestAttrPtg.java new file mode 100644 index 000000000..fb517a31d --- /dev/null +++ b/src/testcases/org/apache/poi/ss/formula/ptg/TestAttrPtg.java @@ -0,0 +1,50 @@ +/* ==================================================================== + 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.ptg; + +import java.util.Arrays; + +import junit.framework.AssertionFailedError; + +import org.apache.poi.hssf.record.TestcaseRecordInputStream; +import org.apache.poi.util.HexRead; +import org.apache.poi.util.LittleEndianInput; + +/** + * Tests for {@link AttrPtg}. + * + * @author Josh Micich + */ +public final class TestAttrPtg extends AbstractPtgTestCase { + + /** + * Fix for bug visible around svn r706772. + */ + public void testReserializeAttrChoose() { + byte[] data = HexRead.readFromString("19, 04, 03, 00, 08, 00, 11, 00, 1A, 00, 23, 00"); + LittleEndianInput in = TestcaseRecordInputStream.createLittleEndian(data); + Ptg[] ptgs = Ptg.readTokens(data.length, in); + byte[] data2 = new byte[data.length]; + try { + Ptg.serializePtgs(ptgs, data2, 0); + } catch (ArrayIndexOutOfBoundsException e) { + throw new AssertionFailedError("incorrect re-serialization of tAttrChoose"); + } + assertTrue(Arrays.equals(data, data2)); + } +} diff --git a/src/testcases/org/apache/poi/ss/formula/ptg/TestErrPtg.java b/src/testcases/org/apache/poi/ss/formula/ptg/TestErrPtg.java new file mode 100644 index 000000000..735ba393e --- /dev/null +++ b/src/testcases/org/apache/poi/ss/formula/ptg/TestErrPtg.java @@ -0,0 +1,38 @@ +/* ==================================================================== + 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.ptg; + +import org.apache.poi.hssf.usermodel.HSSFCell; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; + +/** + * Tests for {@link ErrPtg}. + * + * @author Daniel Noll (daniel at nuix dot com dot au) + */ +public final class TestErrPtg extends AbstractPtgTestCase { + /** + * Tests reading a file containing this ptg. + */ + public void testReading() { + HSSFWorkbook workbook = loadWorkbook("ErrPtg.xls"); + HSSFCell cell = workbook.getSheetAt(0).getRow(3).getCell(0); + assertEquals("Wrong cell value", 4.0, cell.getNumericCellValue(), 0.0); + assertEquals("Wrong cell formula", "ERROR.TYPE(#REF!)", cell.getCellFormula()); + } +} diff --git a/src/testcases/org/apache/poi/ss/formula/ptg/TestExternalFunctionFormulas.java b/src/testcases/org/apache/poi/ss/formula/ptg/TestExternalFunctionFormulas.java new file mode 100644 index 000000000..f1edbe21d --- /dev/null +++ b/src/testcases/org/apache/poi/ss/formula/ptg/TestExternalFunctionFormulas.java @@ -0,0 +1,92 @@ +/* ==================================================================== + 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.ptg; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; + +import junit.framework.TestCase; + +import org.apache.poi.hssf.HSSFTestDataSamples; +import org.apache.poi.hssf.model.HSSFFormulaParser; +import org.apache.poi.hssf.usermodel.HSSFCell; +import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator; +import org.apache.poi.hssf.usermodel.HSSFSheet; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.ss.usermodel.CellValue; +/** + * Tests for functions from external workbooks (e.g. YEARFRAC). + * + * + * @author Josh Micich + */ +public final class TestExternalFunctionFormulas extends TestCase { + + /** + * tests NameXPtg.toFormulaString(Workbook) and logic in Workbook below that + */ + public void testReadFormulaContainingExternalFunction() { + HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("externalFunctionExample.xls"); + + String expectedFormula = "YEARFRAC(B1,C1)"; + HSSFSheet sht = wb.getSheetAt(0); + String cellFormula = sht.getRow(0).getCell(0).getCellFormula(); + assertEquals(expectedFormula, cellFormula); + } + + public void testParse() { + HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("externalFunctionExample.xls"); + Ptg[] ptgs = HSSFFormulaParser.parse("YEARFRAC(B1,C1)", wb); + assertEquals(4, ptgs.length); + assertEquals(NameXPtg.class, ptgs[0].getClass()); + + wb.getSheetAt(0).getRow(0).createCell(6).setCellFormula("YEARFRAC(C1,B1)"); + if (false) { + // In case you fancy checking in excel + try { + File tempFile = File.createTempFile("testExtFunc", ".xls"); + FileOutputStream fout = new FileOutputStream(tempFile); + wb.write(fout); + fout.close(); + System.out.println("check out " + tempFile.getAbsolutePath()); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + + public void testEvaluate() { + HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("externalFunctionExample.xls"); + HSSFSheet sheet = wb.getSheetAt(0); + HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb); + confirmCellEval(sheet, 0, 0, fe, "YEARFRAC(B1,C1)", 29.0/90.0); + confirmCellEval(sheet, 1, 0, fe, "YEARFRAC(B2,C2)", 0.0); + confirmCellEval(sheet, 2, 0, fe, "YEARFRAC(B3,C3,D3)", 0.0); + confirmCellEval(sheet, 3, 0, fe, "IF(ISEVEN(3),1.2,1.6)", 1.6); + confirmCellEval(sheet, 4, 0, fe, "IF(ISODD(3),1.2,1.6)", 1.2); + } + + private static void confirmCellEval(HSSFSheet sheet, int rowIx, int colIx, + HSSFFormulaEvaluator fe, String expectedFormula, double expectedResult) { + HSSFCell cell = sheet.getRow(rowIx).getCell(colIx); + assertEquals(expectedFormula, cell.getCellFormula()); + CellValue cv = fe.evaluate(cell); + assertEquals(expectedResult, cv.getNumberValue(), 0.0); + } +} diff --git a/src/testcases/org/apache/poi/ss/formula/ptg/TestExternalNameReference.java b/src/testcases/org/apache/poi/ss/formula/ptg/TestExternalNameReference.java new file mode 100644 index 000000000..16c77fdfb --- /dev/null +++ b/src/testcases/org/apache/poi/ss/formula/ptg/TestExternalNameReference.java @@ -0,0 +1,106 @@ +/* ==================================================================== + 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.ptg; + + +import junit.framework.TestCase; + +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.HSSFWorkbook; +import org.apache.poi.hssf.util.CellReference; +/** + * Tests for proper calculation of named ranges from external workbooks. + * + * + * @author Stephen Wolke (smwolke at geistig.com) + */ +public final class TestExternalNameReference extends TestCase { + double MARKUP_COST = 1.9d; + double MARKUP_COST_1 = 1.8d; + double MARKUP_COST_2 = 1.5d; + double PART_COST = 12.3d; + double NEW_QUANT = 7.0d; + double NEW_PART_COST = 15.3d; + /** + * tests NameXPtg for external cell reference by name and logic in Workbook below that + */ + public void testReadCalcSheet() { + try{ + HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("XRefCalc.xls"); + assertEquals("Sheet1!$A$2", wb.getName("QUANT").getRefersToFormula()); + assertEquals("Sheet1!$B$2", wb.getName("PART").getRefersToFormula()); + assertEquals("x123",wb.getSheet("Sheet1").getRow(1).getCell(1).getStringCellValue()); + assertEquals("Sheet1!$C$2", wb.getName("UNITCOST").getRefersToFormula()); + CellReference cellRef = new CellReference(wb.getName("UNITCOST").getRefersToFormula()); + HSSFCell cell = wb.getSheet(cellRef.getSheetName()).getRow(cellRef.getRow()).getCell((int)cellRef.getCol()); + assertEquals("VLOOKUP(PART,COSTS,2,FALSE)",cell.getCellFormula()); + assertEquals("Sheet1!$D$2", wb.getName("COST").getRefersToFormula()); + cellRef = new CellReference(wb.getName("COST").getRefersToFormula()); + cell = wb.getSheet(cellRef.getSheetName()).getRow(cellRef.getRow()).getCell((int)cellRef.getCol()); + assertEquals("UNITCOST*Quant",cell.getCellFormula()); + assertEquals("Sheet1!$E$2", wb.getName("TOTALCOST").getRefersToFormula()); + cellRef = new CellReference(wb.getName("TOTALCOST").getRefersToFormula()); + cell = wb.getSheet(cellRef.getSheetName()).getRow(cellRef.getRow()).getCell((int)cellRef.getCol()); + assertEquals("Cost*Markup_Cost",cell.getCellFormula()); + }catch(Exception e){ + fail(); + } + } + + public void testReadReferencedSheet() { + try{ + HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("XRefCalcData.xls"); + assertEquals("CostSheet!$A$2:$B$3", wb.getName("COSTS").getRefersToFormula()); + assertEquals("x123",wb.getSheet("CostSheet").getRow(1).getCell(0).getStringCellValue()); + assertEquals(PART_COST,wb.getSheet("CostSheet").getRow(1).getCell(1).getNumericCellValue()); + assertEquals("MarkupSheet!$B$1", wb.getName("Markup_Cost").getRefersToFormula()); + assertEquals(MARKUP_COST_1,wb.getSheet("MarkupSheet").getRow(0).getCell(1).getNumericCellValue()); + }catch(Exception e){ + fail(); + } + } + + public void testEvaluate() throws Exception { + HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("XRefCalc.xls"); + HSSFWorkbook wb2 = HSSFTestDataSamples.openSampleWorkbook("XRefCalcData.xls"); + CellReference cellRef = new CellReference(wb.getName("QUANT").getRefersToFormula()); + HSSFCell cell = wb.getSheet(cellRef.getSheetName()).getRow(cellRef.getRow()).getCell((int)cellRef.getCol()); + cell.setCellValue(NEW_QUANT); + cell = wb2.getSheet("CostSheet").getRow(1).getCell(1); + cell.setCellValue(NEW_PART_COST); + HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(wb); + HSSFFormulaEvaluator evaluatorCost = new HSSFFormulaEvaluator(wb2); + String[] bookNames = { "XRefCalc.xls", "XRefCalcData.xls" }; + HSSFFormulaEvaluator[] evaluators = { evaluator, evaluatorCost, }; + HSSFFormulaEvaluator.setupEnvironment(bookNames, evaluators); + cellRef = new CellReference(wb.getName("UNITCOST").getRefersToFormula()); + HSSFCell uccell = wb.getSheet(cellRef.getSheetName()).getRow(cellRef.getRow()).getCell((int)cellRef.getCol()); + cellRef = new CellReference(wb.getName("COST").getRefersToFormula()); + HSSFCell ccell = wb.getSheet(cellRef.getSheetName()).getRow(cellRef.getRow()).getCell((int)cellRef.getCol()); + cellRef = new CellReference(wb.getName("TOTALCOST").getRefersToFormula()); + HSSFCell tccell = wb.getSheet(cellRef.getSheetName()).getRow(cellRef.getRow()).getCell((int)cellRef.getCol()); + evaluator.evaluateFormulaCell(uccell); + evaluator.evaluateFormulaCell(ccell); + evaluator.evaluateFormulaCell(tccell); + assertEquals(NEW_PART_COST, uccell.getNumericCellValue()); + assertEquals(NEW_PART_COST*NEW_QUANT, ccell.getNumericCellValue()); + assertEquals(NEW_PART_COST*NEW_QUANT*MARKUP_COST_2, tccell.getNumericCellValue()); + } +} diff --git a/src/testcases/org/apache/poi/ss/formula/ptg/TestFuncPtg.java b/src/testcases/org/apache/poi/ss/formula/ptg/TestFuncPtg.java new file mode 100644 index 000000000..fd1af26dd --- /dev/null +++ b/src/testcases/org/apache/poi/ss/formula/ptg/TestFuncPtg.java @@ -0,0 +1,46 @@ +/* ==================================================================== + 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.ptg; + +import junit.framework.TestCase; +import org.apache.poi.hssf.record.TestcaseRecordInputStream; + +/** + * Make sure the FuncPtg performs as expected + * + * @author Danny Mui (dmui at apache dot org) + */ +public final class TestFuncPtg extends TestCase { + + public void testRead() { + // This function index represents the LEN() function + byte[] fakeData = { 0x20, 0x00,}; + + FuncPtg ptg = FuncPtg.create(TestcaseRecordInputStream.createLittleEndian(fakeData) ); + assertEquals( "Len formula index is not 32(20H)", 0x20, ptg.getFunctionIndex() ); + assertEquals( "Number of operands in the len formula", 1, ptg.getNumberOfOperands() ); + assertEquals( "Function Name", "LEN", ptg.getName() ); + assertEquals( "Ptg Size", 3, ptg.getSize() ); + } + + public void testNumberOfOperands() { + FuncPtg funcPtg = FuncPtg.create(27); // ROUND() - takes 2 args + assertEquals(2, funcPtg.getNumberOfOperands()); + assertEquals("ROUND", funcPtg.getName()); + } +} diff --git a/src/testcases/org/apache/poi/ss/formula/ptg/TestFuncVarPtg.java b/src/testcases/org/apache/poi/ss/formula/ptg/TestFuncVarPtg.java new file mode 100644 index 000000000..ecc07aac4 --- /dev/null +++ b/src/testcases/org/apache/poi/ss/formula/ptg/TestFuncVarPtg.java @@ -0,0 +1,53 @@ +/* ==================================================================== + 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.ptg; + +import org.apache.poi.hssf.model.HSSFFormulaParser; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; + +import junit.framework.AssertionFailedError; +import junit.framework.TestCase; +/** + * @author Josh Micich + */ +public final class TestFuncVarPtg extends TestCase { + + /** + * The first fix for bugzilla 44675 broke the encoding of SUM formulas (and probably others). + * The operand classes of the parameters to SUM() should be coerced to 'reference' not 'value'. + * In the case of SUM, Excel evaluates the formula to '#VALUE!' if a parameter operand class is + * wrong. In other cases Excel seems to tolerate bad operand classes.

+ * This functionality is related to the setParameterRVA() methods of FormulaParser + */ + public void testOperandClass() { + HSSFWorkbook book = new HSSFWorkbook(); + Ptg[] ptgs = HSSFFormulaParser.parse("sum(A1:A2)", book); + assertEquals(2, ptgs.length); + assertEquals(AreaPtg.class, ptgs[0].getClass()); + + switch(ptgs[0].getPtgClass()) { + case Ptg.CLASS_REF: + // correct behaviour + break; + case Ptg.CLASS_VALUE: + throw new AssertionFailedError("Identified bug 44675b"); + default: + throw new RuntimeException("Unexpected operand class"); + } + } +} diff --git a/src/testcases/org/apache/poi/ss/formula/ptg/TestIntersectionPtg.java b/src/testcases/org/apache/poi/ss/formula/ptg/TestIntersectionPtg.java new file mode 100644 index 000000000..c06b80e38 --- /dev/null +++ b/src/testcases/org/apache/poi/ss/formula/ptg/TestIntersectionPtg.java @@ -0,0 +1,38 @@ +/* ==================================================================== + 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.ptg; + +import org.apache.poi.hssf.usermodel.HSSFCell; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; + +/** + * Tests for {@link IntersectionPtg}. + * + * @author Daniel Noll (daniel at nuix dot com dot au) + */ +public final class TestIntersectionPtg extends AbstractPtgTestCase { + /** + * Tests reading a file containing this ptg. + */ + public void testReading() { + HSSFWorkbook workbook = loadWorkbook("IntersectionPtg.xls"); + HSSFCell cell = workbook.getSheetAt(0).getRow(4).getCell(2); + assertEquals("Wrong cell value", 5.0, cell.getNumericCellValue(), 0.0); + assertEquals("Wrong cell formula", "SUM(A1:B2 B2:C3)", cell.getCellFormula()); + } +} diff --git a/src/testcases/org/apache/poi/ss/formula/ptg/TestPercentPtg.java b/src/testcases/org/apache/poi/ss/formula/ptg/TestPercentPtg.java new file mode 100644 index 000000000..79d34530a --- /dev/null +++ b/src/testcases/org/apache/poi/ss/formula/ptg/TestPercentPtg.java @@ -0,0 +1,43 @@ +/* ==================================================================== + 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.ptg; + +import org.apache.poi.hssf.usermodel.HSSFSheet; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; + +/** + * Tests for {@link PercentPtg}. + * + * @author Daniel Noll (daniel at nuix dot com dot au) + */ +public final class TestPercentPtg extends AbstractPtgTestCase { + /** + * Tests reading a file containing this ptg. + */ + public void testReading() { + HSSFWorkbook workbook = loadWorkbook("PercentPtg.xls"); + HSSFSheet sheet = workbook.getSheetAt(0); + + assertEquals("Wrong numeric value for original number", 53000.0, + sheet.getRow(0).getCell(0).getNumericCellValue(), 0.0); + assertEquals("Wrong numeric value for percent formula result", 5300.0, + sheet.getRow(1).getCell(0).getNumericCellValue(), 0.0); + assertEquals("Wrong formula string for percent formula", "A1*10%", + sheet.getRow(1).getCell(0).getCellFormula()); + } +} diff --git a/src/testcases/org/apache/poi/ss/formula/ptg/TestRangePtg.java b/src/testcases/org/apache/poi/ss/formula/ptg/TestRangePtg.java new file mode 100644 index 000000000..3b02684bb --- /dev/null +++ b/src/testcases/org/apache/poi/ss/formula/ptg/TestRangePtg.java @@ -0,0 +1,38 @@ +/* ==================================================================== + 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.ptg; + +import org.apache.poi.hssf.usermodel.HSSFCell; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; + +/** + * Tests for {@link RangePtg}. + * + * @author Daniel Noll (daniel at nuix dot com dot au) + */ +public final class TestRangePtg extends AbstractPtgTestCase { + /** + * Tests reading a file containing this ptg. + */ + public void testReading() { + HSSFWorkbook workbook = loadWorkbook("RangePtg.xls"); + HSSFCell cell = workbook.getSheetAt(0).getRow(3).getCell(1); + assertEquals("Wrong cell value", 10.0, cell.getNumericCellValue(), 0.0); + assertEquals("Wrong cell formula", "SUM(pineapple:B2)", cell.getCellFormula()); + } +} diff --git a/src/testcases/org/apache/poi/ss/formula/ptg/TestRef3DPtg.java b/src/testcases/org/apache/poi/ss/formula/ptg/TestRef3DPtg.java new file mode 100644 index 000000000..3aca4c4e0 --- /dev/null +++ b/src/testcases/org/apache/poi/ss/formula/ptg/TestRef3DPtg.java @@ -0,0 +1,44 @@ +/* ==================================================================== + 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.ptg; + +import org.apache.poi.hssf.usermodel.HSSFEvaluationWorkbook; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; + +/** + * Tests for Ref3DPtg + * + * @author Josh Micich + */ +public final class TestRef3DPtg extends AbstractPtgTestCase { + + public void testToFormulaString() { + + Ref3DPtg target = new Ref3DPtg("A1", (short)0); + + HSSFWorkbook wb = createWorkbookWithSheet("my sheet"); + HSSFEvaluationWorkbook book = HSSFEvaluationWorkbook.create(wb); + assertEquals("'my sheet'!A1", target.toFormulaString(book)); + + wb.setSheetName(0, "ProfitAndLoss"); + assertEquals("ProfitAndLoss!A1", target.toFormulaString(book)); + + wb.setSheetName(0, "profit+loss"); + assertEquals("'profit+loss'!A1", target.toFormulaString(book)); + } +} diff --git a/src/testcases/org/apache/poi/ss/formula/ptg/TestReferencePtg.java b/src/testcases/org/apache/poi/ss/formula/ptg/TestReferencePtg.java new file mode 100644 index 000000000..db02279f3 --- /dev/null +++ b/src/testcases/org/apache/poi/ss/formula/ptg/TestReferencePtg.java @@ -0,0 +1,122 @@ +/* ==================================================================== + 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.ptg; + +import java.util.Arrays; + +import junit.framework.AssertionFailedError; +import junit.framework.TestCase; + +import org.apache.poi.hssf.HSSFTestDataSamples; +import org.apache.poi.hssf.record.TestcaseRecordInputStream; +import org.apache.poi.hssf.usermodel.HSSFSheet; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.util.LittleEndianInput; + +/** + * Tests for {@link RefPtg}. + */ +public final class TestReferencePtg extends TestCase { + /** + * Tests reading a file containing this ptg. + */ + public void testReading() { + HSSFWorkbook workbook = HSSFTestDataSamples.openSampleWorkbook("ReferencePtg.xls"); + HSSFSheet sheet = workbook.getSheetAt(0); + + // First row + assertEquals("Wrong numeric value for original number", 55.0, + sheet.getRow(0).getCell(0).getNumericCellValue(), 0.0); + assertEquals("Wrong numeric value for referemce", 55.0, + sheet.getRow(0).getCell(1).getNumericCellValue(), 0.0); + assertEquals("Wrong formula string for reference", "A1", + sheet.getRow(0).getCell(1).getCellFormula()); + + // Now moving over the 2**15 boundary + // (Remember that excel row (n) is poi row (n-1) + assertEquals("Wrong numeric value for original number", 32767.0, + sheet.getRow(32766).getCell(0).getNumericCellValue(), 0.0); + assertEquals("Wrong numeric value for referemce", 32767.0, + sheet.getRow(32766).getCell(1).getNumericCellValue(), 0.0); + assertEquals("Wrong formula string for reference", "A32767", + sheet.getRow(32766).getCell(1).getCellFormula()); + + assertEquals("Wrong numeric value for original number", 32768.0, + sheet.getRow(32767).getCell(0).getNumericCellValue(), 0.0); + assertEquals("Wrong numeric value for referemce", 32768.0, + sheet.getRow(32767).getCell(1).getNumericCellValue(), 0.0); + assertEquals("Wrong formula string for reference", "A32768", + sheet.getRow(32767).getCell(1).getCellFormula()); + + assertEquals("Wrong numeric value for original number", 32769.0, + sheet.getRow(32768).getCell(0).getNumericCellValue(), 0.0); + assertEquals("Wrong numeric value for referemce", 32769.0, + sheet.getRow(32768).getCell(1).getNumericCellValue(), 0.0); + assertEquals("Wrong formula string for reference", "A32769", + sheet.getRow(32768).getCell(1).getCellFormula()); + + assertEquals("Wrong numeric value for original number", 32770.0, + sheet.getRow(32769).getCell(0).getNumericCellValue(), 0.0); + assertEquals("Wrong numeric value for referemce", 32770.0, + sheet.getRow(32769).getCell(1).getNumericCellValue(), 0.0); + assertEquals("Wrong formula string for reference", "A32770", + sheet.getRow(32769).getCell(1).getCellFormula()); + } + + public void testBug44921() { + HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("ex44921-21902.xls"); + + try { + HSSFTestDataSamples.writeOutAndReadBack(wb); + } catch (RuntimeException e) { + if(e.getMessage().equals("Coding Error: This method should never be called. This ptg should be converted")) { + throw new AssertionFailedError("Identified bug 44921"); + } + throw e; + } + } + private static final byte[] tRefN_data = { + 0x2C, 33, 44, 55, 66, + }; + public void testReadWrite_tRefN_bug45091() { + LittleEndianInput in = TestcaseRecordInputStream.createLittleEndian(tRefN_data); + Ptg[] ptgs = Ptg.readTokens(tRefN_data.length, in); + byte[] outData = new byte[5]; + Ptg.serializePtgs(ptgs, outData, 0); + if (outData[0] == 0x24) { + throw new AssertionFailedError("Identified bug 45091"); + } + assertTrue(Arrays.equals(tRefN_data, outData)); + } + + /** + * test that RefPtgBase can handle references with column index greater than 255, + * see Bugzilla 50096 + */ + public void testColumnGreater255() { + RefPtgBase ptg; + ptg = new RefPtg("IW1"); + assertEquals(256, ptg.getColumn()); + assertEquals("IW1", ptg.formatReferenceAsString()); + + ptg = new RefPtg("JA1"); + assertEquals(260, ptg.getColumn()); + assertEquals("JA1", ptg.formatReferenceAsString()); + } +} + diff --git a/src/testcases/org/apache/poi/ss/formula/ptg/TestUnionPtg.java b/src/testcases/org/apache/poi/ss/formula/ptg/TestUnionPtg.java new file mode 100644 index 000000000..9ea756061 --- /dev/null +++ b/src/testcases/org/apache/poi/ss/formula/ptg/TestUnionPtg.java @@ -0,0 +1,38 @@ +/* ==================================================================== + 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.ptg; + +import org.apache.poi.hssf.usermodel.HSSFCell; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; + +/** + * Tests for {@link UnionPtg}. + * + * @author Daniel Noll (daniel at nuix dot com dot au) + */ +public final class TestUnionPtg extends AbstractPtgTestCase { + /** + * Tests reading a file containing this ptg. + */ + public void testReading() { + HSSFWorkbook workbook = loadWorkbook("UnionPtg.xls"); + HSSFCell cell = workbook.getSheetAt(0).getRow(4).getCell(2); + assertEquals("Wrong cell value", 24.0, cell.getNumericCellValue(), 0.0); + assertEquals("Wrong cell formula", "SUM(A1:B2,B2:C3)", cell.getCellFormula()); + } +} diff --git a/src/testcases/org/apache/poi/ss/util/TestNumberToTextConverter.java b/src/testcases/org/apache/poi/ss/util/TestNumberToTextConverter.java index c8e80d778..48fe7a3f8 100644 --- a/src/testcases/org/apache/poi/ss/util/TestNumberToTextConverter.java +++ b/src/testcases/org/apache/poi/ss/util/TestNumberToTextConverter.java @@ -22,9 +22,8 @@ import junit.framework.ComparisonFailure; import junit.framework.TestCase; import org.apache.poi.hssf.record.FormulaRecord; -import org.apache.poi.hssf.record.constant.ConstantValueParser; -import org.apache.poi.hssf.record.formula.NumberPtg; -import org.apache.poi.ss.util.NumberToTextConverter; +import org.apache.poi.ss.formula.constant.ConstantValueParser; +import org.apache.poi.ss.formula.ptg.NumberPtg; import org.apache.poi.ss.util.NumberToTextConversionExamples.ExampleConversion; /** * Tests for {@link NumberToTextConverter}