RegressionTest.java
package com.github.junrar.regression;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.github.junrar.Archive;
import com.github.junrar.exception.RarException;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Timeout;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.junit.platform.commons.logging.Logger;
import org.junit.platform.commons.logging.LoggerFactory;
import org.junitpioneer.jupiter.DefaultTimeZone;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.stream.Collectors;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
public class RegressionTest {
private static final Logger logger = LoggerFactory.getLogger(RegressionTest.class);
private final ObjectMapper mapper = new ObjectMapper()
.registerModule(new JavaTimeModule())
.enable(SerializationFeature.INDENT_OUTPUT);
/**
* The root of the corpus. Used to compute relative path when storing test output.
*/
private static final Path root;
/**
* The directory containing files under test. Must be a subdirectory of root, or root itself.
*/
private static final Path testDir;
private static final String corpus = "corpus";
/**
* The directory containing result JSON files.
*/
private static final Path resourcesDir;
static {
String corpusRoot = System.getenv("JUNRAR_REGRESSION_TEST_CORPUS_ROOT");
if (corpusRoot == null) throw new IllegalArgumentException("Environment variable not set: JUNRAR_REGRESSION_TEST_CORPUS_ROOT");
root = Paths.get(corpusRoot);
if (!Files.isDirectory(root)) throw new IllegalArgumentException("Corpus root dir is not a directory: " + root);
logger.info(() -> "Corpus root dir: " + root);
String corpusTestDir = System.getenv("JUNRAR_REGRESSION_TEST_CORPUS_DIR");
if (corpusTestDir == null) throw new IllegalArgumentException("Environment variable not set: JUNRAR_REGRESSION_TEST_CORPUS_DIR");
testDir = Paths.get(corpusTestDir);
logger.info(() -> "Corpus test dir: " + testDir);
if (!testDir.startsWith(root)) throw new IllegalArgumentException("test directory must be within root");
String resourcesDirProp = System.getProperty("regressionTest.resourcesDir");
resourcesDir = Paths.get(resourcesDirProp, corpus);
logger.info(() -> "Resources dir: " + resourcesDir);
}
static List<Path> listTestFiles() throws IOException {
try (var stream =
Files.find(testDir, 100, (path, attr) -> attr.isRegularFile() && !path.getFileName().toString().startsWith("."))) {
return stream.collect(Collectors.toList());
}
}
@Tag("generate")
@ParameterizedTest
@MethodSource("listTestFiles")
@DefaultTimeZone("UTC")
@Timeout(30)
void generateData(Path filePath) throws Exception {
Path relativeFile = root.relativize(filePath.getParent().resolve(filePath.getFileName().toString() + ".json"));
Path outputFile = resourcesDir.resolve(relativeFile);
Files.createDirectories(outputFile.getParent());
try (var archive = new Archive(filePath.toFile())) {
var record = ArchiveRecord.fromArchive(archive);
mapper.writeValue(outputFile.toFile(), record);
} catch (RarException e) {
var record = ArchiveRecord.fromException(e);
mapper.writeValue(outputFile.toFile(), record);
}
}
@Tag("check")
@ParameterizedTest
@MethodSource("listTestFiles")
@DefaultTimeZone("UTC")
@Timeout(30)
void check(Path filePath) throws Exception {
var relativeFile = root.relativize(filePath.getParent().resolve(filePath.getFileName().toString() + ".json"));
var resourceName = Paths.get("/", corpus, relativeFile.toString()).toString();
var resource = getClass().getResource(resourceName);
if (resource == null) {
fail("Could not load resource: " + resourceName);
} else {
var inputFile = new File(resource.toURI());
var inputRecord = mapper.readValue(inputFile, ArchiveRecord.class);
ArchiveRecord record;
try (var archive = new Archive(filePath.toFile())) {
record = ArchiveRecord.fromArchive(archive);
} catch (RarException e) {
record = ArchiveRecord.fromException(e);
}
assertThat(record).isEqualTo(inputRecord);
}
}
}