Compare commits

...

10 Commits

Author SHA1 Message Date
Andreas Isler bbaacfb439 Fixed issue in isSubset 2025-12-05 09:19:33 +01:00
Andreas Isler b105c63c7e Simplified ParameterizedTest 2025-12-02 18:41:17 +01:00
Andreas Isler bc9f2a7451 Added __N_A for negative tests 2025-11-27 17:40:26 +01:00
Andreas Isler ff8f71abf4 Moved isSubset to mapper test 2025-11-25 11:58:10 +01:00
Andreas Isler f8ee09c97a Added isSubset for testing nodes 2025-11-25 05:58:25 +01:00
Andreas Isler 3806797041 Moved parseExcelBook into parseExcelBookFromResource 2025-11-19 14:28:34 +01:00
Andreas Isler d570e04087 Bugfix in parseSheet 2025-11-19 08:37:36 +01:00
Andreas Isler 0cc2304ad8 Removed bug in example data 2025-11-18 20:44:11 +01:00
Andreas Isler caa1e4b8f8 Parse Excel as String only 2025-11-18 20:36:53 +01:00
Andreas Isler 861633d373 Added parseExcel for backwards compatibility 2025-11-18 09:57:28 +01:00
18 changed files with 310 additions and 124 deletions
+1 -1
View File
@@ -74,7 +74,7 @@
</profile-state> </profile-state>
</entry> </entry>
</component> </component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="homebrew-17" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="homebrew-17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" /> <output url="file://$PROJECT_DIR$/out" />
</component> </component>
</project> </project>
@@ -6,10 +6,11 @@ import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.apache.poi.ss.usermodel.DateUtil;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.time.*; import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.*; import java.util.*;
@@ -28,7 +29,7 @@ public class FlowableExcelMapper {
// excelPath defines the location of the Excel file // excelPath defines the location of the Excel file
// FlowableExcelParser is used to create an ArrayList from the Excel file // FlowableExcelParser is used to create an ArrayList from the Excel file
// The first row of every sheet contains the path of the variables to be created in the JsonNode // The 1st row of every sheet contains the path of the variables to be created in the JsonNode
// Delimiter is "." for an ObjectNode and "*" for an ArrayNode // Delimiter is "." for an ObjectNode and "*" for an ArrayNode
// The 2nd row contains tht type of the variable. Supported types are: // The 2nd row contains tht type of the variable. Supported types are:
// - String // - String
@@ -39,29 +40,29 @@ public class FlowableExcelMapper {
// All sheets are added to an ArrayNode // All sheets are added to an ArrayNode
// All rows are added to an ArrayNode in the sheets ArrayNode // All rows are added to an ArrayNode in the sheets ArrayNode
// All cell values are added to an ObjectNode in the rows ArrayNode // All cell values are added to an ObjectNode in the rows ArrayNode
public ArrayNode excelBookToJsonNode(String excelPath) { public ArrayNode excelBookResourceToJsonNode(String resourcePath) {
ArrayList<ArrayList<ArrayList<Object>>> book = flowableExcelParser.parseExcelBook(excelPath); ArrayList<ArrayList<ArrayList<String>>> book = flowableExcelParser.parseExcelBookFromResource(resourcePath);
return bookToJsonNode(book); return bookToJsonNode(book);
} }
protected ArrayNode bookToJsonNode(ArrayList<ArrayList<ArrayList<Object>>> book) { protected ArrayNode bookToJsonNode(ArrayList<ArrayList<ArrayList<String>>> book) {
ArrayNode bookNode = objectMapper.createArrayNode(); ArrayNode bookNode = objectMapper.createArrayNode();
for (ArrayList<ArrayList<Object>> sheet : book) { for (ArrayList<ArrayList<String>> sheet : book) {
bookNode.add(sheetToJsonNode(sheet)); bookNode.add(sheetToJsonNode(sheet));
} }
return bookNode; return bookNode;
} }
protected ArrayNode sheetToJsonNode(ArrayList<ArrayList<Object>> rows) { protected ArrayNode sheetToJsonNode(ArrayList<ArrayList<String>> rows) {
ArrayList<Object> paths = new ArrayList<>(); ArrayList<String> paths = new ArrayList<>();
ArrayList<Object> types = new ArrayList<>(); ArrayList<String> types = new ArrayList<>();
ArrayNode arrayNode = objectMapper.createArrayNode(); ArrayNode arrayNode = objectMapper.createArrayNode();
for (int rowNum = 0; rowNum < rows.size(); rowNum++) { for (int rowNum = 0; rowNum < rows.size(); rowNum++) {
if (rowNum == 0) { if (rowNum == 0) {
// The 1st row contains the paths // The 1st row contains the paths
paths.addAll(rows.get(rowNum)); paths.addAll(rows.get(rowNum));
} else if (rowNum == 1) { } else if (rowNum == 1) {
// The 1st row contains the types of the variables // The 2nd row contains the types of the variables
types.addAll(rows.get(rowNum)); types.addAll(rows.get(rowNum));
} else { } else {
// All other rows contain the values of the variables // All other rows contain the values of the variables
@@ -71,25 +72,47 @@ public class FlowableExcelMapper {
return arrayNode; return arrayNode;
} }
protected JsonNode rowToJsonNode(ArrayList<Object> types, ArrayList<Object> paths, ArrayList<Object> row, JsonNode jsonNode) { protected JsonNode rowToJsonNode(ArrayList<String> types, ArrayList<String> paths, ArrayList<String> row, JsonNode jsonNode) {
for (int cellNum = 0; cellNum < row.size(); cellNum++) { for (int cellNum = 0; cellNum < row.size(); cellNum++) {
Object content = row.get(cellNum); String cellValue = row.get(cellNum);
if (content != null) { // Empty cells are not added to node
String type = types.get(cellNum).toString(); if (cellValue != null && !cellValue.isEmpty()) {
switch (type) { String type = types.get(cellNum);
case "String": content = content.toString(); break; Object content;
case "Boolean": content = Boolean.parseBoolean(content.toString()); break; switch (cellValue) {
case "Integer": content = (int) Double.parseDouble(content.toString()); break; case "__NULL": content = null; break;
case "Double": content = Double.parseDouble(content.toString()); break; case "__N_A": content = "__N_A"; break;
case "Date": default:
// Excel considers dates as local dates, but we want them as UTC switch (type) {
Date dateTime = DateUtil.getJavaDate(Double.parseDouble(content.toString())); case "String":
content = dateTime.toInstant().plusSeconds(ZonedDateTime.now().getOffset().getTotalSeconds()); switch (cellValue) {
break; case "__EMPTY": content = ""; break;
default: break; case "__BLANK": content = " "; break;
default: content = cellValue;
}
break;
case "Boolean": content = Boolean.parseBoolean(cellValue); break;
case "Integer": content = Integer.parseInt(cellValue); break;
case "Double": content = Double.parseDouble(cellValue); break;
case "Long": content = Long.parseLong(cellValue); break;
case "Date":
// Excel considers dates as local dates, but we want them as UTC
Instant instant;
try {
LocalDateTime localDateTime = LocalDateTime.parse(cellValue, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
} catch (DateTimeParseException e) {
LocalDate localDate = LocalDate.parse(cellValue, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
instant = localDate.atStartOfDay(ZoneId.systemDefault()).toInstant();
}
content = instant.plusSeconds(ZonedDateTime.now().getOffset().getTotalSeconds());
break;
default:
throw new RuntimeException("Variable type not supported: " + type);
}
} }
jsonNode = addNode(jsonNode, paths.get(cellNum), content);
} }
jsonNode = addNode(jsonNode, paths.get(cellNum).toString(), content);
} }
return jsonNode; return jsonNode;
} }
@@ -7,7 +7,9 @@ import org.springframework.stereotype.Component;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashMap;
@Component @Component
@@ -15,16 +17,16 @@ public class FlowableExcelParser {
// excelPath defines the location of the Excel file // excelPath defines the location of the Excel file
// Return all cells in all sheets with the following restrictions: // Return all cells in all sheets with the following restrictions:
// - Max columns per sheet is defined in the first row // - Max column count per sheet is defined in the first row
// - Max column count starts with the 1st cell and ends with the 1st empty cell // - Max column count starts with the 1st cell and ends with the 1st empty cell
// - Parsing the sheet stops after the 1st empty row // - Parsing the sheet stops after the 1st empty row
// All sheets are added to an ArrayList // All sheets are added to an ArrayList
// All rows are added to an ArrayList in the sheets ArrayList // All rows are added to an ArrayList in the sheets ArrayList
// All cell values are added to an ArrayList in the rows ArrayList // All cell values are added to an ArrayList in the rows ArrayList
// Formulas in cells are evaluated // Formulas in cells are evaluated
// Excel values can have only 3 types: String, boolean, double // All values are returned as String
public ArrayList<ArrayList<ArrayList<Object>>> parseExcelBook(String excelPath) { public ArrayList<ArrayList<ArrayList<String>>> parseExcelBookFromResource(String excelResourcePath) {
try (FileInputStream fileInputStream = new FileInputStream(excelPath)) { try (FileInputStream fileInputStream = new FileInputStream(getResourcePath(excelResourcePath))) {
Workbook workBook = new XSSFWorkbook(fileInputStream); Workbook workBook = new XSSFWorkbook(fileInputStream);
return parseBook(workBook); return parseBook(workBook);
} catch (IOException e) { } catch (IOException e) {
@@ -32,8 +34,9 @@ public class FlowableExcelParser {
} }
} }
public ArrayList<ArrayList<Object>> parseExcelSheet(String excelPath) { @Deprecated
try (FileInputStream fileInputStream = new FileInputStream(excelPath)) { public ArrayList<ArrayList<String>> parseExcelSheetFromResource(String excelResourcePath) {
try (FileInputStream fileInputStream = new FileInputStream(getResourcePath(excelResourcePath))) {
Workbook workBook = new XSSFWorkbook(fileInputStream); Workbook workBook = new XSSFWorkbook(fileInputStream);
FormulaEvaluator formulaEvaluator = workBook.getCreationHelper().createFormulaEvaluator(); FormulaEvaluator formulaEvaluator = workBook.getCreationHelper().createFormulaEvaluator();
Sheet workSheet = workBook.getSheetAt(0); Sheet workSheet = workBook.getSheetAt(0);
@@ -43,8 +46,17 @@ public class FlowableExcelParser {
} }
} }
protected ArrayList<ArrayList<ArrayList<Object>>> parseBook(Workbook workBook ) { private String getResourcePath(String resourcePath) {
ArrayList<ArrayList<ArrayList<Object>>> book = new ArrayList<>(); ClassLoader classLoader = FlowableExcelParser.class.getClassLoader();
URL resourceUrl = classLoader.getResource(resourcePath);
if (resourceUrl == null) {
throw new RuntimeException("Resource not found: " + resourcePath);
}
return resourceUrl.getPath();
}
private ArrayList<ArrayList<ArrayList<String>>> parseBook(Workbook workBook ) {
ArrayList<ArrayList<ArrayList<String>>> book = new ArrayList<>();
FormulaEvaluator formulaEvaluator = workBook.getCreationHelper().createFormulaEvaluator(); FormulaEvaluator formulaEvaluator = workBook.getCreationHelper().createFormulaEvaluator();
for (Sheet workSheet : workBook) { for (Sheet workSheet : workBook) {
book.add(parseSheet(workSheet, formulaEvaluator)); book.add(parseSheet(workSheet, formulaEvaluator));
@@ -52,14 +64,13 @@ public class FlowableExcelParser {
return book; return book;
} }
protected ArrayList<ArrayList<Object>> parseSheet(Sheet workSheet, FormulaEvaluator formulaEvaluator) { private ArrayList<ArrayList<String>> parseSheet(Sheet workSheet, FormulaEvaluator formulaEvaluator) {
ArrayList<ArrayList<Object>> sheet = new ArrayList<>(); ArrayList<ArrayList<String>> sheet = new ArrayList<>();
// Count columns of first row // Count columns of first row
int maxCols = getMaxCols(workSheet.getRow(0)); int maxCols = getMaxCols(workSheet.getRow(0));
int lastRowNum = workSheet.getLastRowNum(); DataFormatter dataFormatter = new DataFormatter();
for (int rowIndex = 0; rowIndex < lastRowNum; rowIndex++) { for (Row workRow : workSheet) {
Row workRow = workSheet.getRow(rowIndex); ArrayList<String> row = parseRow(workRow, maxCols, formulaEvaluator, dataFormatter);
ArrayList<Object> row = parseRow(workRow, maxCols, formulaEvaluator);
if (row == null) { if (row == null) {
// Take all rows until the first empty row // Take all rows until the first empty row
break; break;
@@ -70,34 +81,19 @@ public class FlowableExcelParser {
return sheet; return sheet;
} }
protected ArrayList<Object> parseRow(Row workRow, int maxCols, FormulaEvaluator formulaEvaluator) { private ArrayList<String> parseRow(Row workRow, int maxCols, FormulaEvaluator formulaEvaluator, DataFormatter dataFormatter) {
if (workRow == null) { if (workRow == null) {
// Row is empty // Row is empty
return null; return null;
} }
ArrayList<Object> row = new ArrayList<>(); ArrayList<String> row = new ArrayList<>();
boolean allCellsNull = true; boolean allCellsNull = true;
for (int colIndex = 0; colIndex < maxCols; colIndex++) { for (int colIndex = 0; colIndex < maxCols; colIndex++) {
Object content = null;
Cell workCell = workRow.getCell(colIndex); Cell workCell = workRow.getCell(colIndex);
if (workCell != null) { formulaEvaluator.evaluate(workCell);
CellType workCellType = workCell.getCellType(); String content = dataFormatter.formatCellValue(workCell, formulaEvaluator);
if (workCellType != CellType.BLANK && workCellType != CellType._NONE) { if (content != null && !content.isEmpty()) {
allCellsNull = false; allCellsNull = false;
switch (workCellType) {
case STRING : content = workCell.getStringCellValue(); break;
case BOOLEAN : content = workCell.getBooleanCellValue(); break;
case NUMERIC : content = workCell.getNumericCellValue(); break;
case FORMULA :
CellValue evaluatedValue = formulaEvaluator.evaluate(workCell);
switch (evaluatedValue.getCellType()) {
case STRING : content = evaluatedValue.getStringValue(); break;
case BOOLEAN : content = evaluatedValue.getBooleanValue(); break;
case NUMERIC : content = evaluatedValue.getNumberValue(); break;
}
break;
}
}
} }
row.add(content); row.add(content);
} }
@@ -109,7 +105,7 @@ public class FlowableExcelParser {
} }
} }
protected int getMaxCols(Row workRow) { private int getMaxCols(Row workRow) {
int maxCol = workRow.getLastCellNum(); int maxCol = workRow.getLastCellNum();
for (int colIndex = 0; colIndex < maxCol; colIndex++) { for (int colIndex = 0; colIndex < maxCol; colIndex++) {
Cell workCell = workRow.getCell(colIndex); Cell workCell = workRow.getCell(colIndex);
@@ -120,4 +116,33 @@ public class FlowableExcelParser {
} }
return maxCol; return maxCol;
} }
@Deprecated
public ArrayList<LinkedHashMap<String, Object>> parseExcelFromResource(String resourcePath) {
try (FileInputStream fileInputStream = new FileInputStream(getResourcePath(resourcePath))) {
Workbook workBook = new XSSFWorkbook(fileInputStream);
FormulaEvaluator formulaEvaluator = workBook.getCreationHelper().createFormulaEvaluator();
ArrayList<ArrayList<String>> sheet = parseSheet(workBook.getSheetAt(0), formulaEvaluator);
ArrayList<String> colHeaders = new ArrayList<>();
ArrayList<LinkedHashMap<String, Object>> rowList = new ArrayList<>();
for (int rowIndex = 0; rowIndex < sheet.size(); rowIndex++) {
ArrayList<String> row = sheet.get(rowIndex);
if (rowIndex == 0) {
// Header row
for (Object cell : row) {
colHeaders.add(String.valueOf(cell));
}
continue;
}
LinkedHashMap<String, Object> rowMap = new LinkedHashMap<>();
for (int colIndex = 0; colIndex < row.size(); colIndex++) {
rowMap.put(colHeaders.get(colIndex), row.get(colIndex));
}
rowList.add(rowMap);
}
return rowList;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
} }
@@ -8,7 +8,6 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.URL;
import java.util.Map; import java.util.Map;
@SpringBootApplication @SpringBootApplication
@@ -29,12 +28,8 @@ public class ParserApp {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
URL resourceUrl = ParserApp.class.getClassLoader().getResource("flowableExcelParserExampleData.xlsx"); logger.info("parsed excel={}", flowableExcelParser.parseExcelBookFromResource("flowableExcelParserExampleData.xlsx"));
assert resourceUrl != null;
logger.info("parsed excel={}", flowableExcelParser.parseExcelBook(resourceUrl.getPath()));
resourceUrl = ParserApp.class.getClassLoader().getResource("flowableExcelMapperExampleData.xlsx"); logger.info("mapped excel={}", flowableExcelMapper.excelBookResourceToJsonNode("flowableExcelMapperExampleData.xlsx"));
assert resourceUrl != null;
logger.info("mapped excel={}", flowableExcelMapper.excelBookToJsonNode(resourceUrl.getPath()));
} }
} }
@@ -2,18 +2,15 @@ package com.example.parser;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import org.assertj.core.api.Assertions; import org.assertj.core.api.Assertions;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.MethodSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator;
import java.util.stream.Stream; import java.util.stream.Stream;
@@ -24,19 +21,70 @@ class FlowableExcelMapperTest {
@Autowired @Autowired
private FlowableExcelMapper flowableExcelMapper; private FlowableExcelMapper flowableExcelMapper;
private static final Logger logger = LoggerFactory.getLogger(FlowableExcelMapperTest.class);
public boolean isSubset(JsonNode root, JsonNode test) {
protected String getResourcePath(String path) { // If test is null, it is always a subset of root
ClassLoader classLoader = FlowableExcelMapperTest.class.getClassLoader(); if (test == null) {
URL resourceUrl = classLoader.getResource(path); return true;
Assertions.assertThat(resourceUrl).isNotNull(); }
return resourceUrl.getPath(); // If test is a value node, compare values
if (test.isValueNode()) {
if (test.isTextual() && "__N_A".equals(test.asText())) {
return false;
}
if (root == null) {
return false;
}
return root.isValueNode() && root.asText().equals(test.asText());
}
// If test is an array node, check if all elements of test exist in root
if(test.isArray()){
for (int i = 0; i < test.size(); i++) {
JsonNode testElement = test.get(i);
JsonNode rootElement = null;
if (root != null) {
rootElement = root.get(i);
}
if (testElement.isTextual() && "__N_A".equals(testElement.asText())) {
if (rootElement != null && !rootElement.isNull()) {
return false;
}
continue;
}
if (!isSubset(rootElement, testElement)) {
return false;
}
}
return true;
}
// If test is an object node, check if all fields in test exist in root
if (test.isObject()){
for (Iterator<String> iterator = test.fieldNames(); iterator.hasNext(); ) {
String fieldName = iterator.next();
JsonNode testValue = test.get(fieldName);
JsonNode rootValue = null;
if (root != null) {
rootValue = root.get(fieldName);
}
if (testValue.isTextual() && "__N_A".equals(testValue.asText())) {
if (root != null && root.has(fieldName)) {
return false;
}
continue;
}
if (!isSubset(rootValue, testValue)){
return false;
}
}
return true;
}
// If none of the above matches, return false
return false;
} }
protected Stream<Arguments> getArgumentsFromExcel(String path) { protected Stream<Arguments> getArgumentsFromExcel(String path) {
ArrayList<Arguments> argumentList = new ArrayList<>(); ArrayList<Arguments> argumentList = new ArrayList<>();
JsonNode book = flowableExcelMapper.excelBookToJsonNode(getResourcePath(path)); JsonNode book = flowableExcelMapper.excelBookResourceToJsonNode(path);
for (JsonNode sheet : book) { for (JsonNode sheet : book) {
for (JsonNode row : sheet) { for (JsonNode row : sheet) {
argumentList.add(Arguments.of(row)); argumentList.add(Arguments.of(row));
@@ -45,13 +93,27 @@ class FlowableExcelMapperTest {
return argumentList.stream(); return argumentList.stream();
} }
@NotNull protected Stream<Arguments> excelMapperTestOk() {
protected Stream<Arguments> excelMapperTestData() { return getArgumentsFromExcel("flowableExcelMapperTestData_ok.xlsx");
return getArgumentsFromExcel("flowableExcelMapperTestData.xlsx");
} }
@ParameterizedTest @ParameterizedTest
@MethodSource("excelMapperTestData") @MethodSource
public void excelMapperTest(JsonNode sheet) { public void excelMapperTestOk(JsonNode row) {
logger.info("node2={}{}", System.lineSeparator(), sheet.toPrettyString()); JsonNode root = row.get("root");
JsonNode test = row.get("test");
Assertions.assertThat(isSubset(root, test))
.withFailMessage(System.lineSeparator() + "test :" + test + System.lineSeparator() + "root :" + root).isTrue();
}
protected Stream<Arguments> excelMapperTestFail() {
return getArgumentsFromExcel("flowableExcelMapperTestData_fail.xlsx");
}
@ParameterizedTest
@MethodSource
public void excelMapperTestFail(JsonNode row) {
JsonNode root = row.get("root");
JsonNode test = row.get("test");
Assertions.assertThat(isSubset(root, test))
.withFailMessage(System.lineSeparator() + "test :" + test + System.lineSeparator() + "root :" + root).isFalse();
} }
} }
@@ -9,7 +9,6 @@ import org.junit.jupiter.params.provider.MethodSource;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import java.net.URL;
import java.util.*; import java.util.*;
import java.util.stream.Stream; import java.util.stream.Stream;
@@ -21,49 +20,42 @@ class FlowableExcelParserTest {
@Autowired @Autowired
private FlowableExcelParser flowableExcelParser; private FlowableExcelParser flowableExcelParser;
protected String getResourcePath(String path) { protected Stream<Arguments> getArgumentsFromExcelBook(String resourcePath) {
ClassLoader classLoader = FlowableExcelParserTest.class.getClassLoader();
URL resourceUrl = classLoader.getResource(path);
Assertions.assertThat(resourceUrl).isNotNull();
return resourceUrl.getPath();
}
protected Stream<Arguments> getArgumentsFromExcel(String path) {
ArrayList<Arguments> argumentList = new ArrayList<>(); ArrayList<Arguments> argumentList = new ArrayList<>();
ArrayList<ArrayList<ArrayList<Object>>> book = flowableExcelParser.parseExcelBook(getResourcePath(path)); ArrayList<ArrayList<ArrayList<String>>> book = flowableExcelParser.parseExcelBookFromResource(resourcePath);
for (ArrayList<ArrayList<Object>> sheet : book) { for (ArrayList<ArrayList<String>> sheet : book) {
for (ArrayList<Object> row : sheet) { for (ArrayList<String> row : sheet) {
argumentList.add(Arguments.of(row)); argumentList.add(Arguments.of(row));
} }
} }
ArrayList<ArrayList<Object>> sheet = flowableExcelParser.parseExcelSheet(getResourcePath(path)); ArrayList<ArrayList<String>> sheet = flowableExcelParser.parseExcelSheetFromResource(resourcePath);
for (ArrayList<Object> row : sheet) { for (ArrayList<String> row : sheet) {
argumentList.add(Arguments.of(row)); argumentList.add(Arguments.of(row));
} }
return argumentList.stream(); return argumentList.stream();
} }
@NotNull @NotNull
protected Stream<Arguments> booleanExcelParserTestData() { protected Stream<Arguments> booleanExcelParserTest() {
return getArgumentsFromExcel("flowableExcelParserTestData1.xlsx"); return getArgumentsFromExcelBook("flowableExcelParserTestDataBoolean.xlsx");
} }
@ParameterizedTest @ParameterizedTest
@MethodSource("booleanExcelParserTestData") @MethodSource
void booleanExcelParserTest(ArrayList<Object> row) { public void booleanExcelParserTest(ArrayList<Object> row) {
Boolean valOr = (Boolean) row.get(0) || (Boolean) row.get(1) || (Boolean) row.get(2); Boolean valOr = Boolean.parseBoolean(row.get(0).toString()) || Boolean.parseBoolean(row.get(1).toString()) || Boolean.parseBoolean(row.get(2).toString());
Assertions.assertThat(row.get(3)).isEqualTo(valOr); Assertions.assertThat(Boolean.parseBoolean(row.get(3).toString())).isEqualTo(valOr);
Boolean valAnd = (Boolean) row.get(0) && (Boolean) row.get(1) && (Boolean) row.get(2); Boolean valAnd = Boolean.parseBoolean(row.get(0).toString()) && Boolean.parseBoolean(row.get(1).toString()) && Boolean.parseBoolean(row.get(2).toString());
Assertions.assertThat(row.get(4)).isEqualTo(valAnd); Assertions.assertThat(Boolean.parseBoolean(row.get(4).toString())).isEqualTo(valAnd);
} }
@NotNull @NotNull
protected Stream<Arguments> stringExcelParserTestData() { protected Stream<Arguments> stringExcelParserTest() {
return getArgumentsFromExcel("flowableExcelParserTestData2.xlsx"); return getArgumentsFromExcelBook("flowableExcelParserTestDataString.xlsx");
} }
@ParameterizedTest @ParameterizedTest
@MethodSource("stringExcelParserTestData") @MethodSource
void stringExcelParserTest(ArrayList<Object> row) { public void stringExcelParserTest(ArrayList<Object> row) {
String val12 = row.get(0).toString() + row.get(1).toString(); String val12 = row.get(0).toString() + row.get(1).toString();
Assertions.assertThat(row.get(3)).isEqualTo(val12); Assertions.assertThat(row.get(3)).isEqualTo(val12);
@@ -75,19 +67,108 @@ class FlowableExcelParserTest {
} }
@NotNull @NotNull
protected Stream<Arguments> numberExcelParserTestData() { protected Stream<Arguments> numberExcelParserTest() {
return getArgumentsFromExcel("flowableExcelParserTestData3.xlsx"); return getArgumentsFromExcelBook("flowableExcelParserTestDataInteger.xlsx");
} }
@ParameterizedTest @ParameterizedTest
@MethodSource("numberExcelParserTestData") @MethodSource
void numberExcelParserTest(ArrayList<Object> row) { public void numberExcelParserTest(ArrayList<Object> row) {
Double val12 = (Double) row.get(0) + (Double) row.get(1); Integer val12 = Integer.parseInt(row.get(0).toString()) + Integer.parseInt(row.get(1).toString());
Assertions.assertThat(row.get(3)).isEqualTo(val12); Assertions.assertThat(Integer.parseInt(row.get(3).toString())).isEqualTo(val12);
Double val23 = (Double) row.get(1) + (Double) row.get(2); Integer val23 = Integer.parseInt(row.get(1).toString()) + Integer.parseInt(row.get(2).toString());
Assertions.assertThat(row.get(4)).isEqualTo(val23); Assertions.assertThat(Integer.parseInt(row.get(4).toString())).isEqualTo(val23);
Double val123 = (Double) row.get(0) + (Double) row.get(1) + (Double) row.get(2); Integer val123 = Integer.parseInt(row.get(0).toString()) + Integer.parseInt(row.get(1).toString()) + Integer.parseInt(row.get(2).toString());
Assertions.assertThat(row.get(5)).isEqualTo(val123); Assertions.assertThat(Integer.parseInt(row.get(5).toString())).isEqualTo(val123);
}
@Deprecated
protected Stream<Arguments> getArgumentsFromExcel(String resourcePath) {
ArrayList<Arguments> argumentList = new ArrayList<>();
ArrayList<LinkedHashMap<String, Object>> rowList = flowableExcelParser.parseExcelFromResource(resourcePath);
for (LinkedHashMap<String, Object> row : rowList) {
LinkedHashMap<String, Object> inputMap = new LinkedHashMap<>();
LinkedHashMap<String, Object> outputMap = new LinkedHashMap<>();
for (Map.Entry<String, Object> entry : row.entrySet()) {
String key = entry.getKey();
if (List.of("input1", "input2", "input3").contains(key)) {
inputMap.put(key, entry.getValue());
}
if (List.of("output1", "output2", "output3").contains(key)) {
outputMap.put(key, entry.getValue());
}
}
argumentList.add(Arguments.of(inputMap, outputMap));
}
return argumentList.stream();
}
@NotNull
protected Stream<Arguments> booleanOldExcelParserTest() {
return getArgumentsFromExcel("flowableExcelParserTestDataBooleanOld.xlsx");
}
@ParameterizedTest
@MethodSource
public void booleanOldExcelParserTest(LinkedHashMap<String, Object> inputMap, LinkedHashMap<String, Object> outputMap) {
for (Map.Entry<String, Object> entry : outputMap.entrySet()) {
String key = entry.getKey();
if (key.equals("output1")) {
Boolean val = Boolean.parseBoolean(inputMap.get("input1").toString()) || Boolean.parseBoolean(inputMap.get("input2").toString()) || Boolean.parseBoolean(inputMap.get("input3").toString());
Assertions.assertThat(Boolean.parseBoolean(entry.getValue().toString())).isEqualTo(val);
}
if (key.equals("output2")) {
Boolean val = Boolean.parseBoolean(inputMap.get("input1").toString()) && Boolean.parseBoolean(inputMap.get("input2").toString()) && Boolean.parseBoolean(inputMap.get("input3").toString());
Assertions.assertThat(Boolean.parseBoolean(entry.getValue().toString())).isEqualTo(val);
}
}
}
@NotNull
protected Stream<Arguments> stringOldExcelParserTest() {
return getArgumentsFromExcel("flowableExcelParserTestDataStringOld.xlsx");
}
@ParameterizedTest
@MethodSource
public void stringOldExcelParserTest(LinkedHashMap<String, Object> inputMap, LinkedHashMap<String, Object> outputMap) {
for (Map.Entry<String, Object> entry : outputMap.entrySet()) {
String key = entry.getKey();
if (key.equals("output1")) {
String val = inputMap.get("input1").toString() + inputMap.get("input2").toString();
Assertions.assertThat(entry.getValue()).isEqualTo(val);
}
if (key.equals("output2")) {
String val = inputMap.get("input2").toString() + inputMap.get("input3").toString();
Assertions.assertThat(entry.getValue()).isEqualTo(val);
}
if (key.equals("output3")) {
String val = inputMap.get("input1").toString() + inputMap.get("input2").toString() + inputMap.get("input3").toString();
Assertions.assertThat(entry.getValue()).isEqualTo(val);
}
}
}
@NotNull
protected Stream<Arguments> numberOldExcelParserTest() {
return getArgumentsFromExcel("flowableExcelParserTestDataIntegerOld.xlsx");
}
@ParameterizedTest
@MethodSource
public void numberOldExcelParserTest(LinkedHashMap<String, Object> inputMap, LinkedHashMap<String, Object> outputMap) {
for (Map.Entry<String, Object> entry : outputMap.entrySet()) {
String key = entry.getKey();
if (key.equals("output1")) {
Integer val12 = Integer.parseInt(inputMap.get("input1").toString()) + Integer.parseInt(inputMap.get("input2").toString());
Assertions.assertThat(Integer.parseInt(entry.getValue().toString())).isEqualTo(val12);
}
if (key.equals("output2")) {
Integer val23 = Integer.parseInt(inputMap.get("input2").toString()) + Integer.parseInt(inputMap.get("input3").toString());
Assertions.assertThat(Integer.parseInt(entry.getValue().toString())).isEqualTo(val23);
}
if (key.equals("output3")) {
Integer val12 = Integer.parseInt(inputMap.get("input1").toString()) + Integer.parseInt(inputMap.get("input2").toString()) + Integer.parseInt(inputMap.get("input3").toString());
Assertions.assertThat(Integer.parseInt(entry.getValue().toString())).isEqualTo(val12);
}
}
} }
} }
Binary file not shown.
Binary file not shown.
Binary file not shown.