poi-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From j...@apache.org
Subject svn commit: r707942 [2/2] - in /poi/branches/ooxml: ./ src/documentation/content/xdocs/ src/java/org/apache/poi/hssf/record/ src/java/org/apache/poi/hssf/record/formula/ src/java/org/apache/poi/ss/formula/ src/java/org/apache/poi/util/ src/testcases/or...
Date Sun, 26 Oct 2008 06:40:37 GMT
Modified: poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/TestSubRecord.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/TestSubRecord.java?rev=707942&r1=707941&r2=707942&view=diff
==============================================================================
--- poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/TestSubRecord.java (original)
+++ poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/TestSubRecord.java Sat Oct
25 23:40:36 2008
@@ -19,81 +19,94 @@
 package org.apache.poi.hssf.record;
 
 
+import java.util.Arrays;
+
+import junit.framework.AssertionFailedError;
 import junit.framework.TestCase;
 
+import org.apache.poi.util.HexRead;
+
 /**
  * Tests Subrecord components of an OBJ record.  Test data taken directly
  * from a real Excel file.
  *
  * @author Michael Zalewski (zalewski@optonline.net)
  */
-public class TestSubRecord
-        extends TestCase
-{
-    /*
-       The following is a dump of the OBJ record corresponding to an auto-filter
-       drop-down list. The 3rd subrecord beginning at offset 0x002e (type=0x0013)
-       does not conform to the documentation, because the length field is 0x1fee,
-       which is longer than the entire OBJ record.
-
-       00000000 15 00 12 00 14 00 01 00 01 21 00 00 00 00 3C 13 .........!....<.  Type=0x15
Len=0x0012 ftCmo
-       00000010 F4 03 00 00 00 00
-                                  0C 00 14 00 00 00 00 00 00 00 ................  Type=0x0c
Len=0x0014 ftSbs
-       00000020 00 00 00 00 01 00 08 00 00 00 10 00 00 00
-                                                          13 00 ................  Type=0x13
Len=0x1FEE ftLbsData
-       00000030 EE 1F 00 00 08 00 08 00 01 03 00 00 0A 00 14 00 ................
-       00000040 6C 00
-                      00 00 00 00                               l.....            Type=0x00
Len=0x0000 ftEnd
-    */
-
-    byte[] dataAutoFilter = new byte[]{
-        // ftCmo
-        (byte) 0x15, (byte) 0x00, (byte) 0x12, (byte) 0x00, (byte) 0x14, (byte) 0x00, (byte)
0x01, (byte) 0x00
-        , (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x21, (byte) 0x00, (byte) 0x00, (byte)
0x3c, (byte) 0x13
-        , (byte) 0xf4, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00
-
-        // ftSbs (currently UnknownSubrecord)
-        , (byte) 0x0c, (byte) 0x00
-        , (byte) 0x14, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte)
0x00, (byte) 0x00
-        , (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte)
0x08, (byte) 0x00
-        , (byte) 0x00, (byte) 0x00, (byte) 0x10, (byte) 0x00, (byte) 0x00, (byte) 0x00
-
-        // ftLbsData (currently UnknownSubrecord)
-        , (byte) 0x13, (byte) 0x00
-        , (byte) 0xee, (byte) 0x1f, (byte) 0x00, (byte) 0x00, (byte) 0x08, (byte) 0x00, (byte)
0x08, (byte) 0x00
-        , (byte) 0x01, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x0a, (byte) 0x00, (byte)
0x14, (byte) 0x00
-        , (byte) 0x6c, (byte) 0x00
-
-        // ftEnd
-        , (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00
-    };
-
-    public TestSubRecord( String name )
-    {
-        super( name );
-    }
-
-    public void testParseCmo()
-    {
-//jmh        Record r = SubRecord.createSubRecord( (short) 0x0015, (short) 0x0012, dataAutoFilter,
0x0000 );
-//jmh        assertEquals( "ftCmo is 22 bytes", 22, r.getRecordSize() );
-//jmh        assertEquals( "ftCmo is a CommonObjectDataSubRecord"
-//jmh                , "org.apache.poi.hssf.record.CommonObjectDataSubRecord"
-//jmh                , r.getClass().getName() );
-    }
-
-    public void testParseAutoFilterLbsData()
-    {
-//jmh        Record r = SubRecord.createSubRecord( (short) 0x0013, (short) 0x1fee, dataAutoFilter,
0x0032 );
-//jmh        assertEquals( "ftLbsData is 20 bytes", 20, r.getRecordSize() );
-    }
-
-    public void testParseEnd()
-    {
-//jmh        Record r = SubRecord.createSubRecord( (short) 0x0000, (short) 0x0000, dataAutoFilter,
0x0046 );
-//jmh        assertEquals( "ftEnd is 4 bytes", 4, r.getRecordSize() );
-//jmh        assertEquals( "ftEnd is a EndSubRecord"
-//jmh                , "org.apache.poi.hssf.record.EndSubRecord"
-//jmh                , r.getClass().getName() );
-    }
+public final class TestSubRecord extends TestCase {
+	/*
+	   The following is a dump of the OBJ record corresponding to an auto-filter
+	   drop-down list. The 3rd subrecord beginning at offset 0x002e (type=0x0013)
+	   does not conform to the documentation, because the length field is 0x1fee,
+	   which is longer than the entire OBJ record.
+
+	   00000000 15 00 12 00 14 00 01 00 01 21 00 00 00 00 3C 13 .........!....<.  Type=0x15
Len=0x0012 ftCmo
+	   00000010 F4 03 00 00 00 00
+	                              0C 00 14 00 00 00 00 00 00 00 ................  Type=0x0c
Len=0x0014 ftSbs
+	   00000020 00 00 00 00 01 00 08 00 00 00 10 00 00 00
+	                                                      13 00 ................  Type=0x13
Len=0x1FEE ftLbsData
+	   00000030 EE 1F 00 00 08 00 08 00 01 03 00 00 0A 00 14 00 ................
+	   00000040 6C 00
+	                  00 00 00 00                               l.....            Type=0x00
Len=0x0000 ftEnd
+	*/
+
+	private static final byte[] dataAutoFilter 
+		= HexRead.readFromString(""
+			+ "5D 00 46 00 " // ObjRecord.sid, size=70
+			// ftCmo
+			+ "15 00 12 00 "
+			+ "14 00 01 00 01 00 01 21 00 00 3C 13 F4 03 00 00 00 00 "
+			// ftSbs (currently UnknownSubrecord)
+			+ "0C 00 14 00 "
+			+ "00 00 00 00 00 00 00 00 00 00 01 00 08 00 00 00 10 00 00 00 "
+			// ftLbsData (currently UnknownSubrecord)
+			+ "13 00 EE 1F 00 00 "
+			+ "08 00 08 00 01 03 00 00 0A 00 14 00 6C 00 "
+			// ftEnd
+			+ "00 00 00 00"
+		);
+
+
+	/**
+	 * Make sure that ftLbsData (which has abnormal size info) is parsed correctly.
+	 * If the size field is interpreted incorrectly, the resulting ObjRecord becomes way too
big.
+	 * At the time of fixing (Oct-2008 svn r707447) {@link RecordInputStream} allowed  buffer

+	 * read overruns, so the bug was mostly silent.
+	 */
+	public void testReadAll_bug45778() {
+		RecordInputStream in = TestcaseRecordInputStream.create(dataAutoFilter);
+		ObjRecord or = new ObjRecord(in);
+		byte[] data2 = or.serialize();
+		if (data2.length == 8228) {
+			throw new AssertionFailedError("Identified bug 45778");
+		}
+		assertEquals(74, data2.length);
+		assertTrue(Arrays.equals(dataAutoFilter, data2));
+	}
+	
+	public void testReadManualComboWithFormula() {
+		byte[] data = HexRead.readFromString(""
+   			+ "5D 00 66 00 "
+   			+ "15 00 12 00 14 00 02 00 11 20 00 00 00 00 "
+   			+ "20 44 C6 04 00 00 00 00 0C 00 14 00 04 F0 C6 04 "
+   			+ "00 00 00 00 00 00 01 00 06 00 00 00 10 00 00 00 "
+   			+ "0E 00 0C 00 05 00 80 44 C6 04 24 09 00 02 00 02 "
+   			+ "13 00 DE 1F 10 00 09 00 80 44 C6 04 25 0A 00 0F "
+   			+ "00 02 00 02 00 02 06 00 03 00 08 00 00 00 00 00 "
+   			+ "08 00 00 00 00 00 00 00 " // TODO sometimes last byte is non-zero
+   		);
+		
+		RecordInputStream in = TestcaseRecordInputStream.create(data);
+		ObjRecord or = new ObjRecord(in);
+		byte[] data2 = or.serialize();
+		if (data2.length == 8228) {
+			throw new AssertionFailedError("Identified bug XXXXX");
+		}
+		assertEquals("Encoded length", data.length, data2.length);
+		for (int i = 0; i < data.length; i++) {
+			if (data[i] != data2[i]) {
+				throw new AssertionFailedError("Encoded data differs at index " + i);
+			}
+		}
+		assertTrue(Arrays.equals(data, data2));
+	}
 }

