diff --git a/src/contrib/src/org/apache/poi/ss/ExcelComparator.java b/src/contrib/src/org/apache/poi/ss/ExcelComparator.java deleted file mode 100644 index f1e658734..000000000 --- a/src/contrib/src/org/apache/poi/ss/ExcelComparator.java +++ /dev/null @@ -1,1348 +0,0 @@ -/* ==================================================================== - 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; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.ss.usermodel.Cell; -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.util.CellReference; -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. - * - *

This utility will be used to compare Excel File Contents cell by cell for all sheets programmatically.

- * - *

Below are the list of Attribute comparison supported in this version.

- * - * - * - *

(Some of the above attribute comparison only work for *.xlsx format currently. In future it can be enhanced.)

- * - *

Usage:

- * - *
- * {@code
- *  Workbook wb1 = WorkbookFactory.create(new File("workBook1.xls"));
- *  Workbook wb2 = WorkbookFactory.create(new File("workBook2.xls"));
- *  ExcelFileDifference excelFileDifference = ExcelComparator.compare(wb1, wb2);
- *  for (String differences : excelFileDifference.listOfDifferences)
- *      System.out.println(differences);
- *  System.out.println("DifferenceFound = "+ excelFileDifference.isDifferenceFound);
- *  }
- * 
- */ -public class ExcelComparator { - - private static final String BOLD = "BOLD"; - private static final String BOTTOM_BORDER = "BOTTOM BORDER"; - private static final String BRACKET_END = "]"; - private static final String BRACKET_START = " ["; - private static final String CELL_ALIGNMENT_DOES_NOT_MATCH = "Cell Alignment does not Match ::"; - private static final String CELL_BORDER_ATTRIBUTES_DOES_NOT_MATCH = "Cell Border Attributes does not Match ::"; - private static final String CELL_DATA_DOES_NOT_MATCH = "Cell Data does not Match ::"; - private static final String CELL_DATA_TYPE_DOES_NOT_MATCH = "Cell Data-Type does not Match in :: "; - private static final String CELL_FILL_COLOR_DOES_NOT_MATCH = "Cell Fill Color does not Match ::"; - private static final String CELL_FILL_PATTERN_DOES_NOT_MATCH = "Cell Fill pattern does not Match ::"; - private static final String CELL_FONT_ATTRIBUTES_DOES_NOT_MATCH = "Cell Font Attributes does not Match ::"; - private static final String CELL_FONT_FAMILY_DOES_NOT_MATCH = "Cell Font Family does not Match ::"; - private static final String CELL_FONT_SIZE_DOES_NOT_MATCH = "Cell Font Size does not Match ::"; - private static final String CELL_PROTECTION_DOES_NOT_MATCH = "Cell Protection does not Match ::"; - private static final String ITALICS = "ITALICS"; - private static final String LEFT_BORDER = "LEFT BORDER"; - private static final String LINE_SEPARATOR = "line.separator"; - private static final String NAME_OF_THE_SHEETS_DO_NOT_MATCH = "Name of the sheets do not match :: "; - private static final String NEXT_STR = " -> "; - private static final String NO_BOTTOM_BORDER = "NO BOTTOM BORDER"; - private static final String NO_COLOR = "NO COLOR"; - private static final String NO_LEFT_BORDER = "NO LEFT BORDER"; - private static final String NO_RIGHT_BORDER = "NO RIGHT BORDER"; - private static final String NO_TOP_BORDER = "NO TOP BORDER"; - private static final String NOT_BOLD = "NOT BOLD"; - private static final String NOT_EQUALS = " != "; - private static final String NOT_ITALICS = "NOT ITALICS"; - private static final String NOT_UNDERLINE = "NOT UNDERLINE"; - private static final String NUMBER_OF_COLUMNS_DOES_NOT_MATCH = "Number Of Columns does not Match :: "; - private static final String NUMBER_OF_ROWS_DOES_NOT_MATCH = "Number Of Rows does not Match :: "; - private static final String NUMBER_OF_SHEETS_DO_NOT_MATCH = "Number of Sheets do not match :: "; - private static final String RIGHT_BORDER = "RIGHT BORDER"; - private static final String TOP_BORDER = "TOP BORDER"; - private static final String UNDERLINE = "UNDERLINE"; - private static final String WORKBOOK1 = "workbook1"; - private static final String WORKBOOK2 = "workbook2"; - - /** - * 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 ExcelFileDifference compare(Workbook workbook1, - Workbook workbook2) { - List listOfDifferences = compareWorkBookContents(workbook1, - workbook2); - return populateListOfDifferences(listOfDifferences); - } - - /** - * Compare work book contents. - * - * @param workbook1 - * the workbook1 - * @param workbook2 - * the workbook2 - * @return the list - */ - private static List compareWorkBookContents(Workbook workbook1, - Workbook workbook2) { - ExcelComparator excelComparator = new ExcelComparator(); - List listOfDifferences = new ArrayList(); - excelComparator.compareNumberOfSheets(workbook1, workbook2, - listOfDifferences); - excelComparator.compareSheetNames(workbook1, workbook2, - listOfDifferences); - excelComparator.compareSheetData(workbook1, workbook2, - listOfDifferences); - return listOfDifferences; - } - - /** - * Populate list of differences. - * - * @param listOfDifferences - * the list of differences - * @return the excel file difference - */ - private static ExcelFileDifference populateListOfDifferences( - List listOfDifferences) { - ExcelFileDifference excelFileDifference = new ExcelFileDifference(); - excelFileDifference.isDifferenceFound = listOfDifferences.size() > 0; - excelFileDifference.listOfDifferences = listOfDifferences; - return excelFileDifference; - } - - /** - * 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(Workbook workbook1, Workbook workbook2, - List listOfDifferences) { - for (int i = 0; i < workbook1.getNumberOfSheets(); i++) { - Sheet sheetWorkBook1 = workbook1.getSheetAt(i); - Sheet sheetWorkBook2; - if (workbook2.getNumberOfSheets() > i) { - sheetWorkBook2 = workbook2.getSheetAt(i); - } else { - sheetWorkBook2 = null; - } - - for (int j = 0; j < sheetWorkBook1.getPhysicalNumberOfRows(); j++) { - Row rowWorkBook1 = sheetWorkBook1.getRow(j); - Row rowWorkBook2; - if (sheetWorkBook2 != null) { - rowWorkBook2 = sheetWorkBook2.getRow(j); - } else { - rowWorkBook2 = null; - } - - if ((rowWorkBook1 == null) || (rowWorkBook2 == null)) { - continue; - } - for (int k = 0; k < rowWorkBook1.getLastCellNum(); k++) { - Cell cellWorkBook1 = rowWorkBook1.getCell(k); - Cell cellWorkBook2 = rowWorkBook2.getCell(k); - - if (!((null == cellWorkBook1) || (null == cellWorkBook2))) { - if (isCellTypeMatches(cellWorkBook1, cellWorkBook2)) { - - listOfDifferences.add(getMessage(workbook1, - workbook2, i, cellWorkBook1, cellWorkBook2, - CELL_DATA_TYPE_DOES_NOT_MATCH, - cellWorkBook1.getCellType() + "", - cellWorkBook2.getCellType() + "")); - } - - if (isCellContentTypeBlank(cellWorkBook1)) { - if (isCellContentMatches(cellWorkBook1, - cellWorkBook2)) { - - listOfDifferences.add(getMessage(workbook1, - workbook2, i, cellWorkBook1, - cellWorkBook2, - CELL_DATA_DOES_NOT_MATCH, - cellWorkBook1.getRichStringCellValue() - + "", - cellWorkBook2.getRichStringCellValue() - + "")); - - } - - } else if (isCellContentTypeBoolean(cellWorkBook1)) { - if (isCellContentMatchesForBoolean(cellWorkBook1, - cellWorkBook2)) { - listOfDifferences.add(getMessage(workbook1, - workbook2, i, cellWorkBook1, - cellWorkBook2, - CELL_DATA_DOES_NOT_MATCH, - cellWorkBook1.getBooleanCellValue() - + "", - cellWorkBook2.getBooleanCellValue() - + "")); - - } - - } else if (isCellContentInError(cellWorkBook1)) { - if (isCellContentMatches(cellWorkBook1, - cellWorkBook2)) { - - listOfDifferences.add(getMessage(workbook1, - workbook2, i, cellWorkBook1, - cellWorkBook2, - CELL_DATA_DOES_NOT_MATCH, - cellWorkBook1.getRichStringCellValue() - + "", - cellWorkBook2.getRichStringCellValue() - + "")); - - } - } else if (isCellContentFormula(cellWorkBook1)) { - if (isCellContentMatchesForFormula(cellWorkBook1, - cellWorkBook2)) { - - listOfDifferences.add(getMessage(workbook1, - workbook2, i, cellWorkBook1, - cellWorkBook2, - CELL_DATA_DOES_NOT_MATCH, - cellWorkBook1.getCellFormula() + "", - cellWorkBook2.getCellFormula() + "")); - - } - - } else if (isCellContentTypeNumeric(cellWorkBook1)) { - if (DateUtil.isCellDateFormatted(cellWorkBook1)) { - if (isCellContentMatchesForDate(cellWorkBook1, - cellWorkBook2)) { - listOfDifferences.add(getMessage(workbook1, - workbook2, i, cellWorkBook1, - cellWorkBook2, - CELL_DATA_DOES_NOT_MATCH, - cellWorkBook1.getDateCellValue() - + "", - cellWorkBook2.getDateCellValue() - + "")); - - } - } else { - if (isCellContentMatchesForNumeric( - cellWorkBook1, cellWorkBook2)) { - listOfDifferences.add(getMessage(workbook1, - workbook2, i, cellWorkBook1, - cellWorkBook2, - CELL_DATA_DOES_NOT_MATCH, - cellWorkBook1.getNumericCellValue() - + "", - cellWorkBook2.getNumericCellValue() - + "")); - - } - } - - } else if (isCellContentTypeString(cellWorkBook1)) { - if (isCellContentMatches(cellWorkBook1, - cellWorkBook2)) { - listOfDifferences.add(getMessage(workbook1, - workbook2, i, cellWorkBook1, - cellWorkBook2, - CELL_DATA_DOES_NOT_MATCH, cellWorkBook1 - .getRichStringCellValue() - .getString(), cellWorkBook2 - .getRichStringCellValue() - .getString())); - } - } - - if (isCellFillPatternMatches(cellWorkBook1, - cellWorkBook2)) { - listOfDifferences.add(getMessage(workbook1, - workbook2, i, cellWorkBook1, cellWorkBook2, - CELL_FILL_PATTERN_DOES_NOT_MATCH, - cellWorkBook1.getCellStyle() - .getFillPattern() + "", - cellWorkBook2.getCellStyle() - .getFillPattern() + "")); - - } - - if (isCellAlignmentMatches(cellWorkBook1, cellWorkBook2)) { - listOfDifferences.add(getMessage(workbook1, - workbook2, i, cellWorkBook1, cellWorkBook2, - CELL_ALIGNMENT_DOES_NOT_MATCH, - cellWorkBook1.getRichStringCellValue() - .getString(), cellWorkBook2 - .getRichStringCellValue() - .getString())); - - } - - if (isCellHiddenMatches(cellWorkBook1, cellWorkBook2)) { - listOfDifferences - .add(getMessage(workbook1, workbook2, i, - cellWorkBook1, cellWorkBook2, - CELL_PROTECTION_DOES_NOT_MATCH, - cellWorkBook1.getCellStyle() - .getHidden() ? "HIDDEN" - : "NOT HIDDEN", - cellWorkBook2.getCellStyle() - .getHidden() ? "HIDDEN" - : "NOT HIDDEN")); - - } - - if (isCellLockedMatches(cellWorkBook1, cellWorkBook2)) { - listOfDifferences - .add(getMessage(workbook1, workbook2, i, - cellWorkBook1, cellWorkBook2, - CELL_PROTECTION_DOES_NOT_MATCH, - cellWorkBook1.getCellStyle() - .getLocked() ? "LOCKED" - : "NOT LOCKED", - cellWorkBook2.getCellStyle() - .getLocked() ? "LOCKED" - : "NOT LOCKED")); - - } - - if (isCellFontFamilyMatches(cellWorkBook1, - cellWorkBook2)) { - listOfDifferences.add(getMessage(workbook1, - workbook2, i, cellWorkBook1, cellWorkBook2, - CELL_FONT_FAMILY_DOES_NOT_MATCH, - ((XSSFCellStyle) cellWorkBook1 - .getCellStyle()).getFont() - .getFontName(), - ((XSSFCellStyle) cellWorkBook2 - .getCellStyle()).getFont() - .getFontName())); - - } - - if (isCellFontSizeMatches(cellWorkBook1, cellWorkBook2)) { - listOfDifferences.add(getMessage( - workbook1, - workbook2, - i, - cellWorkBook1, - cellWorkBook2, - CELL_FONT_SIZE_DOES_NOT_MATCH, - ((XSSFCellStyle) cellWorkBook1 - .getCellStyle()).getFont() - .getFontHeightInPoints() - + "", - ((XSSFCellStyle) cellWorkBook2 - .getCellStyle()).getFont() - .getFontHeightInPoints() - + "")); - - } - - if (isCellFontBoldMatches(cellWorkBook1, cellWorkBook2)) { - listOfDifferences.add(getMessage(workbook1, - workbook2, i, cellWorkBook1, cellWorkBook2, - CELL_FONT_ATTRIBUTES_DOES_NOT_MATCH, - ((XSSFCellStyle) cellWorkBook1 - .getCellStyle()).getFont() - .getBold() ? BOLD : NOT_BOLD, - ((XSSFCellStyle) cellWorkBook2 - .getCellStyle()).getFont() - .getBold() ? BOLD : NOT_BOLD)); - - } - - if (isCellUnderLineMatches(cellWorkBook1, cellWorkBook2)) { - listOfDifferences.add(getMessage(workbook1, - workbook2, i, cellWorkBook1, cellWorkBook2, - CELL_FONT_ATTRIBUTES_DOES_NOT_MATCH, - ((XSSFCellStyle) cellWorkBook1 - .getCellStyle()).getFont() - .getUnderline() == 1 ? UNDERLINE - : NOT_UNDERLINE, - ((XSSFCellStyle) cellWorkBook2 - .getCellStyle()).getFont() - .getUnderline() == 1 ? UNDERLINE - : NOT_UNDERLINE)); - - } - - if (isCellFontItalicsMatches(cellWorkBook1, - cellWorkBook2)) { - listOfDifferences.add(getMessage(workbook1, - workbook2, i, cellWorkBook1, cellWorkBook2, - CELL_FONT_ATTRIBUTES_DOES_NOT_MATCH, - ((XSSFCellStyle) cellWorkBook1 - .getCellStyle()).getFont() - .getItalic() ? ITALICS - : NOT_ITALICS, - ((XSSFCellStyle) cellWorkBook2 - .getCellStyle()).getFont() - .getItalic() ? ITALICS - : NOT_ITALICS)); - - } - - if (isCellBorderBottomMatches(cellWorkBook1, - cellWorkBook2)) { - listOfDifferences - .add(getMessage( - workbook1, - workbook2, - i, - cellWorkBook1, - cellWorkBook2, - CELL_BORDER_ATTRIBUTES_DOES_NOT_MATCH, - ((XSSFCellStyle) cellWorkBook1 - .getCellStyle()) - .getBorderBottom() == 1 ? BOTTOM_BORDER - : NO_BOTTOM_BORDER, - ((XSSFCellStyle) cellWorkBook2 - .getCellStyle()) - .getBorderBottom() == 1 ? BOTTOM_BORDER - : NO_BOTTOM_BORDER)); - - } - - if (isCellBorderLeftMatches(cellWorkBook1, - cellWorkBook2)) { - listOfDifferences - .add(getMessage( - workbook1, - workbook2, - i, - cellWorkBook1, - cellWorkBook2, - CELL_BORDER_ATTRIBUTES_DOES_NOT_MATCH, - ((XSSFCellStyle) cellWorkBook1 - .getCellStyle()) - .getBorderLeft() == 1 ? LEFT_BORDER - : NO_LEFT_BORDER, - ((XSSFCellStyle) cellWorkBook2 - .getCellStyle()) - .getBorderLeft() == 1 ? LEFT_BORDER - : NO_LEFT_BORDER)); - - } - - if (isCellBorderRightMatches(cellWorkBook1, - cellWorkBook2)) { - listOfDifferences - .add(getMessage( - workbook1, - workbook2, - i, - cellWorkBook1, - cellWorkBook2, - CELL_BORDER_ATTRIBUTES_DOES_NOT_MATCH, - ((XSSFCellStyle) cellWorkBook1 - .getCellStyle()) - .getBorderRight() == 1 ? RIGHT_BORDER - : NO_RIGHT_BORDER, - ((XSSFCellStyle) cellWorkBook2 - .getCellStyle()) - .getBorderRight() == 1 ? RIGHT_BORDER - : NO_RIGHT_BORDER)); - - } - - if (isCellBorderTopMatches(cellWorkBook1, cellWorkBook2)) { - listOfDifferences - .add(getMessage( - workbook1, - workbook2, - i, - cellWorkBook1, - cellWorkBook2, - CELL_BORDER_ATTRIBUTES_DOES_NOT_MATCH, - ((XSSFCellStyle) cellWorkBook1 - .getCellStyle()) - .getBorderTop() == 1 ? TOP_BORDER - : NO_TOP_BORDER, - ((XSSFCellStyle) cellWorkBook2 - .getCellStyle()) - .getBorderTop() == 1 ? TOP_BORDER - : NO_TOP_BORDER)); - - } - - if (isCellBackGroundFillMatchesAndEmpty(cellWorkBook1, - cellWorkBook2)) { - continue; - } else if (isCellFillBackGroundMatchesAndEitherEmpty( - cellWorkBook1, cellWorkBook2)) { - listOfDifferences.add(getMessage( - workbook1, - workbook2, - i, - cellWorkBook1, - cellWorkBook2, - CELL_FILL_COLOR_DOES_NOT_MATCH, - NO_COLOR, - ((XSSFColor) cellWorkBook2.getCellStyle() - .getFillForegroundColorColor()) - .getARGBHex() - + "")); - - } else if (isCellFillBackGroundMatchesAndSecondEmpty( - cellWorkBook1, cellWorkBook2)) { - listOfDifferences.add(getMessage( - workbook1, - workbook2, - i, - cellWorkBook1, - cellWorkBook2, - CELL_FILL_COLOR_DOES_NOT_MATCH, - ((XSSFColor) cellWorkBook1.getCellStyle() - .getFillForegroundColorColor()) - .getARGBHex() - + "", NO_COLOR)); - - } else { - if (isCellFileBackGroundMatches(cellWorkBook1, - cellWorkBook2)) { - listOfDifferences.add(getMessage( - workbook1, - workbook2, - i, - cellWorkBook1, - cellWorkBook2, - CELL_FILL_COLOR_DOES_NOT_MATCH, - ((XSSFColor) cellWorkBook1 - .getCellStyle() - .getFillForegroundColorColor()) - .getARGBHex() - + "", - ((XSSFColor) cellWorkBook2 - .getCellStyle() - .getFillForegroundColorColor()) - .getARGBHex() - + "")); - - } - } - - } - } - } - } - } - - /** - * Compare number of columns in sheets. - * - * @param workbook1 - * the workbook1 - * @param workbook2 - * the workbook2 - * @param listOfDifferences - * the list of differences - * @throws ExcelCompareException - * the excel compare exception - */ - private void compareNumberOfColumnsInSheets(Workbook workbook1, - Workbook workbook2, List listOfDifferences) { - for (int i = 0; i < workbook1.getNumberOfSheets(); i++) { - Sheet sheetWorkBook1 = workbook1.getSheetAt(i); - Sheet sheetWorkBook2; - if (workbook2.getNumberOfSheets() > i) { - sheetWorkBook2 = workbook2.getSheetAt(i); - } else { - sheetWorkBook2 = null; - } - if (isWorkBookEmpty(sheetWorkBook1, sheetWorkBook2)) { - if (isNumberOfColumnsMatches(sheetWorkBook1, sheetWorkBook2)) { - String noOfCols; - String sheetName; - if (sheetWorkBook2 != null) { - noOfCols = sheetWorkBook2.getRow(0).getLastCellNum() - + ""; - sheetName = workbook2.getSheetName(i); - } else { - noOfCols = ""; - sheetName = ""; - } - short lastCellNumForWbk1 = sheetWorkBook1.getRow(0) != null ? sheetWorkBook1 - .getRow(0).getLastCellNum() : 0; - listOfDifferences.add(NUMBER_OF_COLUMNS_DOES_NOT_MATCH - + System.getProperty(LINE_SEPARATOR) + WORKBOOK1 - + NEXT_STR + workbook1.getSheetName(i) + NEXT_STR - + lastCellNumForWbk1 + NOT_EQUALS + WORKBOOK2 - + NEXT_STR + sheetName + NEXT_STR + noOfCols); - } - } - } - } - - /** - * Compare number of rows in sheets. - * - * @param workbook1 - * the workbook1 - * @param workbook2 - * the workbook2 - * @param listOfDifferences - * the list of differences - * @throws ExcelCompareException - * the excel compare exception - */ - private void compareNumberOfRowsInSheets(Workbook workbook1, - Workbook workbook2, List listOfDifferences) { - for (int i = 0; i < workbook1.getNumberOfSheets(); i++) { - Sheet sheetWorkBook1 = workbook1.getSheetAt(i); - Sheet sheetWorkBook2; - if (workbook2.getNumberOfSheets() > i) { - sheetWorkBook2 = workbook2.getSheetAt(i); - } else { - sheetWorkBook2 = null; - } - if (isNumberOfRowsMatches(sheetWorkBook1, sheetWorkBook2)) { - String noOfRows; - String sheetName; - if (sheetWorkBook2 != null) { - noOfRows = sheetWorkBook2.getPhysicalNumberOfRows() + ""; - sheetName = workbook2.getSheetName(i); - } else { - noOfRows = ""; - sheetName = ""; - } - listOfDifferences.add(NUMBER_OF_ROWS_DOES_NOT_MATCH - + System.getProperty(LINE_SEPARATOR) + WORKBOOK1 - + NEXT_STR + workbook1.getSheetName(i) + NEXT_STR - + sheetWorkBook1.getPhysicalNumberOfRows() + NOT_EQUALS - + WORKBOOK2 + NEXT_STR + sheetName + NEXT_STR - + noOfRows); - } - } - - } - - /** - * Compare number of sheets. - * - * @param workbook1 - * the workbook1 - * @param workbook2 - * the workbook2 - * @param listOfDifferences - * - * @throws ExcelCompareException - * the excel compare exception - */ - private void compareNumberOfSheets(Workbook workbook1, Workbook workbook2, - List listOfDifferences) { - if (isNumberOfSheetsMatches(workbook1, workbook2)) { - listOfDifferences.add(NUMBER_OF_SHEETS_DO_NOT_MATCH - + System.getProperty(LINE_SEPARATOR) + WORKBOOK1 + NEXT_STR - + workbook1.getNumberOfSheets() + NOT_EQUALS + WORKBOOK2 - + NEXT_STR + workbook2.getNumberOfSheets()); - } - } - - /** - * Compare sheet data. - * - * @param workbook1 - * the workbook1 - * @param workbook2 - * the workbook2 - * @param listOfDifferences - * - * @throws ExcelCompareException - * the excel compare exception - */ - private void compareSheetData(Workbook workbook1, Workbook workbook2, - List listOfDifferences) { - compareNumberOfRowsInSheets(workbook1, workbook2, listOfDifferences); - compareNumberOfColumnsInSheets(workbook1, workbook2, listOfDifferences); - compareDataInAllSheets(workbook1, workbook2, listOfDifferences); - - } - - /** - * Compare sheet names. - * - * @param workbook1 - * the workbook1 - * @param workbook2 - * the workbook2 - * @param listOfDifferences - * - * @throws ExcelCompareException - * the excel compare exception - */ - private void compareSheetNames(Workbook workbook1, Workbook workbook2, - List listOfDifferences) { - for (int i = 0; i < workbook1.getNumberOfSheets(); i++) { - if (isNameOfSheetMatches(workbook1, workbook2, i)) { - String sheetname = workbook2.getNumberOfSheets() > i ? workbook2 - .getSheetName(i) : ""; - listOfDifferences.add(NAME_OF_THE_SHEETS_DO_NOT_MATCH - + System.getProperty(LINE_SEPARATOR) + WORKBOOK1 - + NEXT_STR + workbook1.getSheetName(i) + BRACKET_START - + (i + 1) + BRACKET_END + NOT_EQUALS + WORKBOOK2 - + NEXT_STR + sheetname + BRACKET_START + (i + 1) - + BRACKET_END); - } - } - } - - /** - * Gets the message. - * - * @param workbook1 - * the workbook1 - * @param workbook2 - * the workbook2 - * @param i - * the i - * @param cellWorkBook1 - * the cell work book1 - * @param cellWorkBook2 - * the cell work book2 - * @param messageStart - * the message start - * @param workBook1Value - * the work book1 value - * @param workBook2Value - * the work book2 value - * @return the message - */ - private String getMessage(Workbook workbook1, Workbook workbook2, int i, - Cell cellWorkBook1, Cell cellWorkBook2, String messageStart, - String workBook1Value, String workBook2Value) { - StringBuilder sb = new StringBuilder(); - return sb - .append(messageStart) - .append(System.getProperty(LINE_SEPARATOR)) - .append(WORKBOOK1) - .append(NEXT_STR) - .append(workbook1.getSheetName(i)) - .append(NEXT_STR) - .append(new CellReference(cellWorkBook1.getRowIndex(), - cellWorkBook1.getColumnIndex()).formatAsString()) - .append(BRACKET_START) - .append(workBook1Value) - .append(BRACKET_END) - .append(NOT_EQUALS) - .append(WORKBOOK2) - .append(NEXT_STR) - .append(workbook2.getSheetName(i)) - .append(NEXT_STR) - .append(new CellReference(cellWorkBook2.getRowIndex(), - cellWorkBook2.getColumnIndex()).formatAsString()) - .append(BRACKET_START).append(workBook2Value) - .append(BRACKET_END).toString(); - } - - /** - * Checks if cell alignment matches. - * - * @param cellWorkBook1 - * the cell work book1 - * @param cellWorkBook2 - * the cell work book2 - * @return true, if cell alignment matches - */ - private boolean isCellAlignmentMatches(Cell cellWorkBook1, - Cell cellWorkBook2) { - return cellWorkBook1.getCellStyle().getAlignment() != cellWorkBook2 - .getCellStyle().getAlignment(); - } - - /** - * Checks if cell back ground fill matches and empty. - * - * @param cellWorkBook1 - * the cell work book1 - * @param cellWorkBook2 - * the cell work book2 - * @return true, if cell back ground fill matches and empty - */ - private boolean isCellBackGroundFillMatchesAndEmpty(Cell cellWorkBook1, - Cell cellWorkBook2) { - return (cellWorkBook1.getCellStyle().getFillForegroundColorColor() == null) - && (cellWorkBook2.getCellStyle().getFillForegroundColorColor() == null); - } - - /** - * Checks if cell border bottom matches. - * - * @param cellWorkBook1 - * the cell work book1 - * @param cellWorkBook2 - * the cell work book2 - * @return true, if cell border bottom matches - */ - private boolean isCellBorderBottomMatches(Cell cellWorkBook1, - Cell cellWorkBook2) { - if (cellWorkBook1.getCellStyle() instanceof XSSFCellStyle) { - return ((XSSFCellStyle) cellWorkBook1.getCellStyle()) - .getBorderBottom() != ((XSSFCellStyle) cellWorkBook2 - .getCellStyle()).getBorderBottom(); - } else { - return false; - } - - } - - /** - * Checks if cell border left matches. - * - * @param cellWorkBook1 - * the cell work book1 - * @param cellWorkBook2 - * the cell work book2 - * @return true, if cell border left matches - */ - private boolean isCellBorderLeftMatches(Cell cellWorkBook1, - Cell cellWorkBook2) { - if (cellWorkBook1.getCellStyle() instanceof XSSFCellStyle) { - return ((XSSFCellStyle) cellWorkBook1.getCellStyle()) - .getBorderLeft() != ((XSSFCellStyle) cellWorkBook2 - .getCellStyle()).getBorderLeft(); - } else { - return false; - } - - } - - /** - * Checks if cell border right matches. - * - * @param cellWorkBook1 - * the cell work book1 - * @param cellWorkBook2 - * the cell work book2 - * @return true, if cell border right matches - */ - private boolean isCellBorderRightMatches(Cell cellWorkBook1, - Cell cellWorkBook2) { - if (cellWorkBook1.getCellStyle() instanceof XSSFCellStyle) { - return ((XSSFCellStyle) cellWorkBook1.getCellStyle()) - .getBorderRight() != ((XSSFCellStyle) cellWorkBook2 - .getCellStyle()).getBorderRight(); - } else { - return false; - } - - } - - /** - * Checks if cell border top matches. - * - * @param cellWorkBook1 - * the cell work book1 - * @param cellWorkBook2 - * the cell work book2 - * @return true, if cell border top matches - */ - private boolean isCellBorderTopMatches(Cell cellWorkBook1, - Cell cellWorkBook2) { - if (cellWorkBook1.getCellStyle() instanceof XSSFCellStyle) { - return ((XSSFCellStyle) cellWorkBook1.getCellStyle()) - .getBorderTop() != ((XSSFCellStyle) cellWorkBook2 - .getCellStyle()).getBorderTop(); - } else { - return false; - } - - } - - /** - * Checks if cell content formula. - * - * @param cellWorkBook1 - * the cell work book1 - * @return true, if cell content formula - */ - private boolean isCellContentFormula(Cell cellWorkBook1) { - return cellWorkBook1.getCellType() == Cell.CELL_TYPE_FORMULA; - } - - /** - * Checks if cell content in error. - * - * @param cellWorkBook1 - * the cell work book1 - * @return true, if cell content in error - */ - private boolean isCellContentInError(Cell cellWorkBook1) { - return cellWorkBook1.getCellType() == Cell.CELL_TYPE_ERROR; - } - - /** - * Checks if cell content matches. - * - * @param cellWorkBook1 - * the cell work book1 - * @param cellWorkBook2 - * the cell work book2 - * @return true, if cell content matches - */ - private boolean isCellContentMatches(Cell cellWorkBook1, Cell cellWorkBook2) { - return !(cellWorkBook1.getRichStringCellValue().getString() - .equals(cellWorkBook2.getRichStringCellValue().getString())); - } - - /** - * Checks if cell content matches for boolean. - * - * @param cellWorkBook1 - * the cell work book1 - * @param cellWorkBook2 - * the cell work book2 - * @return true, if cell content matches for boolean - */ - private boolean isCellContentMatchesForBoolean(Cell cellWorkBook1, - Cell cellWorkBook2) { - return !(cellWorkBook1.getBooleanCellValue() == cellWorkBook2 - .getBooleanCellValue()); - } - - /** - * Checks if cell content matches for date. - * - * @param cellWorkBook1 - * the cell work book1 - * @param cellWorkBook2 - * the cell work book2 - * @return true, if cell content matches for date - */ - private boolean isCellContentMatchesForDate(Cell cellWorkBook1, - Cell cellWorkBook2) { - return !(cellWorkBook1.getDateCellValue().equals(cellWorkBook2 - .getDateCellValue())); - } - - /** - * Checks if cell content matches for formula. - * - * @param cellWorkBook1 - * the cell work book1 - * @param cellWorkBook2 - * the cell work book2 - * @return true, if cell content matches for formula - */ - private boolean isCellContentMatchesForFormula(Cell cellWorkBook1, - Cell cellWorkBook2) { - return !(cellWorkBook1.getCellFormula().equals(cellWorkBook2 - .getCellFormula())); - } - - /** - * Checks if cell content matches for numeric. - * - * @param cellWorkBook1 - * the cell work book1 - * @param cellWorkBook2 - * the cell work book2 - * @return true, if cell content matches for numeric - */ - private boolean isCellContentMatchesForNumeric(Cell cellWorkBook1, - Cell cellWorkBook2) { - return !(cellWorkBook1.getNumericCellValue() == cellWorkBook2 - .getNumericCellValue()); - } - - /** - * Checks if cell content type blank. - * - * @param cellWorkBook1 - * the cell work book1 - * @return true, if cell content type blank - */ - private boolean isCellContentTypeBlank(Cell cellWorkBook1) { - return cellWorkBook1.getCellType() == Cell.CELL_TYPE_BLANK; - } - - /** - * Checks if cell content type boolean. - * - * @param cellWorkBook1 - * the cell work book1 - * @return true, if cell content type boolean - */ - private boolean isCellContentTypeBoolean(Cell cellWorkBook1) { - return cellWorkBook1.getCellType() == Cell.CELL_TYPE_BOOLEAN; - } - - /** - * Checks if cell content type numeric. - * - * @param cellWorkBook1 - * the cell work book1 - * @return true, if cell content type numeric - */ - private boolean isCellContentTypeNumeric(Cell cellWorkBook1) { - return cellWorkBook1.getCellType() == Cell.CELL_TYPE_NUMERIC; - } - - /** - * Checks if cell content type string. - * - * @param cellWorkBook1 - * the cell work book1 - * @return true, if cell content type string - */ - private boolean isCellContentTypeString(Cell cellWorkBook1) { - return cellWorkBook1.getCellType() == Cell.CELL_TYPE_STRING; - } - - /** - * Checks if cell file back ground matches. - * - * @param cellWorkBook1 - * the cell work book1 - * @param cellWorkBook2 - * the cell work book2 - * @return true, if cell file back ground matches - */ - private boolean isCellFileBackGroundMatches(Cell cellWorkBook1, - Cell cellWorkBook2) { - if (cellWorkBook1.getCellStyle() instanceof XSSFCellStyle) { - return !((XSSFColor) cellWorkBook1.getCellStyle() - .getFillForegroundColorColor()).getARGBHex().equals( - ((XSSFColor) cellWorkBook2.getCellStyle() - .getFillForegroundColorColor()).getARGBHex()); - } else { - return false; - } - - } - - /** - * Checks if cell fill back ground matches and either empty. - * - * @param cellWorkBook1 - * the cell work book1 - * @param cellWorkBook2 - * the cell work book2 - * @return true, if cell fill back ground matches and either empty - */ - private boolean isCellFillBackGroundMatchesAndEitherEmpty( - Cell cellWorkBook1, Cell cellWorkBook2) { - return (cellWorkBook1.getCellStyle().getFillForegroundColorColor() == null) - && (cellWorkBook2.getCellStyle().getFillForegroundColorColor() != null); - } - - /** - * Checks if cell fill back ground matches and second empty. - * - * @param cellWorkBook1 - * the cell work book1 - * @param cellWorkBook2 - * the cell work book2 - * @return true, if cell fill back ground matches and second empty - */ - private boolean isCellFillBackGroundMatchesAndSecondEmpty( - Cell cellWorkBook1, Cell cellWorkBook2) { - return (cellWorkBook1.getCellStyle().getFillForegroundColorColor() != null) - && (cellWorkBook2.getCellStyle().getFillForegroundColorColor() == null); - } - - /** - * Checks if cell fill pattern matches. - * - * @param cellWorkBook1 - * the cell work book1 - * @param cellWorkBook2 - * the cell work book2 - * @return true, if cell fill pattern matches - */ - private boolean isCellFillPatternMatches(Cell cellWorkBook1, - Cell cellWorkBook2) { - return cellWorkBook1.getCellStyle().getFillPattern() != cellWorkBook2 - .getCellStyle().getFillPattern(); - } - - /** - * Checks if cell font bold matches. - * - * @param cellWorkBook1 - * the cell work book1 - * @param cellWorkBook2 - * the cell work book2 - * @return true, if cell font bold matches - */ - private boolean isCellFontBoldMatches(Cell cellWorkBook1, Cell cellWorkBook2) { - if (cellWorkBook1.getCellStyle() instanceof XSSFCellStyle) { - return ((XSSFCellStyle) cellWorkBook1.getCellStyle()).getFont() - .getBold() != ((XSSFCellStyle) cellWorkBook2.getCellStyle()) - .getFont().getBold(); - } else { - return false; - } - - } - - /** - * Checks if cell font family matches. - * - * @param cellWorkBook1 - * the cell work book1 - * @param cellWorkBook2 - * the cell work book2 - * @return true, if cell font family matches - */ - private boolean isCellFontFamilyMatches(Cell cellWorkBook1, - Cell cellWorkBook2) { - if (cellWorkBook1.getCellStyle() instanceof XSSFCellStyle) { - return !(((XSSFCellStyle) cellWorkBook1.getCellStyle()).getFont() - .getFontName().equals(((XSSFCellStyle) cellWorkBook2 - .getCellStyle()).getFont().getFontName())); - } else { - return false; - } - } - - /** - * Checks if cell font italics matches. - * - * @param cellWorkBook1 - * the cell work book1 - * @param cellWorkBook2 - * the cell work book2 - * @return true, if cell font italics matches - */ - private boolean isCellFontItalicsMatches(Cell cellWorkBook1, - Cell cellWorkBook2) { - if (cellWorkBook1.getCellStyle() instanceof XSSFCellStyle) { - return ((XSSFCellStyle) cellWorkBook1.getCellStyle()).getFont() - .getItalic() != ((XSSFCellStyle) cellWorkBook2 - .getCellStyle()).getFont().getItalic(); - } else { - return false; - } - - } - - /** - * Checks if cell font size matches. - * - * @param cellWorkBook1 - * the cell work book1 - * @param cellWorkBook2 - * the cell work book2 - * @return true, if cell font size matches - */ - private boolean isCellFontSizeMatches(Cell cellWorkBook1, Cell cellWorkBook2) { - if (cellWorkBook1.getCellStyle() instanceof XSSFCellStyle) { - return ((XSSFCellStyle) cellWorkBook1.getCellStyle()).getFont() - .getFontHeightInPoints() != ((XSSFCellStyle) cellWorkBook2 - .getCellStyle()).getFont().getFontHeightInPoints(); - } else { - return false; - } - - } - - /** - * Checks if cell hidden matches. - * - * @param cellWorkBook1 - * the cell work book1 - * @param cellWorkBook2 - * the cell work book2 - * @return true, if cell hidden matches - */ - private boolean isCellHiddenMatches(Cell cellWorkBook1, Cell cellWorkBook2) { - return cellWorkBook1.getCellStyle().getHidden() != cellWorkBook2 - .getCellStyle().getHidden(); - } - - /** - * Checks if cell locked matches. - * - * @param cellWorkBook1 - * the cell work book1 - * @param cellWorkBook2 - * the cell work book2 - * @return true, if cell locked matches - */ - private boolean isCellLockedMatches(Cell cellWorkBook1, Cell cellWorkBook2) { - return cellWorkBook1.getCellStyle().getLocked() != cellWorkBook2 - .getCellStyle().getLocked(); - } - - /** - * Checks if cell type matches. - * - * @param cellWorkBook1 - * the cell work book1 - * @param cellWorkBook2 - * the cell work book2 - * @return true, if cell type matches - */ - private boolean isCellTypeMatches(Cell cellWorkBook1, Cell cellWorkBook2) { - return !(cellWorkBook1.getCellType() == cellWorkBook2.getCellType()); - } - - /** - * 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 boolean isCellUnderLineMatches(Cell cellWorkBook1, - Cell cellWorkBook2) { - if (cellWorkBook1.getCellStyle() instanceof XSSFCellStyle) { - return ((XSSFCellStyle) cellWorkBook1.getCellStyle()).getFont() - .getUnderline() != ((XSSFCellStyle) cellWorkBook2 - .getCellStyle()).getFont().getUnderline(); - } else { - return false; - } - - } - - /** - * Checks if name of sheet matches. - * - * @param workbook1 - * the workbook1 - * @param workbook2 - * the workbook2 - * @param i - * the i - * @return true, if name of sheet matches - */ - private boolean isNameOfSheetMatches(Workbook workbook1, - Workbook workbook2, int i) { - if (workbook2.getNumberOfSheets() > i) { - return !(workbook1.getSheetName(i) - .equals(workbook2.getSheetName(i))); - } else { - return true; - } - - } - - /** - * Checks if number of columns matches. - * - * @param sheetWorkBook1 - * the sheet work book1 - * @param sheetWorkBook2 - * the sheet work book2 - * @return true, if number of columns matches - */ - private boolean isNumberOfColumnsMatches(Sheet sheetWorkBook1, - Sheet sheetWorkBook2) { - if (sheetWorkBook2 != null) { - return !(sheetWorkBook1.getRow(0).getLastCellNum() == sheetWorkBook2 - .getRow(0).getLastCellNum()); - } else { - return true; - } - - } - - /** - * Checks if number of rows matches. - * - * @param sheetWorkBook1 - * the sheet work book1 - * @param sheetWorkBook2 - * the sheet work book2 - * @return true, if number of rows matches - */ - private boolean isNumberOfRowsMatches(Sheet sheetWorkBook1, - Sheet sheetWorkBook2) { - if (sheetWorkBook2 != null) { - return !(sheetWorkBook1.getPhysicalNumberOfRows() == sheetWorkBook2 - .getPhysicalNumberOfRows()); - } else { - return true; - } - - } - - /** - * Checks if number of sheets matches. - * - * @param workbook1 - * the workbook1 - * @param workbook2 - * the workbook2 - * @return true, if number of sheets matches - */ - private boolean isNumberOfSheetsMatches(Workbook workbook1, - Workbook workbook2) { - return !(workbook1.getNumberOfSheets() == workbook2.getNumberOfSheets()); - } - - private boolean isWorkBookEmpty(Sheet sheetWorkBook1, Sheet sheetWorkBook2) { - if (sheetWorkBook2 != null) { - return !((null == sheetWorkBook1.getRow(0)) || (null == sheetWorkBook2 - .getRow(0))); - } else { - return true; - } - - } - -} - -class ExcelFileDifference { - boolean isDifferenceFound; - List listOfDifferences; -} diff --git a/src/examples/src/org/apache/poi/ss/examples/ExcelComparator.java b/src/examples/src/org/apache/poi/ss/examples/ExcelComparator.java new file mode 100644 index 000000000..7833dbce1 --- /dev/null +++ b/src/examples/src/org/apache/poi/ss/examples/ExcelComparator.java @@ -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. + * + *

