package org.teachingextensions.approvals.lite.namer;
import java.io.File;
import java.lang.reflect.Method;
import junit.framework.TestCase;
import org.junit.Test;
import org.teachingextensions.approvals.lite.util.ObjectUtils;
import org.teachingextensions.approvals.lite.util.StackTraceReflectionResult;
import org.teachingextensions.approvals.lite.util.TestUtils;
import org.teachingextensions.approvals.lite.util.io.StackElementSelector;
public class JUnitStackTraceNamer implements ApprovalNamer {
private StackTraceReflectionResult info;
public JUnitStackTraceNamer() {
info = TestUtils.getCurrentFileForMethod(new JUnit3StackSelector());
}
@Override
public String getApprovalName() {
return String.format("%s.%s", info.getClassName(), info.getMethodName());
}
@Override
public String getSourceFilePath() {
return info.getSourceFile().getAbsolutePath() + File.separator;
}
/**************************************************************/
/* INNER CLASSES */
/**
* **********************************************************
*/
public static class JUnit3StackSelector implements StackElementSelector {
@Override
public StackTraceElement selectElement(StackTraceElement[] trace) throws Exception {
boolean inTestCase = false;
for (int i = 0; i < trace.length; i++) {
if (isTestCase(trace[i])) {
inTestCase = true;
} else if (inTestCase) {
return trace[i - 1];
}
}
throw new RuntimeException("Could not find Junit TestCase you are running");
}
private boolean isTestCase(StackTraceElement element) throws ClassNotFoundException {
String fullClassName = element.getClassName();
Class<?> clazz = Class.forName(fullClassName);
boolean junit3 = ObjectUtils.isThisInstanceOfThat(clazz, TestCase.class);
if (!junit3) {
junit3 = isTestAttribute(clazz, element.getMethodName());
}
return junit3;
}
private boolean isTestAttribute(Class<?> clazz, String methodName) throws ClassNotFoundException, SecurityException {
Method method;
try {
method = clazz.getMethod(methodName);
} catch (Throwable e) {
return false;
}
return method.isAnnotationPresent(Test.class);
}
}
}