package org.test4j.junit.suitetest.suite;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.junit.experimental.categories.Category;
import org.junit.runner.Description;
import org.junit.runner.manipulation.Filter;
import org.junit.runner.manipulation.NoTestsRemainException;
import org.junit.runners.Suite;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.RunnerBuilder;
import org.test4j.junit.annotations.AnnotationDefaultValue;
import org.test4j.junit.annotations.Group;
import org.test4j.junit.annotations.RunGroup;
import org.test4j.module.core.utility.MessageHelper;
import org.test4j.tools.commons.StringHelper;
public class GroupSuite extends Suite {
public GroupSuite(Class<?> klass, RunnerBuilder builder) throws InitializationError {
super(klass, builder);
try {
RunGroup annotation = SuiteHelper.findRunGroup(klass, builder);
String[] includedGroups = annotation == null ? AnnotationDefaultValue.DEFAULT_GROUP_VALUE : annotation
.includes();
String[] excludedGroups = annotation == null ? AnnotationDefaultValue.DEFAULT_GROUP_VALUE : annotation
.excludes();
Filter filter = new GroupFilter(includedGroups, excludedGroups);
filter(filter);
} catch (NoTestsRemainException e) {
MessageHelper.error("please check your test filter, there are no tests detected.", e);
throw new InitializationError(e);
}
assertNoCategorizedDescendentsOfUncategorizeableParents(getDescription());
}
private void assertNoCategorizedDescendentsOfUncategorizeableParents(Description description)
throws InitializationError {
if (!canHaveCategorizedChildren(description))
assertNoDescendantsHaveCategoryAnnotations(description);
for (Description each : description.getChildren())
assertNoCategorizedDescendentsOfUncategorizeableParents(each);
}
private void assertNoDescendantsHaveCategoryAnnotations(Description description) throws InitializationError {
for (Description each : description.getChildren()) {
if (each.getAnnotation(Category.class) != null)
throw new InitializationError(
"Category annotations on Parameterized classes are not supported on individual methods.");
assertNoDescendantsHaveCategoryAnnotations(each);
}
}
// If children have names like [0], our current magical category code can't
// determine their
// parentage.
private static boolean canHaveCategorizedChildren(Description description) {
for (Description each : description.getChildren())
if (each.getTestClass() == null)
return false;
return true;
}
public static class GroupFilter extends Filter {
public static GroupFilter include(String[] includedGroups) {
return new GroupFilter(includedGroups, AnnotationDefaultValue.DEFAULT_GROUP_VALUE);
}
private final List<String> gIncluded;
private final List<String> gExcluded;
public GroupFilter(String[] includedGroups, String[] excludedGroups) {
gIncluded = Arrays.asList(includedGroups);
gExcluded = Arrays.asList(excludedGroups);
}
@Override
public String describe() {
return "groups " + StringHelper.merger(gIncluded, ',');
}
@Override
public boolean shouldRun(Description description) {
if (hasCorrectGroupAnnotation(description)) {
return true;
}
for (Description each : description.getChildren()) {
if (shouldRun(each)) {
return true;
}
}
return false;
}
/**
* 测试对象是否包含包含在执行组中,或者是被排除运行
*
* @param description
* @return
*/
private boolean hasCorrectGroupAnnotation(Description description) {
Set<String> groups = groups(description);
if (groups.isEmpty()) {
return gIncluded.size() == 0;
}
for (String group : groups) {
if (gExcluded.contains(group)) {
return false;
}
}
if (gIncluded.size() == 0) {
return true;
}
for (String group : groups) {
if (gIncluded.contains(group)) {
return true;
}
}
return false;
}
private Set<String> groups(Description description) {
Set<String> groups = new HashSet<String>();
Group group = description.getAnnotation(Group.class);
if (group != null) {
groups.addAll(Arrays.asList(group.value()));
}
Class<?> testClaz = description.getTestClass();
while (!Object.class.equals(testClaz)) {
group = testClaz.getAnnotation(Group.class);
if (group != null) {
groups.addAll(Arrays.asList(group.value()));
}
testClaz = testClaz.getSuperclass();
}
return groups;
}
}
}