Skip to content

Commit

Permalink
Add methods to ResourceUtils to work with both resources and files
Browse files Browse the repository at this point in the history
  • Loading branch information
vkepin committed Oct 7, 2024
1 parent 6867677 commit 7089d2f
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 30 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019-2023 the original author or authors.
* Copyright 2019-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -56,7 +56,12 @@ public List<Map<String, String>> readCsvFile(Path path, String... header) throws

public List<Map<String, String>> readCsvString(String csvString, String... header) throws IOException
{
try (Reader reader = new InputStreamReader(new ByteArrayInputStream(csvString.getBytes(StandardCharsets.UTF_8)),
return readCsvBytes(csvString.getBytes(StandardCharsets.UTF_8), header);
}

public List<Map<String, String>> readCsvBytes(byte[] csvAsBytes, String... header) throws IOException
{
try (Reader reader = new InputStreamReader(new ByteArrayInputStream(csvAsBytes),
StandardCharsets.UTF_8))
{
return collectCsv(reader, header);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import static java.util.stream.Collectors.toList;
import static org.apache.commons.lang3.Validate.isTrue;
import static org.apache.commons.lang3.Validate.notEmpty;
import static org.vividus.util.ResourceUtils.findResource;
import static org.vividus.util.ResourceUtils.loadResourceOrFileAsByteArray;

import java.io.IOException;
import java.io.UncheckedIOException;
Expand All @@ -29,7 +29,6 @@
import java.util.Properties;

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVRecord;
import org.apache.commons.lang3.StringUtils;
import org.jbehave.core.model.ExamplesTable.TableProperties;
import org.jbehave.core.model.TableParsers;
Expand Down Expand Up @@ -89,8 +88,7 @@ private List<Map<String, String>> readCsvFromFile(CSVFormat csvFormat, String pa
{
try
{
return new CsvReader(csvFormat).readCsvFile(findResource(getClass(), path))
.stream().map(CSVRecord::toMap).toList();
return new CsvReader(csvFormat).readCsvBytes(loadResourceOrFileAsByteArray(path));
}
catch (IOException e)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,10 @@
import static org.junit.jupiter.params.provider.Arguments.arguments;
import static org.mockito.Mockito.mockConstruction;
import static org.mockito.Mockito.when;
import static org.vividus.util.ResourceUtils.findResource;
import static org.vividus.util.ResourceUtils.loadResourceOrFileAsByteArray;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.net.URL;
import java.util.List;
import java.util.stream.Stream;

Expand Down Expand Up @@ -80,8 +79,8 @@ class CsvTableTransformerTests

@ParameterizedTest
@ValueSource(strings = {
"csvPath=test.csv",
"csvPath=test-with-semicolon.csv, delimiterChar=;"
"csvPath=org/vividus/csv/transformer/test.csv",
"csvPath=org/vividus/csv/transformer/test-with-semicolon.csv, delimiterChar=;"
})
void shouldCreateExamplesTableFromCsvDeprecatedProperty(String propertiesAsString)
{
Expand Down Expand Up @@ -114,8 +113,8 @@ static Stream<Arguments> variableProvider()

@ParameterizedTest
@ValueSource(strings = {
"path=test.csv",
"path=test-with-semicolon.csv, delimiterChar=;"
"path=org/vividus/csv/transformer/test.csv",
"path=org/vividus/csv/transformer/test-with-semicolon.csv, delimiterChar=;"
})
void shouldCreateExamplesTableFromCsv(String propertiesAsString)
{
Expand All @@ -126,8 +125,10 @@ void shouldCreateExamplesTableFromCsv(String propertiesAsString)

@ParameterizedTest
@CsvSource({
"'path=test.csv,delimiterChar=--', 'CSV delimiter must be a single char, but value ''--'' has length of 2'",
"'path=test.csv,delimiterChar= ', 'CSV delimiter must be a single char, but value '''' has length of 0'"
"'path=org/vividus/csv/transformer/test.csv,delimiterChar=--',"
+ "'CSV delimiter must be a single char, but value ''--'' has length of 2'",
"'path=org/vividus/csv/transformer/test.csv,delimiterChar= ',"
+ "'CSV delimiter must be a single char, but value '''' has length of 0'"
})
void shouldThrowErrorIfInvalidParametersAreProvided(String propertiesAsString, String errorMessage)
{
Expand All @@ -140,18 +141,18 @@ void shouldThrowErrorIfInvalidParametersAreProvided(String propertiesAsString, S

@SuppressWarnings("try")
@Test
void testCsvFileReaderExceptionCatching()
void testCsvFileReaderExceptionCatching() throws IOException
{
var csvFileName = "test.csv";
var csvFileName = "org/vividus/csv/transformer/test.csv";
var tableProperties = new TableProperties("path=" + csvFileName, keywords, converters);

URL csvResource = findResource(getClass(), csvFileName);
byte[] csvResourceAsBytes = loadResourceOrFileAsByteArray(csvFileName);
var ioException = new IOException();
try (MockedConstruction<CsvReader> ignored = mockConstruction(CsvReader.class,
(mock, context) -> {
assertEquals(1, context.getCount());
assertEquals(List.of(CSVFormat.DEFAULT), context.arguments());
when(mock.readCsvFile(csvResource)).thenThrow(ioException);
when(mock.readCsvBytes(csvResourceAsBytes)).thenThrow(ioException);
}))
{
var transformer = new CsvTableTransformer(CSVFormat.DEFAULT, variableContext);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ else if (PAGE_URL_PROPERTY_KEY.equals(sourceKey))
}
else
{
documentSuppler = () -> Jsoup.parse(ResourceUtils.loadResource(getClass(), sourceValue));
documentSuppler = () -> Jsoup.parse(ResourceUtils.loadResourceOrFileAsString(sourceValue));
}

String column = tableProperties.getMandatoryNonBlankProperty("column", String.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ void shouldBuildTableByElementAttributeFromVariableValue()
@Test
void shouldBuildTableByElementAttributeFromResource()
{
TableProperties tableProperties = new TableProperties("column=col, path=index.html, xpathSelector=//a/text()",
TableProperties tableProperties = new TableProperties("column=col,"
+ " path=org/vividus/html/transfromer/index.html, xpathSelector=//a/text()",
new Keywords(), new ParameterConverters());
HtmlDocumentTableTransformer transformer = new HtmlDocumentTableTransformer(Optional.empty(),
variableContext);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public String transform(String tableAsString, TableParsers tableParsers, TablePr
String sourceKey = entry.getKey();
String sourceValue = entry.getValue();
String jsonData = VARIABLE_NAME_PROPERTY_KEY.equals(sourceKey) ? variableContext.getVariable(sourceValue)
: ResourceUtils.loadResource(getClass(), sourceValue);
: ResourceUtils.loadResourceOrFileAsString(sourceValue);

String columns = tableProperties.getMandatoryNonBlankProperty("columns", String.class);
Map<String, String> columnsPerJsonPaths = Splitter.on(';').withKeyValueSeparator(Splitter.on('=').limit(2))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ void testTransformFromVariable()
@Test
void testTransformFromPath()
{
var tableProperties = createProperties("path=data.json" + EXAMPLE_TABLE_COLUMNS_CONFIG);
var tableProperties = createProperties("path=org/vividus/json/transformer/data.json"
+ EXAMPLE_TABLE_COLUMNS_CONFIG);
var table = jsonTableTransformer.transform(StringUtils.EMPTY, null, tableProperties);
assertEquals(EXPECTED_TABLE, table);
}
Expand Down Expand Up @@ -102,6 +103,6 @@ private TableProperties createProperties(String propertiesAsString)

private static String readJsonData()
{
return ResourceUtils.loadResource(JsonTableTransformerTests.class, "data.json");
return ResourceUtils.loadResourceOrFileAsString("org/vividus/json/transformer/data.json");
}
}
58 changes: 52 additions & 6 deletions vividus-util/src/main/java/org/vividus/util/ResourceUtils.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019-2021 the original author or authors.
* Copyright 2019-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -25,6 +25,7 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.function.Predicate;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
Expand Down Expand Up @@ -87,18 +88,53 @@ public static byte[] loadResourceAsByteArray(Class<?> clazz, String resourceName
* @throws IOException if an I/O error occurs
*/
public static byte[] loadResourceOrFileAsByteArray(String resourceNameOrFilePath) throws IOException
{
Path path = loadResourceOrFile(resourceNameOrFilePath).toPath();
return Files.readAllBytes(path);
}

/**
* Loads resource or file as String
*
* @param resourceNameOrFilePath Resource name or file path to load
* @return Resource or file content as String
*/
public static String loadResourceOrFileAsString(String resourceNameOrFilePath)
{
try
{
return new String(loadResourceOrFileAsByteArray(resourceNameOrFilePath), StandardCharsets.UTF_8);
}
catch (IOException e)
{
throw new UncheckedIOException(e);
}
}

/**
* Loads resource or file as file
*
* @param resourceNameOrFilePath Resource name or file path to load
* @return File
*/
private static File loadResourceOrFile(String resourceNameOrFilePath)
{
String resourcePath = ensureRootPath(resourceNameOrFilePath);
Predicate<File> isValidFile = f -> f.exists() && f.isFile();
URL resource = ResourceUtils.class.getResource(resourcePath);
if (resource != null)
{
return IOUtils.toByteArray(resource);
File resourceFile = loadFile(resource);
if (isValidFile.test(resourceFile))
{
return resourceFile;
}
}
Path path = Paths.get(resourceNameOrFilePath);
File file = path.toFile();
if (file.exists() && file.isFile())

File file = new File(resourceNameOrFilePath);
if (isValidFile.test(file))
{
return Files.readAllBytes(path);
return file;
}
throw new IllegalArgumentException(
"Neither resource with name '" + resourcePath + "' nor file at path '" + resourceNameOrFilePath
Expand Down Expand Up @@ -130,6 +166,16 @@ public static URL findResource(Class<?> clazz, String resourceName)
public static File loadFile(Class<?> clazz, String filePath)
{
URL resourceUrl = findResource(clazz, filePath);
return loadFile(resourceUrl);
}

/**
* Loads File from resource
* @param resourceUrl Resource
* @return File
*/
public static File loadFile(URL resourceUrl)
{
try
{
return Paths.get(resourceUrl.toURI()).toFile();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019-2023 the original author or authors.
* Copyright 2019-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -188,4 +188,24 @@ public void shouldCreateTempFileUsingName() throws IOException
Path tempFilePath = ResourceUtils.createTempFile("test.json");
assertThat(tempFilePath.toString(), matchesPattern(".+test.+\\.json"));
}

@Test
public void testLoadResourceOrFileAsString()
{
String fileAsString = ResourceUtils.loadResourceOrFileAsString(RESOURCE_NAME);
assertEquals(ROOT_RESOURCE_CONTENT, normalizeLineFeeds(fileAsString));
}

@Test
@PrepareForTest(ResourceUtils.class)
public void testLoadResourceOrFileAsStringWithIoException() throws IOException
{
PowerMockito.spy(ResourceUtils.class);
IOException ioException = new IOException("some IOException");

PowerMockito.when(ResourceUtils.loadResourceOrFileAsByteArray(RESOURCE_NAME)).thenThrow(ioException);
UncheckedIOException exception = assertThrows(UncheckedIOException.class,
() -> ResourceUtils.loadResourceOrFileAsString(RESOURCE_NAME));
assertEquals(ioException, exception.getCause());
}
}

0 comments on commit 7089d2f

Please sign in to comment.