This utility will be used to compare Excel File Contents cell by cell for all sheets programmatically.

+ * + *

Below are the list of Attribute comparison supported in this version.

+ * + *
    + *
  • Cell Alignment
  • + *
  • Cell Border Attributes
  • + *
  • Cell Data
  • + *
  • Cell Data-Type
  • + *
  • Cell Fill Color
  • + *
  • Cell Fill pattern
  • + *
  • Cell Font Attributes
  • + *
  • Cell Font Family
  • + *
  • Cell Font Size
  • + *
  • Cell Protection
  • + *
  • Name of the sheets
  • + *
  • Number of Columns
  • + *
  • Number of Rows
  • + *
  • Number of Sheet
  • + *
+ * + *

(Some of the above attribute comparison only work for *.xlsx format currently. In future it can be enhanced.)

+ * + *

Usage:

+ * + *
+ * {@code
+ *  Workbook wb1 = WorkbookFactory.create(new File("workBook1.xls"));
+ *  Workbook wb2 = WorkbookFactory.create(new File("workBook2.xls"));
+ *  List listOfDifferences = ExcelComparator.compare(wb1, wb2);
+ *  for (String differences : listOfDifferences)
+ *      System.out.println(differences);
+ *  System.out.println("DifferenceFound = "+ excelFileDifference.isDifferenceFound);
+ *  }
+ * 
+ */ +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 listOfDifferences = new ArrayList(); + + 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 "+ExcelComparator.class.getCanonicalName()+" 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 ri1 = loc1.sheet.rowIterator(); + Iterator 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" + ); + } + } +} \ No newline at end of file diff --git a/src/examples/src/org/apache/poi/xssf/eventusermodel/XLSX2CSV.java b/src/examples/src/org/apache/poi/xssf/eventusermodel/XLSX2CSV.java index 6ef160431..41d4b132b 100644 --- a/src/examples/src/org/apache/poi/xssf/eventusermodel/XLSX2CSV.java +++ b/src/examples/src/org/apache/poi/xssf/eventusermodel/XLSX2CSV.java @@ -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(); } } diff --git a/src/java/org/apache/poi/hssf/record/UnknownRecord.java b/src/java/org/apache/poi/hssf/record/UnknownRecord.java index aa1e0e449..8ab1fb479 100644 --- a/src/java/org/apache/poi/hssf/record/UnknownRecord.java +++ b/src/java/org/apache/poi/hssf/record/UnknownRecord.java @@ -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)); +// } } /** diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFootnote.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFootnote.java index 7b51ed454..2d0c8d6dd 100644 --- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFootnote.java +++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFootnote.java @@ -211,9 +211,6 @@ public class XWPFFootnote implements Iterable, IBody { return null; } XWPFTableRow tableRow = table.getRow(row); - if (row == null) { - return null; - } return tableRow.getTableCell(cell); } diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeaderFooter.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeaderFooter.java index e4e1ba177..b5d3a6ad1 100644 --- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeaderFooter.java +++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeaderFooter.java @@ -139,7 +139,6 @@ public abstract class XWPFHeaderFooter extends POIXMLDocumentPart implements IBo } } - List 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); } diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSettings.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSettings.java index 778f020f2..30afbb925 100644 --- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSettings.java +++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSettings.java @@ -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 diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestFormulaEvaluatorOnXSSF.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestFormulaEvaluatorOnXSSF.java index dd966bddc..55b0725a3 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestFormulaEvaluatorOnXSSF.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestFormulaEvaluatorOnXSSF.java @@ -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 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) { diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestMultiSheetFormulaEvaluatorOnXSSF.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestMultiSheetFormulaEvaluatorOnXSSF.java index d75961f3c..95fe30803 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestMultiSheetFormulaEvaluatorOnXSSF.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestMultiSheetFormulaEvaluatorOnXSSF.java @@ -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 = ""; + String FUNCTION_NAMES_END_SENTINEL = ""; /** * 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 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 data = new ArrayList(); - 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 null to test all functions + */ + private static void processFunctionGroup(List 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 null 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= 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; inull 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 null 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 ""; } - + } diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFDocument.java b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFDocument.java index 034e7118b..43d8cce0f 100644 --- a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFDocument.java +++ b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFDocument.java @@ -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 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 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()); diff --git a/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestRangeInsertion.java b/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestRangeInsertion.java index f2e2ea332..ededa3275 100644 --- a/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestRangeInsertion.java +++ b/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestRangeInsertion.java @@ -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); diff --git a/src/testcases/org/apache/poi/hssf/model/TestRVA.java b/src/testcases/org/apache/poi/hssf/model/TestRVA.java index b2d508daf..e1345c2e9 100644 --- a/src/testcases/org/apache/poi/hssf/model/TestRVA.java +++ b/src/testcases/org/apache/poi/hssf/model/TestRVA.java @@ -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 * OperandClassTransformer 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 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 data = new ArrayList(); + + 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) { diff --git a/src/testcases/org/apache/poi/hssf/model/TestSheet.java b/src/testcases/org/apache/poi/hssf/model/TestSheet.java index 176bb0446..969978829 100644 --- a/src/testcases/org/apache/poi/hssf/model/TestSheet.java +++ b/src/testcases/org/apache/poi/hssf/model/TestSheet.java @@ -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 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 records = new ArrayList(); @@ -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 records = new ArrayList(); @@ -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 records = new ArrayList(); @@ -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 UncalcedRecord was present.

