Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

TestDataValidation.java 7.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /* ====================================================================
  2. Licensed to the Apache Software Foundation (ASF) under one or more
  3. contributor license agreements. See the NOTICE file distributed with
  4. this work for additional information regarding copyright ownership.
  5. The ASF licenses this file to You under the Apache License, Version 2.0
  6. (the "License"); you may not use this file except in compliance with
  7. the License. You may obtain a copy of the License at
  8. http://www.apache.org/licenses/LICENSE-2.0
  9. Unless required by applicable law or agreed to in writing, software
  10. distributed under the License is distributed on an "AS IS" BASIS,
  11. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. See the License for the specific language governing permissions and
  13. limitations under the License.
  14. ==================================================================== */
  15. package org.apache.poi.hssf.usermodel;
  16. import java.io.ByteArrayInputStream;
  17. import java.io.ByteArrayOutputStream;
  18. import java.io.File;
  19. import java.io.FileOutputStream;
  20. import java.io.IOException;
  21. import java.io.InputStream;
  22. import java.io.PrintStream;
  23. import junit.framework.AssertionFailedError;
  24. import junit.framework.TestCase;
  25. import org.apache.poi.hssf.HSSFITestDataProvider;
  26. import org.apache.poi.hssf.HSSFTestDataSamples;
  27. import org.apache.poi.hssf.eventmodel.ERFListener;
  28. import org.apache.poi.hssf.eventmodel.EventRecordFactory;
  29. import org.apache.poi.hssf.record.DVRecord;
  30. import org.apache.poi.hssf.record.RecordFormatException;
  31. import org.apache.poi.hssf.util.HSSFColor;
  32. import org.apache.poi.poifs.filesystem.POIFSFileSystem;
  33. import org.apache.poi.ss.usermodel.*;
  34. import org.apache.poi.ss.util.CellRangeAddress;
  35. import org.apache.poi.ss.util.CellRangeAddressList;
  36. /**
  37. * Class for testing Excel's data validation mechanism
  38. *
  39. * @author Dragos Buleandra ( dragos.buleandra@trade2b.ro )
  40. */
  41. public final class TestDataValidation extends BaseTestDataValidation {
  42. public TestDataValidation(){
  43. super(HSSFITestDataProvider.instance);
  44. }
  45. public void assertDataValidation(Workbook wb) {
  46. ByteArrayOutputStream baos = new ByteArrayOutputStream(22000);
  47. try {
  48. wb.write(baos);
  49. baos.close();
  50. } catch (IOException e) {
  51. throw new RuntimeException(e);
  52. }
  53. byte[] generatedContent = baos.toByteArray();
  54. boolean isSame;
  55. if (false) {
  56. // TODO - add proof spreadsheet and compare
  57. InputStream proofStream = HSSFTestDataSamples.openSampleFileStream("TestDataValidation.xls");
  58. isSame = compareStreams(proofStream, generatedContent);
  59. }
  60. isSame = true;
  61. if (isSame) {
  62. return;
  63. }
  64. File tempDir = new File(System.getProperty("java.io.tmpdir"));
  65. File generatedFile = new File(tempDir, "GeneratedTestDataValidation.xls");
  66. try {
  67. FileOutputStream fileOut = new FileOutputStream(generatedFile);
  68. fileOut.write(generatedContent);
  69. fileOut.close();
  70. } catch (IOException e) {
  71. throw new RuntimeException(e);
  72. }
  73. PrintStream ps = System.out;
  74. ps.println("This test case has failed because the generated file differs from proof copy '"
  75. ); // TODO+ proofFile.getAbsolutePath() + "'.");
  76. ps.println("The cause is usually a change to this test, or some common spreadsheet generation code. "
  77. + "The developer has to decide whether the changes were wanted or unwanted.");
  78. ps.println("If the changes to the generated version were unwanted, "
  79. + "make the fix elsewhere (do not modify this test or the proof spreadsheet to get the test working).");
  80. ps.println("If the changes were wanted, make sure to open the newly generated file in Excel "
  81. + "and verify it manually. The new proof file should be submitted after it is verified to be correct.");
  82. ps.println("");
  83. ps.println("One other possible (but less likely) cause of a failed test is a problem in the "
  84. + "comparison logic used here. Perhaps some extra file regions need to be ignored.");
  85. ps.println("The generated file has been saved to '" + generatedFile.getAbsolutePath() + "' for manual inspection.");
  86. fail("Generated file differs from proof copy. See sysout comments for details on how to fix.");
  87. }
  88. private static boolean compareStreams(InputStream isA, byte[] generatedContent) {
  89. InputStream isB = new ByteArrayInputStream(generatedContent);
  90. // The allowable regions where the generated file can differ from the
  91. // proof should be small (i.e. much less than 1K)
  92. int[] allowableDifferenceRegions = {
  93. 0x0228, 16, // a region of the file containing the OS username
  94. 0x506C, 8, // See RootProperty (super fields _seconds_2 and _days_2)
  95. };
  96. int[] diffs = StreamUtility.diffStreams(isA, isB, allowableDifferenceRegions);
  97. if (diffs == null) {
  98. return true;
  99. }
  100. System.err.println("Diff from proof: ");
  101. for (int i = 0; i < diffs.length; i++) {
  102. System.err.println("diff at offset: 0x" + Integer.toHexString(diffs[i]));
  103. }
  104. return false;
  105. }
  106. /* package */ static void setCellValue(HSSFCell cell, String text) {
  107. cell.setCellValue(new HSSFRichTextString(text));
  108. }
  109. public void testAddToExistingSheet() {
  110. // dvEmpty.xls is a simple one sheet workbook. With a DataValidations header record but no
  111. // DataValidations. It's important that the example has one SHEETPROTECTION record.
  112. // Such a workbook can be created in Excel (2007) by adding datavalidation for one cell
  113. // and then deleting the row that contains the cell.
  114. HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("dvEmpty.xls");
  115. int dvRow = 0;
  116. Sheet sheet = wb.getSheetAt(0);
  117. DataValidationHelper dataValidationHelper = sheet.getDataValidationHelper();
  118. DataValidationConstraint dc = dataValidationHelper.createIntegerConstraint(OP.EQUAL, "42", null);
  119. DataValidation dv = dataValidationHelper.createValidation(dc,new CellRangeAddressList(dvRow, dvRow, 0, 0));
  120. dv.setEmptyCellAllowed(false);
  121. dv.setErrorStyle(ES.STOP);
  122. dv.setShowPromptBox(true);
  123. dv.createErrorBox("Xxx", "Yyy");
  124. dv.setSuppressDropDownArrow(true);
  125. sheet.addValidationData(dv);
  126. ByteArrayOutputStream baos = new ByteArrayOutputStream();
  127. try {
  128. wb.write(baos);
  129. } catch (IOException e) {
  130. throw new RuntimeException(e);
  131. }
  132. byte[] wbData = baos.toByteArray();
  133. if (false) { // TODO (Jul 2008) fix EventRecordFactory to process unknown records, (and DV records for that matter)
  134. ERFListener erfListener = null; // new MyERFListener();
  135. EventRecordFactory erf = new EventRecordFactory(erfListener, null);
  136. try {
  137. POIFSFileSystem fs = new POIFSFileSystem(new ByteArrayInputStream(baos.toByteArray()));
  138. erf.processRecords(fs.createDocumentInputStream("Workbook"));
  139. } catch (RecordFormatException e) {
  140. throw new RuntimeException(e);
  141. } catch (IOException e) {
  142. throw new RuntimeException(e);
  143. }
  144. }
  145. // else verify record ordering by navigating the raw bytes
  146. byte[] dvHeaderRecStart= { (byte)0xB2, 0x01, 0x12, 0x00, };
  147. int dvHeaderOffset = findIndex(wbData, dvHeaderRecStart);
  148. assertTrue(dvHeaderOffset > 0);
  149. int nextRecIndex = dvHeaderOffset + 22;
  150. int nextSid
  151. = ((wbData[nextRecIndex + 0] << 0) & 0x00FF)
  152. + ((wbData[nextRecIndex + 1] << 8) & 0xFF00)
  153. ;
  154. // nextSid should be for a DVRecord. If anything comes between the DV header record
  155. // and the DV records, Excel will not be able to open the workbook without error.
  156. if (nextSid == 0x0867) {
  157. throw new AssertionFailedError("Identified bug 45519");
  158. }
  159. assertEquals(DVRecord.sid, nextSid);
  160. }
  161. private int findIndex(byte[] largeData, byte[] searchPattern) {
  162. byte firstByte = searchPattern[0];
  163. for (int i = 0; i < largeData.length; i++) {
  164. if(largeData[i] != firstByte) {
  165. continue;
  166. }
  167. boolean match = true;
  168. for (int j = 1; j < searchPattern.length; j++) {
  169. if(searchPattern[j] != largeData[i+j]) {
  170. match = false;
  171. break;
  172. }
  173. }
  174. if (match) {
  175. return i;
  176. }
  177. }
  178. return -1;
  179. }
  180. }