Modified: poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/AllFormulaTests.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/AllFormulaTests.java?rev=707942&r1=707941&r2=707942&view=diff
==============================================================================
--- poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/AllFormulaTests.java
(original)
+++ poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/AllFormulaTests.java
Sat Oct 25 23:40:36 2008
@@ -41,6 +41,7 @@
 		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);

Modified: poi/branches/ooxml/src/testcases/org/apache/poi/ss/formula/EvaluationListener.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/testcases/org/apache/poi/ss/formula/EvaluationListener.java?rev=707942&r1=707941&r2=707942&view=diff
==============================================================================
--- poi/branches/ooxml/src/testcases/org/apache/poi/ss/formula/EvaluationListener.java (original)
+++ poi/branches/ooxml/src/testcases/org/apache/poi/ss/formula/EvaluationListener.java Sat
Oct 25 23:40:36 2008
@@ -19,7 +19,6 @@
 
 import org.apache.poi.hssf.record.formula.Ptg;
 import org.apache.poi.hssf.record.formula.eval.ValueEval;
-import org.apache.poi.hssf.usermodel.HSSFCell;
 
 /**
  * Tests should extend this class if they need to track the internal working of the {@link
WorkbookEvaluator}.<br/>
@@ -47,6 +46,10 @@
 	public void onClearCachedValue(ICacheEntry entry) {
 		// do nothing 
 	}
+	public void onChangeFromBlankValue(int sheetIndex, int rowIndex, int columnIndex,
+			EvaluationCell cell, ICacheEntry entry) {
+		// do nothing 
+	}
 	public void sortDependentCachedValues(ICacheEntry[] entries) {
 		// do nothing 
 	}

Modified: poi/branches/ooxml/src/testcases/org/apache/poi/ss/formula/TestEvaluationCache.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/testcases/org/apache/poi/ss/formula/TestEvaluationCache.java?rev=707942&r1=707941&r2=707942&view=diff
==============================================================================
--- poi/branches/ooxml/src/testcases/org/apache/poi/ss/formula/TestEvaluationCache.java (original)
+++ poi/branches/ooxml/src/testcases/org/apache/poi/ss/formula/TestEvaluationCache.java Sat
Oct 25 23:40:36 2008
@@ -38,11 +38,13 @@
 import org.apache.poi.hssf.record.formula.eval.ValueEval;
 import org.apache.poi.hssf.usermodel.HSSFCell;
 import org.apache.poi.hssf.usermodel.HSSFEvaluationTestHelper;
+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.util.CellReference;
 import org.apache.poi.ss.formula.PlainCellCache.Loc;
+import org.apache.poi.ss.usermodel.CellValue;
 
 /**
  * Tests {@link EvaluationCache}.  Makes sure that where possible (previously calculated)
cached 
@@ -134,7 +136,19 @@
 		}
 		public void onClearDependentCachedValue(ICacheEntry entry, int depth) {
 			EvaluationCell cell = (EvaluationCell) _formulaCellsByCacheEntry.get(entry);
-   			log("clear" + depth, cell.getRowIndex(), cell.getColumnIndex(),  entry.getValue());
+			log("clear" + depth, cell.getRowIndex(), cell.getColumnIndex(), entry.getValue());
+		}
+
+		public void onChangeFromBlankValue(int sheetIndex, int rowIndex, int columnIndex,
+				EvaluationCell cell, ICacheEntry entry) {
+			log("changeFromBlank", rowIndex, columnIndex, entry.getValue());
+			if (entry.getValue() == null) { // hack to tell the difference between formula and plain
value
+				// perhaps the API could be improved: onChangeFromBlankToValue, onChangeFromBlankToFormula
+				_formulaCellsByCacheEntry.put(entry, cell);
+			} else {
+				Loc loc = new Loc(0, sheetIndex, rowIndex, columnIndex);
+				_plainCellLocsByCacheEntry.put(entry, loc);
+			}
 		}
 		private void log(String tag, int rowIndex, int columnIndex, Object value) {
 			StringBuffer sb = new StringBuffer(64);
@@ -213,6 +227,11 @@
 			cell.setCellValue(value);
 			_evaluator.notifyUpdateCell(wrapCell(cell));
 		}
+		public void clearCell(String cellRefText) {
+			HSSFCell cell = getOrCreateCell(cellRefText);
+			cell.setCellType(HSSFCell.CELL_TYPE_BLANK);
+			_evaluator.notifyUpdateCell(wrapCell(cell));
+		}
 
 		public void setCellFormula(String cellRefText, String formulaText) {
 			HSSFCell cell = getOrCreateCell(cellRefText);
@@ -555,6 +574,75 @@
 		});
 	}
 	
+	/**
+	 * Make sure that when blank cells are changed to value/formula cells, any dependent formulas
+	 * have their cached results cleared.
+	 */
+	public void testBlankCellChangedToValueCell_bug46053() {
+		HSSFWorkbook wb = new HSSFWorkbook();
+		HSSFSheet sheet = wb.createSheet("Sheet1");
+		HSSFRow row = sheet.createRow(0);
+		HSSFCell cellA1 = row.createCell(0);
+		HSSFCell cellB1 = row.createCell(1);
+		HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
+
+		cellA1.setCellFormula("B1+2.2");
+		cellB1.setCellValue(1.5);
+
+		fe.notifyUpdateCell(cellA1);
+		fe.notifyUpdateCell(cellB1);
+
+		CellValue cv;
+		cv = fe.evaluate(cellA1);
+		assertEquals(3.7, cv.getNumberValue(), 0.0);
+
+		cellB1.setCellType(HSSFCell.CELL_TYPE_BLANK);
+		fe.notifyUpdateCell(cellB1);
+		cv = fe.evaluate(cellA1); // B1 was used to evaluate A1
+		assertEquals(2.2, cv.getNumberValue(), 0.0);
+
+		cellB1.setCellValue(0.4);  // changing B1, so A1 cached result should be cleared 
+		fe.notifyUpdateCell(cellB1);
+		cv = fe.evaluate(cellA1);
+		if (cv.getNumberValue() == 2.2) {
+			// looks like left-over cached result from before change to B1
+			throw new AssertionFailedError("Identified bug 46053");
+		}
+		assertEquals(2.6, cv.getNumberValue(), 0.0);
+	}
+	
+	/**
+	 * same use-case as the test for bug 46053, but checking trace values too
+	 */
+	public void testBlankCellChangedToValueCell() {
+
+		MySheet ms = new MySheet();
+
+		ms.setCellFormula("A1", "B1+2.2");
+		ms.setCellValue("B1", 1.5);
+		ms.clearAllCachedResultValues();
+		ms.clearCell("B1");
+		ms.getAndClearLog();
+
+		confirmEvaluate(ms, "A1", 2.2);
+		confirmLog(ms, new String[] {
+			"start A1 B1+2.2",
+			"end A1 2.2",
+		});
+		ms.setCellValue("B1", 0.4);
+		confirmLog(ms, new String[] {
+			"changeFromBlank B1 0.4",
+			"clear A1",
+		});
+
+		confirmEvaluate(ms, "A1", 2.6);
+		confirmLog(ms, new String[] {
+			"start A1 B1+2.2",
+			"hit B1 0.4",
+			"end A1 2.6",
+		});
+	}
+	
 	private static void confirmEvaluate(MySheet ms, String cellRefText, double expectedValue)
{
 		ValueEval v = ms.evaluateCell(cellRefText);
 		assertEquals(NumberEval.class, v.getClass());



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


Mime
View raw message