package lombok;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import org.junit.runner.Description;
import org.junit.runner.Runner;
import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunNotifier;
import lombok.eclipse.Eclipse;
import lombok.javac.Javac;
public class DirectoryRunner extends Runner {
private static final List<String> DEBUG_FOCUS_ON_FILE = Arrays.asList(
);
public enum Compiler {
DELOMBOK {
@Override public int getVersion() {
return Javac.getJavaCompilerVersion();
}
},
JAVAC {
@Override public int getVersion() {
return DELOMBOK.getVersion();
}
},
ECJ {
@Override public int getVersion() {
return Eclipse.getEcjCompilerVersion();
}
};
public abstract int getVersion();
}
public static abstract class TestParams {
public abstract Compiler getCompiler();
public abstract boolean printErrors();
public abstract File getBeforeDirectory();
public abstract File getAfterDirectory();
public abstract File getMessagesDirectory();
public int getVersion() {
return getCompiler().getVersion();
}
public boolean accept(File file) {
return true;
}
public abstract boolean expectChanges();
}
private static final FileFilter JAVA_FILE_FILTER = new FileFilter() {
@Override public boolean accept(File file) {
if (!file.isFile() || !file.getName().endsWith(".java")) return false;
boolean positiveFilter = false;
for (String dfof : DEBUG_FOCUS_ON_FILE) {
if (dfof.isEmpty()) continue;
if (!dfof.endsWith(".java")) dfof = dfof + ".java";
boolean invert = dfof.startsWith("!");
if (invert) dfof = dfof.substring(1);
positiveFilter = positiveFilter || !invert;
int starIdx = dfof.indexOf('*');
if (starIdx == -1) {
if (file.getName().equals(dfof)) return !invert;
} else {
if (file.getName().startsWith(dfof.substring(0, starIdx)) && file.getName().endsWith(dfof.substring(starIdx + 1))) return !invert;
}
}
return !positiveFilter;
}
};
private final Description description;
private final Map<String, Description> tests = new TreeMap<String, Description>();
private final Throwable failure;
private final TestParams params;
public DirectoryRunner(Class<?> testClass) throws Exception {
description = Description.createSuiteDescription(testClass);
this.params = (TestParams) testClass.getConstructor().newInstance();
Throwable error = null;
try {
addTests(testClass);
}
catch (Throwable t) {
error = t;
}
this.failure = error;
}
private void addTests(Class<?> testClass) throws Exception {
for (File file : params.getBeforeDirectory().listFiles(JAVA_FILE_FILTER)) {
if (!params.accept(file)) continue;
Description testDescription = Description.createTestDescription(testClass, file.getName());
description.addChild(testDescription);
tests.put(file.getName(), testDescription);
}
}
@Override
public Description getDescription() {
return description;
}
@Override
public void run(RunNotifier notifier) {
if (failure != null) {
reportInitializationFailure(notifier, description, failure);
return;
}
for (Map.Entry<String, Description> entry : tests.entrySet()) {
Description testDescription = entry.getValue();
FileTester tester;
try {
tester = createTester(entry.getKey());
} catch (IOException e) {
reportInitializationFailure(notifier, testDescription, e);
continue;
}
if (tester == null) {
notifier.fireTestIgnored(testDescription);
continue;
}
notifier.fireTestStarted(testDescription);
try {
tester.runTest();
} catch (Throwable t) {
notifier.fireTestFailure(new Failure(testDescription, t));
}
notifier.fireTestFinished(testDescription);
}
}
private void reportInitializationFailure(RunNotifier notifier, Description description, Throwable throwable) {
notifier.fireTestStarted(description);
notifier.fireTestFailure(new Failure(description, throwable));
notifier.fireTestFinished(description);
}
private FileTester createTester(String fileName) throws IOException {
File file = new File(params.getBeforeDirectory(), fileName);
switch (params.getCompiler()) {
case DELOMBOK:
return new RunTestsViaDelombok().createTester(params, file, "javac", params.getVersion());
case ECJ:
String platform = RunTestsViaEcj.eclipseAvailable() ? "eclipse" : "ecj";
return new RunTestsViaEcj().createTester(params, file, platform, params.getVersion());
default:
case JAVAC:
throw new UnsupportedOperationException();
}
}
public interface FileTester {
void runTest() throws Throwable;
}
}