From d6c2aeea797694016ac41b4614785b76fa396d5e Mon Sep 17 00:00:00 2001 From: Guy Davenport Date: Mon, 14 Oct 2024 20:12:01 +1300 Subject: [PATCH] updated XLSX support --- .../core/markdown/MarkdownGenerator.java | 3 +- .../core/utils/BrAPITClassCacheUtil.java | 63 ++++++++ .../core/valdiation/Validation.java | 137 +++++++++++++++++- .../core/xlsx/XSSFWorkbookGenerator.java | 98 ++++++++----- .../core/xlsx/options/ColumnOption.java | 13 ++ .../xlsx/options/ValuePropertyOption.java | 44 ++++++ .../options/XSSFWorkbookGeneratorOptions.java | 11 +- .../core/src/main/resources/xlsx-options.yaml | 23 ++- .../core/utils/BrAPITClassCacheUtilTest.java | 46 ++++++ .../xlsx/options/ValuePropertyOptionTest.java | 89 ++++++++++++ .../XSSFWorkbookGeneratorOptionsTest.java | 20 +++ 11 files changed, 494 insertions(+), 53 deletions(-) create mode 100644 java/core/src/main/java/org/brapi/schematools/core/utils/BrAPITClassCacheUtil.java create mode 100644 java/core/src/main/java/org/brapi/schematools/core/xlsx/options/ColumnOption.java create mode 100644 java/core/src/main/java/org/brapi/schematools/core/xlsx/options/ValuePropertyOption.java create mode 100644 java/core/src/test/java/org/brapi/schematools/core/utils/BrAPITClassCacheUtilTest.java create mode 100644 java/core/src/test/java/org/brapi/schematools/core/xlsx/options/ValuePropertyOptionTest.java create mode 100644 java/core/src/test/java/org/brapi/schematools/core/xlsx/options/XSSFWorkbookGeneratorOptionsTest.java diff --git a/java/core/src/main/java/org/brapi/schematools/core/markdown/MarkdownGenerator.java b/java/core/src/main/java/org/brapi/schematools/core/markdown/MarkdownGenerator.java index fecea13..caf157f 100644 --- a/java/core/src/main/java/org/brapi/schematools/core/markdown/MarkdownGenerator.java +++ b/java/core/src/main/java/org/brapi/schematools/core/markdown/MarkdownGenerator.java @@ -41,7 +41,8 @@ public class MarkdownGenerator { * @return the paths of the Markdown files generated from the complete BrAPI Specification */ public Response> generate(Path schemaDirectory) { - return schemaReader.readDirectories(schemaDirectory).mapResultToResponse(brAPISchemas -> new MarkdownGenerator.Generator(brAPISchemas).generate()) ; + return schemaReader.readDirectories(schemaDirectory) + .mapResultToResponse(brAPISchemas -> new MarkdownGenerator.Generator(brAPISchemas).generate()) ; } private class Generator { diff --git a/java/core/src/main/java/org/brapi/schematools/core/utils/BrAPITClassCacheUtil.java b/java/core/src/main/java/org/brapi/schematools/core/utils/BrAPITClassCacheUtil.java new file mode 100644 index 0000000..1d8a0b2 --- /dev/null +++ b/java/core/src/main/java/org/brapi/schematools/core/utils/BrAPITClassCacheUtil.java @@ -0,0 +1,63 @@ +package org.brapi.schematools.core.utils; + +import lombok.AllArgsConstructor; +import org.brapi.schematools.core.model.*; + +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import java.util.function.Predicate; + +/** + * Utility class for creating a cache of {@link BrAPIClass}es. Takes a list of + * classes and caches those in the list if they pass the provided {@link #cachePredicate}. + * Additional classes are added to the cached depending on the subclass of {@link BrAPIClass} + * For {@link BrAPIObjectType} utility checks the properties and + * tries to cache any that are the return type of these properties {@link BrAPIClass}es. + * If an {@link BrAPIArrayType} is encountered then the {@link BrAPIArrayType#getItems()} is + * checked recursively to be included in the cache. + * For {@link BrAPIOneOfType} it is added to the cache and any of {@link BrAPIOneOfType#getPossibleTypes()} + * are checked recursively to be included in the cache. + * {@link BrAPIAllOfType} are ignored. + */ +@AllArgsConstructor +public class BrAPITClassCacheUtil { + + private Predicate cachePredicate ; + + public Map createMap(List brAPIClasses) { + return new Cache(brAPIClasses).brAPIClassMap ; + } + + private class Cache { + + private final Map brAPIClassMap ; + + public Cache(List brAPIClasses) { + + brAPIClassMap = new TreeMap<>(); + + for (BrAPIClass brAPIClass : brAPIClasses) { + cacheClass(brAPIClass); + } + } + + private void cacheClass(BrAPIType brAPIType) { + if (brAPIType instanceof BrAPIClass brAPIClass && cachePredicate.test(brAPIClass) && !brAPIClassMap.containsKey(brAPIClass.getName())) { + if (brAPIClass instanceof BrAPIObjectType brAPIObjectType) { + brAPIClassMap.put(brAPIClass.getName(), brAPIObjectType); + + brAPIObjectType.getProperties().forEach(property -> cacheClass(property.getType())); + } else if (brAPIType instanceof BrAPIOneOfType brAPIOneOfType) { + brAPIClassMap.put(brAPIClass.getName(), brAPIOneOfType); + + brAPIOneOfType.getPossibleTypes().forEach(this::cacheClass); + } else if (brAPIClass instanceof BrAPIEnumType brAPIEnumType) { + brAPIClassMap.put(brAPIClass.getName(), brAPIEnumType); + } + } else if (brAPIType instanceof BrAPIArrayType brAPIArrayType) { + cacheClass(brAPIArrayType.getItems()); + } + } + } +} diff --git a/java/core/src/main/java/org/brapi/schematools/core/valdiation/Validation.java b/java/core/src/main/java/org/brapi/schematools/core/valdiation/Validation.java index 4a27e65..33175d8 100644 --- a/java/core/src/main/java/org/brapi/schematools/core/valdiation/Validation.java +++ b/java/core/src/main/java/org/brapi/schematools/core/valdiation/Validation.java @@ -1,11 +1,13 @@ package org.brapi.schematools.core.valdiation; import lombok.Getter; -import org.brapi.schematools.core.options.Options; +import org.apache.commons.beanutils.PropertyUtils; import org.brapi.schematools.core.response.Response; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.stream.Collectors; import static org.brapi.schematools.core.response.Response.empty; @@ -33,13 +35,51 @@ public static Validation valid() { */ public Validation assertNotNull(Object value, String errorMessage, Object... args) { if (value == null) { - String message = args != null && args.length > 0 ? String.format(errorMessage, args) : errorMessage; - errors.add(Response.Error.of("", message, Response.ErrorType.VALIDATION)); + addError(errorMessage, args) ; } return this; } + /** + * Validate that only one of the provided properties is non-null + * @param value the value to be tested + * @param properties the array of properties to be checked + * @return this Validation + */ + public Validation assertMutuallyExclusive(Object value, String... properties) { + if (value == null) { + addError("Value is null!") ; + } else { + int count = 0; + + for (String property : properties) { + try { + if (PropertyUtils.getProperty(value, property) != null) { + ++count; + } + } catch (Exception e) { + addError(e); + } + } + + if (count > 1) { + addError("Only one of '%s' can be provided", String.join(", ", Arrays.asList(properties))); + } + } + + return this ; + } + + public Validation assertClass(Object value, List> classes) { + if (value != null && classes.stream().noneMatch(aClass -> value.getClass().isAssignableFrom(aClass))) { + addError("Value must one of '%s', but was '%s'", + classes.stream().map(Class::getName).collect(Collectors.joining(", ")), value.getClass().getName()); + } + + return this ; + } + /** * Was the validation successful, * @return true if the validation was successful, false otherwise @@ -49,13 +89,73 @@ public boolean isValid() { } /** - * Merge the options to Validation, by calling the {@link Options#validate()} method + * Merge the objects to Validation, by calling the {@link Validatable#validate()} method * and adding any errors to this Validation - * @param options the options to be validated + * @param validatable the object to be validated * @return this Validation */ - public Validation merge(Options options) { - errors.addAll(options.validate().getErrors()) ; + public Validation merge(Validatable validatable) { + addAllErrors(validatable.validate().getErrors()) ; + + return this ; + } + + /** + * Merge the objects to Validation, by calling the {@link Validatable#validate()} method + * and adding any errors to this Validation + * @param validatable the object to be validated + * @param prefixMessage prefix any errors with this message + * @return this Validation + */ + public Validation merge(Validatable validatable, String prefixMessage) { + addAllErrors(validatable.validate().getErrors(), prefixMessage) ; + + return this ; + } + + /** + * If the condition is true, merge the objects to Validation, by calling the {@link Validatable#validate()} method + * and adding any errors to this Validation + * @param condition if true merge, otherwise don't + * @param validatable the object to be validated + * @return this Validation + */ + public Validation mergeOnCondition(boolean condition, Validatable validatable) { + if (condition) { + addAllErrors(validatable.validate().getErrors()); + } + + return this ; + } + + /** + * If the condition is true, merge the objects to Validation, by calling the {@link Validatable#validate()} method + * and adding any errors to this Validation + * @param condition if true merge, otherwise don't + * @param validatable the object to be validated + * @param prefixMessage prefix any errors with this message + * @return this Validation + */ + public Validation mergeOnCondition(boolean condition, Validatable validatable, String prefixMessage) { + if (condition) { + addAllErrors(validatable.validate().getErrors(), prefixMessage); + } + + return this ; + } + + /** + * Merge the objects to Validation, by calling the {@link Validatable#validate()} method + * in each object and adding any errors to this Validation + * @param validatableList the options to be validated + * @return this Validation + */ + public Validation merge(List validatableList) { + validatableList + .stream() + .map(Validatable::validate) + .map(Validation::getErrors) + .forEach(this::addAllErrors); return this ; } @@ -72,4 +172,27 @@ public Response asResponse () { return empty().merge(this) ; } } + + private void addError(String errorMessage, Object... args) { + String message = args != null && args.length > 0 ? String.format(errorMessage, args) : errorMessage; + errors.add(Response.Error.of("", message, Response.ErrorType.VALIDATION)); + } + + private void addError(String message) { + errors.add(Response.Error.of("", message, Response.ErrorType.VALIDATION)); + } + + private void addError(Exception e) { + errors.add(Response.Error.of("", e.getMessage(), Response.ErrorType.VALIDATION)); + } + + private void addAllErrors(List errors) { + this.errors.addAll(errors); + } + + private void addAllErrors(List errors, String prefixMessage) { + errors.forEach(error -> + this.errors.add(Response.Error.of(error.getCode(), String.format("%s %s", prefixMessage, error.getMessage()), error.getType())) + ); + } } diff --git a/java/core/src/main/java/org/brapi/schematools/core/xlsx/XSSFWorkbookGenerator.java b/java/core/src/main/java/org/brapi/schematools/core/xlsx/XSSFWorkbookGenerator.java index aabc3bf..debe8df 100644 --- a/java/core/src/main/java/org/brapi/schematools/core/xlsx/XSSFWorkbookGenerator.java +++ b/java/core/src/main/java/org/brapi/schematools/core/xlsx/XSSFWorkbookGenerator.java @@ -13,20 +13,23 @@ import org.brapi.schematools.core.model.BrAPIObjectType; import org.brapi.schematools.core.ontmodel.options.OntModelGeneratorOptions; import org.brapi.schematools.core.response.Response; +import org.brapi.schematools.core.utils.BrAPITClassCacheUtil; import org.brapi.schematools.core.utils.StringUtils; +import org.brapi.schematools.core.xlsx.options.ColumnOption; +import org.brapi.schematools.core.xlsx.options.ValuePropertyOption; import org.brapi.schematools.core.xlsx.options.XSSFWorkbookGeneratorOptions; -import java.beans.PropertyDescriptor; import java.io.FileOutputStream; import java.io.IOException; import java.lang.reflect.InvocationTargetException; -import java.nio.file.Files; import java.nio.file.Path; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; -import static java.util.function.Function.identity; import static org.brapi.schematools.core.response.Response.fail; /** @@ -75,24 +78,24 @@ public Response> generate(Path schemaDirectory) { private class Generator { - private final List brAPISchemas ; + private final Map brAPIClasses ; public Generator(List brAPISchemas) { - this.brAPISchemas = brAPISchemas.stream().filter(this::isGenerating). - sorted(Comparator.comparing(BrAPIClass::getName)).collect(Collectors.toList()) ; + + brAPIClasses = new BrAPITClassCacheUtil(this::isGenerating).createMap(brAPISchemas) ; } public Response> generate() { try { Function>, Response> saveWorkbooks; - return generateDataClasses(brAPISchemas) ; + return generateDataClasses(new ArrayList<>(brAPIClasses.values())) ; } catch (Exception e) { return fail(Response.ErrorType.VALIDATION, e.getMessage()) ; } } private boolean isGenerating(BrAPIClass brAPIClass) { - return brAPIClass.getMetadata() != null && !(brAPIClass.getMetadata().isRequest() || brAPIClass.getMetadata().isParameters()); + return brAPIClass.getMetadata() == null || !(brAPIClass.getMetadata().isRequest() || brAPIClass.getMetadata().isParameters()); } private Response> generateDataClasses(List brAPIClasses) { @@ -109,7 +112,7 @@ private Response> generateDataClasses(List brAPIClasses) sheet = workbook.createSheet("Data Classes Fields"); - createHeaderRow(workbook, sheet, options.getDataClassFieldProperties()) ; + createHeaderRow(workbook, sheet, options.getDataClassFieldProperties(), options.getDataClassFieldHeader()) ; createRows(sheet, 1, BrAPIClass::getName, options.getDataClassFieldProperties(), brAPIClasses, this::findFields); formatSheet(sheet, brAPIClasses.size()) ; @@ -146,11 +149,11 @@ private void formatSheet(Sheet sheet, int lastIndex) { sheet.setAutoFilter(ca); } - private void createHeaderRow(Workbook workbook, Sheet sheet, List properties) { - createHeaderRow(workbook, sheet, properties, null); + private void createHeaderRow(Workbook workbook, Sheet sheet, List columns) { + createHeaderRow(workbook, sheet, columns, null); } - private void createHeaderRow(Workbook workbook, Sheet sheet, List properties, String header) { + private void createHeaderRow(Workbook workbook, Sheet sheet, List columns, String header) { Row headerRow = sheet.createRow(0); CellStyle headerStyle = createHeaderStyle(workbook); @@ -165,10 +168,10 @@ private void createHeaderRow(Workbook workbook, Sheet sheet, List proper ++columnIndex ; } - for (String property : properties) { + for (ColumnOption column : columns) { sheet.setColumnWidth(columnIndex, 6000); Cell headerCell = headerRow.createCell(columnIndex); - headerCell.setCellValue(StringUtils.toLabel(property)); + headerCell.setCellValue(column.getLabel() != null ? column.getLabel() : StringUtils.toLabel(column.getName())); headerCell.setCellStyle(headerStyle); ++columnIndex ; } @@ -188,11 +191,11 @@ private CellStyle createHeaderStyle(Workbook workbook) { return headerStyle ; } - private int createRows(Sheet sheet, int startIndex, String header, List properties, List values) { + private int createRows(Sheet sheet, int startIndex, String header, List columns, List values) { int rowIndex = startIndex ; for (Object value : values) { - createRow(sheet, properties, rowIndex, header, value); + createRow(sheet, columns, rowIndex, header, value); ++rowIndex ; } @@ -200,15 +203,15 @@ private int createRows(Sheet sheet, int startIndex, String header, List void createRows(Sheet sheet, int startIndex, Function headerFunction, List properties, List values, Function> valuesFunction) { + private void createRows(Sheet sheet, int startIndex, Function headerFunction, List columns, List values, Function> valuesFunction) { int rowIndex = startIndex ; for (T value : values) { - rowIndex = createRows(sheet, rowIndex, headerFunction.apply(value), properties, valuesFunction.apply(value)); + rowIndex = createRows(sheet, rowIndex, headerFunction.apply(value), columns, valuesFunction.apply(value)); } } - private void createRow(Sheet sheet, List properties, int rowIndex, String header, T bean) { + private void createRow(Sheet sheet, List columns, int rowIndex, String header, T bean) { Row row = sheet.createRow(rowIndex); int columnIndex = 0 ; @@ -219,29 +222,50 @@ private void createRow(Sheet sheet, List properties, int rowIndex, S ++columnIndex ; } - for (String property : properties) { - Cell cell = row.createCell(columnIndex); - Object value = null; + for (ColumnOption column : columns) { try { - value = PropertyUtils.getProperty(bean, property); - if (value instanceof Boolean booleanValue) { - cell.setCellValue(booleanValue); - } else if (value instanceof Integer integerValue) { - cell.setCellValue(integerValue); - } else if (value instanceof Double doubleValue) { - cell.setCellValue(doubleValue); - } else if (value instanceof List listValue) { + updateCellValue(row.createCell(columnIndex), column, column.getDefaultValue(), rowIndex, PropertyUtils.getProperty(bean, column.getName())) ; + } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { + log.warn(String.format("Error parsing bean with property '%s', at index '%d' due to '%s'", column.getName(), rowIndex, e.getMessage())) ; + } + ++columnIndex ; + } + } + + private void updateCellValue(Cell cell, ValuePropertyOption column, Object defaultValue, int rowIndex, Object value) { + try { + if (value instanceof Boolean booleanValue) { + cell.setCellValue(booleanValue); + } else if (value instanceof Integer integerValue) { + cell.setCellValue(integerValue); + } else if (value instanceof Double doubleValue) { + cell.setCellValue(doubleValue); + } else if (value instanceof List listValue) { + if (column.getIndex() != null) { + updateCellValue(cell, column, defaultValue, rowIndex, listValue.get(column.getIndex())); + } else { cell.setCellValue(listValue.stream().collect(Collectors.joining(", ")).toString()); - } else if (value != null) { + } + } else if (value instanceof Map mapValue) { + if (column.getKey() != null) { + updateCellValue(cell, column, defaultValue, rowIndex, mapValue.get(column.getKey())); + } else { + cell.setCellValue(mapValue.entrySet().stream().collect(Collectors.joining(", ")).toString()); + } + } else if (value != null) { + if (column.getChildProperty() != null) { + updateCellValue(cell, column.getChildProperty(), defaultValue, rowIndex, PropertyUtils.getProperty(value, column.getChildProperty().getName())) ; + } else { cell.setCellValue(value.toString()); } - } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { - log.warn(String.format("Error parsing bean with property '%s', at index '%d' due to '%s'", property, rowIndex, e.getMessage())) ; + } else if (column.getDefaultValue() != null) { + updateCellValue(cell, column, null, rowIndex, column.getDefaultValue()); + } else if (defaultValue != null) { + updateCellValue(cell, column, null, rowIndex, defaultValue); } - - ++columnIndex ; + } catch (Exception e) { + log.warn(String.format("Error parsing bean with property '%s', at row index '%d' due to '%s'", column.getName(), rowIndex, e.getMessage())) ; } } } - } diff --git a/java/core/src/main/java/org/brapi/schematools/core/xlsx/options/ColumnOption.java b/java/core/src/main/java/org/brapi/schematools/core/xlsx/options/ColumnOption.java new file mode 100644 index 0000000..9869956 --- /dev/null +++ b/java/core/src/main/java/org/brapi/schematools/core/xlsx/options/ColumnOption.java @@ -0,0 +1,13 @@ +package org.brapi.schematools.core.xlsx.options; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class ColumnOption extends ValuePropertyOption { + /** + * The label for the column + */ + private String label ; +} diff --git a/java/core/src/main/java/org/brapi/schematools/core/xlsx/options/ValuePropertyOption.java b/java/core/src/main/java/org/brapi/schematools/core/xlsx/options/ValuePropertyOption.java new file mode 100644 index 0000000..1229f1f --- /dev/null +++ b/java/core/src/main/java/org/brapi/schematools/core/xlsx/options/ValuePropertyOption.java @@ -0,0 +1,44 @@ +package org.brapi.schematools.core.xlsx.options; + +import lombok.Getter; +import lombok.Setter; +import org.brapi.schematools.core.options.Options; +import org.brapi.schematools.core.valdiation.Validation; + +import java.util.Arrays; +import java.util.Map; + +@Getter +@Setter +public class ValuePropertyOption implements Options { + /** + * The name of the property + */ + private String name ; + /** + * The label for the column + */ + private Integer index ; + /** + * If the value of the property is a {@link Map} with key {@link String} use the value with this key + */ + private String key ; + /** + * If the value used if the property is null + */ + private Object defaultValue ; + /** + * If the value is an object allows to recursively reference a child property + */ + private ValuePropertyOption childProperty ; + + @Override + public Validation validate() { + return Validation + .valid() + .assertNotNull(name, "'name' option on %s is null", this.getClass().getSimpleName()) + .assertMutuallyExclusive(this, "index", "key") + .assertClass(defaultValue, Arrays.asList(Integer.class, String.class, Boolean.class)) + .mergeOnCondition(childProperty != null, childProperty, "Child property:") ; + } +} diff --git a/java/core/src/main/java/org/brapi/schematools/core/xlsx/options/XSSFWorkbookGeneratorOptions.java b/java/core/src/main/java/org/brapi/schematools/core/xlsx/options/XSSFWorkbookGeneratorOptions.java index 9e2d8c2..e17204c 100644 --- a/java/core/src/main/java/org/brapi/schematools/core/xlsx/options/XSSFWorkbookGeneratorOptions.java +++ b/java/core/src/main/java/org/brapi/schematools/core/xlsx/options/XSSFWorkbookGeneratorOptions.java @@ -26,8 +26,9 @@ @Accessors(chain = true) public class XSSFWorkbookGeneratorOptions implements Options { - List dataClassProperties ; - List dataClassFieldProperties ; + List dataClassProperties ; + String dataClassFieldHeader ; + List dataClassFieldProperties ; /** * Load the options from an options file in YAML or Json. The options file may have missing @@ -71,6 +72,10 @@ public static XSSFWorkbookGeneratorOptions load(InputStream inputStream) throws } public Validation validate() { - return Validation.valid() ; + + return Validation.valid() + .merge(dataClassProperties) + .assertNotNull(dataClassFieldHeader, "'dataClassFieldHeader' option on %s is null", this.getClass().getSimpleName()) + .merge(dataClassFieldProperties) ; } } \ No newline at end of file diff --git a/java/core/src/main/resources/xlsx-options.yaml b/java/core/src/main/resources/xlsx-options.yaml index 02526ff..53c0ea8 100644 --- a/java/core/src/main/resources/xlsx-options.yaml +++ b/java/core/src/main/resources/xlsx-options.yaml @@ -1,7 +1,20 @@ dataClassProperties: - - name - - module - - description + - name: name + - name: module + - name: metadata + label: Primary Model + key: metadata + defaultValue: false + childProperty: + name: primaryModel + - name: metadata + label: Interface + key: metadata + defaultValue: false + childProperty: + name: interfaceClass + - name: description +dataClassFieldHeader: Class Name dataClassFieldProperties: - - name - - description \ No newline at end of file + - name: name + - name: description \ No newline at end of file diff --git a/java/core/src/test/java/org/brapi/schematools/core/utils/BrAPITClassCacheUtilTest.java b/java/core/src/test/java/org/brapi/schematools/core/utils/BrAPITClassCacheUtilTest.java new file mode 100644 index 0000000..b2112b3 --- /dev/null +++ b/java/core/src/test/java/org/brapi/schematools/core/utils/BrAPITClassCacheUtilTest.java @@ -0,0 +1,46 @@ +package org.brapi.schematools.core.utils; + +import org.brapi.schematools.core.brapischema.BrAPISchemaReader; +import org.brapi.schematools.core.model.BrAPIClass; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.net.URISyntaxException; +import java.nio.file.Path; +import java.util.List; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +class BrAPITClassCacheUtilTest { + + List brAPIClasses ; + + @BeforeEach + void setUp() throws URISyntaxException { + + brAPIClasses = new BrAPISchemaReader() + .readDirectories(Path.of(ClassLoader.getSystemResource("BrAPI-Schema").toURI())) + .onFailDoWithResponse(response -> fail(response.getMessagesCombined(","))) + .getResult(); + } + + @Test + void createMap() { + BrAPITClassCacheUtil subject = new BrAPITClassCacheUtil(this::isCaching) ; + Map map = subject.createMap(brAPIClasses); + + assertEquals(102, map.size()); + + assertTrue(map.containsKey("Trial")) ; + assertTrue(map.containsKey("Attribute")) ; + assertTrue(map.containsKey("GermplasmAttribute")) ; + assertTrue(map.containsKey("GermplasmAttributeValue")) ; + } + + private boolean isCaching(BrAPIClass brAPIClass) { + return brAPIClass.getMetadata() == null || !(brAPIClass.getMetadata().isRequest() || brAPIClass.getMetadata().isParameters()); + } +} \ No newline at end of file diff --git a/java/core/src/test/java/org/brapi/schematools/core/xlsx/options/ValuePropertyOptionTest.java b/java/core/src/test/java/org/brapi/schematools/core/xlsx/options/ValuePropertyOptionTest.java new file mode 100644 index 0000000..5d57ba8 --- /dev/null +++ b/java/core/src/test/java/org/brapi/schematools/core/xlsx/options/ValuePropertyOptionTest.java @@ -0,0 +1,89 @@ +package org.brapi.schematools.core.xlsx.options; + +import org.brapi.schematools.core.response.Response; +import org.brapi.schematools.core.valdiation.Validation; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class ValuePropertyOptionTest { + + @Test + void validate() { + ValuePropertyOption option = new ValuePropertyOption() ; + + option.setName("test"); + + ValuePropertyOption childProperty = new ValuePropertyOption() ; + + childProperty.setName("test"); + + option.setChildProperty(childProperty); + + Validation validation = option.validate(); + + validation.getErrors().stream().map(Response.Error::getMessage).forEach(System.err::println); + + assertTrue(validation.isValid()) ; + } + + @Test + void noName() { + ValuePropertyOption option = new ValuePropertyOption() ; + + Validation validation = option.validate(); + + assertFalse(validation.isValid()) ; + + assertEquals(1, validation.getErrors().size()); + } + + @Test + void indexAndKey() { + ValuePropertyOption option = new ValuePropertyOption() ; + + option.setName("test"); + option.setKey("test"); + option.setIndex(0); + + Validation validation = option.validate(); + + assertFalse(validation.isValid()) ; + + assertEquals(1, validation.getErrors().size()); + } + + @Test + void invalidChildProperty() { + ValuePropertyOption option = new ValuePropertyOption() ; + + option.setName("test"); + + ValuePropertyOption childProperty = new ValuePropertyOption() ; + + option.setChildProperty(childProperty); + + Validation validation = option.validate(); + + assertFalse(validation.isValid()) ; + + assertEquals(1, validation.getErrors().size()); + } + + @Test + void invalidDefaultValue() { + ValuePropertyOption option = new ValuePropertyOption() ; + + option.setName("test"); + + option.setDefaultValue(1.2); + + Validation validation = option.validate(); + + assertFalse(validation.isValid()) ; + + assertEquals(1, validation.getErrors().size()); + } +} \ No newline at end of file diff --git a/java/core/src/test/java/org/brapi/schematools/core/xlsx/options/XSSFWorkbookGeneratorOptionsTest.java b/java/core/src/test/java/org/brapi/schematools/core/xlsx/options/XSSFWorkbookGeneratorOptionsTest.java new file mode 100644 index 0000000..7bbe2a3 --- /dev/null +++ b/java/core/src/test/java/org/brapi/schematools/core/xlsx/options/XSSFWorkbookGeneratorOptionsTest.java @@ -0,0 +1,20 @@ +package org.brapi.schematools.core.xlsx.options; + +import org.brapi.schematools.core.response.Response; +import org.brapi.schematools.core.valdiation.Validation; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +class XSSFWorkbookGeneratorOptionsTest { + @Test + void load() { + XSSFWorkbookGeneratorOptions options = XSSFWorkbookGeneratorOptions.load(); + + Validation validation = options.validate(); + + validation.getErrors().stream().map(Response.Error::getMessage).forEach(System.err::println); + + assertTrue(validation.isValid()) ; + } +} \ No newline at end of file