aboutsummaryrefslogtreecommitdiffstats
path: root/src/testcases/org
diff options
context:
space:
mode:
authorJosh Micich <josh@apache.org>2008-10-26 06:40:36 +0000
committerJosh Micich <josh@apache.org>2008-10-26 06:40:36 +0000
commit063dd2ad03e30263b45167615cddb69dd9189584 (patch)
tree8ecbe039c21e44bac69636eb51d30b4efe7bec22 /src/testcases/org
parentacfcbeb3c568b596bd052edca73d448e2f9b5b3d (diff)
downloadpoi-063dd2ad03e30263b45167615cddb69dd9189584.tar.gz
poi-063dd2ad03e30263b45167615cddb69dd9189584.zip
Merged revisions 706772,707450,707481 via svnmerge from
https://svn.apache.org/repos/asf/poi/trunk ........ r706772 | josh | 2008-10-21 14:25:50 -0700 (Tue, 21 Oct 2008) | 1 line Fix for bug 46053 - fixed evaluation cache dependency analysis when changing blank cells ........ r707450 | josh | 2008-10-23 12:08:42 -0700 (Thu, 23 Oct 2008) | 1 line Fix for bug 45778 - made ObjRecord read sub-record ftLbsData properly ........ r707481 | josh | 2008-10-23 14:42:05 -0700 (Thu, 23 Oct 2008) | 1 line fixed re-serialization of tAttrChoose ........ git-svn-id: https://svn.apache.org/repos/asf/poi/branches/ooxml@707942 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/testcases/org')
-rw-r--r--src/testcases/org/apache/poi/hssf/record/TestCommonObjectDataSubRecord.java80
-rw-r--r--src/testcases/org/apache/poi/hssf/record/TestEmbeddedObjectRefSubRecord.java10
-rw-r--r--src/testcases/org/apache/poi/hssf/record/TestEndSubRecord.java9
-rw-r--r--src/testcases/org/apache/poi/hssf/record/TestNoteStructureSubRecord.java8
-rw-r--r--src/testcases/org/apache/poi/hssf/record/TestObjRecord.java10
-rw-r--r--src/testcases/org/apache/poi/hssf/record/TestSubRecord.java151
-rw-r--r--src/testcases/org/apache/poi/hssf/record/formula/AllFormulaTests.java1
-rw-r--r--src/testcases/org/apache/poi/hssf/record/formula/TestAttrPtg.java50
-rw-r--r--src/testcases/org/apache/poi/ss/formula/EvaluationListener.java5
-rw-r--r--src/testcases/org/apache/poi/ss/formula/TestEvaluationCache.java90
-rw-r--r--src/testcases/org/apache/poi/util/TestLittleEndianStreams.java53
11 files changed, 335 insertions, 132 deletions
diff --git a/src/testcases/org/apache/poi/hssf/record/TestCommonObjectDataSubRecord.java b/src/testcases/org/apache/poi/hssf/record/TestCommonObjectDataSubRecord.java
index ad629c3f17..53a49fda0d 100644
--- a/src/testcases/org/apache/poi/hssf/record/TestCommonObjectDataSubRecord.java
+++ b/src/testcases/org/apache/poi/hssf/record/TestCommonObjectDataSubRecord.java
@@ -21,56 +21,54 @@ package org.apache.poi.hssf.record;
import junit.framework.TestCase;
/**
- * Tests the serialization and deserialization of the CommonObjectDataSubRecord
+ * Tests the serialization and deserialization of the {@link CommonObjectDataSubRecord}
* class works correctly. Test data taken directly from a real
* Excel file.
*
-
* @author Glen Stampoultzis (glens at apache.org)
*/
public final class TestCommonObjectDataSubRecord extends TestCase {
- byte[] data = new byte[] {
- (byte)0x12,(byte)0x00,(byte)0x01,(byte)0x00,
- (byte)0x01,(byte)0x00,(byte)0x11,(byte)0x60,
- (byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,
- (byte)0x00,(byte)0x0D,(byte)0x26,(byte)0x01,
- (byte)0x00,(byte)0x00,
- };
+ byte[] data = new byte[] {
+ (byte)0x12,(byte)0x00,(byte)0x01,(byte)0x00,
+ (byte)0x01,(byte)0x00,(byte)0x11,(byte)0x60,
+ (byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,
+ (byte)0x00,(byte)0x0D,(byte)0x26,(byte)0x01,
+ (byte)0x00,(byte)0x00,
+ };
- public void testLoad() {
- CommonObjectDataSubRecord record = new CommonObjectDataSubRecord(TestcaseRecordInputStream.create(0x15, data));
+ public void testLoad() {
+ CommonObjectDataSubRecord record = new CommonObjectDataSubRecord(TestcaseRecordInputStream.createWithFakeSid(data), data.length);
- assertEquals( CommonObjectDataSubRecord.OBJECT_TYPE_LIST_BOX, record.getObjectType());
- assertEquals( (short)1, record.getObjectId());
- assertEquals( (short)1, record.getOption());
- assertEquals( true , record.isLocked() );
- assertEquals( false, record.isPrintable() );
- assertEquals( false, record.isAutofill() );
- assertEquals( false, record.isAutoline() );
- assertEquals( (int)24593, record.getReserved1());
- assertEquals( (int)218103808, record.getReserved2());
- assertEquals( (int)294, record.getReserved3());
- assertEquals( 22 , record.getRecordSize() );
- }
+ assertEquals( CommonObjectDataSubRecord.OBJECT_TYPE_LIST_BOX, record.getObjectType());
+ assertEquals((short) 1, record.getObjectId());
+ assertEquals((short) 1, record.getOption());
+ assertEquals(true, record.isLocked());
+ assertEquals(false, record.isPrintable());
+ assertEquals(false, record.isAutofill());
+ assertEquals(false, record.isAutoline());
+ assertEquals(24593, record.getReserved1());
+ assertEquals(218103808, record.getReserved2());
+ assertEquals(294, record.getReserved3());
+ assertEquals(18, record.getDataSize());
+ }
- public void testStore()
- {
- CommonObjectDataSubRecord record = new CommonObjectDataSubRecord();
+ public void testStore() {
+ CommonObjectDataSubRecord record = new CommonObjectDataSubRecord();
- record.setObjectType( CommonObjectDataSubRecord.OBJECT_TYPE_LIST_BOX );
- record.setObjectId( (short) 1);
- record.setOption( (short) 1);
- record.setLocked( true );
- record.setPrintable( false );
- record.setAutofill( false );
- record.setAutoline( false );
- record.setReserved1( (int) 24593);
- record.setReserved2( (int) 218103808);
- record.setReserved3( (int) 294);
+ record.setObjectType(CommonObjectDataSubRecord.OBJECT_TYPE_LIST_BOX);
+ record.setObjectId((short) 1);
+ record.setOption((short) 1);
+ record.setLocked(true);
+ record.setPrintable(false);
+ record.setAutofill(false);
+ record.setAutoline(false);
+ record.setReserved1(24593);
+ record.setReserved2(218103808);
+ record.setReserved3(294);
- byte [] recordBytes = record.serialize();
- assertEquals(recordBytes.length - 4, data.length);
- for (int i = 0; i < data.length; i++)
- assertEquals("At offset " + i, data[i], recordBytes[i+4]);
- }
+ byte [] recordBytes = record.serialize();
+ assertEquals(recordBytes.length - 4, data.length);
+ for (int i = 0; i < data.length; i++)
+ assertEquals("At offset " + i, data[i], recordBytes[i+4]);
+ }
}
diff --git a/src/testcases/org/apache/poi/hssf/record/TestEmbeddedObjectRefSubRecord.java b/src/testcases/org/apache/poi/hssf/record/TestEmbeddedObjectRefSubRecord.java
index bf8da6fece..deaf779bbb 100644
--- a/src/testcases/org/apache/poi/hssf/record/TestEmbeddedObjectRefSubRecord.java
+++ b/src/testcases/org/apache/poi/hssf/record/TestEmbeddedObjectRefSubRecord.java
@@ -42,13 +42,13 @@ public final class TestEmbeddedObjectRefSubRecord extends TestCase {
RecordInputStream in = new RecordInputStream(new ByteArrayInputStream(src));
in.nextRecord();
- EmbeddedObjectRefSubRecord record1 = new EmbeddedObjectRefSubRecord(in);
+ EmbeddedObjectRefSubRecord record1 = new EmbeddedObjectRefSubRecord(in, src.length-4);
byte[] ser = record1.serialize();
RecordInputStream in2 = new RecordInputStream(new ByteArrayInputStream(ser));
in2.nextRecord();
- EmbeddedObjectRefSubRecord record2 = new EmbeddedObjectRefSubRecord(in2);
+ EmbeddedObjectRefSubRecord record2 = new EmbeddedObjectRefSubRecord(in2, ser.length-4);
assertTrue(Arrays.equals(src, ser));
assertEquals(record1.getOLEClassName(), record2.getOLEClassName());
@@ -64,7 +64,7 @@ public final class TestEmbeddedObjectRefSubRecord extends TestCase {
byte[] ser = record1.serialize();
RecordInputStream in2 = new RecordInputStream(new ByteArrayInputStream(ser));
in2.nextRecord();
- EmbeddedObjectRefSubRecord record2 = new EmbeddedObjectRefSubRecord(in2);
+ EmbeddedObjectRefSubRecord record2 = new EmbeddedObjectRefSubRecord(in2, ser.length-4);
assertEquals(record1.getOLEClassName(), record2.getOLEClassName());
assertEquals(record1.getStreamId(), record2.getStreamId());
@@ -88,7 +88,7 @@ public final class TestEmbeddedObjectRefSubRecord extends TestCase {
RecordInputStream in = new RecordInputStream(new ByteArrayInputStream(data));
in.nextRecord();
- EmbeddedObjectRefSubRecord rec = new EmbeddedObjectRefSubRecord(in);
+ EmbeddedObjectRefSubRecord rec = new EmbeddedObjectRefSubRecord(in, data.length-4);
byte[] ser2 = rec.serialize();
assertTrue(Arrays.equals(data, ser2));
@@ -129,7 +129,7 @@ public final class TestEmbeddedObjectRefSubRecord extends TestCase {
private static void confirmRead(byte[] data, int i) {
RecordInputStream in = TestcaseRecordInputStream.create(EmbeddedObjectRefSubRecord.sid, data);
- EmbeddedObjectRefSubRecord rec = new EmbeddedObjectRefSubRecord(in);
+ EmbeddedObjectRefSubRecord rec = new EmbeddedObjectRefSubRecord(in, data.length);
byte[] ser2 = rec.serialize();
byte[] d2 = (byte[]) data.clone(); // remove sid+len for compare
System.arraycopy(ser2, 4, d2, 0, d2.length);
diff --git a/src/testcases/org/apache/poi/hssf/record/TestEndSubRecord.java b/src/testcases/org/apache/poi/hssf/record/TestEndSubRecord.java
index d16c227149..ab4a80120f 100644
--- a/src/testcases/org/apache/poi/hssf/record/TestEndSubRecord.java
+++ b/src/testcases/org/apache/poi/hssf/record/TestEndSubRecord.java
@@ -28,14 +28,11 @@ import junit.framework.TestCase;
* @author Glen Stampoultzis (glens at apache.org)
*/
public final class TestEndSubRecord extends TestCase {
- byte[] data = new byte[] {
-
- };
+ private static final byte[] data = { };
public void testLoad() {
- EndSubRecord record = new EndSubRecord(TestcaseRecordInputStream.create(0x00, data));
-
- assertEquals( 4, record.getRecordSize() );
+ EndSubRecord record = new EndSubRecord(TestcaseRecordInputStream.create(0x00, data), 0);
+ assertEquals(0, record.getDataSize());
}
public void testStore()
diff --git a/src/testcases/org/apache/poi/hssf/record/TestNoteStructureSubRecord.java b/src/testcases/org/apache/poi/hssf/record/TestNoteStructureSubRecord.java
index fd2ae059b7..ff93c90c24 100644
--- a/src/testcases/org/apache/poi/hssf/record/TestNoteStructureSubRecord.java
+++ b/src/testcases/org/apache/poi/hssf/record/TestNoteStructureSubRecord.java
@@ -38,16 +38,16 @@ public final class TestNoteStructureSubRecord extends TestCase {
public void testRead() {
- NoteStructureSubRecord record = new NoteStructureSubRecord(TestcaseRecordInputStream.create(NoteStructureSubRecord.sid, data));
+ NoteStructureSubRecord record = new NoteStructureSubRecord(TestcaseRecordInputStream.create(NoteStructureSubRecord.sid, data), data.length);
assertEquals(NoteStructureSubRecord.sid, record.getSid());
- assertEquals(data.length + 4, record.getRecordSize());
+ assertEquals(data.length, record.getDataSize());
}
public void testWrite() {
NoteStructureSubRecord record = new NoteStructureSubRecord();
assertEquals(NoteStructureSubRecord.sid, record.getSid());
- assertEquals(data.length + 4, record.getRecordSize());
+ assertEquals(data.length, record.getDataSize());
byte [] ser = record.serialize();
assertEquals(ser.length - 4, data.length);
@@ -62,7 +62,7 @@ public final class TestNoteStructureSubRecord extends TestCase {
NoteStructureSubRecord cloned = (NoteStructureSubRecord)record.clone();
byte[] cln = cloned.serialize();
- assertEquals(record.getRecordSize(), cloned.getRecordSize());
+ assertEquals(record.getDataSize(), cloned.getDataSize());
assertTrue(Arrays.equals(src, cln));
}
}
diff --git a/src/testcases/org/apache/poi/hssf/record/TestObjRecord.java b/src/testcases/org/apache/poi/hssf/record/TestObjRecord.java
index df26797807..c143120de8 100644
--- a/src/testcases/org/apache/poi/hssf/record/TestObjRecord.java
+++ b/src/testcases/org/apache/poi/hssf/record/TestObjRecord.java
@@ -41,19 +41,19 @@ public final class TestObjRecord extends TestCase {
private static final byte[] recdata = {
0x15, 0x00, 0x12, 0x00, 0x06, 0x00, 0x01, 0x00, 0x11, 0x60,
(byte)0xF4, 0x02, 0x41, 0x01, 0x14, 0x10, 0x1F, 0x02, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// TODO - this data seems to require two extra bytes padding. not sure where original file is.
// it's not bug 38607 attachment 17639
};
private static final byte[] recdataNeedingPadding = {
- 21, 0, 18, 0, 0, 0, 1, 0, 17, 96, 0, 0, 0, 0, 56, 111, -52, 3, 0, 0, 0, 0, 6, 0, 2, 0, 0, 0, 0, 0, 0, 0
+ 21, 0, 18, 0, 0, 0, 1, 0, 17, 96, 0, 0, 0, 0, 56, 111, -52, 3, 0, 0, 0, 0, 6, 0, 2, 0, 0, 0, 0, 0, 0, 0
};
public void testLoad() {
ObjRecord record = new ObjRecord(TestcaseRecordInputStream.create(ObjRecord.sid, recdata));
- assertEquals(28, record.getRecordSize() - 4);
+ assertEquals(26, record.getRecordSize() - 4);
List subrecords = record.getSubRecords();
assertEquals(2, subrecords.size() );
@@ -66,7 +66,7 @@ public final class TestObjRecord extends TestCase {
ObjRecord record = new ObjRecord(TestcaseRecordInputStream.create(ObjRecord.sid, recdata));
byte [] recordBytes = record.serialize();
- assertEquals(28, recordBytes.length - 4);
+ assertEquals(26, recordBytes.length - 4);
byte[] subData = new byte[recdata.length];
System.arraycopy(recordBytes, 4, subData, 0, subData.length);
assertTrue(Arrays.equals(recdata, subData));
@@ -102,7 +102,7 @@ public final class TestObjRecord extends TestCase {
ObjRecord record = new ObjRecord(TestcaseRecordInputStream.create(ObjRecord.sid, recdataNeedingPadding));
if (record.getRecordSize() == 34) {
- throw new AssertionFailedError("Identified bug 45133");
+ throw new AssertionFailedError("Identified bug 45133");
}
assertEquals(36, record.getRecordSize());
diff --git a/src/testcases/org/apache/poi/hssf/record/TestSubRecord.java b/src/testcases/org/apache/poi/hssf/record/TestSubRecord.java
index f8060b149a..9d0edd1c14 100644
--- a/src/testcases/org/apache/poi/hssf/record/TestSubRecord.java
+++ b/src/testcases/org/apache/poi/hssf/record/TestSubRecord.java
@@ -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));
+ }
}
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 5f63f31a0b..248f7ca59d 100644
--- a/src/testcases/org/apache/poi/hssf/record/formula/AllFormulaTests.java
+++ b/src/testcases/org/apache/poi/hssf/record/formula/AllFormulaTests.java
@@ -41,6 +41,7 @@ public final class AllFormulaTests {
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);
diff --git a/src/testcases/org/apache/poi/hssf/record/formula/TestAttrPtg.java b/src/testcases/org/apache/poi/hssf/record/formula/TestAttrPtg.java
new file mode 100644
index 0000000000..d9342d61c0
--- /dev/null
+++ b/src/testcases/org/apache/poi/hssf/record/formula/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.hssf.record.formula;
+
+import java.util.Arrays;
+
+import junit.framework.AssertionFailedError;
+
+import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.hssf.record.TestcaseRecordInputStream;
+import org.apache.poi.util.HexRead;
+
+/**
+ * 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");
+ RecordInputStream in = TestcaseRecordInputStream.createWithFakeSid(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/EvaluationListener.java b/src/testcases/org/apache/poi/ss/formula/EvaluationListener.java
index 46bb061722..1158c73b22 100644
--- a/src/testcases/org/apache/poi/ss/formula/EvaluationListener.java
+++ b/src/testcases/org/apache/poi/ss/formula/EvaluationListener.java
@@ -19,7 +19,6 @@ package org.apache.poi.ss.formula;
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 abstract class EvaluationListener implements IEvaluationListener {
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
}
diff --git a/src/testcases/org/apache/poi/ss/formula/TestEvaluationCache.java b/src/testcases/org/apache/poi/ss/formula/TestEvaluationCache.java
index 068c97a255..d42bfacd2d 100644
--- a/src/testcases/org/apache/poi/ss/formula/TestEvaluationCache.java
+++ b/src/testcases/org/apache/poi/ss/formula/TestEvaluationCache.java
@@ -38,11 +38,13 @@ import org.apache.poi.hssf.record.formula.eval.StringEval;
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 class TestEvaluationCache extends TestCase {
}
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 @@ public class TestEvaluationCache extends TestCase {
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 @@ public class TestEvaluationCache extends TestCase {
});
}
+ /**
+ * 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());
diff --git a/src/testcases/org/apache/poi/util/TestLittleEndianStreams.java b/src/testcases/org/apache/poi/util/TestLittleEndianStreams.java
new file mode 100644
index 0000000000..b8fdf7a9d4
--- /dev/null
+++ b/src/testcases/org/apache/poi/util/TestLittleEndianStreams.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.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+
+import junit.framework.TestCase;
+
+/**
+ * Class to test {@link LittleEndianInputStream} and {@link LittleEndianOutputStream}
+ *
+ * @author Josh Micich
+ */
+public final class TestLittleEndianStreams extends TestCase {
+
+ public void testRead() {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ LittleEndianOutput leo = new LittleEndianOutputStream(baos);
+ leo.writeInt(12345678);
+ leo.writeShort(12345);
+ leo.writeByte(123);
+ leo.writeShort(40000);
+ leo.writeByte(200);
+ leo.writeLong(1234567890123456789L);
+ leo.writeDouble(123.456);
+
+ LittleEndianInput lei = new LittleEndianInputStream(new ByteArrayInputStream(baos.toByteArray()));
+
+ assertEquals(12345678, lei.readInt());
+ assertEquals(12345, lei.readShort());
+ assertEquals(123, lei.readByte());
+ assertEquals(40000, lei.readUShort());
+ assertEquals(200, lei.readUByte());
+ assertEquals(1234567890123456789L, lei.readLong());
+ assertEquals(123.456, lei.readDouble(), 0.0);
+ }
+}