fix eclipse warning - mostly generics cosmetics

close resources in tests
junit4 conversions
convert spreadsheet based formular test to junit parameterized tests

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1702773 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andreas Beeker 2015-09-13 12:36:56 +00:00
parent fbcf869f48
commit 118e3ec20a
16 changed files with 1120 additions and 1832 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,612 @@
/* ====================================================================
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.examples;
import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Color;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFColor;
/**
* Utility to compare Excel File Contents cell by cell for all sheets.
*
* <p>This utility will be used to compare Excel File Contents cell by cell for all sheets programmatically.</p>
*
* <p>Below are the list of Attribute comparison supported in this version.</p>
*
* <ul>
* <li>Cell Alignment</li>
* <li>Cell Border Attributes</li>
* <li>Cell Data</li>
* <li>Cell Data-Type</li>
* <li>Cell Fill Color</li>
* <li>Cell Fill pattern</li>
* <li>Cell Font Attributes</li>
* <li>Cell Font Family</li>
* <li>Cell Font Size</li>
* <li>Cell Protection</li>
* <li>Name of the sheets</li>
* <li>Number of Columns</li>
* <li>Number of Rows</li>
* <li>Number of Sheet</li>
* </ul>
*
* <p>(Some of the above attribute comparison only work for *.xlsx format currently. In future it can be enhanced.)</p>
*
* <p><b>Usage:</b></p>
*
* <pre>
* {@code
* Workbook wb1 = WorkbookFactory.create(new File("workBook1.xls"));
* Workbook wb2 = WorkbookFactory.create(new File("workBook2.xls"));
* List<String> listOfDifferences = ExcelComparator.compare(wb1, wb2);
* for (String differences : listOfDifferences)
* System.out.println(differences);
* System.out.println("DifferenceFound = "+ excelFileDifference.isDifferenceFound);
* }
* </pre>
*/
public class ExcelComparator {
private static final String CELL_DATA_DOES_NOT_MATCH = "Cell Data does not Match ::";
private static final String CELL_FONT_ATTRIBUTES_DOES_NOT_MATCH = "Cell Font Attributes does not Match ::";
private static class Locator {
Workbook workbook;
Sheet sheet;
Row row;
Cell cell;
}
List<String> listOfDifferences = new ArrayList<String>();
public static void main(String args[]) throws Exception {
if (args.length != 2 || !(new File(args[0]).exists()) || !(new File(args[1]).exists())) {
System.err.println("java -cp <classpath> "+ExcelComparator.class.getCanonicalName()+" <workbook1.xls/x> <workbook2.xls/x");
System.exit(-1);
}
Workbook wb1 = WorkbookFactory.create(new File(args[0]));
Workbook wb2 = WorkbookFactory.create(new File(args[1]));
for (String d : ExcelComparator.compare(wb1, wb2)) {
System.out.println(d);
}
wb2.close();
wb1.close();
}
/**
* Utility to compare Excel File Contents cell by cell for all sheets.
*
* @param workbook1 the workbook1
* @param workbook2 the workbook2
* @return the Excel file difference containing a flag and a list of differences
* @throws ExcelCompareException the excel compare exception
*/
public static List<String> compare(Workbook wb1, Workbook wb2) {
Locator loc1 = new Locator();
Locator loc2 = new Locator();
loc1.workbook = wb1;
loc2.workbook = wb2;
ExcelComparator excelComparator = new ExcelComparator();
excelComparator.compareNumberOfSheets(loc1, loc2 );
excelComparator.compareSheetNames(loc1, loc2);
excelComparator.compareSheetData(loc1, loc2);
return excelComparator.listOfDifferences;
}
/**
* Compare data in all sheets.
*
* @param workbook1 the workbook1
* @param workbook2 the workbook2
* @param listOfDifferences the list of differences
* @throws ExcelCompareException the excel compare exception
*/
private void compareDataInAllSheets(Locator loc1, Locator loc2) {
for (int i = 0; i < loc1.workbook.getNumberOfSheets(); i++) {
if (loc2.workbook.getNumberOfSheets() <= i) return;
loc1.sheet = loc1.workbook.getSheetAt(i);
loc2.sheet = loc2.workbook.getSheetAt(i);
compareDataInSheet(loc1, loc2);
}
}
private void compareDataInSheet(Locator loc1, Locator loc2) {
for (int j = 0; j < loc1.sheet.getPhysicalNumberOfRows(); j++) {
if (loc2.sheet.getPhysicalNumberOfRows() <= j) return;
loc1.row = loc1.sheet.getRow(j);
loc2.row = loc2.sheet.getRow(j);
if ((loc1.row == null) || (loc2.row == null)) {
continue;
}
compareDataInRow(loc1, loc2);
}
}
private void compareDataInRow(Locator loc1, Locator loc2) {
for (int k = 0; k < loc1.row.getLastCellNum(); k++) {
if (loc2.row.getPhysicalNumberOfCells() <= k) return;
loc1.cell = loc1.row.getCell(k);
loc2.cell = loc2.row.getCell(k);
if ((loc1.cell == null) || (loc2.cell == null)) {
continue;
}
compareDataInCell(loc1, loc2);
}
}
private void compareDataInCell(Locator loc1, Locator loc2) {
if (isCellTypeMatches(loc1, loc2)) {
switch(loc1.cell.getCellType()) {
case Cell.CELL_TYPE_BLANK:
case Cell.CELL_TYPE_STRING:
case Cell.CELL_TYPE_ERROR:
isCellContentMatches(loc1,loc2);
break;
case Cell.CELL_TYPE_BOOLEAN:
isCellContentMatchesForBoolean(loc1,loc2);
break;
case Cell.CELL_TYPE_FORMULA:
isCellContentMatchesForFormula(loc1,loc2);
break;
case Cell.CELL_TYPE_NUMERIC:
if (DateUtil.isCellDateFormatted(loc1.cell)) {
isCellContentMatchesForDate(loc1,loc2);
} else {
isCellContentMatchesForNumeric(loc1,loc2);
}
break;
}
}
isCellFillPatternMatches(loc1,loc2);
isCellAlignmentMatches(loc1,loc2);
isCellHiddenMatches(loc1,loc2);
isCellLockedMatches(loc1,loc2);
isCellFontFamilyMatches(loc1,loc2);
isCellFontSizeMatches(loc1,loc2);
isCellFontBoldMatches(loc1,loc2);
isCellUnderLineMatches(loc1,loc2);
isCellFontItalicsMatches(loc1,loc2);
isCellBorderMatches(loc1,loc2,'t');
isCellBorderMatches(loc1,loc2,'l');
isCellBorderMatches(loc1,loc2,'b');
isCellBorderMatches(loc1,loc2,'r');
isCellFillBackGroundMatches(loc1,loc2);
}
/**
* Compare number of columns in sheets.
*/
private void compareNumberOfColumnsInSheets(Locator loc1, Locator loc2) {
for (int i = 0; i < loc1.workbook.getNumberOfSheets(); i++) {
if (loc2.workbook.getNumberOfSheets() <= i) return;
loc1.sheet = loc1.workbook.getSheetAt(i);
loc2.sheet = loc2.workbook.getSheetAt(i);
Iterator<Row> ri1 = loc1.sheet.rowIterator();
Iterator<Row> ri2 = loc2.sheet.rowIterator();
int num1 = (ri1.hasNext()) ? ri1.next().getPhysicalNumberOfCells() : 0;
int num2 = (ri2.hasNext()) ? ri2.next().getPhysicalNumberOfCells() : 0;
if (num1 != num2) {
String str = String.format(Locale.ROOT, "%s\nworkbook1 -> %s [%d] != workbook2 -> %s [%d]",
"Number Of Columns does not Match ::",
loc1.sheet.getSheetName(), num1,
loc2.sheet.getSheetName(), num2
);
listOfDifferences.add(str);
}
}
}
/**
* Compare number of rows in sheets.
*/
private void compareNumberOfRowsInSheets(Locator loc1, Locator loc2) {
for (int i = 0; i < loc1.workbook.getNumberOfSheets(); i++) {
if (loc2.workbook.getNumberOfSheets() <= i) return;
loc1.sheet = loc1.workbook.getSheetAt(i);
loc2.sheet = loc2.workbook.getSheetAt(i);
int num1 = loc1.sheet.getPhysicalNumberOfRows();
int num2 = loc2.sheet.getPhysicalNumberOfRows();
if (num1 != num2) {
String str = String.format(Locale.ROOT, "%s\nworkbook1 -> %s [%d] != workbook2 -> %s [%d]",
"Number Of Rows does not Match ::",
loc1.sheet.getSheetName(), num1,
loc2.sheet.getSheetName(), num2
);
listOfDifferences.add(str);
}
}
}
/**
* Compare number of sheets.
*/
private void compareNumberOfSheets(Locator loc1, Locator loc2) {
int num1 = loc1.workbook.getNumberOfSheets();
int num2 = loc2.workbook.getNumberOfSheets();
if (num1 != num2) {
String str = String.format(Locale.ROOT, "%s\nworkbook1 [%d] != workbook2 [%d]",
"Number of Sheets do not match ::",
num1, num2
);
listOfDifferences.add(str);
}
}
/**
* Compare sheet data.
*
* @param workbook1
* the workbook1
* @param workbook2
* the workbook2
* @param listOfDifferences
*
* @throws ExcelCompareException
* the excel compare exception
*/
private void compareSheetData(Locator loc1, Locator loc2) {
compareNumberOfRowsInSheets(loc1, loc2);
compareNumberOfColumnsInSheets(loc1, loc2);
compareDataInAllSheets(loc1, loc2);
}
/**
* Compare sheet names.
*/
private void compareSheetNames(Locator loc1, Locator loc2) {
for (int i = 0; i < loc1.workbook.getNumberOfSheets(); i++) {
String name1 = loc1.workbook.getSheetName(i);
String name2 = (loc2.workbook.getNumberOfSheets() > i) ? loc2.workbook.getSheetName(i) : "";
if (!name1.equals(name2)) {
String str = String.format(Locale.ROOT, "%s\nworkbook1 -> %s [%d] != workbook2 -> %s [%d]",
"Name of the sheets do not match ::",
loc1.sheet.getSheetName(), name1, i+1,
loc2.sheet.getSheetName(), name2, i+1
);
listOfDifferences.add(str);
}
}
}
/**
* Formats the message.
*/
private void addMessage(Locator loc1, Locator loc2, String messageStart, String value1, String value2) {
String str =
String.format(Locale.ROOT, "%s\nworkbook1 -> %s -> %s [%s] != workbook2 -> %s -> %s [%s]",
messageStart,
loc1.sheet.getSheetName(), new CellReference(loc1.cell).formatAsString(), value1,
loc2.sheet.getSheetName(), new CellReference(loc2.cell).formatAsString(), value2
);
listOfDifferences.add(str);
}
/**
* Checks if cell alignment matches.
*/
private void isCellAlignmentMatches(Locator loc1, Locator loc2) {
// TODO: check for NPE
short align1 = loc1.cell.getCellStyle().getAlignment();
short align2 = loc2.cell.getCellStyle().getAlignment();
if (align1 != align2) {
addMessage(loc1, loc2,
"Cell Alignment does not Match ::",
Short.toString(align1),
Short.toString(align2)
);
}
}
/**
* Checks if cell border bottom matches.
*/
private void isCellBorderMatches(Locator loc1, Locator loc2, char borderSide) {
if (!(loc1.cell instanceof XSSFCell)) return;
XSSFCellStyle style1 = ((XSSFCell)loc1.cell).getCellStyle();
XSSFCellStyle style2 = ((XSSFCell)loc2.cell).getCellStyle();
boolean b1, b2;
String borderName;
switch (borderSide) {
case 't': default:
b1 = style1.getBorderTop() == 1;
b2 = style2.getBorderTop() == 1;
borderName = "TOP";
break;
case 'b':
b1 = style1.getBorderBottom() == 1;
b2 = style2.getBorderBottom() == 1;
borderName = "BOTTOM";
break;
case 'l':
b1 = style1.getBorderLeft() == 1;
b2 = style2.getBorderLeft() == 1;
borderName = "LEFT";
break;
case 'r':
b1 = style1.getBorderRight() == 1;
b2 = style2.getBorderRight() == 1;
borderName = "RIGHT";
break;
}
if (b1 != b2) {
addMessage(loc1, loc2,
"Cell Border Attributes does not Match ::",
(b1 ? "" : "NOT ")+borderName+" BORDER",
(b2 ? "" : "NOT ")+borderName+" BORDER"
);
}
}
/**
* Checks if cell content matches.
*/
private void isCellContentMatches(Locator loc1, Locator loc2) {
// TODO: check for null and non-rich-text cells
String str1 = loc1.cell.getRichStringCellValue().getString();
String str2 = loc2.cell.getRichStringCellValue().getString();
if (!str1.equals(str2)) {
addMessage(loc1,loc2,CELL_DATA_DOES_NOT_MATCH,str1,str2);
}
}
/**
* Checks if cell content matches for boolean.
*/
private void isCellContentMatchesForBoolean(Locator loc1, Locator loc2) {
boolean b1 = loc1.cell.getBooleanCellValue();
boolean b2 = loc2.cell.getBooleanCellValue();
if (b1 != b2) {
addMessage(loc1,loc2,CELL_DATA_DOES_NOT_MATCH,Boolean.toString(b1),Boolean.toString(b2));
}
}
/**
* Checks if cell content matches for date.
*/
private void isCellContentMatchesForDate(Locator loc1, Locator loc2) {
Date date1 = loc1.cell.getDateCellValue();
Date date2 = loc2.cell.getDateCellValue();
if (!date1.equals(date2)) {
addMessage(loc1, loc2, CELL_DATA_DOES_NOT_MATCH, date1.toGMTString(), date2.toGMTString());
}
}
/**
* Checks if cell content matches for formula.
*/
private void isCellContentMatchesForFormula(Locator loc1, Locator loc2) {
// TODO: actually evaluate the formula / NPE checks
String form1 = loc1.cell.getCellFormula();
String form2 = loc2.cell.getCellFormula();
if (!form1.equals(form2)) {
addMessage(loc1, loc2, CELL_DATA_DOES_NOT_MATCH, form1, form2);
}
}
/**
* Checks if cell content matches for numeric.
*/
private void isCellContentMatchesForNumeric(Locator loc1, Locator loc2) {
// TODO: Check for NaN
double num1 = loc1.cell.getNumericCellValue();
double num2 = loc2.cell.getNumericCellValue();
if (num1 != num2) {
addMessage(loc1, loc2, CELL_DATA_DOES_NOT_MATCH, Double.toString(num1), Double.toString(num2));
}
}
private String getCellFillBackground(Locator loc) {
Color col = loc.cell.getCellStyle().getFillForegroundColorColor();
return (col instanceof XSSFColor) ? ((XSSFColor)col).getARGBHex() : "NO COLOR";
}
/**
* Checks if cell file back ground matches.
*/
private void isCellFillBackGroundMatches(Locator loc1, Locator loc2) {
String col1 = getCellFillBackground(loc1);
String col2 = getCellFillBackground(loc2);
if (!col1.equals(col2)) {
addMessage(loc1, loc2, "Cell Fill Color does not Match ::", col1, col2);
}
}
/**
* Checks if cell fill pattern matches.
*/
private void isCellFillPatternMatches(Locator loc1, Locator loc2) {
// TOOO: Check for NPE
short fill1 = loc1.cell.getCellStyle().getFillPattern();
short fill2 = loc2.cell.getCellStyle().getFillPattern();
if (fill1 != fill2) {
addMessage(loc1, loc2,
"Cell Fill pattern does not Match ::",
Short.toString(fill1),
Short.toString(fill2)
);
}
}
/**
* Checks if cell font bold matches.
*/
private void isCellFontBoldMatches(Locator loc1, Locator loc2) {
if (!(loc1.cell instanceof XSSFCell)) return;
boolean b1 = ((XSSFCell)loc1.cell).getCellStyle().getFont().getBold();
boolean b2 = ((XSSFCell)loc2.cell).getCellStyle().getFont().getBold();
if (b1 != b2) {
addMessage(loc1, loc2,
CELL_FONT_ATTRIBUTES_DOES_NOT_MATCH,
(b1 ? "" : "NOT ")+"BOLD",
(b2 ? "" : "NOT ")+"BOLD"
);
}
}
/**
* Checks if cell font family matches.
*/
private void isCellFontFamilyMatches(Locator loc1, Locator loc2) {
// TODO: Check for NPEs
if (!(loc1.cell instanceof XSSFCell)) return;
String family1 = ((XSSFCell)loc1.cell).getCellStyle().getFont().getFontName();
String family2 = ((XSSFCell)loc2.cell).getCellStyle().getFont().getFontName();
if (!family1.equals(family2)) {
addMessage(loc1, loc2, "Cell Font Family does not Match ::", family1, family2);
}
}
/**
* Checks if cell font italics matches.
*/
private void isCellFontItalicsMatches(Locator loc1, Locator loc2) {
if (!(loc1.cell instanceof XSSFCell)) return;
boolean b1 = ((XSSFCell)loc1.cell).getCellStyle().getFont().getItalic();
boolean b2 = ((XSSFCell)loc2.cell).getCellStyle().getFont().getItalic();
if (b1 != b2) {
addMessage(loc1, loc2,
CELL_FONT_ATTRIBUTES_DOES_NOT_MATCH,
(b1 ? "" : "NOT ")+"ITALICS",
(b2 ? "" : "NOT ")+"ITALICS"
);
}
}
/**
* Checks if cell font size matches.
*/
private void isCellFontSizeMatches(Locator loc1, Locator loc2) {
if (!(loc1.cell instanceof XSSFCell)) return;
short size1 = ((XSSFCell)loc1.cell).getCellStyle().getFont().getFontHeightInPoints();
short size2 = ((XSSFCell)loc2.cell).getCellStyle().getFont().getFontHeightInPoints();
if (size1 != size2) {
addMessage(loc1, loc2,
"Cell Font Size does not Match ::",
Short.toString(size1),
Short.toString(size2)
);
}
}
/**
* Checks if cell hidden matches.
*/
private void isCellHiddenMatches(Locator loc1, Locator loc2) {
boolean b1 = loc1.cell.getCellStyle().getHidden();
boolean b2 = loc1.cell.getCellStyle().getHidden();
if (b1 != b2) {
addMessage(loc1, loc2,
"Cell Visibility does not Match ::",
(b1 ? "" : "NOT ")+"HIDDEN",
(b2 ? "" : "NOT ")+"HIDDEN"
);
}
}
/**
* Checks if cell locked matches.
*/
private void isCellLockedMatches(Locator loc1, Locator loc2) {
boolean b1 = loc1.cell.getCellStyle().getLocked();
boolean b2 = loc1.cell.getCellStyle().getLocked();
if (b1 != b2) {
addMessage(loc1, loc2,
"Cell Protection does not Match ::",
(b1 ? "" : "NOT ")+"LOCKED",
(b2 ? "" : "NOT ")+"LOCKED"
);
}
}
/**
* Checks if cell type matches.
*/
private boolean isCellTypeMatches(Locator loc1, Locator loc2) {
int type1 = loc1.cell.getCellType();
int type2 = loc2.cell.getCellType();
if (type1 == type2) return true;
addMessage(loc1, loc2,
"Cell Data-Type does not Match in :: ",
Integer.toString(type1),
Integer.toString(type2)
);
return false;
}
/**
* Checks if cell under line matches.
*
* @param cellWorkBook1
* the cell work book1
* @param cellWorkBook2
* the cell work book2
* @return true, if cell under line matches
*/
private void isCellUnderLineMatches(Locator loc1, Locator loc2) {
// TOOO: distinguish underline type
if (!(loc1.cell instanceof XSSFCell)) return;
byte b1 = ((XSSFCell)loc1.cell).getCellStyle().getFont().getUnderline();
byte b2 = ((XSSFCell)loc2.cell).getCellStyle().getFont().getUnderline();
if (b1 != b2) {
addMessage(loc1, loc2,
CELL_FONT_ATTRIBUTES_DOES_NOT_MATCH,
(b1 == 1 ? "" : "NOT ")+"UNDERLINE",
(b2 == 1 ? "" : "NOT ")+"UNDERLINE"
);
}
}
}