*/ + @Test public void testUncalcSize_bug45066() { List records = new ArrayList(); @@ -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); diff --git a/src/testcases/org/apache/poi/hssf/record/aggregates/TestValueRecordsAggregate.java b/src/testcases/org/apache/poi/hssf/record/aggregates/TestValueRecordsAggregate.java index ce252052e..2bdc7f051 100644 --- a/src/testcases/org/apache/poi/hssf/record/aggregates/TestValueRecordsAggregate.java +++ b/src/testcases/org/apache/poi/hssf/record/aggregates/TestValueRecordsAggregate.java @@ -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 records = new ArrayList(); 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); diff --git a/src/testcases/org/apache/poi/ss/formula/function/TestReadMissingBuiltInFuncs.java b/src/testcases/org/apache/poi/ss/formula/function/TestReadMissingBuiltInFuncs.java index 9de7e764e..d28653743 100644 --- a/src/testcases/org/apache/poi/ss/formula/function/TestReadMissingBuiltInFuncs.java +++ b/src/testcases/org/apache/poi/ss/formula/function/TestReadMissingBuiltInFuncs.java @@ -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); - } } diff --git a/src/testcases/org/apache/poi/ss/formula/functions/TestIndirect.java b/src/testcases/org/apache/poi/ss/formula/functions/TestIndirect.java index 2c4de2474..10f7a70a1 100644 --- a/src/testcases/org/apache/poi/ss/formula/functions/TestIndirect.java +++ b/src/testcases/org/apache/poi/ss/formula/functions/TestIndirect.java @@ -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.

- * - * @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() + "'."); } }