+++ /dev/null
-/* ====================================================================\r
- Licensed to the Apache Software Foundation (ASF) under one or more\r
- contributor license agreements. See the NOTICE file distributed with\r
- this work for additional information regarding copyright ownership.\r
- The ASF licenses this file to You under the Apache License, Version 2.0\r
- (the "License"); you may not use this file except in compliance with\r
- the License. You may obtain a copy of the License at\r
-\r
- http://www.apache.org/licenses/LICENSE-2.0\r
-\r
- Unless required by applicable law or agreed to in writing, software\r
- distributed under the License is distributed on an "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- See the License for the specific language governing permissions and\r
- limitations under the License.\r
-==================================================================== */\r
-package org.apache.poi.ss;\r
-\r
-import java.util.ArrayList;\r
-import java.util.List;\r
-\r
-import org.apache.poi.ss.usermodel.Cell;\r
-import org.apache.poi.ss.usermodel.DateUtil;\r
-import org.apache.poi.ss.usermodel.Row;\r
-import org.apache.poi.ss.usermodel.Sheet;\r
-import org.apache.poi.ss.usermodel.Workbook;\r
-import org.apache.poi.ss.util.CellReference;\r
-import org.apache.poi.xssf.usermodel.XSSFCellStyle;\r
-import org.apache.poi.xssf.usermodel.XSSFColor;\r
-\r
-/**\r
- * Utility to compare Excel File Contents cell by cell for all sheets.\r
- * \r
- * <p>This utility will be used to compare Excel File Contents cell by cell for all sheets programmatically.</p>\r
- * \r
- * <p>Below are the list of Attribute comparison supported in this version.</p>\r
- * \r
- * <ul>\r
- * <li>Cell Alignment</li>\r
- * <li>Cell Border Attributes</li>\r
- * <li>Cell Data</li>\r
- * <li>Cell Data-Type</li>\r
- * <li>Cell Fill Color</li>\r
- * <li>Cell Fill pattern</li>\r
- * <li>Cell Font Attributes</li>\r
- * <li>Cell Font Family</li>\r
- * <li>Cell Font Size</li>\r
- * <li>Cell Protection</li>\r
- * <li>Name of the sheets</li>\r
- * <li>Number of Columns</li>\r
- * <li>Number of Rows</li>\r
- * <li>Number of Sheet</li>\r
- * </ul>\r
- * \r
- * <p>(Some of the above attribute comparison only work for *.xlsx format currently. In future it can be enhanced.)</p>\r
- * \r
- * <p><b>Usage:</b></p>\r
- * \r
- * <pre>\r
- * {@code\r
- * Workbook wb1 = WorkbookFactory.create(new File("workBook1.xls"));\r
- * Workbook wb2 = WorkbookFactory.create(new File("workBook2.xls"));\r
- * ExcelFileDifference excelFileDifference = ExcelComparator.compare(wb1, wb2);\r
- * for (String differences : excelFileDifference.listOfDifferences)\r
- * System.out.println(differences);\r
- * System.out.println("DifferenceFound = "+ excelFileDifference.isDifferenceFound);\r
- * }\r
- * </pre>\r
- */\r
-public class ExcelComparator {\r
-\r
- private static final String BOLD = "BOLD";\r
- private static final String BOTTOM_BORDER = "BOTTOM BORDER";\r
- private static final String BRACKET_END = "]";\r
- private static final String BRACKET_START = " [";\r
- private static final String CELL_ALIGNMENT_DOES_NOT_MATCH = "Cell Alignment does not Match ::";\r
- private static final String CELL_BORDER_ATTRIBUTES_DOES_NOT_MATCH = "Cell Border Attributes does not Match ::";\r
- private static final String CELL_DATA_DOES_NOT_MATCH = "Cell Data does not Match ::";\r
- private static final String CELL_DATA_TYPE_DOES_NOT_MATCH = "Cell Data-Type does not Match in :: ";\r
- private static final String CELL_FILL_COLOR_DOES_NOT_MATCH = "Cell Fill Color does not Match ::";\r
- private static final String CELL_FILL_PATTERN_DOES_NOT_MATCH = "Cell Fill pattern does not Match ::";\r
- private static final String CELL_FONT_ATTRIBUTES_DOES_NOT_MATCH = "Cell Font Attributes does not Match ::";\r
- private static final String CELL_FONT_FAMILY_DOES_NOT_MATCH = "Cell Font Family does not Match ::";\r
- private static final String CELL_FONT_SIZE_DOES_NOT_MATCH = "Cell Font Size does not Match ::";\r
- private static final String CELL_PROTECTION_DOES_NOT_MATCH = "Cell Protection does not Match ::";\r
- private static final String ITALICS = "ITALICS";\r
- private static final String LEFT_BORDER = "LEFT BORDER";\r
- private static final String LINE_SEPARATOR = "line.separator";\r
- private static final String NAME_OF_THE_SHEETS_DO_NOT_MATCH = "Name of the sheets do not match :: ";\r
- private static final String NEXT_STR = " -> ";\r
- private static final String NO_BOTTOM_BORDER = "NO BOTTOM BORDER";\r
- private static final String NO_COLOR = "NO COLOR";\r
- private static final String NO_LEFT_BORDER = "NO LEFT BORDER";\r
- private static final String NO_RIGHT_BORDER = "NO RIGHT BORDER";\r
- private static final String NO_TOP_BORDER = "NO TOP BORDER";\r
- private static final String NOT_BOLD = "NOT BOLD";\r
- private static final String NOT_EQUALS = " != ";\r
- private static final String NOT_ITALICS = "NOT ITALICS";\r
- private static final String NOT_UNDERLINE = "NOT UNDERLINE";\r
- private static final String NUMBER_OF_COLUMNS_DOES_NOT_MATCH = "Number Of Columns does not Match :: ";\r
- private static final String NUMBER_OF_ROWS_DOES_NOT_MATCH = "Number Of Rows does not Match :: ";\r
- private static final String NUMBER_OF_SHEETS_DO_NOT_MATCH = "Number of Sheets do not match :: ";\r
- private static final String RIGHT_BORDER = "RIGHT BORDER";\r
- private static final String TOP_BORDER = "TOP BORDER";\r
- private static final String UNDERLINE = "UNDERLINE";\r
- private static final String WORKBOOK1 = "workbook1";\r
- private static final String WORKBOOK2 = "workbook2";\r
-\r
- /**\r
- * Utility to compare Excel File Contents cell by cell for all sheets.\r
- *\r
- * @param workbook1\r
- * the workbook1\r
- * @param workbook2\r
- * the workbook2\r
- * @return the Excel file difference containing a flag and a list of\r
- * differences\r
- * @throws ExcelCompareException\r
- * the excel compare exception\r
- */\r
- public static ExcelFileDifference compare(Workbook workbook1,\r
- Workbook workbook2) {\r
- List<String> listOfDifferences = compareWorkBookContents(workbook1,\r
- workbook2);\r
- return populateListOfDifferences(listOfDifferences);\r
- }\r
-\r
- /**\r
- * Compare work book contents.\r
- *\r
- * @param workbook1\r
- * the workbook1\r
- * @param workbook2\r
- * the workbook2\r
- * @return the list\r
- */\r
- private static List<String> compareWorkBookContents(Workbook workbook1,\r
- Workbook workbook2) {\r
- ExcelComparator excelComparator = new ExcelComparator();\r
- List<String> listOfDifferences = new ArrayList<String>();\r
- excelComparator.compareNumberOfSheets(workbook1, workbook2,\r
- listOfDifferences);\r
- excelComparator.compareSheetNames(workbook1, workbook2,\r
- listOfDifferences);\r
- excelComparator.compareSheetData(workbook1, workbook2,\r
- listOfDifferences);\r
- return listOfDifferences;\r
- }\r
-\r
- /**\r
- * Populate list of differences.\r
- *\r
- * @param listOfDifferences\r
- * the list of differences\r
- * @return the excel file difference\r
- */\r
- private static ExcelFileDifference populateListOfDifferences(\r
- List<String> listOfDifferences) {\r
- ExcelFileDifference excelFileDifference = new ExcelFileDifference();\r
- excelFileDifference.isDifferenceFound = listOfDifferences.size() > 0;\r
- excelFileDifference.listOfDifferences = listOfDifferences;\r
- return excelFileDifference;\r
- }\r
-\r
- /**\r
- * Compare data in all sheets.\r
- *\r
- * @param workbook1\r
- * the workbook1\r
- * @param workbook2\r
- * the workbook2\r
- * @param listOfDifferences\r
- * the list of differences\r
- * @throws ExcelCompareException\r
- * the excel compare exception\r
- */\r
- private void compareDataInAllSheets(Workbook workbook1, Workbook workbook2,\r
- List<String> listOfDifferences) {\r
- for (int i = 0; i < workbook1.getNumberOfSheets(); i++) {\r
- Sheet sheetWorkBook1 = workbook1.getSheetAt(i);\r
- Sheet sheetWorkBook2;\r
- if (workbook2.getNumberOfSheets() > i) {\r
- sheetWorkBook2 = workbook2.getSheetAt(i);\r
- } else {\r
- sheetWorkBook2 = null;\r
- }\r
-\r
- for (int j = 0; j < sheetWorkBook1.getPhysicalNumberOfRows(); j++) {\r
- Row rowWorkBook1 = sheetWorkBook1.getRow(j);\r
- Row rowWorkBook2;\r
- if (sheetWorkBook2 != null) {\r
- rowWorkBook2 = sheetWorkBook2.getRow(j);\r
- } else {\r
- rowWorkBook2 = null;\r
- }\r
-\r
- if ((rowWorkBook1 == null) || (rowWorkBook2 == null)) {\r
- continue;\r
- }\r
- for (int k = 0; k < rowWorkBook1.getLastCellNum(); k++) {\r
- Cell cellWorkBook1 = rowWorkBook1.getCell(k);\r
- Cell cellWorkBook2 = rowWorkBook2.getCell(k);\r
-\r
- if (!((null == cellWorkBook1) || (null == cellWorkBook2))) {\r
- if (isCellTypeMatches(cellWorkBook1, cellWorkBook2)) {\r
-\r
- listOfDifferences.add(getMessage(workbook1,\r
- workbook2, i, cellWorkBook1, cellWorkBook2,\r
- CELL_DATA_TYPE_DOES_NOT_MATCH,\r
- cellWorkBook1.getCellType() + "",\r
- cellWorkBook2.getCellType() + ""));\r
- }\r
-\r
- if (isCellContentTypeBlank(cellWorkBook1)) {\r
- if (isCellContentMatches(cellWorkBook1,\r
- cellWorkBook2)) {\r
-\r
- listOfDifferences.add(getMessage(workbook1,\r
- workbook2, i, cellWorkBook1,\r
- cellWorkBook2,\r
- CELL_DATA_DOES_NOT_MATCH,\r
- cellWorkBook1.getRichStringCellValue()\r
- + "",\r
- cellWorkBook2.getRichStringCellValue()\r
- + ""));\r
-\r
- }\r
-\r
- } else if (isCellContentTypeBoolean(cellWorkBook1)) {\r
- if (isCellContentMatchesForBoolean(cellWorkBook1,\r
- cellWorkBook2)) {\r
- listOfDifferences.add(getMessage(workbook1,\r
- workbook2, i, cellWorkBook1,\r
- cellWorkBook2,\r
- CELL_DATA_DOES_NOT_MATCH,\r
- cellWorkBook1.getBooleanCellValue()\r
- + "",\r
- cellWorkBook2.getBooleanCellValue()\r
- + ""));\r
-\r
- }\r
-\r
- } else if (isCellContentInError(cellWorkBook1)) {\r
- if (isCellContentMatches(cellWorkBook1,\r
- cellWorkBook2)) {\r
-\r
- listOfDifferences.add(getMessage(workbook1,\r
- workbook2, i, cellWorkBook1,\r
- cellWorkBook2,\r
- CELL_DATA_DOES_NOT_MATCH,\r
- cellWorkBook1.getRichStringCellValue()\r
- + "",\r
- cellWorkBook2.getRichStringCellValue()\r
- + ""));\r
-\r
- }\r
- } else if (isCellContentFormula(cellWorkBook1)) {\r
- if (isCellContentMatchesForFormula(cellWorkBook1,\r
- cellWorkBook2)) {\r
-\r
- listOfDifferences.add(getMessage(workbook1,\r
- workbook2, i, cellWorkBook1,\r
- cellWorkBook2,\r
- CELL_DATA_DOES_NOT_MATCH,\r
- cellWorkBook1.getCellFormula() + "",\r
- cellWorkBook2.getCellFormula() + ""));\r
-\r
- }\r
-\r
- } else if (isCellContentTypeNumeric(cellWorkBook1)) {\r
- if (DateUtil.isCellDateFormatted(cellWorkBook1)) {\r
- if (isCellContentMatchesForDate(cellWorkBook1,\r
- cellWorkBook2)) {\r
- listOfDifferences.add(getMessage(workbook1,\r
- workbook2, i, cellWorkBook1,\r
- cellWorkBook2,\r
- CELL_DATA_DOES_NOT_MATCH,\r
- cellWorkBook1.getDateCellValue()\r
- + "",\r
- cellWorkBook2.getDateCellValue()\r
- + ""));\r
-\r
- }\r
- } else {\r
- if (isCellContentMatchesForNumeric(\r
- cellWorkBook1, cellWorkBook2)) {\r
- listOfDifferences.add(getMessage(workbook1,\r
- workbook2, i, cellWorkBook1,\r
- cellWorkBook2,\r
- CELL_DATA_DOES_NOT_MATCH,\r
- cellWorkBook1.getNumericCellValue()\r
- + "",\r
- cellWorkBook2.getNumericCellValue()\r
- + ""));\r
-\r
- }\r
- }\r
-\r
- } else if (isCellContentTypeString(cellWorkBook1)) {\r
- if (isCellContentMatches(cellWorkBook1,\r
- cellWorkBook2)) {\r
- listOfDifferences.add(getMessage(workbook1,\r
- workbook2, i, cellWorkBook1,\r
- cellWorkBook2,\r
- CELL_DATA_DOES_NOT_MATCH, cellWorkBook1\r
- .getRichStringCellValue()\r
- .getString(), cellWorkBook2\r
- .getRichStringCellValue()\r
- .getString()));\r
- }\r
- }\r
-\r
- if (isCellFillPatternMatches(cellWorkBook1,\r
- cellWorkBook2)) {\r
- listOfDifferences.add(getMessage(workbook1,\r
- workbook2, i, cellWorkBook1, cellWorkBook2,\r
- CELL_FILL_PATTERN_DOES_NOT_MATCH,\r
- cellWorkBook1.getCellStyle()\r
- .getFillPattern() + "",\r
- cellWorkBook2.getCellStyle()\r
- .getFillPattern() + ""));\r
-\r
- }\r
-\r
- if (isCellAlignmentMatches(cellWorkBook1, cellWorkBook2)) {\r
- listOfDifferences.add(getMessage(workbook1,\r
- workbook2, i, cellWorkBook1, cellWorkBook2,\r
- CELL_ALIGNMENT_DOES_NOT_MATCH,\r
- cellWorkBook1.getRichStringCellValue()\r
- .getString(), cellWorkBook2\r
- .getRichStringCellValue()\r
- .getString()));\r
-\r
- }\r
-\r
- if (isCellHiddenMatches(cellWorkBook1, cellWorkBook2)) {\r
- listOfDifferences\r
- .add(getMessage(workbook1, workbook2, i,\r
- cellWorkBook1, cellWorkBook2,\r
- CELL_PROTECTION_DOES_NOT_MATCH,\r
- cellWorkBook1.getCellStyle()\r
- .getHidden() ? "HIDDEN"\r
- : "NOT HIDDEN",\r
- cellWorkBook2.getCellStyle()\r
- .getHidden() ? "HIDDEN"\r
- : "NOT HIDDEN"));\r
-\r
- }\r
-\r
- if (isCellLockedMatches(cellWorkBook1, cellWorkBook2)) {\r
- listOfDifferences\r
- .add(getMessage(workbook1, workbook2, i,\r
- cellWorkBook1, cellWorkBook2,\r
- CELL_PROTECTION_DOES_NOT_MATCH,\r
- cellWorkBook1.getCellStyle()\r
- .getLocked() ? "LOCKED"\r
- : "NOT LOCKED",\r
- cellWorkBook2.getCellStyle()\r
- .getLocked() ? "LOCKED"\r
- : "NOT LOCKED"));\r
-\r
- }\r
-\r
- if (isCellFontFamilyMatches(cellWorkBook1,\r
- cellWorkBook2)) {\r
- listOfDifferences.add(getMessage(workbook1,\r
- workbook2, i, cellWorkBook1, cellWorkBook2,\r
- CELL_FONT_FAMILY_DOES_NOT_MATCH,\r
- ((XSSFCellStyle) cellWorkBook1\r
- .getCellStyle()).getFont()\r
- .getFontName(),\r
- ((XSSFCellStyle) cellWorkBook2\r
- .getCellStyle()).getFont()\r
- .getFontName()));\r
-\r
- }\r
-\r
- if (isCellFontSizeMatches(cellWorkBook1, cellWorkBook2)) {\r
- listOfDifferences.add(getMessage(\r
- workbook1,\r
- workbook2,\r
- i,\r
- cellWorkBook1,\r
- cellWorkBook2,\r
- CELL_FONT_SIZE_DOES_NOT_MATCH,\r
- ((XSSFCellStyle) cellWorkBook1\r
- .getCellStyle()).getFont()\r
- .getFontHeightInPoints()\r
- + "",\r
- ((XSSFCellStyle) cellWorkBook2\r
- .getCellStyle()).getFont()\r
- .getFontHeightInPoints()\r
- + ""));\r
-\r
- }\r
-\r
- if (isCellFontBoldMatches(cellWorkBook1, cellWorkBook2)) {\r
- listOfDifferences.add(getMessage(workbook1,\r
- workbook2, i, cellWorkBook1, cellWorkBook2,\r
- CELL_FONT_ATTRIBUTES_DOES_NOT_MATCH,\r
- ((XSSFCellStyle) cellWorkBook1\r
- .getCellStyle()).getFont()\r
- .getBold() ? BOLD : NOT_BOLD,\r
- ((XSSFCellStyle) cellWorkBook2\r
- .getCellStyle()).getFont()\r
- .getBold() ? BOLD : NOT_BOLD));\r
-\r
- }\r
-\r
- if (isCellUnderLineMatches(cellWorkBook1, cellWorkBook2)) {\r
- listOfDifferences.add(getMessage(workbook1,\r
- workbook2, i, cellWorkBook1, cellWorkBook2,\r
- CELL_FONT_ATTRIBUTES_DOES_NOT_MATCH,\r
- ((XSSFCellStyle) cellWorkBook1\r
- .getCellStyle()).getFont()\r
- .getUnderline() == 1 ? UNDERLINE\r
- : NOT_UNDERLINE,\r
- ((XSSFCellStyle) cellWorkBook2\r
- .getCellStyle()).getFont()\r
- .getUnderline() == 1 ? UNDERLINE\r
- : NOT_UNDERLINE));\r
-\r
- }\r
-\r
- if (isCellFontItalicsMatches(cellWorkBook1,\r
- cellWorkBook2)) {\r
- listOfDifferences.add(getMessage(workbook1,\r
- workbook2, i, cellWorkBook1, cellWorkBook2,\r
- CELL_FONT_ATTRIBUTES_DOES_NOT_MATCH,\r
- ((XSSFCellStyle) cellWorkBook1\r
- .getCellStyle()).getFont()\r
- .getItalic() ? ITALICS\r
- : NOT_ITALICS,\r
- ((XSSFCellStyle) cellWorkBook2\r
- .getCellStyle()).getFont()\r
- .getItalic() ? ITALICS\r
- : NOT_ITALICS));\r
-\r
- }\r
-\r
- if (isCellBorderBottomMatches(cellWorkBook1,\r
- cellWorkBook2)) {\r
- listOfDifferences\r
- .add(getMessage(\r
- workbook1,\r
- workbook2,\r
- i,\r
- cellWorkBook1,\r
- cellWorkBook2,\r
- CELL_BORDER_ATTRIBUTES_DOES_NOT_MATCH,\r
- ((XSSFCellStyle) cellWorkBook1\r
- .getCellStyle())\r
- .getBorderBottom() == 1 ? BOTTOM_BORDER\r
- : NO_BOTTOM_BORDER,\r
- ((XSSFCellStyle) cellWorkBook2\r
- .getCellStyle())\r
- .getBorderBottom() == 1 ? BOTTOM_BORDER\r
- : NO_BOTTOM_BORDER));\r
-\r
- }\r
-\r
- if (isCellBorderLeftMatches(cellWorkBook1,\r
- cellWorkBook2)) {\r
- listOfDifferences\r
- .add(getMessage(\r
- workbook1,\r
- workbook2,\r
- i,\r
- cellWorkBook1,\r
- cellWorkBook2,\r
- CELL_BORDER_ATTRIBUTES_DOES_NOT_MATCH,\r
- ((XSSFCellStyle) cellWorkBook1\r
- .getCellStyle())\r
- .getBorderLeft() == 1 ? LEFT_BORDER\r
- : NO_LEFT_BORDER,\r
- ((XSSFCellStyle) cellWorkBook2\r
- .getCellStyle())\r
- .getBorderLeft() == 1 ? LEFT_BORDER\r
- : NO_LEFT_BORDER));\r
-\r
- }\r
-\r
- if (isCellBorderRightMatches(cellWorkBook1,\r
- cellWorkBook2)) {\r
- listOfDifferences\r
- .add(getMessage(\r
- workbook1,\r
- workbook2,\r
- i,\r
- cellWorkBook1,\r
- cellWorkBook2,\r
- CELL_BORDER_ATTRIBUTES_DOES_NOT_MATCH,\r
- ((XSSFCellStyle) cellWorkBook1\r
- .getCellStyle())\r
- .getBorderRight() == 1 ? RIGHT_BORDER\r
- : NO_RIGHT_BORDER,\r
- ((XSSFCellStyle) cellWorkBook2\r
- .getCellStyle())\r
- .getBorderRight() == 1 ? RIGHT_BORDER\r
- : NO_RIGHT_BORDER));\r
-\r
- }\r
-\r
- if (isCellBorderTopMatches(cellWorkBook1, cellWorkBook2)) {\r
- listOfDifferences\r
- .add(getMessage(\r
- workbook1,\r
- workbook2,\r
- i,\r
- cellWorkBook1,\r
- cellWorkBook2,\r
- CELL_BORDER_ATTRIBUTES_DOES_NOT_MATCH,\r
- ((XSSFCellStyle) cellWorkBook1\r
- .getCellStyle())\r
- .getBorderTop() == 1 ? TOP_BORDER\r
- : NO_TOP_BORDER,\r
- ((XSSFCellStyle) cellWorkBook2\r
- .getCellStyle())\r
- .getBorderTop() == 1 ? TOP_BORDER\r
- : NO_TOP_BORDER));\r
-\r
- }\r
-\r
- if (isCellBackGroundFillMatchesAndEmpty(cellWorkBook1,\r
- cellWorkBook2)) {\r
- continue;\r
- } else if (isCellFillBackGroundMatchesAndEitherEmpty(\r
- cellWorkBook1, cellWorkBook2)) {\r
- listOfDifferences.add(getMessage(\r
- workbook1,\r
- workbook2,\r
- i,\r
- cellWorkBook1,\r
- cellWorkBook2,\r
- CELL_FILL_COLOR_DOES_NOT_MATCH,\r
- NO_COLOR,\r
- ((XSSFColor) cellWorkBook2.getCellStyle()\r
- .getFillForegroundColorColor())\r
- .getARGBHex()\r
- + ""));\r
-\r
- } else if (isCellFillBackGroundMatchesAndSecondEmpty(\r
- cellWorkBook1, cellWorkBook2)) {\r
- listOfDifferences.add(getMessage(\r
- workbook1,\r
- workbook2,\r
- i,\r
- cellWorkBook1,\r
- cellWorkBook2,\r
- CELL_FILL_COLOR_DOES_NOT_MATCH,\r
- ((XSSFColor) cellWorkBook1.getCellStyle()\r
- .getFillForegroundColorColor())\r
- .getARGBHex()\r
- + "", NO_COLOR));\r
-\r
- } else {\r
- if (isCellFileBackGroundMatches(cellWorkBook1,\r
- cellWorkBook2)) {\r
- listOfDifferences.add(getMessage(\r
- workbook1,\r
- workbook2,\r
- i,\r
- cellWorkBook1,\r
- cellWorkBook2,\r
- CELL_FILL_COLOR_DOES_NOT_MATCH,\r
- ((XSSFColor) cellWorkBook1\r
- .getCellStyle()\r
- .getFillForegroundColorColor())\r
- .getARGBHex()\r
- + "",\r
- ((XSSFColor) cellWorkBook2\r
- .getCellStyle()\r
- .getFillForegroundColorColor())\r
- .getARGBHex()\r
- + ""));\r
-\r
- }\r
- }\r
-\r
- }\r
- }\r
- }\r
- }\r
- }\r
-\r
- /**\r
- * Compare number of columns in sheets.\r
- *\r
- * @param workbook1\r
- * the workbook1\r
- * @param workbook2\r
- * the workbook2\r
- * @param listOfDifferences\r
- * the list of differences\r
- * @throws ExcelCompareException\r
- * the excel compare exception\r
- */\r
- private void compareNumberOfColumnsInSheets(Workbook workbook1,\r
- Workbook workbook2, List<String> listOfDifferences) {\r
- for (int i = 0; i < workbook1.getNumberOfSheets(); i++) {\r
- Sheet sheetWorkBook1 = workbook1.getSheetAt(i);\r
- Sheet sheetWorkBook2;\r
- if (workbook2.getNumberOfSheets() > i) {\r
- sheetWorkBook2 = workbook2.getSheetAt(i);\r
- } else {\r
- sheetWorkBook2 = null;\r
- }\r
- if (isWorkBookEmpty(sheetWorkBook1, sheetWorkBook2)) {\r
- if (isNumberOfColumnsMatches(sheetWorkBook1, sheetWorkBook2)) {\r
- String noOfCols;\r
- String sheetName;\r
- if (sheetWorkBook2 != null) {\r
- noOfCols = sheetWorkBook2.getRow(0).getLastCellNum()\r
- + "";\r
- sheetName = workbook2.getSheetName(i);\r
- } else {\r
- noOfCols = "";\r
- sheetName = "";\r
- }\r
- short lastCellNumForWbk1 = sheetWorkBook1.getRow(0) != null ? sheetWorkBook1\r
- .getRow(0).getLastCellNum() : 0;\r
- listOfDifferences.add(NUMBER_OF_COLUMNS_DOES_NOT_MATCH\r
- + System.getProperty(LINE_SEPARATOR) + WORKBOOK1\r
- + NEXT_STR + workbook1.getSheetName(i) + NEXT_STR\r
- + lastCellNumForWbk1 + NOT_EQUALS + WORKBOOK2\r
- + NEXT_STR + sheetName + NEXT_STR + noOfCols);\r
- }\r
- }\r
- }\r
- }\r
-\r
- /**\r
- * Compare number of rows in sheets.\r
- *\r
- * @param workbook1\r
- * the workbook1\r
- * @param workbook2\r
- * the workbook2\r
- * @param listOfDifferences\r
- * the list of differences\r
- * @throws ExcelCompareException\r
- * the excel compare exception\r
- */\r
- private void compareNumberOfRowsInSheets(Workbook workbook1,\r
- Workbook workbook2, List<String> listOfDifferences) {\r
- for (int i = 0; i < workbook1.getNumberOfSheets(); i++) {\r
- Sheet sheetWorkBook1 = workbook1.getSheetAt(i);\r
- Sheet sheetWorkBook2;\r
- if (workbook2.getNumberOfSheets() > i) {\r
- sheetWorkBook2 = workbook2.getSheetAt(i);\r
- } else {\r
- sheetWorkBook2 = null;\r
- }\r
- if (isNumberOfRowsMatches(sheetWorkBook1, sheetWorkBook2)) {\r
- String noOfRows;\r
- String sheetName;\r
- if (sheetWorkBook2 != null) {\r
- noOfRows = sheetWorkBook2.getPhysicalNumberOfRows() + "";\r
- sheetName = workbook2.getSheetName(i);\r
- } else {\r
- noOfRows = "";\r
- sheetName = "";\r
- }\r
- listOfDifferences.add(NUMBER_OF_ROWS_DOES_NOT_MATCH\r
- + System.getProperty(LINE_SEPARATOR) + WORKBOOK1\r
- + NEXT_STR + workbook1.getSheetName(i) + NEXT_STR\r
- + sheetWorkBook1.getPhysicalNumberOfRows() + NOT_EQUALS\r
- + WORKBOOK2 + NEXT_STR + sheetName + NEXT_STR\r
- + noOfRows);\r
- }\r
- }\r
-\r
- }\r
-\r
- /**\r
- * Compare number of sheets.\r
- *\r
- * @param workbook1\r
- * the workbook1\r
- * @param workbook2\r
- * the workbook2\r
- * @param listOfDifferences\r
- *\r
- * @throws ExcelCompareException\r
- * the excel compare exception\r
- */\r
- private void compareNumberOfSheets(Workbook workbook1, Workbook workbook2,\r
- List<String> listOfDifferences) {\r
- if (isNumberOfSheetsMatches(workbook1, workbook2)) {\r
- listOfDifferences.add(NUMBER_OF_SHEETS_DO_NOT_MATCH\r
- + System.getProperty(LINE_SEPARATOR) + WORKBOOK1 + NEXT_STR\r
- + workbook1.getNumberOfSheets() + NOT_EQUALS + WORKBOOK2\r
- + NEXT_STR + workbook2.getNumberOfSheets());\r
- }\r
- }\r
-\r
- /**\r
- * Compare sheet data.\r
- *\r
- * @param workbook1\r
- * the workbook1\r
- * @param workbook2\r
- * the workbook2\r
- * @param listOfDifferences\r
- *\r
- * @throws ExcelCompareException\r
- * the excel compare exception\r
- */\r
- private void compareSheetData(Workbook workbook1, Workbook workbook2,\r
- List<String> listOfDifferences) {\r
- compareNumberOfRowsInSheets(workbook1, workbook2, listOfDifferences);\r
- compareNumberOfColumnsInSheets(workbook1, workbook2, listOfDifferences);\r
- compareDataInAllSheets(workbook1, workbook2, listOfDifferences);\r
-\r
- }\r
-\r
- /**\r
- * Compare sheet names.\r
- *\r
- * @param workbook1\r
- * the workbook1\r
- * @param workbook2\r
- * the workbook2\r
- * @param listOfDifferences\r
- *\r
- * @throws ExcelCompareException\r
- * the excel compare exception\r
- */\r
- private void compareSheetNames(Workbook workbook1, Workbook workbook2,\r
- List<String> listOfDifferences) {\r
- for (int i = 0; i < workbook1.getNumberOfSheets(); i++) {\r
- if (isNameOfSheetMatches(workbook1, workbook2, i)) {\r
- String sheetname = workbook2.getNumberOfSheets() > i ? workbook2\r
- .getSheetName(i) : "";\r
- listOfDifferences.add(NAME_OF_THE_SHEETS_DO_NOT_MATCH\r
- + System.getProperty(LINE_SEPARATOR) + WORKBOOK1\r
- + NEXT_STR + workbook1.getSheetName(i) + BRACKET_START\r
- + (i + 1) + BRACKET_END + NOT_EQUALS + WORKBOOK2\r
- + NEXT_STR + sheetname + BRACKET_START + (i + 1)\r
- + BRACKET_END);\r
- }\r
- }\r
- }\r
-\r
- /**\r
- * Gets the message.\r
- *\r
- * @param workbook1\r
- * the workbook1\r
- * @param workbook2\r
- * the workbook2\r
- * @param i\r
- * the i\r
- * @param cellWorkBook1\r
- * the cell work book1\r
- * @param cellWorkBook2\r
- * the cell work book2\r
- * @param messageStart\r
- * the message start\r
- * @param workBook1Value\r
- * the work book1 value\r
- * @param workBook2Value\r
- * the work book2 value\r
- * @return the message\r
- */\r
- private String getMessage(Workbook workbook1, Workbook workbook2, int i,\r
- Cell cellWorkBook1, Cell cellWorkBook2, String messageStart,\r
- String workBook1Value, String workBook2Value) {\r
- StringBuilder sb = new StringBuilder();\r
- return sb\r
- .append(messageStart)\r
- .append(System.getProperty(LINE_SEPARATOR))\r
- .append(WORKBOOK1)\r
- .append(NEXT_STR)\r
- .append(workbook1.getSheetName(i))\r
- .append(NEXT_STR)\r
- .append(new CellReference(cellWorkBook1.getRowIndex(),\r
- cellWorkBook1.getColumnIndex()).formatAsString())\r
- .append(BRACKET_START)\r
- .append(workBook1Value)\r
- .append(BRACKET_END)\r
- .append(NOT_EQUALS)\r
- .append(WORKBOOK2)\r
- .append(NEXT_STR)\r
- .append(workbook2.getSheetName(i))\r
- .append(NEXT_STR)\r
- .append(new CellReference(cellWorkBook2.getRowIndex(),\r
- cellWorkBook2.getColumnIndex()).formatAsString())\r
- .append(BRACKET_START).append(workBook2Value)\r
- .append(BRACKET_END).toString();\r
- }\r
-\r
- /**\r
- * Checks if cell alignment matches.\r
- *\r
- * @param cellWorkBook1\r
- * the cell work book1\r
- * @param cellWorkBook2\r
- * the cell work book2\r
- * @return true, if cell alignment matches\r
- */\r
- private boolean isCellAlignmentMatches(Cell cellWorkBook1,\r
- Cell cellWorkBook2) {\r
- return cellWorkBook1.getCellStyle().getAlignment() != cellWorkBook2\r
- .getCellStyle().getAlignment();\r
- }\r
-\r
- /**\r
- * Checks if cell back ground fill matches and empty.\r
- *\r
- * @param cellWorkBook1\r
- * the cell work book1\r
- * @param cellWorkBook2\r
- * the cell work book2\r
- * @return true, if cell back ground fill matches and empty\r
- */\r
- private boolean isCellBackGroundFillMatchesAndEmpty(Cell cellWorkBook1,\r
- Cell cellWorkBook2) {\r
- return (cellWorkBook1.getCellStyle().getFillForegroundColorColor() == null)\r
- && (cellWorkBook2.getCellStyle().getFillForegroundColorColor() == null);\r
- }\r
-\r
- /**\r
- * Checks if cell border bottom matches.\r
- *\r
- * @param cellWorkBook1\r
- * the cell work book1\r
- * @param cellWorkBook2\r
- * the cell work book2\r
- * @return true, if cell border bottom matches\r
- */\r
- private boolean isCellBorderBottomMatches(Cell cellWorkBook1,\r
- Cell cellWorkBook2) {\r
- if (cellWorkBook1.getCellStyle() instanceof XSSFCellStyle) {\r
- return ((XSSFCellStyle) cellWorkBook1.getCellStyle())\r
- .getBorderBottom() != ((XSSFCellStyle) cellWorkBook2\r
- .getCellStyle()).getBorderBottom();\r
- } else {\r
- return false;\r
- }\r
-\r
- }\r
-\r
- /**\r
- * Checks if cell border left matches.\r
- *\r
- * @param cellWorkBook1\r
- * the cell work book1\r
- * @param cellWorkBook2\r
- * the cell work book2\r
- * @return true, if cell border left matches\r
- */\r
- private boolean isCellBorderLeftMatches(Cell cellWorkBook1,\r
- Cell cellWorkBook2) {\r
- if (cellWorkBook1.getCellStyle() instanceof XSSFCellStyle) {\r
- return ((XSSFCellStyle) cellWorkBook1.getCellStyle())\r
- .getBorderLeft() != ((XSSFCellStyle) cellWorkBook2\r
- .getCellStyle()).getBorderLeft();\r
- } else {\r
- return false;\r
- }\r
-\r
- }\r
-\r
- /**\r
- * Checks if cell border right matches.\r
- *\r
- * @param cellWorkBook1\r
- * the cell work book1\r
- * @param cellWorkBook2\r
- * the cell work book2\r
- * @return true, if cell border right matches\r
- */\r
- private boolean isCellBorderRightMatches(Cell cellWorkBook1,\r
- Cell cellWorkBook2) {\r
- if (cellWorkBook1.getCellStyle() instanceof XSSFCellStyle) {\r
- return ((XSSFCellStyle) cellWorkBook1.getCellStyle())\r
- .getBorderRight() != ((XSSFCellStyle) cellWorkBook2\r
- .getCellStyle()).getBorderRight();\r
- } else {\r
- return false;\r
- }\r
-\r
- }\r
-\r
- /**\r
- * Checks if cell border top matches.\r
- *\r
- * @param cellWorkBook1\r
- * the cell work book1\r
- * @param cellWorkBook2\r
- * the cell work book2\r
- * @return true, if cell border top matches\r
- */\r
- private boolean isCellBorderTopMatches(Cell cellWorkBook1,\r
- Cell cellWorkBook2) {\r
- if (cellWorkBook1.getCellStyle() instanceof XSSFCellStyle) {\r
- return ((XSSFCellStyle) cellWorkBook1.getCellStyle())\r
- .getBorderTop() != ((XSSFCellStyle) cellWorkBook2\r
- .getCellStyle()).getBorderTop();\r
- } else {\r
- return false;\r
- }\r
-\r
- }\r
-\r
- /**\r
- * Checks if cell content formula.\r
- *\r
- * @param cellWorkBook1\r
- * the cell work book1\r
- * @return true, if cell content formula\r
- */\r
- private boolean isCellContentFormula(Cell cellWorkBook1) {\r
- return cellWorkBook1.getCellType() == Cell.CELL_TYPE_FORMULA;\r
- }\r
-\r
- /**\r
- * Checks if cell content in error.\r
- *\r
- * @param cellWorkBook1\r
- * the cell work book1\r
- * @return true, if cell content in error\r
- */\r
- private boolean isCellContentInError(Cell cellWorkBook1) {\r
- return cellWorkBook1.getCellType() == Cell.CELL_TYPE_ERROR;\r
- }\r
-\r
- /**\r
- * Checks if cell content matches.\r
- *\r
- * @param cellWorkBook1\r
- * the cell work book1\r
- * @param cellWorkBook2\r
- * the cell work book2\r
- * @return true, if cell content matches\r
- */\r
- private boolean isCellContentMatches(Cell cellWorkBook1, Cell cellWorkBook2) {\r
- return !(cellWorkBook1.getRichStringCellValue().getString()\r
- .equals(cellWorkBook2.getRichStringCellValue().getString()));\r
- }\r
-\r
- /**\r
- * Checks if cell content matches for boolean.\r
- *\r
- * @param cellWorkBook1\r
- * the cell work book1\r
- * @param cellWorkBook2\r
- * the cell work book2\r
- * @return true, if cell content matches for boolean\r
- */\r
- private boolean isCellContentMatchesForBoolean(Cell cellWorkBook1,\r
- Cell cellWorkBook2) {\r
- return !(cellWorkBook1.getBooleanCellValue() == cellWorkBook2\r
- .getBooleanCellValue());\r
- }\r
-\r
- /**\r
- * Checks if cell content matches for date.\r
- *\r
- * @param cellWorkBook1\r
- * the cell work book1\r
- * @param cellWorkBook2\r
- * the cell work book2\r
- * @return true, if cell content matches for date\r
- */\r
- private boolean isCellContentMatchesForDate(Cell cellWorkBook1,\r
- Cell cellWorkBook2) {\r
- return !(cellWorkBook1.getDateCellValue().equals(cellWorkBook2\r
- .getDateCellValue()));\r
- }\r
-\r
- /**\r
- * Checks if cell content matches for formula.\r
- *\r
- * @param cellWorkBook1\r
- * the cell work book1\r
- * @param cellWorkBook2\r
- * the cell work book2\r
- * @return true, if cell content matches for formula\r
- */\r
- private boolean isCellContentMatchesForFormula(Cell cellWorkBook1,\r
- Cell cellWorkBook2) {\r
- return !(cellWorkBook1.getCellFormula().equals(cellWorkBook2\r
- .getCellFormula()));\r
- }\r
-\r
- /**\r
- * Checks if cell content matches for numeric.\r
- *\r
- * @param cellWorkBook1\r
- * the cell work book1\r
- * @param cellWorkBook2\r
- * the cell work book2\r
- * @return true, if cell content matches for numeric\r
- */\r
- private boolean isCellContentMatchesForNumeric(Cell cellWorkBook1,\r
- Cell cellWorkBook2) {\r
- return !(cellWorkBook1.getNumericCellValue() == cellWorkBook2\r
- .getNumericCellValue());\r
- }\r
-\r
- /**\r
- * Checks if cell content type blank.\r
- *\r
- * @param cellWorkBook1\r
- * the cell work book1\r
- * @return true, if cell content type blank\r
- */\r
- private boolean isCellContentTypeBlank(Cell cellWorkBook1) {\r
- return cellWorkBook1.getCellType() == Cell.CELL_TYPE_BLANK;\r
- }\r
-\r
- /**\r
- * Checks if cell content type boolean.\r
- *\r
- * @param cellWorkBook1\r
- * the cell work book1\r
- * @return true, if cell content type boolean\r
- */\r
- private boolean isCellContentTypeBoolean(Cell cellWorkBook1) {\r
- return cellWorkBook1.getCellType() == Cell.CELL_TYPE_BOOLEAN;\r
- }\r
-\r
- /**\r
- * Checks if cell content type numeric.\r
- *\r
- * @param cellWorkBook1\r
- * the cell work book1\r
- * @return true, if cell content type numeric\r
- */\r
- private boolean isCellContentTypeNumeric(Cell cellWorkBook1) {\r
- return cellWorkBook1.getCellType() == Cell.CELL_TYPE_NUMERIC;\r
- }\r
-\r
- /**\r
- * Checks if cell content type string.\r
- *\r
- * @param cellWorkBook1\r
- * the cell work book1\r
- * @return true, if cell content type string\r
- */\r
- private boolean isCellContentTypeString(Cell cellWorkBook1) {\r
- return cellWorkBook1.getCellType() == Cell.CELL_TYPE_STRING;\r
- }\r
-\r
- /**\r
- * Checks if cell file back ground matches.\r
- *\r
- * @param cellWorkBook1\r
- * the cell work book1\r
- * @param cellWorkBook2\r
- * the cell work book2\r
- * @return true, if cell file back ground matches\r
- */\r
- private boolean isCellFileBackGroundMatches(Cell cellWorkBook1,\r
- Cell cellWorkBook2) {\r
- if (cellWorkBook1.getCellStyle() instanceof XSSFCellStyle) {\r
- return !((XSSFColor) cellWorkBook1.getCellStyle()\r
- .getFillForegroundColorColor()).getARGBHex().equals(\r
- ((XSSFColor) cellWorkBook2.getCellStyle()\r
- .getFillForegroundColorColor()).getARGBHex());\r
- } else {\r
- return false;\r
- }\r
-\r
- }\r
-\r
- /**\r
- * Checks if cell fill back ground matches and either empty.\r
- *\r
- * @param cellWorkBook1\r
- * the cell work book1\r
- * @param cellWorkBook2\r
- * the cell work book2\r
- * @return true, if cell fill back ground matches and either empty\r
- */\r
- private boolean isCellFillBackGroundMatchesAndEitherEmpty(\r
- Cell cellWorkBook1, Cell cellWorkBook2) {\r
- return (cellWorkBook1.getCellStyle().getFillForegroundColorColor() == null)\r
- && (cellWorkBook2.getCellStyle().getFillForegroundColorColor() != null);\r
- }\r
-\r
- /**\r
- * Checks if cell fill back ground matches and second empty.\r
- *\r
- * @param cellWorkBook1\r
- * the cell work book1\r
- * @param cellWorkBook2\r
- * the cell work book2\r
- * @return true, if cell fill back ground matches and second empty\r
- */\r
- private boolean isCellFillBackGroundMatchesAndSecondEmpty(\r
- Cell cellWorkBook1, Cell cellWorkBook2) {\r
- return (cellWorkBook1.getCellStyle().getFillForegroundColorColor() != null)\r
- && (cellWorkBook2.getCellStyle().getFillForegroundColorColor() == null);\r
- }\r
-\r
- /**\r
- * Checks if cell fill pattern matches.\r
- *\r
- * @param cellWorkBook1\r
- * the cell work book1\r
- * @param cellWorkBook2\r
- * the cell work book2\r
- * @return true, if cell fill pattern matches\r
- */\r
- private boolean isCellFillPatternMatches(Cell cellWorkBook1,\r
- Cell cellWorkBook2) {\r
- return cellWorkBook1.getCellStyle().getFillPattern() != cellWorkBook2\r
- .getCellStyle().getFillPattern();\r
- }\r
-\r
- /**\r
- * Checks if cell font bold matches.\r
- *\r
- * @param cellWorkBook1\r
- * the cell work book1\r
- * @param cellWorkBook2\r
- * the cell work book2\r
- * @return true, if cell font bold matches\r
- */\r
- private boolean isCellFontBoldMatches(Cell cellWorkBook1, Cell cellWorkBook2) {\r
- if (cellWorkBook1.getCellStyle() instanceof XSSFCellStyle) {\r
- return ((XSSFCellStyle) cellWorkBook1.getCellStyle()).getFont()\r
- .getBold() != ((XSSFCellStyle) cellWorkBook2.getCellStyle())\r
- .getFont().getBold();\r
- } else {\r
- return false;\r
- }\r
-\r
- }\r
-\r
- /**\r
- * Checks if cell font family matches.\r
- *\r
- * @param cellWorkBook1\r
- * the cell work book1\r
- * @param cellWorkBook2\r
- * the cell work book2\r
- * @return true, if cell font family matches\r
- */\r
- private boolean isCellFontFamilyMatches(Cell cellWorkBook1,\r
- Cell cellWorkBook2) {\r
- if (cellWorkBook1.getCellStyle() instanceof XSSFCellStyle) {\r
- return !(((XSSFCellStyle) cellWorkBook1.getCellStyle()).getFont()\r
- .getFontName().equals(((XSSFCellStyle) cellWorkBook2\r
- .getCellStyle()).getFont().getFontName()));\r
- } else {\r
- return false;\r
- }\r
- }\r
-\r
- /**\r
- * Checks if cell font italics matches.\r
- *\r
- * @param cellWorkBook1\r
- * the cell work book1\r
- * @param cellWorkBook2\r
- * the cell work book2\r
- * @return true, if cell font italics matches\r
- */\r
- private boolean isCellFontItalicsMatches(Cell cellWorkBook1,\r
- Cell cellWorkBook2) {\r
- if (cellWorkBook1.getCellStyle() instanceof XSSFCellStyle) {\r
- return ((XSSFCellStyle) cellWorkBook1.getCellStyle()).getFont()\r
- .getItalic() != ((XSSFCellStyle) cellWorkBook2\r
- .getCellStyle()).getFont().getItalic();\r
- } else {\r
- return false;\r
- }\r
-\r
- }\r
-\r
- /**\r
- * Checks if cell font size matches.\r
- *\r
- * @param cellWorkBook1\r
- * the cell work book1\r
- * @param cellWorkBook2\r
- * the cell work book2\r
- * @return true, if cell font size matches\r
- */\r
- private boolean isCellFontSizeMatches(Cell cellWorkBook1, Cell cellWorkBook2) {\r
- if (cellWorkBook1.getCellStyle() instanceof XSSFCellStyle) {\r
- return ((XSSFCellStyle) cellWorkBook1.getCellStyle()).getFont()\r
- .getFontHeightInPoints() != ((XSSFCellStyle) cellWorkBook2\r
- .getCellStyle()).getFont().getFontHeightInPoints();\r
- } else {\r
- return false;\r
- }\r
-\r
- }\r
-\r
- /**\r
- * Checks if cell hidden matches.\r
- *\r
- * @param cellWorkBook1\r
- * the cell work book1\r
- * @param cellWorkBook2\r
- * the cell work book2\r
- * @return true, if cell hidden matches\r
- */\r
- private boolean isCellHiddenMatches(Cell cellWorkBook1, Cell cellWorkBook2) {\r
- return cellWorkBook1.getCellStyle().getHidden() != cellWorkBook2\r
- .getCellStyle().getHidden();\r
- }\r
-\r
- /**\r
- * Checks if cell locked matches.\r
- *\r
- * @param cellWorkBook1\r
- * the cell work book1\r
- * @param cellWorkBook2\r
- * the cell work book2\r
- * @return true, if cell locked matches\r
- */\r
- private boolean isCellLockedMatches(Cell cellWorkBook1, Cell cellWorkBook2) {\r
- return cellWorkBook1.getCellStyle().getLocked() != cellWorkBook2\r
- .getCellStyle().getLocked();\r
- }\r
-\r
- /**\r
- * Checks if cell type matches.\r
- *\r
- * @param cellWorkBook1\r
- * the cell work book1\r
- * @param cellWorkBook2\r
- * the cell work book2\r
- * @return true, if cell type matches\r
- */\r
- private boolean isCellTypeMatches(Cell cellWorkBook1, Cell cellWorkBook2) {\r
- return !(cellWorkBook1.getCellType() == cellWorkBook2.getCellType());\r
- }\r
-\r
- /**\r
- * Checks if cell under line matches.\r
- *\r
- * @param cellWorkBook1\r
- * the cell work book1\r
- * @param cellWorkBook2\r
- * the cell work book2\r
- * @return true, if cell under line matches\r
- */\r
- private boolean isCellUnderLineMatches(Cell cellWorkBook1,\r
- Cell cellWorkBook2) {\r
- if (cellWorkBook1.getCellStyle() instanceof XSSFCellStyle) {\r
- return ((XSSFCellStyle) cellWorkBook1.getCellStyle()).getFont()\r
- .getUnderline() != ((XSSFCellStyle) cellWorkBook2\r
- .getCellStyle()).getFont().getUnderline();\r
- } else {\r
- return false;\r
- }\r
-\r
- }\r
-\r
- /**\r
- * Checks if name of sheet matches.\r
- *\r
- * @param workbook1\r
- * the workbook1\r
- * @param workbook2\r
- * the workbook2\r
- * @param i\r
- * the i\r
- * @return true, if name of sheet matches\r
- */\r
- private boolean isNameOfSheetMatches(Workbook workbook1,\r
- Workbook workbook2, int i) {\r
- if (workbook2.getNumberOfSheets() > i) {\r
- return !(workbook1.getSheetName(i)\r
- .equals(workbook2.getSheetName(i)));\r
- } else {\r
- return true;\r
- }\r
-\r
- }\r
-\r
- /**\r
- * Checks if number of columns matches.\r
- *\r
- * @param sheetWorkBook1\r
- * the sheet work book1\r
- * @param sheetWorkBook2\r
- * the sheet work book2\r
- * @return true, if number of columns matches\r
- */\r
- private boolean isNumberOfColumnsMatches(Sheet sheetWorkBook1,\r
- Sheet sheetWorkBook2) {\r
- if (sheetWorkBook2 != null) {\r
- return !(sheetWorkBook1.getRow(0).getLastCellNum() == sheetWorkBook2\r
- .getRow(0).getLastCellNum());\r
- } else {\r
- return true;\r
- }\r
-\r
- }\r
-\r
- /**\r
- * Checks if number of rows matches.\r
- *\r
- * @param sheetWorkBook1\r
- * the sheet work book1\r
- * @param sheetWorkBook2\r
- * the sheet work book2\r
- * @return true, if number of rows matches\r
- */\r
- private boolean isNumberOfRowsMatches(Sheet sheetWorkBook1,\r
- Sheet sheetWorkBook2) {\r
- if (sheetWorkBook2 != null) {\r
- return !(sheetWorkBook1.getPhysicalNumberOfRows() == sheetWorkBook2\r
- .getPhysicalNumberOfRows());\r
- } else {\r
- return true;\r
- }\r
-\r
- }\r
-\r
- /**\r
- * Checks if number of sheets matches.\r
- *\r
- * @param workbook1\r
- * the workbook1\r
- * @param workbook2\r
- * the workbook2\r
- * @return true, if number of sheets matches\r
- */\r
- private boolean isNumberOfSheetsMatches(Workbook workbook1,\r
- Workbook workbook2) {\r
- return !(workbook1.getNumberOfSheets() == workbook2.getNumberOfSheets());\r
- }\r
-\r
- private boolean isWorkBookEmpty(Sheet sheetWorkBook1, Sheet sheetWorkBook2) {\r
- if (sheetWorkBook2 != null) {\r
- return !((null == sheetWorkBook1.getRow(0)) || (null == sheetWorkBook2\r
- .getRow(0)));\r
- } else {\r
- return true;\r
- }\r
-\r
- }\r
-\r
-}\r
-\r
-class ExcelFileDifference {\r
- boolean isDifferenceFound;\r
- List<String> listOfDifferences;\r
-}\r
--- /dev/null
+/* ====================================================================\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to You under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+==================================================================== */\r
+package org.apache.poi.ss.examples;\r
+\r
+import java.io.File;\r
+import java.util.ArrayList;\r
+import java.util.Date;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+import java.util.Locale;\r
+\r
+import org.apache.poi.ss.usermodel.Cell;\r
+import org.apache.poi.ss.usermodel.Color;\r
+import org.apache.poi.ss.usermodel.DateUtil;\r
+import org.apache.poi.ss.usermodel.Row;\r
+import org.apache.poi.ss.usermodel.Sheet;\r
+import org.apache.poi.ss.usermodel.Workbook;\r
+import org.apache.poi.ss.usermodel.WorkbookFactory;\r
+import org.apache.poi.ss.util.CellReference;\r
+import org.apache.poi.xssf.usermodel.XSSFCell;\r
+import org.apache.poi.xssf.usermodel.XSSFCellStyle;\r
+import org.apache.poi.xssf.usermodel.XSSFColor;\r
+\r
+/**\r
+ * Utility to compare Excel File Contents cell by cell for all sheets.\r
+ *\r
+ * <p>This utility will be used to compare Excel File Contents cell by cell for all sheets programmatically.</p>\r
+ *\r
+ * <p>Below are the list of Attribute comparison supported in this version.</p>\r
+ *\r
+ * <ul>\r
+ * <li>Cell Alignment</li>\r
+ * <li>Cell Border Attributes</li>\r
+ * <li>Cell Data</li>\r
+ * <li>Cell Data-Type</li>\r
+ * <li>Cell Fill Color</li>\r
+ * <li>Cell Fill pattern</li>\r
+ * <li>Cell Font Attributes</li>\r
+ * <li>Cell Font Family</li>\r
+ * <li>Cell Font Size</li>\r
+ * <li>Cell Protection</li>\r
+ * <li>Name of the sheets</li>\r
+ * <li>Number of Columns</li>\r
+ * <li>Number of Rows</li>\r
+ * <li>Number of Sheet</li>\r
+ * </ul>\r
+ *\r
+ * <p>(Some of the above attribute comparison only work for *.xlsx format currently. In future it can be enhanced.)</p>\r
+ *\r
+ * <p><b>Usage:</b></p>\r
+ *\r
+ * <pre>\r
+ * {@code\r
+ * Workbook wb1 = WorkbookFactory.create(new File("workBook1.xls"));\r
+ * Workbook wb2 = WorkbookFactory.create(new File("workBook2.xls"));\r
+ * List<String> listOfDifferences = ExcelComparator.compare(wb1, wb2);\r
+ * for (String differences : listOfDifferences)\r
+ * System.out.println(differences);\r
+ * System.out.println("DifferenceFound = "+ excelFileDifference.isDifferenceFound);\r
+ * }\r
+ * </pre>\r
+ */\r
+public class ExcelComparator {\r
+ \r
+ private static final String CELL_DATA_DOES_NOT_MATCH = "Cell Data does not Match ::";\r
+ private static final String CELL_FONT_ATTRIBUTES_DOES_NOT_MATCH = "Cell Font Attributes does not Match ::";\r
+\r
+ private static class Locator {\r
+ Workbook workbook;\r
+ Sheet sheet;\r
+ Row row;\r
+ Cell cell;\r
+ }\r
+ \r
+ List<String> listOfDifferences = new ArrayList<String>();\r
+\r
+ public static void main(String args[]) throws Exception {\r
+ if (args.length != 2 || !(new File(args[0]).exists()) || !(new File(args[1]).exists())) {\r
+ System.err.println("java -cp <classpath> "+ExcelComparator.class.getCanonicalName()+" <workbook1.xls/x> <workbook2.xls/x");\r
+ System.exit(-1);\r
+ }\r
+ Workbook wb1 = WorkbookFactory.create(new File(args[0]));\r
+ Workbook wb2 = WorkbookFactory.create(new File(args[1]));\r
+ \r
+ for (String d : ExcelComparator.compare(wb1, wb2)) {\r
+ System.out.println(d);\r
+ }\r
+ \r
+ wb2.close();\r
+ wb1.close();\r
+ }\r
+ \r
+ /**\r
+ * Utility to compare Excel File Contents cell by cell for all sheets.\r
+ *\r
+ * @param workbook1 the workbook1\r
+ * @param workbook2 the workbook2\r
+ * @return the Excel file difference containing a flag and a list of differences\r
+ * @throws ExcelCompareException the excel compare exception\r
+ */\r
+ public static List<String> compare(Workbook wb1, Workbook wb2) {\r
+ Locator loc1 = new Locator();\r
+ Locator loc2 = new Locator();\r
+ loc1.workbook = wb1;\r
+ loc2.workbook = wb2;\r
+\r
+ ExcelComparator excelComparator = new ExcelComparator();\r
+ excelComparator.compareNumberOfSheets(loc1, loc2 );\r
+ excelComparator.compareSheetNames(loc1, loc2);\r
+ excelComparator.compareSheetData(loc1, loc2);\r
+\r
+ return excelComparator.listOfDifferences;\r
+ }\r
+\r
+ /**\r
+ * Compare data in all sheets.\r
+ *\r
+ * @param workbook1 the workbook1\r
+ * @param workbook2 the workbook2\r
+ * @param listOfDifferences the list of differences\r
+ * @throws ExcelCompareException the excel compare exception\r
+ */\r
+ private void compareDataInAllSheets(Locator loc1, Locator loc2) {\r
+ for (int i = 0; i < loc1.workbook.getNumberOfSheets(); i++) {\r
+ if (loc2.workbook.getNumberOfSheets() <= i) return;\r
+\r
+ loc1.sheet = loc1.workbook.getSheetAt(i);\r
+ loc2.sheet = loc2.workbook.getSheetAt(i);\r
+\r
+ compareDataInSheet(loc1, loc2);\r
+ }\r
+ }\r
+\r
+ private void compareDataInSheet(Locator loc1, Locator loc2) {\r
+ for (int j = 0; j < loc1.sheet.getPhysicalNumberOfRows(); j++) {\r
+ if (loc2.sheet.getPhysicalNumberOfRows() <= j) return;\r
+\r
+ loc1.row = loc1.sheet.getRow(j);\r
+ loc2.row = loc2.sheet.getRow(j);\r
+\r
+ if ((loc1.row == null) || (loc2.row == null)) {\r
+ continue;\r
+ }\r
+\r
+ compareDataInRow(loc1, loc2);\r
+ }\r
+ }\r
+\r
+ private void compareDataInRow(Locator loc1, Locator loc2) {\r
+ for (int k = 0; k < loc1.row.getLastCellNum(); k++) {\r
+ if (loc2.row.getPhysicalNumberOfCells() <= k) return;\r
+\r
+ loc1.cell = loc1.row.getCell(k);\r
+ loc2.cell = loc2.row.getCell(k);\r
+\r
+ if ((loc1.cell == null) || (loc2.cell == null)) {\r
+ continue;\r
+ }\r
+\r
+ compareDataInCell(loc1, loc2);\r
+ }\r
+ }\r
+\r
+ private void compareDataInCell(Locator loc1, Locator loc2) {\r
+ if (isCellTypeMatches(loc1, loc2)) {\r
+ switch(loc1.cell.getCellType()) {\r
+ case Cell.CELL_TYPE_BLANK:\r
+ case Cell.CELL_TYPE_STRING:\r
+ case Cell.CELL_TYPE_ERROR:\r
+ isCellContentMatches(loc1,loc2);\r
+ break;\r
+ case Cell.CELL_TYPE_BOOLEAN:\r
+ isCellContentMatchesForBoolean(loc1,loc2);\r
+ break;\r
+ case Cell.CELL_TYPE_FORMULA:\r
+ isCellContentMatchesForFormula(loc1,loc2);\r
+ break;\r
+ case Cell.CELL_TYPE_NUMERIC:\r
+ if (DateUtil.isCellDateFormatted(loc1.cell)) {\r
+ isCellContentMatchesForDate(loc1,loc2);\r
+ } else {\r
+ isCellContentMatchesForNumeric(loc1,loc2);\r
+ }\r
+ break;\r
+ }\r
+ }\r
+\r
+ isCellFillPatternMatches(loc1,loc2);\r
+ isCellAlignmentMatches(loc1,loc2);\r
+ isCellHiddenMatches(loc1,loc2);\r
+ isCellLockedMatches(loc1,loc2);\r
+ isCellFontFamilyMatches(loc1,loc2);\r
+ isCellFontSizeMatches(loc1,loc2);\r
+ isCellFontBoldMatches(loc1,loc2);\r
+ isCellUnderLineMatches(loc1,loc2);\r
+ isCellFontItalicsMatches(loc1,loc2);\r
+ isCellBorderMatches(loc1,loc2,'t');\r
+ isCellBorderMatches(loc1,loc2,'l');\r
+ isCellBorderMatches(loc1,loc2,'b');\r
+ isCellBorderMatches(loc1,loc2,'r');\r
+ isCellFillBackGroundMatches(loc1,loc2);\r
+ }\r
+\r
+ /**\r
+ * Compare number of columns in sheets.\r
+ */\r
+ private void compareNumberOfColumnsInSheets(Locator loc1, Locator loc2) {\r
+ for (int i = 0; i < loc1.workbook.getNumberOfSheets(); i++) {\r
+ if (loc2.workbook.getNumberOfSheets() <= i) return;\r
+ \r
+ loc1.sheet = loc1.workbook.getSheetAt(i);\r
+ loc2.sheet = loc2.workbook.getSheetAt(i);\r
+\r
+ Iterator<Row> ri1 = loc1.sheet.rowIterator();\r
+ Iterator<Row> ri2 = loc2.sheet.rowIterator();\r
+ \r
+ int num1 = (ri1.hasNext()) ? ri1.next().getPhysicalNumberOfCells() : 0;\r
+ int num2 = (ri2.hasNext()) ? ri2.next().getPhysicalNumberOfCells() : 0;\r
+ \r
+ if (num1 != num2) {\r
+ String str = String.format(Locale.ROOT, "%s\nworkbook1 -> %s [%d] != workbook2 -> %s [%d]",\r
+ "Number Of Columns does not Match ::",\r
+ loc1.sheet.getSheetName(), num1,\r
+ loc2.sheet.getSheetName(), num2\r
+ );\r
+ listOfDifferences.add(str);\r
+ }\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Compare number of rows in sheets.\r
+ */\r
+ private void compareNumberOfRowsInSheets(Locator loc1, Locator loc2) {\r
+ for (int i = 0; i < loc1.workbook.getNumberOfSheets(); i++) {\r
+ if (loc2.workbook.getNumberOfSheets() <= i) return;\r
+\r
+ loc1.sheet = loc1.workbook.getSheetAt(i);\r
+ loc2.sheet = loc2.workbook.getSheetAt(i);\r
+ \r
+ int num1 = loc1.sheet.getPhysicalNumberOfRows();\r
+ int num2 = loc2.sheet.getPhysicalNumberOfRows();\r
+\r
+ if (num1 != num2) {\r
+ String str = String.format(Locale.ROOT, "%s\nworkbook1 -> %s [%d] != workbook2 -> %s [%d]",\r
+ "Number Of Rows does not Match ::",\r
+ loc1.sheet.getSheetName(), num1,\r
+ loc2.sheet.getSheetName(), num2\r
+ );\r
+ listOfDifferences.add(str);\r
+ }\r
+ }\r
+\r
+ }\r
+\r
+ /**\r
+ * Compare number of sheets.\r
+ */\r
+ private void compareNumberOfSheets(Locator loc1, Locator loc2) {\r
+ int num1 = loc1.workbook.getNumberOfSheets();\r
+ int num2 = loc2.workbook.getNumberOfSheets();\r
+ if (num1 != num2) {\r
+ String str = String.format(Locale.ROOT, "%s\nworkbook1 [%d] != workbook2 [%d]",\r
+ "Number of Sheets do not match ::",\r
+ num1, num2\r
+ );\r
+\r
+ listOfDifferences.add(str);\r
+ \r
+ }\r
+ }\r
+\r
+ /**\r
+ * Compare sheet data.\r
+ *\r
+ * @param workbook1\r
+ * the workbook1\r
+ * @param workbook2\r
+ * the workbook2\r
+ * @param listOfDifferences\r
+ *\r
+ * @throws ExcelCompareException\r
+ * the excel compare exception\r
+ */\r
+ private void compareSheetData(Locator loc1, Locator loc2) {\r
+ compareNumberOfRowsInSheets(loc1, loc2);\r
+ compareNumberOfColumnsInSheets(loc1, loc2);\r
+ compareDataInAllSheets(loc1, loc2);\r
+\r
+ }\r
+\r
+ /**\r
+ * Compare sheet names.\r
+ */\r
+ private void compareSheetNames(Locator loc1, Locator loc2) {\r
+ for (int i = 0; i < loc1.workbook.getNumberOfSheets(); i++) {\r
+ String name1 = loc1.workbook.getSheetName(i);\r
+ String name2 = (loc2.workbook.getNumberOfSheets() > i) ? loc2.workbook.getSheetName(i) : "";\r
+ \r
+ if (!name1.equals(name2)) {\r
+ String str = String.format(Locale.ROOT, "%s\nworkbook1 -> %s [%d] != workbook2 -> %s [%d]",\r
+ "Name of the sheets do not match ::",\r
+ loc1.sheet.getSheetName(), name1, i+1,\r
+ loc2.sheet.getSheetName(), name2, i+1\r
+ );\r
+ listOfDifferences.add(str);\r
+ }\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Formats the message.\r
+ */\r
+ private void addMessage(Locator loc1, Locator loc2, String messageStart, String value1, String value2) {\r
+ String str =\r
+ String.format(Locale.ROOT, "%s\nworkbook1 -> %s -> %s [%s] != workbook2 -> %s -> %s [%s]",\r
+ messageStart,\r
+ loc1.sheet.getSheetName(), new CellReference(loc1.cell).formatAsString(), value1,\r
+ loc2.sheet.getSheetName(), new CellReference(loc2.cell).formatAsString(), value2\r
+ );\r
+ listOfDifferences.add(str);\r
+ }\r
+\r
+ /**\r
+ * Checks if cell alignment matches.\r
+ */\r
+ private void isCellAlignmentMatches(Locator loc1, Locator loc2) {\r
+ // TODO: check for NPE\r
+ short align1 = loc1.cell.getCellStyle().getAlignment();\r
+ short align2 = loc2.cell.getCellStyle().getAlignment();\r
+ if (align1 != align2) {\r
+ addMessage(loc1, loc2,\r
+ "Cell Alignment does not Match ::",\r
+ Short.toString(align1),\r
+ Short.toString(align2)\r
+ );\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Checks if cell border bottom matches.\r
+ */\r
+ private void isCellBorderMatches(Locator loc1, Locator loc2, char borderSide) {\r
+ if (!(loc1.cell instanceof XSSFCell)) return;\r
+ XSSFCellStyle style1 = ((XSSFCell)loc1.cell).getCellStyle();\r
+ XSSFCellStyle style2 = ((XSSFCell)loc2.cell).getCellStyle();\r
+ boolean b1, b2;\r
+ String borderName;\r
+ switch (borderSide) {\r
+ case 't': default:\r
+ b1 = style1.getBorderTop() == 1;\r
+ b2 = style2.getBorderTop() == 1;\r
+ borderName = "TOP";\r
+ break;\r
+ case 'b':\r
+ b1 = style1.getBorderBottom() == 1;\r
+ b2 = style2.getBorderBottom() == 1;\r
+ borderName = "BOTTOM";\r
+ break;\r
+ case 'l':\r
+ b1 = style1.getBorderLeft() == 1;\r
+ b2 = style2.getBorderLeft() == 1;\r
+ borderName = "LEFT";\r
+ break;\r
+ case 'r':\r
+ b1 = style1.getBorderRight() == 1;\r
+ b2 = style2.getBorderRight() == 1;\r
+ borderName = "RIGHT";\r
+ break;\r
+ }\r
+ if (b1 != b2) {\r
+ addMessage(loc1, loc2,\r
+ "Cell Border Attributes does not Match ::",\r
+ (b1 ? "" : "NOT ")+borderName+" BORDER",\r
+ (b2 ? "" : "NOT ")+borderName+" BORDER"\r
+ );\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Checks if cell content matches.\r
+ */\r
+ private void isCellContentMatches(Locator loc1, Locator loc2) {\r
+ // TODO: check for null and non-rich-text cells\r
+ String str1 = loc1.cell.getRichStringCellValue().getString();\r
+ String str2 = loc2.cell.getRichStringCellValue().getString();\r
+ if (!str1.equals(str2)) {\r
+ addMessage(loc1,loc2,CELL_DATA_DOES_NOT_MATCH,str1,str2);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Checks if cell content matches for boolean.\r
+ */\r
+ private void isCellContentMatchesForBoolean(Locator loc1, Locator loc2) {\r
+ boolean b1 = loc1.cell.getBooleanCellValue();\r
+ boolean b2 = loc2.cell.getBooleanCellValue();\r
+ if (b1 != b2) {\r
+ addMessage(loc1,loc2,CELL_DATA_DOES_NOT_MATCH,Boolean.toString(b1),Boolean.toString(b2));\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Checks if cell content matches for date.\r
+ */\r
+ private void isCellContentMatchesForDate(Locator loc1, Locator loc2) {\r
+ Date date1 = loc1.cell.getDateCellValue();\r
+ Date date2 = loc2.cell.getDateCellValue();\r
+ if (!date1.equals(date2)) {\r
+ addMessage(loc1, loc2, CELL_DATA_DOES_NOT_MATCH, date1.toGMTString(), date2.toGMTString());\r
+ }\r
+ }\r
+\r
+\r
+ /**\r
+ * Checks if cell content matches for formula.\r
+ */\r
+ private void isCellContentMatchesForFormula(Locator loc1, Locator loc2) {\r
+ // TODO: actually evaluate the formula / NPE checks\r
+ String form1 = loc1.cell.getCellFormula();\r
+ String form2 = loc2.cell.getCellFormula();\r
+ if (!form1.equals(form2)) {\r
+ addMessage(loc1, loc2, CELL_DATA_DOES_NOT_MATCH, form1, form2);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Checks if cell content matches for numeric.\r
+ */\r
+ private void isCellContentMatchesForNumeric(Locator loc1, Locator loc2) {\r
+ // TODO: Check for NaN\r
+ double num1 = loc1.cell.getNumericCellValue();\r
+ double num2 = loc2.cell.getNumericCellValue();\r
+ if (num1 != num2) {\r
+ addMessage(loc1, loc2, CELL_DATA_DOES_NOT_MATCH, Double.toString(num1), Double.toString(num2));\r
+ }\r
+ }\r
+\r
+ private String getCellFillBackground(Locator loc) {\r
+ Color col = loc.cell.getCellStyle().getFillForegroundColorColor();\r
+ return (col instanceof XSSFColor) ? ((XSSFColor)col).getARGBHex() : "NO COLOR";\r
+ }\r
+ \r
+ /**\r
+ * Checks if cell file back ground matches.\r
+ */\r
+ private void isCellFillBackGroundMatches(Locator loc1, Locator loc2) {\r
+ String col1 = getCellFillBackground(loc1);\r
+ String col2 = getCellFillBackground(loc2);\r
+ if (!col1.equals(col2)) {\r
+ addMessage(loc1, loc2, "Cell Fill Color does not Match ::", col1, col2);\r
+ }\r
+ }\r
+ /**\r
+ * Checks if cell fill pattern matches.\r
+ */\r
+ private void isCellFillPatternMatches(Locator loc1, Locator loc2) {\r
+ // TOOO: Check for NPE\r
+ short fill1 = loc1.cell.getCellStyle().getFillPattern();\r
+ short fill2 = loc2.cell.getCellStyle().getFillPattern();\r
+ if (fill1 != fill2) {\r
+ addMessage(loc1, loc2,\r
+ "Cell Fill pattern does not Match ::",\r
+ Short.toString(fill1),\r
+ Short.toString(fill2)\r
+ );\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Checks if cell font bold matches.\r
+ */\r
+ private void isCellFontBoldMatches(Locator loc1, Locator loc2) {\r
+ if (!(loc1.cell instanceof XSSFCell)) return;\r
+ boolean b1 = ((XSSFCell)loc1.cell).getCellStyle().getFont().getBold();\r
+ boolean b2 = ((XSSFCell)loc2.cell).getCellStyle().getFont().getBold();\r
+ if (b1 != b2) {\r
+ addMessage(loc1, loc2,\r
+ CELL_FONT_ATTRIBUTES_DOES_NOT_MATCH,\r
+ (b1 ? "" : "NOT ")+"BOLD",\r
+ (b2 ? "" : "NOT ")+"BOLD"\r
+ );\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Checks if cell font family matches.\r
+ */\r
+ private void isCellFontFamilyMatches(Locator loc1, Locator loc2) {\r
+ // TODO: Check for NPEs\r
+ if (!(loc1.cell instanceof XSSFCell)) return;\r
+ String family1 = ((XSSFCell)loc1.cell).getCellStyle().getFont().getFontName();\r
+ String family2 = ((XSSFCell)loc2.cell).getCellStyle().getFont().getFontName();\r
+ if (!family1.equals(family2)) {\r
+ addMessage(loc1, loc2, "Cell Font Family does not Match ::", family1, family2);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Checks if cell font italics matches.\r
+ */\r
+ private void isCellFontItalicsMatches(Locator loc1, Locator loc2) {\r
+ if (!(loc1.cell instanceof XSSFCell)) return;\r
+ boolean b1 = ((XSSFCell)loc1.cell).getCellStyle().getFont().getItalic();\r
+ boolean b2 = ((XSSFCell)loc2.cell).getCellStyle().getFont().getItalic();\r
+ if (b1 != b2) {\r
+ addMessage(loc1, loc2,\r
+ CELL_FONT_ATTRIBUTES_DOES_NOT_MATCH,\r
+ (b1 ? "" : "NOT ")+"ITALICS",\r
+ (b2 ? "" : "NOT ")+"ITALICS"\r
+ );\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Checks if cell font size matches.\r
+ */\r
+ private void isCellFontSizeMatches(Locator loc1, Locator loc2) {\r
+ if (!(loc1.cell instanceof XSSFCell)) return;\r
+ short size1 = ((XSSFCell)loc1.cell).getCellStyle().getFont().getFontHeightInPoints();\r
+ short size2 = ((XSSFCell)loc2.cell).getCellStyle().getFont().getFontHeightInPoints();\r
+ if (size1 != size2) {\r
+ addMessage(loc1, loc2,\r
+ "Cell Font Size does not Match ::",\r
+ Short.toString(size1),\r
+ Short.toString(size2)\r
+ );\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Checks if cell hidden matches.\r
+ */\r
+ private void isCellHiddenMatches(Locator loc1, Locator loc2) {\r
+ boolean b1 = loc1.cell.getCellStyle().getHidden();\r
+ boolean b2 = loc1.cell.getCellStyle().getHidden();\r
+ if (b1 != b2) {\r
+ addMessage(loc1, loc2,\r
+ "Cell Visibility does not Match ::",\r
+ (b1 ? "" : "NOT ")+"HIDDEN",\r
+ (b2 ? "" : "NOT ")+"HIDDEN"\r
+ );\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Checks if cell locked matches.\r
+ */\r
+ private void isCellLockedMatches(Locator loc1, Locator loc2) {\r
+ boolean b1 = loc1.cell.getCellStyle().getLocked();\r
+ boolean b2 = loc1.cell.getCellStyle().getLocked();\r
+ if (b1 != b2) {\r
+ addMessage(loc1, loc2,\r
+ "Cell Protection does not Match ::",\r
+ (b1 ? "" : "NOT ")+"LOCKED",\r
+ (b2 ? "" : "NOT ")+"LOCKED"\r
+ );\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Checks if cell type matches.\r
+ */\r
+ private boolean isCellTypeMatches(Locator loc1, Locator loc2) {\r
+ int type1 = loc1.cell.getCellType();\r
+ int type2 = loc2.cell.getCellType();\r
+ if (type1 == type2) return true;\r
+ addMessage(loc1, loc2,\r
+ "Cell Data-Type does not Match in :: ",\r
+ Integer.toString(type1),\r
+ Integer.toString(type2)\r
+ );\r
+ return false;\r
+ }\r
+\r
+ /**\r
+ * Checks if cell under line matches.\r
+ *\r
+ * @param cellWorkBook1\r
+ * the cell work book1\r
+ * @param cellWorkBook2\r
+ * the cell work book2\r
+ * @return true, if cell under line matches\r
+ */\r
+ private void isCellUnderLineMatches(Locator loc1, Locator loc2) {\r
+ // TOOO: distinguish underline type\r
+ if (!(loc1.cell instanceof XSSFCell)) return;\r
+ byte b1 = ((XSSFCell)loc1.cell).getCellStyle().getFont().getUnderline();\r
+ byte b2 = ((XSSFCell)loc2.cell).getCellStyle().getFont().getUnderline();\r
+ if (b1 != b2) {\r
+ addMessage(loc1, loc2,\r
+ CELL_FONT_ATTRIBUTES_DOES_NOT_MATCH,\r
+ (b1 == 1 ? "" : "NOT ")+"UNDERLINE",\r
+ (b2 == 1 ? "" : "NOT ")+"UNDERLINE"\r
+ );\r
+ }\r
+ }\r
+}
\ No newline at end of file
*/
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;
*/
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();
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) {
if (lastColumnNumber == -1) {
lastColumnNumber = 0;
}
- for (int i = lastColumnNumber; i < (this.minColumnCount); i++) {
+ for (int i = lastColumnNumber; i < minColumns; i++) {
output.print(',');
}
}
///////////////////////////////////////
- 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
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);
}
OPCPackage p = OPCPackage.open(xlsxFile.getPath(), PackageAccess.READ);
XLSX2CSV xlsx2csv = new XLSX2CSV(p, System.out, minColumns);
xlsx2csv.process();
+ p.close();
}
}
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));
+// }
}
/**
return null;\r
}\r
XWPFTableRow tableRow = table.getRow(row);\r
- if (row == null) {\r
- return null;\r
- }\r
return tableRow.getTableCell(cell);\r
}
\r
}
}
- List<XWPFTable> tables = getTables();
for (int i = 0; i < tables.size(); i++) {
String text = tables.get(i).getText();
if (text != null && text.length() > 0) {
return null;
}
XWPFTableRow tableRow = table.getRow(row);
- if (row == null) {
- return null;
- }
return tableRow.getTableCell(cell);
}
} else {
final STCryptProv.Enum providerType;
final int sid;
+ if (hashAlgo == null) {
+ hashAlgo = HashAlgorithm.sha1;
+ }
+
switch (hashAlgo) {
case md2:
providerType = STCryptProv.RSA_FULL;
// 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
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;
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;
*/
@RunWith(Parameterized.class)
public final class TestFormulaEvaluatorOnXSSF {
+ private static final POILogger logger = POILogFactory.getLogger(TestFormulaEvaluatorOnXSSF.class);
private static XSSFWorkbook workbook;
private static Sheet sheet;
private static void processFunctionGroup(List<Object[]> data, int startRowIndex, String testFocusFunctionName) {
for (int rowIndex = startRowIndex; true; rowIndex += SS.NUMBER_OF_ROWS_PER_FUNCTION) {
Row r = sheet.getRow(rowIndex);
+
+ // only evaluate non empty row
+ if(r == null) continue;
+
String targetFunctionName = getTargetFunctionName(r);
- if(targetFunctionName == null) {
- fail("Test spreadsheet cell empty on row ("
- + (rowIndex+1) + "). Expected function name or '"
- + SS.FUNCTION_NAMES_END_SENTINEL + "'");
- }
+ assertNotNull("Test spreadsheet cell empty on row ("
+ + (rowIndex+1) + "). Expected function name or '"
+ + SS.FUNCTION_NAMES_END_SENTINEL + "'", targetFunctionName);
+
if(targetFunctionName.equals(SS.FUNCTION_NAMES_END_SENTINEL)) {
// found end of functions list
break;
// 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});
}
// 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);
/*
* 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));
}
/**
*/
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) {
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;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
-import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
+import org.junit.AfterClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
/**
* Tests formulas for multi sheet reference (i.e. SUM(Sheet1:Sheet5!A1))
*/
-public final class TestMultiSheetFormulaEvaluatorOnXSSF extends TestCase {
+@RunWith(Parameterized.class)
+public final class TestMultiSheetFormulaEvaluatorOnXSSF {
private static final POILogger logger = POILogFactory.getLogger(TestFormulasFromSpreadsheet.class);
- private static final class Result {
- public static final int SOME_EVALUATIONS_FAILED = -1;
- public static final int ALL_EVALUATIONS_SUCCEEDED = +1;
- public static final int NO_EVALUATIONS_FOUND = 0;
- }
+ private static XSSFWorkbook workbook;
+ private static Sheet sheet;
+ private static FormulaEvaluator evaluator;
/**
* This class defines constants for navigating around the test data spreadsheet used for these tests.
*/
- private static final class SS {
+ interface SS {
/**
* Name of the test spreadsheet (found in the standard test data folder)
*/
- public final static String FILENAME = "FormulaSheetRange.xlsx";
+ String FILENAME = "FormulaSheetRange.xlsx";
/**
* Row (zero-based) in the test spreadsheet where the function examples start.
*/
- public static final int START_FUNCTIONS_ROW_INDEX = 10; // Row '11'
+ int START_FUNCTIONS_ROW_INDEX = 10; // Row '11'
/**
* Index of the column that contains the function names
*/
- public static final int COLUMN_INDEX_FUNCTION_NAME = 0; // Column 'A'
+ int COLUMN_INDEX_FUNCTION_NAME = 0; // Column 'A'
/**
* Index of the column that contains the test names
*/
- public static final int COLUMN_INDEX_TEST_NAME = 1; // Column 'B'
+ int COLUMN_INDEX_TEST_NAME = 1; // Column 'B'
/**
* Used to indicate when there are no more functions left
*/
- public static final String FUNCTION_NAMES_END_SENTINEL = "<END>";
+ String FUNCTION_NAMES_END_SENTINEL = "<END>";
/**
* Index of the column where the test expected value is present
*/
- public static final short COLUMN_INDEX_EXPECTED_VALUE = 2; // Column 'C'
+ short COLUMN_INDEX_EXPECTED_VALUE = 2; // Column 'C'
/**
* Index of the column where the test actual value is present
*/
- public static final short COLUMN_INDEX_ACTUAL_VALUE = 3; // Column 'D'
+ short COLUMN_INDEX_ACTUAL_VALUE = 3; // Column 'D'
/**
* Test sheet name (sheet with all test formulae)
*/
- public static final String TEST_SHEET_NAME = "test";
+ String TEST_SHEET_NAME = "test";
}
- private XSSFWorkbook workbook;
- private Sheet sheet;
- // Note - multiple failures are aggregated before ending.
- // If one or more functions fail, a single AssertionFailedError is thrown at the end
- private int _functionFailureCount;
- private int _functionSuccessCount;
- private int _evaluationFailureCount;
- private int _evaluationSuccessCount;
-
- 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;
- }
- }
+ @Parameter(value = 0)
+ public String targetTestName;
+ @Parameter(value = 1)
+ public String targetFunctionName;
+ @Parameter(value = 2)
+ public int formulasRowIdx;
+ @AfterClass
+ public static void closeResource() throws Exception {
+ workbook.close();
+ }
- 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;
- }
+ @Parameters(name="{0}")
+ public static Collection<Object[]> data() throws Exception {
+ workbook = new XSSFWorkbook( OPCPackage.open(HSSFTestDataSamples.getSampleFile(SS.FILENAME), PackageAccess.READ) );
+ sheet = workbook.getSheet( SS.TEST_SHEET_NAME );
+ evaluator = new XSSFFormulaEvaluator(workbook);
- public void testFunctionsFromTestSpreadsheet() {
+ List<Object[]> data = new ArrayList<Object[]>();
- processFunctionGroup(SS.START_FUNCTIONS_ROW_INDEX, null);
+ processFunctionGroup(data, SS.START_FUNCTIONS_ROW_INDEX, null);
- // 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);
- }
+ return data;
+ }
- /**
- * @param startRowIndex row index in the spreadsheet where the first function/operator is found
- * @param testFocusFunctionName name of a single function/operator to test alone.
- * Typically pass <code>null</code> to test all functions
- */
- private void processFunctionGroup(int startRowIndex, String testFocusFunctionName) {
- FormulaEvaluator evaluator = new XSSFFormulaEvaluator(workbook);
-
- 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)) {
-
- // 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 ++;
- }
- }
+ /**
+ * @param startRowIndex row index in the spreadsheet where the first function/operator is found
+ * @param testFocusFunctionName name of a single function/operator to test alone.
+ * Typically pass <code>null</code> to test all functions
+ */
+ private static void processFunctionGroup(List<Object[]> data, int startRowIndex, String testFocusFunctionName) {
+ for (int rowIndex = startRowIndex; true; rowIndex++) {
+ Row r = sheet.getRow(rowIndex);
- /**
- *
- * @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) {
+ // only evaluate non empty row
+ if(r == null) continue;
- int result = Result.NO_EVALUATIONS_FOUND; // so far
+ String targetFunctionName = getTargetFunctionName(r);
+ assertNotNull("Test spreadsheet cell empty on row ("
+ + (rowIndex+1) + "). Expected function name or '"
+ + SS.FUNCTION_NAMES_END_SENTINEL + "'", targetFunctionName);
- Cell c = formulasRow.getCell(SS.COLUMN_INDEX_ACTUAL_VALUE);
- if (c == null || c.getCellType() != Cell.CELL_TYPE_FORMULA) {
- return result;
- }
+ if(targetFunctionName.equals(SS.FUNCTION_NAMES_END_SENTINEL)) {
+ // found end of functions list
+ break;
+ }
- CellValue actualValue = evaluator.evaluate(c);
-
- 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;
- }
+ String targetTestName = getTargetTestName(r);
+ if(testFocusFunctionName == null || targetFunctionName.equalsIgnoreCase(testFocusFunctionName)) {
- /**
- * 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();
-
- int startIx = 0;
- // skip any top frames inside junit.framework.Assert
- while(startIx<stes.length) {
- if(!stes[startIx].getClassName().equals(Assert.class.getName())) {
- break;
- }
- startIx++;
- }
- // skip bottom frames (part of junit framework)
- int endIx = startIx+1;
- while(endIx < stes.length) {
- if(stes[endIx].getClassName().equals(TestCase.class.getName())) {
- break;
- }
- endIx++;
- }
- if(startIx >= endIx) {
- // something went wrong. just print the whole stack trace
- e.printStackTrace(ps);
- }
- endIx -= 4; // skip 4 frames of reflection invocation
- ps.println(e.toString());
- for(int i=startIx; i<endIx; i++) {
- ps.println("\tat " + stes[i].toString());
- }
- }
+ // 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);
- /**
+ data.add(new Object[]{targetTestName, targetFunctionName, rowIndex});
+ }
+ }
+ }
+
+ /**
+ *
+ * @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);
+
+ Cell expValue = r.getCell(SS.COLUMN_INDEX_EXPECTED_VALUE);
+ assertNotNull("Missing expected values cell for function '"
+ + targetFunctionName + ", test" + targetTestName + " (row " +
+ formulasRowIdx + 1 + ")", expValue);
+
+ Cell c = r.getCell(SS.COLUMN_INDEX_ACTUAL_VALUE);
+ assumeNotNull(c);
+ assumeTrue(c.getCellType() == Cell.CELL_TYPE_FORMULA);
+
+ CellValue actValue = evaluator.evaluate(c);
+
+ String msg = String.format(Locale.ROOT, "Function '%s': Test: '%s': Formula: %s @ %d:%d",
+ targetFunctionName, targetTestName, c.getCellFormula(), formulasRowIdx, SS.COLUMN_INDEX_ACTUAL_VALUE);
+
+ assertNotNull(msg + " - actual value was null", actValue);
+
+ switch (expValue.getCellType()) {
+ case Cell.CELL_TYPE_BLANK:
+ assertEquals(msg, Cell.CELL_TYPE_BLANK, actValue.getCellType());
+ break;
+ case Cell.CELL_TYPE_BOOLEAN:
+ assertEquals(msg, Cell.CELL_TYPE_BOOLEAN, actValue.getCellType());
+ assertEquals(msg, expValue.getBooleanCellValue(), actValue.getBooleanValue());
+ break;
+ case Cell.CELL_TYPE_ERROR:
+ assertEquals(msg, Cell.CELL_TYPE_ERROR, actValue.getCellType());
+// if(false) { // TODO: fix ~45 functions which are currently returning incorrect error values
+// assertEquals(msg, expected.getErrorCellValue(), actual.getErrorValue());
+// }
+ break;
+ case Cell.CELL_TYPE_FORMULA: // will never be used, since we will call method after formula evaluation
+ fail("Cannot expect formula as result of formula evaluation: " + msg);
+ case Cell.CELL_TYPE_NUMERIC:
+ assertEquals(msg, Cell.CELL_TYPE_NUMERIC, actValue.getCellType());
+ TestMathX.assertEquals(msg, expValue.getNumericCellValue(), actValue.getNumberValue(), TestMathX.POS_ZERO, TestMathX.DIFF_TOLERANCE_FACTOR);
+// double delta = Math.abs(expected.getNumericCellValue()-actual.getNumberValue());
+// double pctExpected = Math.abs(0.00001*expected.getNumericCellValue());
+// assertTrue(msg, delta <= pctExpected);
+ break;
+ case Cell.CELL_TYPE_STRING:
+ assertEquals(msg, Cell.CELL_TYPE_STRING, actValue.getCellType());
+ assertEquals(msg, expValue.getRichStringCellValue().getString(), actValue.getStringValue());
+ break;
+ }
+ }
+
+ /**
* @return <code>null</code> if cell is missing, empty or blank
*/
private static String getTargetFunctionName(Row r) {
if(r == null) {
- System.err.println("Warning - given null row, can't figure out function name");
+ logger.log(POILogger.WARN, "Warning - given null row, can't figure out function name");
return null;
}
Cell cell = r.getCell(SS.COLUMN_INDEX_FUNCTION_NAME);
if(cell == null) {
- System.err.println("Warning - Row " + r.getRowNum() + " has no cell " + SS.COLUMN_INDEX_FUNCTION_NAME + ", can't figure out function name");
+ logger.log(POILogger.WARN, "Warning - Row " + r.getRowNum() + " has no cell " + SS.COLUMN_INDEX_FUNCTION_NAME + ", can't figure out function name");
return null;
}
if(cell.getCellType() == Cell.CELL_TYPE_BLANK) {
return cell.getRichStringCellValue().getString();
}
- throw new AssertionFailedError("Bad cell type for 'function name' column: ("
- + cell.getCellType() + ") row (" + (r.getRowNum() +1) + ")");
+ fail("Bad cell type for 'function name' column: ("
+ + cell.getCellType() + ") row (" + (r.getRowNum() +1) + ")");
+ return "";
}
/**
* @return <code>null</code> if cell is missing, empty or blank
*/
private static String getTargetTestName(Row r) {
if(r == null) {
- System.err.println("Warning - given null row, can't figure out test name");
+ logger.log(POILogger.WARN, "Warning - given null row, can't figure out test name");
return null;
}
Cell cell = r.getCell(SS.COLUMN_INDEX_TEST_NAME);
if(cell == null) {
- System.err.println("Warning - Row " + r.getRowNum() + " has no cell " + SS.COLUMN_INDEX_TEST_NAME + ", can't figure out test name");
+ logger.log(POILogger.WARN, "Warning - Row " + r.getRowNum() + " has no cell " + SS.COLUMN_INDEX_TEST_NAME + ", can't figure out test name");
return null;
}
if(cell.getCellType() == Cell.CELL_TYPE_BLANK) {
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 "";
}
-
+
}
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;
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();
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());
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());
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());
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");
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();
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());
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");
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");
assertTrue(doc.getAllPictures().contains(part));
assertTrue(doc.getAllPackagePictures().contains(part));
doc.getPackage().revert();
+ doc.close();
}
+ @Test
public void testGetAllPictures() throws IOException {
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("issue_51265_3.docx");
List<XWPFPictureData> allPictures = doc.getAllPictures();
}
doc.getPackage().revert();
+ doc.close();
}
+ @Test
public void testGetAllPackagePictures() throws IOException {
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("issue_51265_3.docx");
List<XWPFPictureData> allPackagePictures = doc.getAllPackagePictures();
}
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());
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);
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();
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());
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);
package org.apache.poi.hssf.model;
-import junit.framework.AssertionFailedError;
-import junit.framework.TestCase;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
import org.apache.poi.hssf.HSSFTestDataSamples;
-import org.apache.poi.ss.formula.ptg.AttrPtg;
-import org.apache.poi.ss.formula.ptg.Ptg;
import org.apache.poi.hssf.usermodel.FormulaExtractor;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
+import org.apache.poi.ss.formula.ptg.AttrPtg;
+import org.apache.poi.ss.formula.ptg.Ptg;
+import org.junit.AfterClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
/**
* Tests 'operand class' transformation performed by
* <tt>OperandClassTransformer</tt> by comparing its results with those
* directly produced by Excel (in a sample spreadsheet).
- *
- * @author Josh Micich
*/
-public final class TestRVA extends TestCase {
+@RunWith(Parameterized.class)
+public final class TestRVA {
private static final String NEW_LINE = System.getProperty("line.separator");
+ private static NPOIFSFileSystem poifs;
+ private static HSSFWorkbook workbook;
+ private static HSSFSheet sheet;
- public void testFormulas() {
- HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("testRVA.xls");
- HSSFSheet sheet = wb.getSheetAt(0);
+
+ @Parameter(value = 0)
+ public HSSFCell formulaCell;
+ @Parameter(value = 1)
+ public String formula;
- int countFailures = 0;
- int countErrors = 0;
+ @AfterClass
+ public static void closeResource() throws Exception {
+ workbook.close();
+ poifs.close();
+ }
- int rowIx = 0;
- while (rowIx < 65535) {
- HSSFRow row = sheet.getRow(rowIx);
- if (row == null) {
- break;
- }
- HSSFCell cell = row.getCell(0);
- if (cell == null || cell.getCellType() == HSSFCell.CELL_TYPE_BLANK) {
- break;
- }
- String formula = cell.getCellFormula();
- try {
- confirmCell(cell, formula, wb);
- } catch (AssertionFailedError e) {
- System.out.flush();
- System.err.println("Problem with row[" + rowIx + "] formula '" + formula + "'");
- System.err.println(e.getMessage());
- System.err.flush();
- countFailures++;
- } catch (RuntimeException e) {
- System.err.println("Problem with row[" + rowIx + "] formula '" + formula + "'");
- countErrors++;
- e.printStackTrace();
- }
- rowIx++;
- }
- if (countErrors + countFailures > 0) {
- String msg = "One or more RVA tests failed: countFailures=" + countFailures
- + " countFailures=" + countErrors + ". See stderr for details.";
- throw new AssertionFailedError(msg);
- }
- }
+ @Parameters(name="{1}")
+ public static Collection<Object[]> data() throws Exception {
+ poifs = new NPOIFSFileSystem(HSSFTestDataSamples.getSampleFile("testRVA.xls"), true);
+ workbook = new HSSFWorkbook(poifs);
+ sheet = workbook.getSheetAt(0);
- private void confirmCell(HSSFCell formulaCell, String formula, HSSFWorkbook wb) {
+ List<Object[]> data = new ArrayList<Object[]>();
+
+ for (int rowIdx = 0; true; rowIdx++) {
+ HSSFRow row = sheet.getRow(rowIdx);
+ if (row == null) {
+ break;
+ }
+ HSSFCell cell = row.getCell(0);
+ if (cell == null || cell.getCellType() == HSSFCell.CELL_TYPE_BLANK) {
+ break;
+ }
+
+ String formula = cell.getCellFormula();
+ data.add(new Object[]{cell,formula});
+ }
+
+ return data;
+ }
+
+ @Test
+ public void confirmCell() {
Ptg[] excelPtgs = FormulaExtractor.getPtgs(formulaCell);
- Ptg[] poiPtgs = HSSFFormulaParser.parse(formula, wb);
+ Ptg[] poiPtgs = HSSFFormulaParser.parse(formula, workbook);
int nExcelTokens = excelPtgs.length;
int nPoiTokens = poiPtgs.length;
if (nExcelTokens != nPoiTokens) {
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;
}
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) {
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;
import org.apache.poi.ss.formula.FormulaShifter;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.util.HexRead;
+import org.junit.Test;
+
+import junit.framework.AssertionFailedError;
/**
* Unit test for the {@link InternalSheet} class.
- *
- * @author Glen Stampoultzis (glens at apache.org)
*/
-public final class TestSheet extends TestCase {
+public final class TestSheet {
private static InternalSheet createSheet(List<Record> inRecs) {
return InternalSheet.createSheet(new RecordStream(inRecs, 0));
}
return rc.getRecords();
}
+ @Test
public void testCreateSheet() {
// Check we're adding row and cell aggregates
List<Record> records = new ArrayList<Record>();
}
}
+ @Test
public void testAddMergedRegion() {
InternalSheet sheet = InternalSheet.createSheet();
int regionsToAdd = 4096;
}
}
+ @Test
public void testRemoveMergedRegion() {
InternalSheet sheet = InternalSheet.createSheet();
int regionsToAdd = 4096;
* fills up the records.
*
*/
+ @Test
public void testMovingMergedRegion() {
List<Record> records = new ArrayList<Record>();
assertEquals("Should be no more merged regions", 0, sheet.getNumMergedRegions());
}
+ @Test
public void testGetMergedRegionAt() {
//TODO
}
+ @Test
public void testGetNumMergedRegions() {
//TODO
}
* Makes sure all rows registered for this sheet are aggregated, they were being skipped
*
*/
+ @Test
public void testRowAggregation() {
List<Record> records = new ArrayList<Record>();
* Make sure page break functionality works (in memory)
*
*/
+ @Test
public void testRowPageBreaks() {
short colFrom = 0;
short colTo = 255;
* Make sure column pag breaks works properly (in-memory)
*
*/
+ @Test
public void testColPageBreaks() {
short rowFrom = 0;
short rowTo = (short)65535;
* test newly added method Sheet.getXFIndexForColAt(..)
* works as designed.
*/
+ @Test
public void testXFIndexForColumn() {
final short TEST_IDX = 10;
final short DEFAULT_IDX = 0xF; // 15
* Prior to bug 45066, POI would get the estimated sheet size wrong
* when an <tt>UncalcedRecord</tt> was present.<p/>
*/
+ @Test
public void testUncalcSize_bug45066() {
List<Record> records = new ArrayList<Record>();
*
* 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();
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);
}
* 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();
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);
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();
}
}
* 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;
* 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();
* 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();
assertNotNull(cft);
}
+ @Test
public void testCloneMulBlank_bug46776() {
Record[] recs = {
InternalSheet.createBOF(),
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" +
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);
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;
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;
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();
* as part of the value records
*/
@SuppressWarnings("deprecation") // uses deprecated {@link ValueRecordsAggregate#getValueRecords()}
+ @Test
public void testSharedFormula() {
List<Record> records = new ArrayList<Record>();
records.add(new FormulaRecord());
}
@SuppressWarnings("deprecation") // uses deprecated {@link ValueRecordsAggregate#getValueRecords()}
+ @Test
public void testInsertCell() {
CellValueRecordInterface[] cvrs = valueRecord.getValueRecords();
assertEquals(0, cvrs.length);
}
@SuppressWarnings("deprecation") // uses deprecated {@link ValueRecordsAggregate#getValueRecords()}
- public void testRemoveCell() {
+ @Test
+ public void testRemoveCell() {
BlankRecord blankRecord1 = newBlankRecord();
valueRecord.insertCell( blankRecord1 );
BlankRecord blankRecord2 = newBlankRecord();
valueRecord.removeCell( blankRecord2 );
}
+ @Test
public void testGetPhysicalNumberOfCells() {
assertEquals(0, valueRecord.getPhysicalNumberOfCells());
BlankRecord blankRecord1 = newBlankRecord();
assertEquals(0, valueRecord.getPhysicalNumberOfCells());
}
+ @Test
public void testGetFirstCellNum() {
assertEquals( -1, valueRecord.getFirstCellNum() );
valueRecord.insertCell( newBlankRecord( 2, 2 ) );
assertEquals( 2, valueRecord.getFirstCellNum() );
}
+ @Test
public void testGetLastCellNum() {
assertEquals( -1, valueRecord.getLastCellNum() );
valueRecord.insertCell( newBlankRecord( 2, 2 ) );
}
}
+ @Test
public void testSerialize() {
byte[] expectedArray = HexRead.readFromString(""
+ "06 00 16 00 " // Formula
* 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;
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();
return crc.getValue();
}
+
+ @Test
public void testRemoveNewRow_bug46312() {
// To make bug occur, rowIndex needs to be >= ValueRecordsAggregate.records.length
int rowIndex = 30;
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);
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);
- }
}
package org.apache.poi.ss.formula.functions;
-import junit.framework.AssertionFailedError;
-import junit.framework.TestCase;
-
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import org.apache.poi.hssf.usermodel.HSSFCell;
+import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
+import org.apache.poi.hssf.usermodel.HSSFName;
+import org.apache.poi.hssf.usermodel.HSSFRow;
+import org.apache.poi.hssf.usermodel.HSSFSheet;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.formula.eval.ErrorEval;
-import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellValue;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
+import org.junit.Test;
/**
* Tests for the INDIRECT() function.</p>
- *
- * @author Josh Micich
*/
-public final class TestIndirect extends TestCase {
+public final class TestIndirect {
// convenient access to namespace
- private static final ErrorEval EE = null;
+ // private static final ErrorEval EE = null;
private static void createDataRow(HSSFSheet sheet, int rowIndex, double... vals) {
HSSFRow row = sheet.createRow(rowIndex);
return wb;
}
- public void testBasic() {
+ @Test
+ public void testBasic() throws Exception {
HSSFWorkbook wbA = createWBA();
HSSFCell c = wbA.getSheetAt(0).createRow(5).createCell(2);
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);
// 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,
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() + "'.");
}
}