View File

@ -102,16 +102,6 @@ public class XLSX2CSV {
*/
private ReadOnlySharedStringsTable sharedStringsTable;
/**
* Destination for data
*/
private final PrintStream output;
/**
* Number of columns to read starting with leftmost
*/
private final int minColumnCount;
// Set when V start element is seen
private boolean vIsOpen;
@ -141,13 +131,9 @@ public class XLSX2CSV {
*/
public MyXSSFSheetHandler(
StylesTable styles,
ReadOnlySharedStringsTable strings,
int cols,
PrintStream target) {
ReadOnlySharedStringsTable strings) {
this.stylesTable = styles;
this.sharedStringsTable = strings;
this.minColumnCount = cols;
this.output = target;
this.value = new StringBuffer();
this.nextDataType = xssfDataType.NUMBER;
this.formatter = new DataFormatter();
@ -201,7 +187,8 @@ public class XLSX2CSV {
if (cellStyleStr != null) {
int styleIndex = Integer.parseInt(cellStyleStr);
style = stylesTable.getStyleAt(styleIndex);
} else if (stylesTable.getNumCellStyles() > 0) {
}
if (style == null && stylesTable.getNumCellStyles() > 0) {
style = stylesTable.getStyleAt(0);
}
if (style != null) {
@ -299,7 +286,7 @@ public class XLSX2CSV {
if (lastColumnNumber == -1) {
lastColumnNumber = 0;
}
for (int i = lastColumnNumber; i < (this.minColumnCount); i++) {
for (int i = lastColumnNumber; i < minColumns; i++) {
output.print(',');
}
}
@ -340,9 +327,17 @@ public class XLSX2CSV {
///////////////////////////////////////
private OPCPackage xlsxPackage;
private int minColumns;
private PrintStream output;
private final OPCPackage xlsxPackage;
/**
* Number of columns to read starting with leftmost
*/
private final int minColumns;
/**
* Destination for data
*/
private final PrintStream output;
/**
* Creates a new XLSX -> CSV converter
@ -375,7 +370,7 @@ public class XLSX2CSV {
SAXParserFactory saxFactory = SAXParserFactory.newInstance();
SAXParser saxParser = saxFactory.newSAXParser();
XMLReader sheetParser = saxParser.getXMLReader();
ContentHandler handler = new MyXSSFSheetHandler(styles, strings, this.minColumns, this.output);
ContentHandler handler = new MyXSSFSheetHandler(styles, strings);
sheetParser.setContentHandler(handler);
sheetParser.parse(sheetSource);
}
@ -428,6 +423,7 @@ public class XLSX2CSV {
OPCPackage p = OPCPackage.open(xlsxFile.getPath(), PackageAccess.READ);
XLSX2CSV xlsx2csv = new XLSX2CSV(p, System.out, minColumns);
xlsx2csv.process();
p.close();
}
}

View File

@ -83,13 +83,13 @@ public final class UnknownRecord extends StandardRecord {
public UnknownRecord(RecordInputStream in) {
_sid = in.getSid();
_rawData = in.readRemainder();
if (false && getBiffName(_sid) == null) {
// unknown sids in the range 0x0004-0x0013 are probably 'sub-records' of ObjectRecord
// those sids are in a different number space.
// TODO - put unknown OBJ sub-records in a different class
System.out.println("Unknown record 0x" +
Integer.toHexString(_sid).toUpperCase(Locale.ROOT));
}
// if (false && getBiffName(_sid) == null) {
// // unknown sids in the range 0x0004-0x0013 are probably 'sub-records' of ObjectRecord
// // those sids are in a different number space.
// // TODO - put unknown OBJ sub-records in a different class
// System.out.println("Unknown record 0x" +
// Integer.toHexString(_sid).toUpperCase(Locale.ROOT));
// }
}
/**

View File

@ -211,9 +211,6 @@ public class XWPFFootnote implements Iterable<XWPFParagraph>, IBody {
return null;
}
XWPFTableRow tableRow = table.getRow(row);
if (row == null) {
return null;
}
return tableRow.getTableCell(cell);
}

View File

@ -139,7 +139,6 @@ public abstract class XWPFHeaderFooter extends POIXMLDocumentPart implements IBo
}
}
List<XWPFTable> tables = getTables();
for (int i = 0; i < tables.size(); i++) {
String text = tables.get(i).getText();
if (text != null && text.length() > 0) {
@ -505,9 +504,6 @@ public abstract class XWPFHeaderFooter extends POIXMLDocumentPart implements IBo
return null;
}
XWPFTableRow tableRow = table.getRow(row);
if (row == null) {
return null;
}
return tableRow.getTableCell(cell);
}

View File

@ -205,6 +205,10 @@ public class XWPFSettings extends POIXMLDocumentPart {
} else {
final STCryptProv.Enum providerType;
final int sid;
if (hashAlgo == null) {
hashAlgo = HashAlgorithm.sha1;
}
switch (hashAlgo) {
case md2:
providerType = STCryptProv.RSA_FULL;
@ -247,8 +251,6 @@ public class XWPFSettings extends POIXMLDocumentPart {
// iteration's result as the input for the next iteration).
int spinCount = 100000;
if (hashAlgo == null) hashAlgo = HashAlgorithm.sha1;
String legacyHash = CryptoFunctions.xorHashPasswordReversed(password);
// Implementation Notes List:
// --> In this third stage, the reversed byte order legacy hash from the second stage shall

View File

@ -20,6 +20,9 @@ package org.apache.poi.xssf.usermodel;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeNotNull;
import static org.junit.Assume.assumeTrue;
import java.util.ArrayList;
import java.util.Collection;
@ -37,6 +40,8 @@ import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.util.LocaleUtil;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.junit.AfterClass;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -56,6 +61,7 @@ import org.junit.runners.Parameterized.Parameters;
*/
@RunWith(Parameterized.class)
public final class TestFormulaEvaluatorOnXSSF {
private static final POILogger logger = POILogFactory.getLogger(TestFormulaEvaluatorOnXSSF.class);
private static XSSFWorkbook workbook;
private static Sheet sheet;
@ -144,12 +150,15 @@ public final class TestFormulaEvaluatorOnXSSF {
private static void processFunctionGroup(List<Object[]> data, int startRowIndex, String testFocusFunctionName) {
for (int rowIndex = startRowIndex; true; rowIndex += SS.NUMBER_OF_ROWS_PER_FUNCTION) {
Row r = sheet.getRow(rowIndex);
// only evaluate non empty row
if(r == null) continue;
String targetFunctionName = getTargetFunctionName(r);
if(targetFunctionName == null) {
fail("Test spreadsheet cell empty on row ("
+ (rowIndex+1) + "). Expected function name or '"
+ SS.FUNCTION_NAMES_END_SENTINEL + "'");
}
assertNotNull("Test spreadsheet cell empty on row ("
+ (rowIndex+1) + "). Expected function name or '"
+ SS.FUNCTION_NAMES_END_SENTINEL + "'", targetFunctionName);
if(targetFunctionName.equals(SS.FUNCTION_NAMES_END_SENTINEL)) {
// found end of functions list
break;
@ -158,11 +167,10 @@ public final class TestFormulaEvaluatorOnXSSF {
// expected results are on the row below
Row expectedValuesRow = sheet.getRow(rowIndex + 1);
if(expectedValuesRow == null) {
int missingRowNum = rowIndex + 2; //+1 for 1-based, +1 for next row
fail("Missing expected values row for function '"
+ targetFunctionName + " (row " + missingRowNum + ")");
}
// +1 for 1-based, +1 for next row
assertNotNull("Missing expected values row for function '"
+ targetFunctionName + " (row " + rowIndex + 2 + ")"
, expectedValuesRow);
data.add(new Object[]{targetFunctionName, rowIndex, rowIndex + 1});
}
@ -180,12 +188,9 @@ public final class TestFormulaEvaluatorOnXSSF {
// iterate across the row for all the evaluation cases
for (short colnum=SS.COLUMN_INDEX_FIRST_TEST_VALUE; colnum < endcolnum; colnum++) {
Cell c = formulasRow.getCell(colnum);
if (c == null || c.getCellType() != Cell.CELL_TYPE_FORMULA) {
continue;
}
if(isIgnoredFormulaTestCase(c.getCellFormula())) {
continue;
}
assumeNotNull(c);
assumeTrue(c.getCellType() == Cell.CELL_TYPE_FORMULA);
ignoredFormulaTestCase(c.getCellFormula());
CellValue actValue = evaluator.evaluate(c);
Cell expValue = (expectedValuesRow == null) ? null : expectedValuesRow.getCell(colnum);
@ -230,19 +235,16 @@ public final class TestFormulaEvaluatorOnXSSF {
/*
* TODO - these are all formulas which currently (Apr-2008) break on ooxml
*/
private static boolean isIgnoredFormulaTestCase(String cellFormula) {
if ("COLUMN(1:2)".equals(cellFormula) || "ROW(2:3)".equals(cellFormula)) {
// full row ranges are not parsed properly yet.
// These cases currently work in svn trunk because of another bug which causes the
// formula to get rendered as COLUMN($A$1:$IV$2) or ROW($A$2:$IV$3)
return true;
}
if ("ISREF(currentcell())".equals(cellFormula)) {
// currently throws NPE because unknown function "currentcell" causes name lookup
// Name lookup requires some equivalent object of the Workbook within xSSFWorkbook.
return true;
}
return false;
private static void ignoredFormulaTestCase(String cellFormula) {
// full row ranges are not parsed properly yet.
// These cases currently work in svn trunk because of another bug which causes the
// formula to get rendered as COLUMN($A$1:$IV$2) or ROW($A$2:$IV$3)
assumeFalse("COLUMN(1:2)".equals(cellFormula));
assumeFalse("ROW(2:3)".equals(cellFormula));
// currently throws NPE because unknown function "currentcell" causes name lookup
// Name lookup requires some equivalent object of the Workbook within xSSFWorkbook.
assumeFalse("ISREF(currentcell())".equals(cellFormula));
}
/**
@ -250,12 +252,12 @@ public final class TestFormulaEvaluatorOnXSSF {
*/
private static String getTargetFunctionName(Row r) {
if(r == null) {
System.err.println("Warning - given null row, can't figure out function name");
logger.log(POILogger.WARN, "Warning - given null row, can't figure out function name");
return null;
}
Cell cell = r.getCell(SS.COLUMN_INDEX_FUNCTION_NAME);
if(cell == null) {
System.err.println("Warning - Row " + r.getRowNum() + " has no cell " + SS.COLUMN_INDEX_FUNCTION_NAME + ", can't figure out function name");
logger.log(POILogger.WARN, "Warning - Row " + r.getRowNum() + " has no cell " + SS.COLUMN_INDEX_FUNCTION_NAME + ", can't figure out function name");
return null;
}
if(cell.getCellType() == Cell.CELL_TYPE_BLANK) {

View File

@ -17,15 +17,20 @@
package org.apache.poi.xssf.usermodel;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.Collection;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeNotNull;
import static org.junit.Assume.assumeTrue;
import junit.framework.Assert;
import junit.framework.AssertionFailedError;
import junit.framework.TestCase;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import org.apache.poi.hssf.HSSFTestDataSamples;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackageAccess;
import org.apache.poi.ss.formula.eval.TestFormulasFromSpreadsheet;
import org.apache.poi.ss.formula.functions.TestMathX;
import org.apache.poi.ss.usermodel.Cell;
@ -33,268 +38,193 @@ import org.apache.poi.ss.usermodel.CellValue;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.junit.AfterClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
/**
* Tests formulas for multi sheet reference (i.e. SUM(Sheet1:Sheet5!A1))
*/
public final class TestMultiSheetFormulaEvaluatorOnXSSF extends TestCase {
@RunWith(Parameterized.class)
public final class TestMultiSheetFormulaEvaluatorOnXSSF {
private static final POILogger logger = POILogFactory.getLogger(TestFormulasFromSpreadsheet.class);
private static final class Result {
public static final int SOME_EVALUATIONS_FAILED = -1;
public static final int ALL_EVALUATIONS_SUCCEEDED = +1;
public static final int NO_EVALUATIONS_FOUND = 0;
}
private static XSSFWorkbook workbook;
private static Sheet sheet;
private static FormulaEvaluator evaluator;
/**
* This class defines constants for navigating around the test data spreadsheet used for these tests.
*/
private static final class SS {
interface SS {
/**
* Name of the test spreadsheet (found in the standard test data folder)
*/
public final static String FILENAME = "FormulaSheetRange.xlsx";
String FILENAME = "FormulaSheetRange.xlsx";
/**
* Row (zero-based) in the test spreadsheet where the function examples start.
*/
public static final int START_FUNCTIONS_ROW_INDEX = 10; // Row '11'
int START_FUNCTIONS_ROW_INDEX = 10; // Row '11'
/**
* Index of the column that contains the function names
*/
public static final int COLUMN_INDEX_FUNCTION_NAME = 0; // Column 'A'
int COLUMN_INDEX_FUNCTION_NAME = 0; // Column 'A'
/**
* Index of the column that contains the test names
*/
public static final int COLUMN_INDEX_TEST_NAME = 1; // Column 'B'
int COLUMN_INDEX_TEST_NAME = 1; // Column 'B'
/**
* Used to indicate when there are no more functions left
*/
public static final String FUNCTION_NAMES_END_SENTINEL = "<END>";
String FUNCTION_NAMES_END_SENTINEL = "<END>";
/**
* Index of the column where the test expected value is present
*/
public static final short COLUMN_INDEX_EXPECTED_VALUE = 2; // Column 'C'
short COLUMN_INDEX_EXPECTED_VALUE = 2; // Column 'C'
/**
* Index of the column where the test actual value is present
*/
public static final short COLUMN_INDEX_ACTUAL_VALUE = 3; // Column 'D'
short COLUMN_INDEX_ACTUAL_VALUE = 3; // Column 'D'
/**
* Test sheet name (sheet with all test formulae)
*/
public static final String TEST_SHEET_NAME = "test";
String TEST_SHEET_NAME = "test";
}
private XSSFWorkbook workbook;
private Sheet sheet;
// Note - multiple failures are aggregated before ending.
// If one or more functions fail, a single AssertionFailedError is thrown at the end
private int _functionFailureCount;
private int _functionSuccessCount;
private int _evaluationFailureCount;
private int _evaluationSuccessCount;
@Parameter(value = 0)
public String targetTestName;
@Parameter(value = 1)
public String targetFunctionName;
@Parameter(value = 2)
public int formulasRowIdx;
private static void confirmExpectedResult(String msg, Cell expected, CellValue actual) {
if (expected == null) {
throw new AssertionFailedError(msg + " - Bad setup data expected value is null");
}
if(actual == null) {
throw new AssertionFailedError(msg + " - actual value was null");
}
switch (expected.getCellType()) {
case Cell.CELL_TYPE_BLANK:
assertEquals(msg, Cell.CELL_TYPE_BLANK, actual.getCellType());
break;
case Cell.CELL_TYPE_BOOLEAN:
assertEquals(msg, Cell.CELL_TYPE_BOOLEAN, actual.getCellType());
assertEquals(msg, expected.getBooleanCellValue(), actual.getBooleanValue());
break;
case Cell.CELL_TYPE_ERROR:
assertEquals(msg, Cell.CELL_TYPE_ERROR, actual.getCellType());
if(false) { // TODO: fix ~45 functions which are currently returning incorrect error values
assertEquals(msg, expected.getErrorCellValue(), actual.getErrorValue());
}
break;
case Cell.CELL_TYPE_FORMULA: // will never be used, since we will call method after formula evaluation
throw new AssertionFailedError("Cannot expect formula as result of formula evaluation: " + msg);
case Cell.CELL_TYPE_NUMERIC:
assertEquals(msg, Cell.CELL_TYPE_NUMERIC, actual.getCellType());
TestMathX.assertEquals(msg, expected.getNumericCellValue(), actual.getNumberValue(), TestMathX.POS_ZERO, TestMathX.DIFF_TOLERANCE_FACTOR);
// double delta = Math.abs(expected.getNumericCellValue()-actual.getNumberValue());
// double pctExpected = Math.abs(0.00001*expected.getNumericCellValue());
// assertTrue(msg, delta <= pctExpected);
break;
case Cell.CELL_TYPE_STRING:
assertEquals(msg, Cell.CELL_TYPE_STRING, actual.getCellType());
assertEquals(msg, expected.getRichStringCellValue().getString(), actual.getStringValue());
break;
}
}
@AfterClass
public static void closeResource() throws Exception {
workbook.close();
}
@Parameters(name="{0}")
public static Collection<Object[]> data() throws Exception {
workbook = new XSSFWorkbook( OPCPackage.open(HSSFTestDataSamples.getSampleFile(SS.FILENAME), PackageAccess.READ) );
sheet = workbook.getSheet( SS.TEST_SHEET_NAME );
evaluator = new XSSFFormulaEvaluator(workbook);
protected void setUp() throws Exception {
if (workbook == null) {
InputStream is = HSSFTestDataSamples.openSampleFileStream(SS.FILENAME);
OPCPackage pkg = OPCPackage.open(is);
workbook = new XSSFWorkbook( pkg );
sheet = workbook.getSheet( SS.TEST_SHEET_NAME );
}
_functionFailureCount = 0;
_functionSuccessCount = 0;
_evaluationFailureCount = 0;
_evaluationSuccessCount = 0;
}
List<Object[]> data = new ArrayList<Object[]>();
public void testFunctionsFromTestSpreadsheet() {
processFunctionGroup(data, SS.START_FUNCTIONS_ROW_INDEX, null);
processFunctionGroup(SS.START_FUNCTIONS_ROW_INDEX, null);
return data;
}
// confirm results
String successMsg = "There were "
+ _evaluationSuccessCount + " successful evaluation(s) and "
+ _functionSuccessCount + " function(s) without error";
if(_functionFailureCount > 0) {
String msg = _functionFailureCount + " function(s) failed in "
+ _evaluationFailureCount + " evaluation(s). " + successMsg;
throw new AssertionFailedError(msg);
}
logger.log(POILogger.INFO, getClass().getName() + ": " + successMsg);
}
/**
* @param startRowIndex row index in the spreadsheet where the first function/operator is found
* @param testFocusFunctionName name of a single function/operator to test alone.
* Typically pass <code>null</code> to test all functions
*/
private static void processFunctionGroup(List<Object[]> data, int startRowIndex, String testFocusFunctionName) {
for (int rowIndex = startRowIndex; true; rowIndex++) {
Row r = sheet.getRow(rowIndex);
/**
* @param startRowIndex row index in the spreadsheet where the first function/operator is found
* @param testFocusFunctionName name of a single function/operator to test alone.
* Typically pass <code>null</code> to test all functions
*/
private void processFunctionGroup(int startRowIndex, String testFocusFunctionName) {
FormulaEvaluator evaluator = new XSSFFormulaEvaluator(workbook);
// only evaluate non empty row
if(r == null) continue;
int rowIndex = startRowIndex;
while (true) {
Row r = sheet.getRow(rowIndex);
// only evaluate non empty row
if( r != null )
{
String targetFunctionName = getTargetFunctionName(r);
String targetTestName = getTargetTestName(r);
if(targetFunctionName == null) {
throw new AssertionFailedError("Test spreadsheet cell empty on row ("
+ (rowIndex+1) + "). Expected function name or '"
+ SS.FUNCTION_NAMES_END_SENTINEL + "'");
}
if(targetFunctionName.equals(SS.FUNCTION_NAMES_END_SENTINEL)) {
// found end of functions list
break;
}
if(testFocusFunctionName == null || targetFunctionName.equalsIgnoreCase(testFocusFunctionName)) {
String targetFunctionName = getTargetFunctionName(r);
assertNotNull("Test spreadsheet cell empty on row ("
+ (rowIndex+1) + "). Expected function name or '"
+ SS.FUNCTION_NAMES_END_SENTINEL + "'", targetFunctionName);
// expected results are on the row below
Cell expectedValueCell = r.getCell(SS.COLUMN_INDEX_EXPECTED_VALUE);
if(expectedValueCell == null) {
int missingRowNum = rowIndex + 1;
throw new AssertionFailedError("Missing expected values cell for function '"
+ targetFunctionName + ", test" + targetTestName + " (row " +
missingRowNum + ")");
}
switch(processFunctionRow(evaluator, targetFunctionName, targetTestName, r, expectedValueCell)) {
case Result.ALL_EVALUATIONS_SUCCEEDED: _functionSuccessCount++; break;
case Result.SOME_EVALUATIONS_FAILED: _functionFailureCount++; break;
default:
throw new RuntimeException("unexpected result");
case Result.NO_EVALUATIONS_FOUND: // do nothing
break;
}
}
}
rowIndex ++;
}
}
if(targetFunctionName.equals(SS.FUNCTION_NAMES_END_SENTINEL)) {
// found end of functions list
break;
}
/**
*
* @return a constant from the local Result class denoting whether there were any evaluation
* cases, and whether they all succeeded.
*/
private int processFunctionRow(FormulaEvaluator evaluator, String targetFunctionName,
String targetTestName, Row formulasRow, Cell expectedValueCell) {
String targetTestName = getTargetTestName(r);
if(testFocusFunctionName == null || targetFunctionName.equalsIgnoreCase(testFocusFunctionName)) {
int result = Result.NO_EVALUATIONS_FOUND; // so far
// expected results are on the row below
Cell expectedValueCell = r.getCell(SS.COLUMN_INDEX_EXPECTED_VALUE);
assertNotNull("Missing expected values cell for function '"
+ targetFunctionName + ", test" + targetTestName + " (row " +
rowIndex + 1 + ")", expectedValueCell);
Cell c = formulasRow.getCell(SS.COLUMN_INDEX_ACTUAL_VALUE);
if (c == null || c.getCellType() != Cell.CELL_TYPE_FORMULA) {
return result;
}
data.add(new Object[]{targetTestName, targetFunctionName, rowIndex});
}
}
}
CellValue actualValue = evaluator.evaluate(c);
/**
*
* @return a constant from the local Result class denoting whether there were any evaluation
* cases, and whether they all succeeded.
*/
@Test
public void processFunctionRow() {
Row r = sheet.getRow(formulasRowIdx);
try {
confirmExpectedResult("Function '" + targetFunctionName + "': Test: '" + targetTestName + "' Formula: " + c.getCellFormula()
+ " @ " + formulasRow.getRowNum() + ":" + SS.COLUMN_INDEX_ACTUAL_VALUE,
expectedValueCell, actualValue);
_evaluationSuccessCount ++;
if(result != Result.SOME_EVALUATIONS_FAILED) {
result = Result.ALL_EVALUATIONS_SUCCEEDED;
}
} catch (AssertionFailedError e) {
_evaluationFailureCount ++;
printShortStackTrace(System.err, e);
result = Result.SOME_EVALUATIONS_FAILED;
}
return result;
}
Cell expValue = r.getCell(SS.COLUMN_INDEX_EXPECTED_VALUE);
assertNotNull("Missing expected values cell for function '"
+ targetFunctionName + ", test" + targetTestName + " (row " +
formulasRowIdx + 1 + ")", expValue);
/**
* Useful to keep output concise when expecting many failures to be reported by this test case
*/
private static void printShortStackTrace(PrintStream ps, AssertionFailedError e) {
StackTraceElement[] stes = e.getStackTrace();
Cell c = r.getCell(SS.COLUMN_INDEX_ACTUAL_VALUE);
assumeNotNull(c);
assumeTrue(c.getCellType() == Cell.CELL_TYPE_FORMULA);
int startIx = 0;
// skip any top frames inside junit.framework.Assert
while(startIx<stes.length) {
if(!stes[startIx].getClassName().equals(Assert.class.getName())) {
break;
}
startIx++;
}
// skip bottom frames (part of junit framework)
int endIx = startIx+1;
while(endIx < stes.length) {
if(stes[endIx].getClassName().equals(TestCase.class.getName())) {
break;
}
endIx++;
}
if(startIx >= endIx) {
// something went wrong. just print the whole stack trace
e.printStackTrace(ps);
}
endIx -= 4; // skip 4 frames of reflection invocation
ps.println(e.toString());
for(int i=startIx; i<endIx; i++) {
ps.println("\tat " + stes[i].toString());
}
}
CellValue actValue = evaluator.evaluate(c);
/**
String msg = String.format(Locale.ROOT, "Function '%s': Test: '%s': Formula: %s @ %d:%d",
targetFunctionName, targetTestName, c.getCellFormula(), formulasRowIdx, SS.COLUMN_INDEX_ACTUAL_VALUE);
assertNotNull(msg + " - actual value was null", actValue);
switch (expValue.getCellType()) {
case Cell.CELL_TYPE_BLANK:
assertEquals(msg, Cell.CELL_TYPE_BLANK, actValue.getCellType());
break;
case Cell.CELL_TYPE_BOOLEAN:
assertEquals(msg, Cell.CELL_TYPE_BOOLEAN, actValue.getCellType());
assertEquals(msg, expValue.getBooleanCellValue(), actValue.getBooleanValue());
break;
case Cell.CELL_TYPE_ERROR:
assertEquals(msg, Cell.CELL_TYPE_ERROR, actValue.getCellType());
// if(false) { // TODO: fix ~45 functions which are currently returning incorrect error values
// assertEquals(msg, expected.getErrorCellValue(), actual.getErrorValue());
// }
break;
case Cell.CELL_TYPE_FORMULA: // will never be used, since we will call method after formula evaluation
fail("Cannot expect formula as result of formula evaluation: " + msg);
case Cell.CELL_TYPE_NUMERIC:
assertEquals(msg, Cell.CELL_TYPE_NUMERIC, actValue.getCellType());
TestMathX.assertEquals(msg, expValue.getNumericCellValue(), actValue.getNumberValue(), TestMathX.POS_ZERO, TestMathX.DIFF_TOLERANCE_FACTOR);
// double delta = Math.abs(expected.getNumericCellValue()-actual.getNumberValue());
// double pctExpected = Math.abs(0.00001*expected.getNumericCellValue());
// assertTrue(msg, delta <= pctExpected);
break;
case Cell.CELL_TYPE_STRING:
assertEquals(msg, Cell.CELL_TYPE_STRING, actValue.getCellType());
assertEquals(msg, expValue.getRichStringCellValue().getString(), actValue.getStringValue());
break;
}
}
/**
* @return <code>null</code> if cell is missing, empty or blank
*/
private static String getTargetFunctionName(Row r) {
if(r == null) {
System.err.println("Warning - given null row, can't figure out function name");
logger.log(POILogger.WARN, "Warning - given null row, can't figure out function name");
return null;
}
Cell cell = r.getCell(SS.COLUMN_INDEX_FUNCTION_NAME);
if(cell == null) {
System.err.println("Warning - Row " + r.getRowNum() + " has no cell " + SS.COLUMN_INDEX_FUNCTION_NAME + ", can't figure out function name");
logger.log(POILogger.WARN, "Warning - Row " + r.getRowNum() + " has no cell " + SS.COLUMN_INDEX_FUNCTION_NAME + ", can't figure out function name");
return null;
}
if(cell.getCellType() == Cell.CELL_TYPE_BLANK) {
@ -304,20 +234,21 @@ public final class TestMultiSheetFormulaEvaluatorOnXSSF extends TestCase {
return cell.getRichStringCellValue().getString();
}
throw new AssertionFailedError("Bad cell type for 'function name' column: ("
+ cell.getCellType() + ") row (" + (r.getRowNum() +1) + ")");
fail("Bad cell type for 'function name' column: ("
+ cell.getCellType() + ") row (" + (r.getRowNum() +1) + ")");
return "";
}
/**
* @return <code>null</code> if cell is missing, empty or blank
*/
private static String getTargetTestName(Row r) {
if(r == null) {
System.err.println("Warning - given null row, can't figure out test name");
logger.log(POILogger.WARN, "Warning - given null row, can't figure out test name");
return null;
}
Cell cell = r.getCell(SS.COLUMN_INDEX_TEST_NAME);
if(cell == null) {
System.err.println("Warning - Row " + r.getRowNum() + " has no cell " + SS.COLUMN_INDEX_TEST_NAME + ", can't figure out test name");
logger.log(POILogger.WARN, "Warning - Row " + r.getRowNum() + " has no cell " + SS.COLUMN_INDEX_TEST_NAME + ", can't figure out test name");
return null;
}
if(cell.getCellType() == Cell.CELL_TYPE_BLANK) {
@ -327,8 +258,9 @@ public final class TestMultiSheetFormulaEvaluatorOnXSSF extends TestCase {
return cell.getRichStringCellValue().getString();
}
throw new AssertionFailedError("Bad cell type for 'test name' column: ("
+ cell.getCellType() + ") row (" + (r.getRowNum() +1) + ")");
fail("Bad cell type for 'test name' column: ("
+ cell.getCellType() + ") row (" + (r.getRowNum() +1) + ")");
return "";
}
}

View File

@ -17,7 +17,8 @@
package org.apache.poi.xwpf.usermodel;
import java.io.FileOutputStream;
import static org.junit.Assert.*;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
@ -34,12 +35,12 @@ import org.apache.poi.openxml4j.opc.PackagingURIHelper;
import org.apache.poi.openxml4j.opc.TargetMode;
import org.apache.poi.xwpf.XWPFTestDataSamples;
import org.apache.xmlbeans.XmlCursor;
import org.junit.Test;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
import junit.framework.TestCase;
public final class TestXWPFDocument extends TestCase {
public final class TestXWPFDocument {
@Test
public void testContainsMainContentType() throws Exception {
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("sample.docx");
OPCPackage pack = doc.getPackage();
@ -49,31 +50,36 @@ public final class TestXWPFDocument extends TestCase {
if (part.getContentType().equals(XWPFRelation.DOCUMENT.getContentType())) {
found = true;
}
if (false) {
// successful tests should be silent
System.out.println(part);
}
// if (false) {
// // successful tests should be silent
// System.out.println(part);
// }
}
assertTrue(found);
pack.close();
doc.close();
}
@Test
public void testOpen() throws Exception {
XWPFDocument xml;
// Simple file
xml = XWPFTestDataSamples.openSampleDocument("sample.docx");
XWPFDocument xml1 = XWPFTestDataSamples.openSampleDocument("sample.docx");
// Check it has key parts
assertNotNull(xml.getDocument());
assertNotNull(xml.getDocument().getBody());
assertNotNull(xml.getStyle());
assertNotNull(xml1.getDocument());
assertNotNull(xml1.getDocument().getBody());
assertNotNull(xml1.getStyle());
xml1.close();
// Complex file
xml = XWPFTestDataSamples.openSampleDocument("IllustrativeCases.docx");
assertNotNull(xml.getDocument());
assertNotNull(xml.getDocument().getBody());
assertNotNull(xml.getStyle());
XWPFDocument xml2 = XWPFTestDataSamples.openSampleDocument("IllustrativeCases.docx");
assertNotNull(xml2.getDocument());
assertNotNull(xml2.getDocument().getBody());
assertNotNull(xml2.getStyle());
xml2.close();
}
@Test
public void testMetadataBasics() throws IOException {
XWPFDocument xml = XWPFTestDataSamples.openSampleDocument("sample.docx");
assertNotNull(xml.getProperties().getCoreProperties());
@ -85,8 +91,10 @@ public final class TestXWPFDocument extends TestCase {
assertEquals(null, xml.getProperties().getCoreProperties().getTitle());
assertEquals(null, xml.getProperties().getCoreProperties().getUnderlyingProperties().getSubjectProperty().getValue());
xml.close();
}
@Test
public void testMetadataComplex() throws IOException {
XWPFDocument xml = XWPFTestDataSamples.openSampleDocument("IllustrativeCases.docx");
assertNotNull(xml.getProperties().getCoreProperties());
@ -98,15 +106,19 @@ public final class TestXWPFDocument extends TestCase {
assertEquals(" ", xml.getProperties().getCoreProperties().getTitle());
assertEquals(" ", xml.getProperties().getCoreProperties().getUnderlyingProperties().getSubjectProperty().getValue());
xml.close();
}
public void testWorkbookProperties() {
@Test
public void testWorkbookProperties() throws Exception {
XWPFDocument doc = new XWPFDocument();
POIXMLProperties props = doc.getProperties();
assertNotNull(props);
assertEquals("Apache POI", props.getExtendedProperties().getUnderlyingProperties().getApplication());
doc.close();
}
@Test
public void testAddParagraph() throws IOException {
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("sample.docx");
assertEquals(3, doc.getParagraphs().size());
@ -125,8 +137,10 @@ public final class TestXWPFDocument extends TestCase {
XWPFParagraph cP = doc.insertNewParagraph(cursor);
assertSame(cP, doc.getParagraphs().get(0));
assertEquals(5, doc.getParagraphs().size());
doc.close();
}
@Test
public void testAddPicture() throws IOException, InvalidFormatException {
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("sample.docx");
byte[] jpeg = XWPFTestDataSamples.getImage("nature1.jpg");
@ -137,8 +151,10 @@ public final class TestXWPFDocument extends TestCase {
for (int i = 0; i < jpeg.length; i++) {
assertEquals(newJpeg[i], jpeg[i]);
}
doc.close();
}
@Test
public void testAllPictureFormats() throws IOException, InvalidFormatException {
XWPFDocument doc = new XWPFDocument();
@ -156,11 +172,13 @@ public final class TestXWPFDocument extends TestCase {
assertEquals(11, doc.getAllPictures().size());
doc = XWPFTestDataSamples.writeOutAndReadBack(doc);
assertEquals(11, doc.getAllPictures().size());
XWPFDocument doc2 = XWPFTestDataSamples.writeOutAndReadBack(doc);
assertEquals(11, doc2.getAllPictures().size());
doc2.close();
doc.close();
}
@Test
public void testRemoveBodyElement() throws IOException {
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("sample.docx");
assertEquals(3, doc.getParagraphs().size());
@ -220,8 +238,10 @@ public final class TestXWPFDocument extends TestCase {
assertEquals(p3, doc.getBodyElements().get(0));
assertEquals(p3, doc.getParagraphs().get(0));
doc.close();
}
@Test
public void testRegisterPackagePictureData() throws IOException, InvalidFormatException {
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("issue_51265_1.docx");
@ -250,8 +270,11 @@ public final class TestXWPFDocument extends TestCase {
assertTrue(doc.getAllPackagePictures().contains(newPicData));
doc.getPackage().revert();
opcPckg.close();
doc.close();
}
@Test
public void testFindPackagePictureData() throws IOException {
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("issue_51265_1.docx");
byte[] nature1 = XWPFTestDataSamples.getImage("nature1.gif");
@ -260,8 +283,10 @@ public final class TestXWPFDocument extends TestCase {
assertTrue(doc.getAllPictures().contains(part));
assertTrue(doc.getAllPackagePictures().contains(part));
doc.getPackage().revert();
doc.close();
}
@Test
public void testGetAllPictures() throws IOException {
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("issue_51265_3.docx");
List<XWPFPictureData> allPictures = doc.getAllPictures();
@ -281,8 +306,10 @@ public final class TestXWPFDocument extends TestCase {
}
doc.getPackage().revert();
doc.close();
}
@Test
public void testGetAllPackagePictures() throws IOException {
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("issue_51265_3.docx");
List<XWPFPictureData> allPackagePictures = doc.getAllPackagePictures();
@ -298,8 +325,10 @@ public final class TestXWPFDocument extends TestCase {
}
doc.getPackage().revert();
doc.close();
}
@Test
public void testPictureHandlingSimpleFile() throws IOException, InvalidFormatException {
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("issue_51265_1.docx");
assertEquals(1, doc.getAllPackagePictures().size());
@ -311,16 +340,20 @@ public final class TestXWPFDocument extends TestCase {
String id2 = doc.addPictureData(newPicCopy, Document.PICTURE_TYPE_JPEG);
assertEquals(id1, id2);
doc.getPackage().revert();
doc.close();
}
@Test
public void testPictureHandlingHeaderDocumentImages() throws IOException {
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("issue_51265_2.docx");
assertEquals(1, doc.getAllPictures().size());
assertEquals(1, doc.getAllPackagePictures().size());
assertEquals(1, doc.getHeaderArray(0).getAllPictures().size());
doc.getPackage().revert();
doc.close();
}
@Test
public void testPictureHandlingComplex() throws IOException, InvalidFormatException {
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("issue_51265_3.docx");
XWPFHeader xwpfHeader = doc.getHeaderArray(0);
@ -336,8 +369,10 @@ public final class TestXWPFDocument extends TestCase {
assertSame(part1, part2);
doc.getPackage().revert();
doc.close();
}
@Test
public void testZeroLengthLibreOfficeDocumentWithWaterMarkHeader() throws IOException {
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("zero-length.docx");
POIXMLProperties properties = doc.getProperties();
@ -352,8 +387,10 @@ public final class TestXWPFDocument extends TestCase {
POIXMLProperties.ExtendedProperties extendedProperties = properties.getExtendedProperties();
assertNotNull(extendedProperties);
assertEquals(0, extendedProperties.getUnderlyingProperties().getCharacters());
doc.close();
}
@Test
public void testSettings() throws IOException {
XWPFSettings settings = new XWPFSettings();
assertEquals(100, settings.getZoomPercent());

View File

@ -85,15 +85,15 @@ public final class TestRangeInsertion extends TestCase {
HWPFDocument daDoc = HWPFTestDataSamples.openSampleFile(illustrativeDocFile);
if (false) { // TODO - delete or resurrect this code
Range range = daDoc.getRange();
Section section = range.getSection(0);
Paragraph para = section.getParagraph(2);
String text = para.getCharacterRun(0).text() + para.getCharacterRun(1).text() +
para.getCharacterRun(2).text();
System.out.println(text);
}
// if (false) { // TODO - delete or resurrect this code
// Range range = daDoc.getRange();
// Section section = range.getSection(0);
// Paragraph para = section.getParagraph(2);
// String text = para.getCharacterRun(0).text() + para.getCharacterRun(1).text() +
// para.getCharacterRun(2).text();
//
// System.out.println(text);
// }
Range range = new Range(insertionPoint, (insertionPoint + 2), daDoc);
range.insertBefore(textToInsert);

View File

@ -17,72 +17,83 @@
package org.apache.poi.hssf.model;
import junit.framework.AssertionFailedError;
import junit.framework.TestCase;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.fail;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.apache.poi.hssf.HSSFTestDataSamples;
import org.apache.poi.ss.formula.ptg.AttrPtg;
import org.apache.poi.ss.formula.ptg.Ptg;
import org.apache.poi.hssf.usermodel.FormulaExtractor;
import org.apache.poi.hssf.usermodel.HSSFCell;
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.poifs.filesystem.NPOIFSFileSystem;
import org.apache.poi.ss.formula.ptg.AttrPtg;
import org.apache.poi.ss.formula.ptg.Ptg;
import org.junit.AfterClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
/**
* Tests 'operand class' transformation performed by
* <tt>OperandClassTransformer</tt> by comparing its results with those
* directly produced by Excel (in a sample spreadsheet).
*
* @author Josh Micich
*/
public final class TestRVA extends TestCase {
@RunWith(Parameterized.class)
public final class TestRVA {
private static final String NEW_LINE = System.getProperty("line.separator");
private static NPOIFSFileSystem poifs;
private static HSSFWorkbook workbook;
private static HSSFSheet sheet;
public void testFormulas() {
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("testRVA.xls");
HSSFSheet sheet = wb.getSheetAt(0);
@Parameter(value = 0)
public HSSFCell formulaCell;
@Parameter(value = 1)
public String formula;
int countFailures = 0;
int countErrors = 0;
@AfterClass
public static void closeResource() throws Exception {
workbook.close();
poifs.close();
}
int rowIx = 0;
while (rowIx < 65535) {
HSSFRow row = sheet.getRow(rowIx);
if (row == null) {
break;
}
HSSFCell cell = row.getCell(0);
if (cell == null || cell.getCellType() == HSSFCell.CELL_TYPE_BLANK) {
break;
}
String formula = cell.getCellFormula();
try {
confirmCell(cell, formula, wb);
} catch (AssertionFailedError e) {
System.out.flush();
System.err.println("Problem with row[" + rowIx + "] formula '" + formula + "'");
System.err.println(e.getMessage());
System.err.flush();
countFailures++;
} catch (RuntimeException e) {
System.err.println("Problem with row[" + rowIx + "] formula '" + formula + "'");
countErrors++;
e.printStackTrace();
}
rowIx++;
}
if (countErrors + countFailures > 0) {
String msg = "One or more RVA tests failed: countFailures=" + countFailures
+ " countFailures=" + countErrors + ". See stderr for details.";
throw new AssertionFailedError(msg);
}
}
@Parameters(name="{1}")
public static Collection<Object[]> data() throws Exception {
poifs = new NPOIFSFileSystem(HSSFTestDataSamples.getSampleFile("testRVA.xls"), true);
workbook = new HSSFWorkbook(poifs);
sheet = workbook.getSheetAt(0);
private void confirmCell(HSSFCell formulaCell, String formula, HSSFWorkbook wb) {
List<Object[]> data = new ArrayList<Object[]>();
for (int rowIdx = 0; true; rowIdx++) {
HSSFRow row = sheet.getRow(rowIdx);
if (row == null) {
break;
}
HSSFCell cell = row.getCell(0);
if (cell == null || cell.getCellType() == HSSFCell.CELL_TYPE_BLANK) {
break;
}
String formula = cell.getCellFormula();
data.add(new Object[]{cell,formula});
}
return data;
}
@Test
public void confirmCell() {
Ptg[] excelPtgs = FormulaExtractor.getPtgs(formulaCell);
Ptg[] poiPtgs = HSSFFormulaParser.parse(formula, wb);
Ptg[] poiPtgs = HSSFFormulaParser.parse(formula, workbook);
int nExcelTokens = excelPtgs.length;
int nPoiTokens = poiPtgs.length;
if (nExcelTokens != nPoiTokens) {
@ -94,8 +105,7 @@ public final class TestRVA extends TestCase {
System.arraycopy(poiPtgs, 0, temp, 1, nPoiTokens);
poiPtgs = temp;
} else {
throw new RuntimeException("Expected " + nExcelTokens + " tokens but got "
+ nPoiTokens);
fail("Expected " + nExcelTokens + " tokens but got " + nPoiTokens);
}
}
boolean hasMismatch = false;
@ -123,13 +133,11 @@ public final class TestRVA extends TestCase {
}
sb.append(NEW_LINE);
}
if (false) { // set 'true' to see trace of RVA values
System.out.println(formulaCell.getRowIndex() + " " + formula);
System.out.println(sb.toString());
}
if (hasMismatch) {
throw new AssertionFailedError(sb.toString());
}
// if (false) { // set 'true' to see trace of RVA values
// System.out.println(formulaCell.getRowIndex() + " " + formula);
// System.out.println(sb.toString());
// }
assertFalse(hasMismatch);
}
private String getShortClassName(Object o) {

View File

@ -17,14 +17,17 @@
package org.apache.poi.hssf.model;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import junit.framework.AssertionFailedError;
import junit.framework.TestCase;
import org.apache.poi.ddf.EscherDggRecord;
import org.apache.poi.hssf.HSSFTestDataSamples;
import org.apache.poi.hssf.record.BOFRecord;
@ -62,13 +65,14 @@ import org.apache.poi.hssf.usermodel.RecordInspector.RecordCollector;
import org.apache.poi.ss.formula.FormulaShifter;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.util.HexRead;
import org.junit.Test;
import junit.framework.AssertionFailedError;
/**
* Unit test for the {@link InternalSheet} class.
*
* @author Glen Stampoultzis (glens at apache.org)
*/
public final class TestSheet extends TestCase {
public final class TestSheet {
private static InternalSheet createSheet(List<Record> inRecs) {
return InternalSheet.createSheet(new RecordStream(inRecs, 0));
}
@ -79,6 +83,7 @@ public final class TestSheet extends TestCase {
return rc.getRecords();
}
@Test
public void testCreateSheet() {
// Check we're adding row and cell aggregates
List<Record> records = new ArrayList<Record>();
@ -124,6 +129,7 @@ public final class TestSheet extends TestCase {
}
}
@Test
public void testAddMergedRegion() {
InternalSheet sheet = InternalSheet.createSheet();
int regionsToAdd = 4096;
@ -164,6 +170,7 @@ public final class TestSheet extends TestCase {
}
}
@Test
public void testRemoveMergedRegion() {
InternalSheet sheet = InternalSheet.createSheet();
int regionsToAdd = 4096;
@ -194,6 +201,7 @@ public final class TestSheet extends TestCase {
* fills up the records.
*
*/
@Test
public void testMovingMergedRegion() {
List<Record> records = new ArrayList<Record>();
@ -218,10 +226,12 @@ public final class TestSheet extends TestCase {
assertEquals("Should be no more merged regions", 0, sheet.getNumMergedRegions());
}
@Test
public void testGetMergedRegionAt() {
//TODO
}
@Test
public void testGetNumMergedRegions() {
//TODO
}
@ -230,6 +240,7 @@ public final class TestSheet extends TestCase {
* Makes sure all rows registered for this sheet are aggregated, they were being skipped
*
*/
@Test
public void testRowAggregation() {
List<Record> records = new ArrayList<Record>();
@ -253,6 +264,7 @@ public final class TestSheet extends TestCase {
* Make sure page break functionality works (in memory)
*
*/
@Test
public void testRowPageBreaks() {
short colFrom = 0;
short colTo = 255;
@ -309,6 +321,7 @@ public final class TestSheet extends TestCase {
* Make sure column pag breaks works properly (in-memory)
*
*/
@Test
public void testColPageBreaks() {
short rowFrom = 0;
short rowTo = (short)65535;
@ -370,6 +383,7 @@ public final class TestSheet extends TestCase {
* test newly added method Sheet.getXFIndexForColAt(..)
* works as designed.
*/
@Test
public void testXFIndexForColumn() {
final short TEST_IDX = 10;
final short DEFAULT_IDX = 0xF; // 15
@ -461,6 +475,7 @@ public final class TestSheet extends TestCase {
* Prior to bug 45066, POI would get the estimated sheet size wrong
* when an <tt>UncalcedRecord</tt> was present.<p/>
*/
@Test
public void testUncalcSize_bug45066() {
List<Record> records = new ArrayList<Record>();
@ -486,6 +501,7 @@ public final class TestSheet extends TestCase {
*
* The code here represents a normal POI use case where a spreadsheet is created from scratch.
*/
@Test
public void testRowValueAggregatesOrder_bug45145() {
InternalSheet sheet = InternalSheet.createSheet();
@ -506,12 +522,12 @@ public final class TestSheet extends TestCase {
throw new AssertionFailedError("Identified bug 45145");
}
if (false) {
// make sure that RRA and VRA are in the right place
// (Aug 2008) since the VRA is now part of the RRA, there is much less chance that
// they could get out of order. Still, one could write serialize the sheet here,
// and read back with EventRecordFactory to make sure...
}
// if (false) {
// // make sure that RRA and VRA are in the right place
// // (Aug 2008) since the VRA is now part of the RRA, there is much less chance that
// // they could get out of order. Still, one could write serialize the sheet here,
// // and read back with EventRecordFactory to make sure...
// }
assertEquals(242, dbCellRecordPos);
}
@ -551,6 +567,7 @@ public final class TestSheet extends TestCase {
* Checks for bug introduced around r682282-r683880 that caused a second GUTS records
* which in turn got the dimensions record out of alignment
*/
@Test
public void testGutsRecord_bug45640() {
InternalSheet sheet = InternalSheet.createSheet();
@ -571,21 +588,25 @@ public final class TestSheet extends TestCase {
assertEquals(1, count);
}
public void testMisplacedMergedCellsRecords_bug45699() {
@Test
public void testMisplacedMergedCellsRecords_bug45699() throws Exception {
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("ex45698-22488.xls");
HSSFSheet sheet = wb.getSheetAt(0);
HSSFRow row = sheet.getRow(3);
HSSFCell cell = row.getCell(4);
if (cell == null) {
throw new AssertionFailedError("Identified bug 45699");
fail("Identified bug 45699");
}
assertEquals("Informations", cell.getRichStringCellValue().getString());
wb.close();
}
/**
* In 3.1, setting margins between creating first row and first cell caused an exception.
*/
public void testSetMargins_bug45717() {
@Test
public void testSetMargins_bug45717() throws Exception {
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = workbook.createSheet("Vorschauliste");
HSSFRow row = sheet.createRow(0);
@ -595,9 +616,11 @@ public final class TestSheet extends TestCase {
row.createCell(0);
} catch (IllegalStateException e) {
if (e.getMessage().equals("Cannot create value records before row records exist")) {
throw new AssertionFailedError("Identified bug 45717");
fail("Identified bug 45717");
}
throw e;
} finally {
workbook.close();
}
}
@ -605,6 +628,7 @@ public final class TestSheet extends TestCase {
* Some apps seem to write files with missing DIMENSION records.
* Excel(2007) tolerates this, so POI should too.
*/
@Test
public void testMissingDims() {
int rowIx = 5;
@ -648,6 +672,7 @@ public final class TestSheet extends TestCase {
* aggregates. However, since this unnecessary creation helped expose bug 46547b,
* and since there is a slight performance hit the fix was made to avoid it.
*/
@Test
public void testShiftFormulasAddCondFormat_bug46547() {
// Create a sheet with data validity (similar to bugzilla attachment id=23131).
InternalSheet sheet = InternalSheet.createSheet();
@ -666,6 +691,7 @@ public final class TestSheet extends TestCase {
* Bug 46547 happened when attempting to add conditional formatting to a sheet
* which already had data validity constraints.
*/
@Test
public void testAddCondFormatAfterDataValidation_bug46547() {
// Create a sheet with data validity (similar to bugzilla attachment id=23131).
InternalSheet sheet = InternalSheet.createSheet();
@ -682,6 +708,7 @@ public final class TestSheet extends TestCase {
assertNotNull(cft);
}
@Test
public void testCloneMulBlank_bug46776() {
Record[] recs = {
InternalSheet.createBOF(),
@ -711,6 +738,7 @@ public final class TestSheet extends TestCase {
assertEquals(recs.length+2, clonedRecs.length); // +2 for INDEX and DBCELL
}
@Test
public void testCreateAggregate() {
String msoDrawingRecord1 =
"0F 00 02 F0 20 01 00 00 10 00 08 F0 08 00 00 00 \n" +
@ -798,6 +826,7 @@ public final class TestSheet extends TestCase {
assertEquals(EOFRecord.sid, ((Record)sheetRecords.get(3)).getSid());
}
@Test
public void testSheetDimensions() throws IOException{
InternalSheet sheet = InternalSheet.createSheet();
DimensionsRecord dimensions = (DimensionsRecord)sheet.findFirstRecordBySid(DimensionsRecord.sid);

View File

@ -17,7 +17,7 @@
package org.apache.poi.hssf.record.aggregates;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.*;
import java.io.IOException;
import java.io.InputStream;
@ -25,9 +25,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.zip.CRC32;
import junit.framework.AssertionFailedError;
import junit.framework.TestCase;
import org.apache.poi.hssf.HSSFTestDataSamples;
import org.apache.poi.hssf.model.RecordStream;
import org.apache.poi.hssf.model.RowBlocksReader;
@ -39,15 +36,17 @@ import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.record.SharedFormulaRecord;
import org.apache.poi.hssf.record.WindowTwoRecord;
import org.apache.poi.hssf.record.aggregates.RecordAggregate.RecordVisitor;
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.util.HexRead;
import org.junit.Test;
import junit.framework.AssertionFailedError;
/**
* Tests for {@link ValueRecordsAggregate}
*/
public final class TestValueRecordsAggregate extends TestCase {
public final class TestValueRecordsAggregate {
private static final String ABNORMAL_SHARED_FORMULA_FLAG_TEST_FILE = "AbnormalSharedFormulaFlag.xls";
private final ValueRecordsAggregate valueRecord = new ValueRecordsAggregate();
@ -56,6 +55,7 @@ public final class TestValueRecordsAggregate extends TestCase {
* as part of the value records
*/
@SuppressWarnings("deprecation") // uses deprecated {@link ValueRecordsAggregate#getValueRecords()}
@Test
public void testSharedFormula() {
List<Record> records = new ArrayList<Record>();
records.add(new FormulaRecord());
@ -97,6 +97,7 @@ public final class TestValueRecordsAggregate extends TestCase {
}
@SuppressWarnings("deprecation") // uses deprecated {@link ValueRecordsAggregate#getValueRecords()}
@Test
public void testInsertCell() {
CellValueRecordInterface[] cvrs = valueRecord.getValueRecords();
assertEquals(0, cvrs.length);
@ -108,7 +109,8 @@ public final class TestValueRecordsAggregate extends TestCase {
}
@SuppressWarnings("deprecation") // uses deprecated {@link ValueRecordsAggregate#getValueRecords()}
public void testRemoveCell() {
@Test
public void testRemoveCell() {
BlankRecord blankRecord1 = newBlankRecord();
valueRecord.insertCell( blankRecord1 );
BlankRecord blankRecord2 = newBlankRecord();
@ -120,6 +122,7 @@ public final class TestValueRecordsAggregate extends TestCase {
valueRecord.removeCell( blankRecord2 );
}
@Test
public void testGetPhysicalNumberOfCells() {
assertEquals(0, valueRecord.getPhysicalNumberOfCells());
BlankRecord blankRecord1 = newBlankRecord();
@ -129,6 +132,7 @@ public final class TestValueRecordsAggregate extends TestCase {
assertEquals(0, valueRecord.getPhysicalNumberOfCells());
}
@Test
public void testGetFirstCellNum() {
assertEquals( -1, valueRecord.getFirstCellNum() );
valueRecord.insertCell( newBlankRecord( 2, 2 ) );
@ -141,6 +145,7 @@ public final class TestValueRecordsAggregate extends TestCase {
assertEquals( 2, valueRecord.getFirstCellNum() );
}
@Test
public void testGetLastCellNum() {
assertEquals( -1, valueRecord.getLastCellNum() );
valueRecord.insertCell( newBlankRecord( 2, 2 ) );
@ -172,6 +177,7 @@ public final class TestValueRecordsAggregate extends TestCase {
}
}
@Test
public void testSerialize() {
byte[] expectedArray = HexRead.readFromString(""
+ "06 00 16 00 " // Formula
@ -230,7 +236,8 @@ public final class TestValueRecordsAggregate extends TestCase {
* There are other variations on this theme to create the same effect.
*
*/
public void testSpuriousSharedFormulaFlag() {
@Test
public void testSpuriousSharedFormulaFlag() throws Exception {
long actualCRC = getFileCRC(HSSFTestDataSamples.openSampleFileStream(ABNORMAL_SHARED_FORMULA_FLAG_TEST_FILE));
long expectedCRC = 2277445406L;
@ -245,18 +252,15 @@ public final class TestValueRecordsAggregate extends TestCase {
String cellFormula;
cellFormula = getFormulaFromFirstCell(s, 0); // row "1"
// the problem is not observable in the first row of the shared formula
if(!cellFormula.equals("\"first formula\"")) {
throw new RuntimeException("Something else wrong with this test case");
}
assertEquals("Something else wrong with this test case", "\"first formula\"", cellFormula);
// but the problem is observable in rows 2,3,4
cellFormula = getFormulaFromFirstCell(s, 1); // row "2"
if(cellFormula.equals("\"second formula\"")) {
throw new AssertionFailedError("found bug 44449 (Wrong SharedFormulaRecord was used).");
}
if(!cellFormula.equals("\"first formula\"")) {
throw new RuntimeException("Something else wrong with this test case");
}
assertNotEquals("found bug 44449 (Wrong SharedFormulaRecord was used).", "\"second formula\"", cellFormula);
assertEquals("Something else wrong with this test case", "\"first formula\"", cellFormula);
wb.close();
}
private static String getFormulaFromFirstCell(HSSFSheet s, int rowIx) {
return s.getRow(rowIx).getCell(0).getCellFormula();
@ -302,6 +306,8 @@ public final class TestValueRecordsAggregate extends TestCase {
return crc.getValue();
}
@Test
public void testRemoveNewRow_bug46312() {
// To make bug occur, rowIndex needs to be >= ValueRecordsAggregate.records.length
int rowIndex = 30;
@ -316,26 +322,27 @@ public final class TestValueRecordsAggregate extends TestCase {
throw e;
}
if (false) { // same bug as demonstrated through usermodel API
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet();
HSSFRow row = sheet.createRow(rowIndex);
if (false) { // must not add any cells to the new row if we want to see the bug
row.createCell(0); // this causes ValueRecordsAggregate.records to auto-extend
}
try {
sheet.createRow(rowIndex);
} catch (IllegalArgumentException e) {
throw new AssertionFailedError("Identified bug 46312");
}
}
// if (false) { // same bug as demonstrated through usermodel API
//
// HSSFWorkbook wb = new HSSFWorkbook();
// HSSFSheet sheet = wb.createSheet();
// HSSFRow row = sheet.createRow(rowIndex);
// if (false) { // must not add any cells to the new row if we want to see the bug
// row.createCell(0); // this causes ValueRecordsAggregate.records to auto-extend
// }
// try {
// sheet.createRow(rowIndex);
// } catch (IllegalArgumentException e) {
// throw new AssertionFailedError("Identified bug 46312");
// }
// }
}
/**
* Tests various manipulations of blank cells, to make sure that {@link MulBlankRecord}s
* are use appropriately
*/
@Test
public void testMultipleBlanks() {
BlankRecord brA2 = newBlankRecord(0, 1);
BlankRecord brB2 = newBlankRecord(1, 1);

View File

@ -17,146 +17,152 @@
package org.apache.poi.ss.formula.function;
import java.lang.reflect.InvocationTargetException;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import junit.framework.AssertionFailedError;
import junit.framework.TestCase;
import java.lang.reflect.InvocationTargetException;
import org.apache.poi.hssf.HSSFTestDataSamples;
import org.apache.poi.hssf.record.RecordFormatException;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
/**
* Tests reading from a sample spreadsheet some built-in functions that were not properly
* registered in POI as of bug #44675, #44733 (March/April 2008).
*
* @author Josh Micich
*/
public final class TestReadMissingBuiltInFuncs extends TestCase {
public final class TestReadMissingBuiltInFuncs {
/**
* This spreadsheet has examples of calls to the interesting built-in functions in cells A1:A7
*/
private static final String SAMPLE_SPREADSHEET_FILE_NAME = "missingFuncs44675.xls";
private static HSSFWorkbook wb;
private static HSSFSheet _sheet;
private static HSSFSheet getSheet() {
if (_sheet == null) {
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook(SAMPLE_SPREADSHEET_FILE_NAME);
_sheet = wb.getSheetAt(0);
}
return _sheet;
@BeforeClass
public static void initSheet() {
wb = HSSFTestDataSamples.openSampleWorkbook(SAMPLE_SPREADSHEET_FILE_NAME);
try {
_sheet = wb.getSheetAt(0);
} catch (RecordFormatException e) {
if(e.getCause() instanceof InvocationTargetException) {
InvocationTargetException ite = (InvocationTargetException) e.getCause();
if(ite.getTargetException() instanceof RuntimeException) {
RuntimeException re = (RuntimeException) ite.getTargetException();
if(re.getMessage().equals("Invalid built-in function index (189)")) {
fail("DPRODUCT() registered with wrong index");
}
}
}
// some other unexpected error
throw e;
}
}
@AfterClass
public static void closeResources() throws Exception {
wb.close();
}
@Test
public void testDatedif() {
String formula;
try {
formula = getCellFormula(0);
} catch (IllegalStateException e) {
if(e.getMessage().startsWith("Too few arguments")) {
if(e.getMessage().startsWith("Too few arguments")) {
if(e.getMessage().indexOf("AttrPtg") > 0) {
throw afe("tAttrVolatile not supported in FormulaParser.toFormulaString");
fail("tAttrVolatile not supported in FormulaParser.toFormulaString");
}
throw afe("NOW() registered with 1 arg instead of 0");
fail("NOW() registered with 1 arg instead of 0");
}
if(e.getMessage().startsWith("too much stuff")) {
throw afe("DATEDIF() not registered");
fail("DATEDIF() not registered");
}
// some other unexpected error
throw e;
}
assertEquals("DATEDIF(NOW(),NOW(),\"d\")", formula);
}
@Test
public void testDdb() {
String formula = getCellFormula(1);
if("externalflag(1,1,1,1,1)".equals(formula)) {
throw afe("DDB() not registered");
fail("DDB() not registered");
}
assertEquals("DDB(1,1,1,1,1)", formula);
}
@Test
public void testAtan() {
String formula = getCellFormula(2);
if(formula.equals("ARCTAN(1)")) {
throw afe("func ix 18 registered as ARCTAN() instead of ATAN()");
if("ARCTAN(1)".equals(formula)) {
fail("func ix 18 registered as ARCTAN() instead of ATAN()");
}
assertEquals("ATAN(1)", formula);
}
@Test
public void testUsdollar() {
String formula = getCellFormula(3);
if(formula.equals("YEN(1)")) {
throw afe("func ix 204 registered as YEN() instead of USDOLLAR()");
if("YEN(1)".equals(formula)) {
fail("func ix 204 registered as YEN() instead of USDOLLAR()");
}
assertEquals("USDOLLAR(1)", formula);
}
@Test
public void testDBCS() {
String formula;
String formula = "";
try {
formula = getCellFormula(4);
} catch (IllegalStateException e) {
if(e.getMessage().startsWith("too much stuff")) {
throw afe("DBCS() not registered");
fail("DBCS() not registered");
}
// some other unexpected error
throw e;
} catch (NegativeArraySizeException e) {
throw afe("found err- DBCS() registered with -1 args");
fail("found err- DBCS() registered with -1 args");
}
if(formula.equals("JIS(\"abc\")")) {
throw afe("func ix 215 registered as JIS() instead of DBCS()");
if("JIS(\"abc\")".equals(formula)) {
fail("func ix 215 registered as JIS() instead of DBCS()");
}
assertEquals("DBCS(\"abc\")", formula);
}
@Test
public void testIsnontext() {
String formula;
try {
formula = getCellFormula(5);
} catch (IllegalStateException e) {
if(e.getMessage().startsWith("too much stuff")) {
throw afe("ISNONTEXT() registered with wrong index");
fail("ISNONTEXT() registered with wrong index");
}
// some other unexpected error
throw e;
}
assertEquals("ISNONTEXT(\"abc\")", formula);
}
@Test
public void testDproduct() {
String formula = getCellFormula(6);
assertEquals("DPRODUCT(C1:E5,\"HarvestYield\",G1:H2)", formula);
}
private String getCellFormula(int rowIx) {
HSSFSheet sheet;
try {
sheet = getSheet();
} catch (RecordFormatException e) {
if(e.getCause() instanceof InvocationTargetException) {
InvocationTargetException ite = (InvocationTargetException) e.getCause();
if(ite.getTargetException() instanceof RuntimeException) {
RuntimeException re = (RuntimeException) ite.getTargetException();
if(re.getMessage().equals("Invalid built-in function index (189)")) {
throw afe("DPRODUCT() registered with wrong index");
}
}
}
// some other unexpected error
throw e;
}
String result = sheet.getRow(rowIx).getCell(0).getCellFormula();
if (false) {
System.err.println(result);
}
String result = _sheet.getRow(rowIx).getCell(0).getCellFormula();
// if (false) {
// System.err.println(result);
// }
return result;
}
private static AssertionFailedError afe(String msg) {
return new AssertionFailedError(msg);
}
}

View File

@ -17,23 +17,27 @@
package org.apache.poi.ss.formula.functions;
import junit.framework.AssertionFailedError;
import junit.framework.TestCase;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
import org.apache.poi.hssf.usermodel.HSSFName;
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.eval.ErrorEval;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellValue;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.junit.Test;
/**
* Tests for the INDIRECT() function.</p>
*
* @author Josh Micich
*/
public final class TestIndirect extends TestCase {
public final class TestIndirect {
// convenient access to namespace
private static final ErrorEval EE = null;
// private static final ErrorEval EE = null;
private static void createDataRow(HSSFSheet sheet, int rowIndex, double... vals) {
HSSFRow row = sheet.createRow(rowIndex);
@ -91,7 +95,8 @@ public final class TestIndirect extends TestCase {
return wb;
}
public void testBasic() {
@Test
public void testBasic() throws Exception {
HSSFWorkbook wbA = createWBA();
HSSFCell c = wbA.getSheetAt(0).createRow(5).createCell(2);
@ -138,14 +143,17 @@ public final class TestIndirect extends TestCase {
confirm(feA, c, "SUM(INDIRECT(\"'John's sales'!A1:C1\"))", ErrorEval.REF_INVALID); // bad quote escaping
confirm(feA, c, "INDIRECT(\"[Book1]Sheet1!A1\")", ErrorEval.REF_INVALID); // unknown external workbook
confirm(feA, c, "INDIRECT(\"Sheet3!A1\")", ErrorEval.REF_INVALID); // unknown sheet
if (false) { // TODO - support evaluation of defined names
confirm(feA, c, "INDIRECT(\"Sheet1!IW1\")", ErrorEval.REF_INVALID); // bad column
confirm(feA, c, "INDIRECT(\"Sheet1!A65537\")", ErrorEval.REF_INVALID); // bad row
}
// if (false) { // TODO - support evaluation of defined names
// confirm(feA, c, "INDIRECT(\"Sheet1!IW1\")", ErrorEval.REF_INVALID); // bad column
// confirm(feA, c, "INDIRECT(\"Sheet1!A65537\")", ErrorEval.REF_INVALID); // bad row
// }
confirm(feA, c, "INDIRECT(\"Sheet1!A 1\")", ErrorEval.REF_INVALID); // space in cell ref
wbA.close();
}
public void testMultipleWorkbooks() {
@Test
public void testMultipleWorkbooks() throws Exception {
HSSFWorkbook wbA = createWBA();
HSSFCell cellA = wbA.getSheetAt(0).createRow(10).createCell(0);
HSSFFormulaEvaluator feA = new HSSFFormulaEvaluator(wbA);
@ -164,6 +172,9 @@ public final class TestIndirect extends TestCase {
// 2 level recursion
confirm(feB, cellB, "INDIRECT(\"[MyBook]Sheet2!A1\")", 50); // set up (and check) first level
confirm(feA, cellA, "INDIRECT(\"'[Figures for January]Sheet1'!A11\")", 50); // points to cellB
wbB.close();
wbA.close();
}
private static void confirm(FormulaEvaluator fe, Cell cell, String formula,
@ -172,21 +183,22 @@ public final class TestIndirect extends TestCase {
cell.setCellFormula(formula);
CellValue cv = fe.evaluate(cell);
if (cv.getCellType() != Cell.CELL_TYPE_NUMERIC) {
throw new AssertionFailedError("expected numeric cell type but got " + cv.formatAsString());
fail("expected numeric cell type but got " + cv.formatAsString());
}
assertEquals(expectedResult, cv.getNumberValue(), 0.0);
}
private static void confirm(FormulaEvaluator fe, Cell cell, String formula,
ErrorEval expectedResult) {
fe.clearAllCachedResultValues();
cell.setCellFormula(formula);
CellValue cv = fe.evaluate(cell);
if (cv.getCellType() != Cell.CELL_TYPE_ERROR) {
throw new AssertionFailedError("expected error cell type but got " + cv.formatAsString());
fail("expected error cell type but got " + cv.formatAsString());
}
int expCode = expectedResult.getErrorCode();
if (cv.getErrorValue() != expCode) {
throw new AssertionFailedError("Expected error '" + ErrorEval.getText(expCode)
fail("Expected error '" + ErrorEval.getText(expCode)
+ "' but got '" + cv.formatAsString() + "'.");
}
}