aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Micich <josh@apache.org>2009-09-30 22:25:53 +0000
committerJosh Micich <josh@apache.org>2009-09-30 22:25:53 +0000
commit38deacac7d2ab320487850ba46f6578118e02aaf (patch)
tree10712104a68e60e87653d8c4374c2405a931ea4a
parent7cf2f8b2f4a0f2c62c935f032f51e30982ca6901 (diff)
downloadpoi-38deacac7d2ab320487850ba46f6578118e02aaf.tar.gz
poi-38deacac7d2ab320487850ba46f6578118e02aaf.zip
Minor improvements to error handling in ForkedEvaluator. Added junits.
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@820479 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationSheet.java6
-rw-r--r--src/testcases/org/apache/poi/ss/formula/AllSSFormulaTests.java7
-rw-r--r--src/testcases/org/apache/poi/ss/formula/eval/forked/TestForkedEvaluator.java118
3 files changed, 129 insertions, 2 deletions
diff --git a/src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationSheet.java b/src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationSheet.java
index c36232a1d8..196bfa69dd 100644
--- a/src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationSheet.java
+++ b/src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationSheet.java
@@ -27,6 +27,7 @@ import org.apache.poi.ss.formula.EvaluationWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.util.CellReference;
/**
* Represents a sheet being used for forked evaluation. Initially, objects of this class contain
@@ -65,6 +66,11 @@ final class ForkedEvaluationSheet implements EvaluationSheet {
ForkedEvaluationCell result = _sharedCellsByRowCol.get(key);
if (result == null) {
EvaluationCell mcell = _masterSheet.getCell(rowIndex, columnIndex);
+ if (mcell == null) {
+ CellReference cr = new CellReference(rowIndex, columnIndex);
+ throw new UnsupportedOperationException("Underlying cell '"
+ + cr.formatAsString() + "' is missing in master sheet.");
+ }
result = new ForkedEvaluationCell(this, mcell);
_sharedCellsByRowCol.put(key, result);
}
diff --git a/src/testcases/org/apache/poi/ss/formula/AllSSFormulaTests.java b/src/testcases/org/apache/poi/ss/formula/AllSSFormulaTests.java
index 13e2cfecdf..970d0f373a 100644
--- a/src/testcases/org/apache/poi/ss/formula/AllSSFormulaTests.java
+++ b/src/testcases/org/apache/poi/ss/formula/AllSSFormulaTests.java
@@ -17,19 +17,22 @@
package org.apache.poi.ss.formula;
+import org.apache.poi.ss.formula.eval.forked.TestForkedEvaluator;
+
import junit.framework.Test;
import junit.framework.TestSuite;
/**
* Test suite for org.apache.poi.ss.formula
- *
+ *
* @author Josh Micich
*/
public final class AllSSFormulaTests {
- public static Test suite() {
+ public static Test suite() {
TestSuite result = new TestSuite(AllSSFormulaTests.class.getName());
result.addTestSuite(TestCellCacheEntry.class);
result.addTestSuite(TestEvaluationCache.class);
result.addTestSuite(TestWorkbookEvaluator.class);
+ result.addTestSuite(TestForkedEvaluator.class);
return result;
}
}
diff --git a/src/testcases/org/apache/poi/ss/formula/eval/forked/TestForkedEvaluator.java b/src/testcases/org/apache/poi/ss/formula/eval/forked/TestForkedEvaluator.java
new file mode 100644
index 0000000000..1e48069828
--- /dev/null
+++ b/src/testcases/org/apache/poi/ss/formula/eval/forked/TestForkedEvaluator.java
@@ -0,0 +1,118 @@
+/* ====================================================================
+ 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.eval.forked;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
+
+import org.apache.poi.hssf.record.formula.eval.NumberEval;
+import org.apache.poi.hssf.usermodel.HSSFRow;
+import org.apache.poi.hssf.usermodel.HSSFSheet;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.formula.IStabilityClassifier;
+
+/**
+ * @author Josh Micich
+ */
+public final class TestForkedEvaluator extends TestCase {
+ /**
+ * set up a calculation workbook with input cells nicely segregated on a
+ * sheet called "Inputs"
+ */
+ private static HSSFWorkbook createWorkbook() {
+ HSSFWorkbook wb = new HSSFWorkbook();
+ HSSFSheet sheet1 = wb.createSheet("Inputs");
+ HSSFSheet sheet2 = wb.createSheet("Calculations");
+ HSSFRow row;
+ row = sheet2.createRow(0);
+ row.createCell(0).setCellFormula("B1*Inputs!A1-Inputs!B1");
+ row.createCell(1).setCellValue(5.0); // Calculations!B1
+
+ // some default input values
+ row = sheet1.createRow(0);
+ row.createCell(0).setCellValue(2.0); // Inputs!A1
+ row.createCell(1).setCellValue(3.0); // Inputs!B1
+ return wb;
+ }
+
+ /**
+ * Shows a basic use-case for {@link ForkedEvaluator}
+ */
+ public void testBasic() {
+ HSSFWorkbook wb = createWorkbook();
+
+ // The stability classifier is useful to reduce memory consumption of caching logic
+ IStabilityClassifier stabilityClassifier = new IStabilityClassifier() {
+ public boolean isCellFinal(int sheetIndex, int rowIndex, int columnIndex) {
+ return sheetIndex == 1;
+ }
+ };
+
+ ForkedEvaluator fe1 = ForkedEvaluator.create(wb, stabilityClassifier, null);
+ ForkedEvaluator fe2 = ForkedEvaluator.create(wb, stabilityClassifier, null);
+
+ // fe1 and fe2 can be used concurrently on separate threads
+
+ fe1.updateCell("Inputs", 0, 0, new NumberEval(4.0));
+ fe1.updateCell("Inputs", 0, 1, new NumberEval(1.1));
+
+ fe2.updateCell("Inputs", 0, 0, new NumberEval(1.2));
+ fe2.updateCell("Inputs", 0, 1, new NumberEval(2.0));
+
+ assertEquals(18.9, ((NumberEval) fe1.evaluate("Calculations", 0, 0)).getNumberValue(), 0.0);
+ assertEquals(4.0, ((NumberEval) fe2.evaluate("Calculations", 0, 0)).getNumberValue(), 0.0);
+ fe1.updateCell("Inputs", 0, 0, new NumberEval(3.0));
+ assertEquals(13.9, ((NumberEval) fe1.evaluate("Calculations", 0, 0)).getNumberValue(), 0.0);
+ }
+
+ /**
+ * As of Sep 2009, the Forked evaluator can update values from existing cells (this is because
+ * the underlying 'master' cell is used as a key into the calculation cache. Prior to the fix
+ * for this bug, an attempt to update a missing cell would result in NPE. This junit tests for
+ * a more meaningful error message.<br/>
+ *
+ * An alternate solution might involve allowing empty cells to be created as necessary. That
+ * was considered less desirable because so far, the underlying 'master' workbook is strictly
+ * <i>read-only</i> with respect to the ForkedEvaluator.
+ */
+ public void testMissingInputCell() {
+ HSSFWorkbook wb = createWorkbook();
+
+ ForkedEvaluator fe = ForkedEvaluator.create(wb, null, null);
+
+ // attempt update input at cell A2 (which is missing)
+ try {
+ fe.updateCell("Inputs", 1, 0, new NumberEval(4.0));
+ throw new AssertionFailedError(
+ "Expected exception to be thrown due to missing input cell");
+ } catch (NullPointerException e) {
+ StackTraceElement[] stes = e.getStackTrace();
+ if (stes[0].getMethodName().equals("getIdentityKey")) {
+ throw new AssertionFailedError("Identified bug with update of missing input cell");
+ }
+ throw e;
+ } catch (UnsupportedOperationException e) {
+ if (e.getMessage().equals(
+ "Underlying cell 'A2' is missing in master sheet.")) {
+ // expected during successful test
+ } else {
+ throw e;
+ }
+ }
+ }
+}