package net.thucydides.core.reports;
import com.google.common.collect.ImmutableList;
import com.google.inject.Inject;
import net.thucydides.core.guice.Injectors;
import net.thucydides.core.model.TestOutcome;
import net.thucydides.core.reports.json.JSONTestOutcomeReporter;
import net.thucydides.core.reports.xml.XMLTestOutcomeReporter;
import net.thucydides.core.util.EnvironmentVariables;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.*;
/**
* Loads test outcomes from a given directory, and reports on their contents.
* This class is used for aggregate reporting.
*/
public class TestOutcomeLoader {
private final EnvironmentVariables environmentVariables;
private final FormatConfiguration formatConfiguration;
public TestOutcomeLoader() {
this(Injectors.getInjector().getProvider(EnvironmentVariables.class).get() );
}
@Inject
public TestOutcomeLoader(EnvironmentVariables environmentVariables) {
this.environmentVariables = environmentVariables;
this.formatConfiguration = new FormatConfiguration(environmentVariables);
}
public TestOutcomeLoader(EnvironmentVariables environmentVariables, FormatConfiguration formatConfiguration) {
this.environmentVariables = environmentVariables;
this.formatConfiguration = formatConfiguration;
}
public TestOutcomeLoader forFormat(OutcomeFormat format) {
return new TestOutcomeLoader(environmentVariables, new FormatConfiguration(format));
}
/**
* Load the test outcomes from a given directory.
*
* @param reportDirectory An existing directory that contains the test outcomes in XML or JSON format.
* @return The full list of test outcomes.
* @throws java.io.IOException Thrown if the specified directory was invalid.
*/
public List<TestOutcome> loadFrom(final File reportDirectory) throws IOException {
final AcceptanceTestLoader testOutcomeReporter = getOutcomeReporter();
List<File> reportFiles = getAllOutcomeFilesFrom(reportDirectory);
final List<TestOutcome> testOutcomes = Collections.synchronizedList(new ArrayList<TestOutcome>());
for(File reportFile : reportFiles) {
testOutcomes.addAll(testOutcomeReporter.loadReportFrom(reportFile).asSet());
}
Collections.sort(testOutcomes, byTitle());
return ImmutableList.copyOf(testOutcomes);
}
private Comparator<? super TestOutcome> byTitle() {
return new Comparator<TestOutcome>() {
@Override
public int compare(TestOutcome a, TestOutcome b) {
return a.getTitle().compareTo(b.getTitle());
}
};
}
private List<File> getAllOutcomeFilesFrom(final File reportsDirectory) throws IOException{
File[] matchingFiles = reportsDirectory.listFiles(new SerializedOutcomeFilenameFilter());
if (matchingFiles == null) {
throw new IOException("Could not find directory " + reportsDirectory);
}
return ImmutableList.copyOf(matchingFiles);
}
public static TestOutcomeLoaderBuilder loadTestOutcomes() {
return new TestOutcomeLoaderBuilder();
}
public static final class TestOutcomeLoaderBuilder {
OutcomeFormat format;
public TestOutcomeLoaderBuilder inFormat(OutcomeFormat format) {
this.format = format;
return this;
}
public TestOutcomes from(final File reportsDirectory) throws IOException {
TestOutcomeLoader loader = new TestOutcomeLoader().forFormat(format);
return TestOutcomes.of(loader.loadFrom(reportsDirectory));
}
}
public static TestOutcomes testOutcomesIn(final File reportsDirectory) throws IOException {
TestOutcomeLoader loader = new TestOutcomeLoader();
return TestOutcomes.of(loader.loadFrom(reportsDirectory));
}
public AcceptanceTestLoader getOutcomeReporter() {
switch (formatConfiguration.getPreferredFormat()) {
case XML: return new XMLTestOutcomeReporter();
case JSON: return new JSONTestOutcomeReporter();
default: throw new IllegalArgumentException("Unsupported report format: " + formatConfiguration.getPreferredFormat());
}
}
private class SerializedOutcomeFilenameFilter implements FilenameFilter {
public boolean accept(final File file, final String filename) {
return filename.toLowerCase(Locale.getDefault()).endsWith(formatConfiguration.getPreferredFormat().getExtension());
}
}
}