aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/junit/experimental/categories/Categories.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/junit/experimental/categories/Categories.java')
-rw-r--r--src/main/java/org/junit/experimental/categories/Categories.java108
1 files changed, 49 insertions, 59 deletions
diff --git a/src/main/java/org/junit/experimental/categories/Categories.java b/src/main/java/org/junit/experimental/categories/Categories.java
index 290c180..0c73ed8 100644
--- a/src/main/java/org/junit/experimental/categories/Categories.java
+++ b/src/main/java/org/junit/experimental/categories/Categories.java
@@ -2,8 +2,10 @@ package org.junit.experimental.categories;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
+import java.util.LinkedHashSet;
import java.util.Set;
import org.junit.runner.Description;
@@ -76,7 +78,7 @@ import org.junit.runners.model.RunnerBuilder;
* </pre>
*
* @version 4.12
- * @see <a href="https://github.com/junit-team/junit/wiki/Categories">Categories at JUnit wiki</a>
+ * @see <a href="https://github.com/junit-team/junit4/wiki/Categories">Categories at JUnit wiki</a>
*/
public class Categories extends Suite {
@@ -86,13 +88,13 @@ public class Categories extends Suite {
* Determines the tests to run that are annotated with categories specified in
* the value of this annotation or their subtypes unless excluded with {@link ExcludeCategory}.
*/
- public Class<?>[] value() default {};
+ Class<?>[] value() default {};
/**
* If <tt>true</tt>, runs tests annotated with <em>any</em> of the categories in
* {@link IncludeCategory#value()}. Otherwise, runs tests only if annotated with <em>all</em> of the categories.
*/
- public boolean matchAny() default true;
+ boolean matchAny() default true;
}
@Retention(RetentionPolicy.RUNTIME)
@@ -101,13 +103,13 @@ public class Categories extends Suite {
* Determines the tests which do not run if they are annotated with categories specified in the
* value of this annotation or their subtypes regardless of being included in {@link IncludeCategory#value()}.
*/
- public Class<?>[] value() default {};
+ Class<?>[] value() default {};
/**
* If <tt>true</tt>, the tests annotated with <em>any</em> of the categories in {@link ExcludeCategory#value()}
* do not run. Otherwise, the tests do not run if and only if annotated with <em>all</em> categories.
*/
- public boolean matchAny() default true;
+ boolean matchAny() default true;
}
public static class CategoryFilter extends Filter {
@@ -117,10 +119,7 @@ public class Categories extends Suite {
private final boolean excludedAny;
public static CategoryFilter include(boolean matchAny, Class<?>... categories) {
- if (hasNull(categories)) {
- throw new NullPointerException("has null category");
- }
- return categoryFilter(matchAny, createSet(categories), true, null);
+ return new CategoryFilter(matchAny, categories, true, null);
}
public static CategoryFilter include(Class<?> category) {
@@ -132,10 +131,7 @@ public class Categories extends Suite {
}
public static CategoryFilter exclude(boolean matchAny, Class<?>... categories) {
- if (hasNull(categories)) {
- throw new NullPointerException("has null category");
- }
- return categoryFilter(true, null, matchAny, createSet(categories));
+ return new CategoryFilter(true, null, matchAny, categories);
}
public static CategoryFilter exclude(Class<?> category) {
@@ -151,14 +147,30 @@ public class Categories extends Suite {
return new CategoryFilter(matchAnyInclusions, inclusions, matchAnyExclusions, exclusions);
}
+ @Deprecated
+ public CategoryFilter(Class<?> includedCategory, Class<?> excludedCategory) {
+ includedAny = true;
+ excludedAny = true;
+ included = nullableClassToSet(includedCategory);
+ excluded = nullableClassToSet(excludedCategory);
+ }
+
protected CategoryFilter(boolean matchAnyIncludes, Set<Class<?>> includes,
- boolean matchAnyExcludes, Set<Class<?>> excludes) {
+ boolean matchAnyExcludes, Set<Class<?>> excludes) {
includedAny = matchAnyIncludes;
excludedAny = matchAnyExcludes;
included = copyAndRefine(includes);
excluded = copyAndRefine(excludes);
}
+ private CategoryFilter(boolean matchAnyIncludes, Class<?>[] inclusions,
+ boolean matchAnyExcludes, Class<?>[] exclusions) {
+ includedAny = matchAnyIncludes;
+ excludedAny = matchAnyExcludes;
+ included = createSet(inclusions);
+ excluded = createSet(exclusions);
+ }
+
/**
* @see #toString()
*/
@@ -284,23 +296,13 @@ public class Categories extends Suite {
}
private static Set<Class<?>> copyAndRefine(Set<Class<?>> classes) {
- HashSet<Class<?>> c= new HashSet<Class<?>>();
+ Set<Class<?>> c= new LinkedHashSet<Class<?>>();
if (classes != null) {
c.addAll(classes);
}
c.remove(null);
return c;
}
-
- private static boolean hasNull(Class<?>... classes) {
- if (classes == null) return false;
- for (Class<?> clazz : classes) {
- if (clazz == null) {
- return true;
- }
- }
- return false;
- }
}
public Categories(Class<?> klass, RunnerBuilder builder) throws InitializationError {
@@ -315,7 +317,6 @@ public class Categories extends Suite {
} catch (NoTestsRemainException e) {
throw new InitializationError(e);
}
- assertNoCategorizedDescendentsOfUncategorizeableParents(getDescription());
}
private static Set<Class<?>> getIncludedCategory(Class<?> klass) {
@@ -338,34 +339,6 @@ public class Categories extends Suite {
return annotation == null || annotation.matchAny();
}
- private static void assertNoCategorizedDescendentsOfUncategorizeableParents(Description description) throws InitializationError {
- if (!canHaveCategorizedChildren(description)) {
- assertNoDescendantsHaveCategoryAnnotations(description);
- }
- for (Description each : description.getChildren()) {
- assertNoCategorizedDescendentsOfUncategorizeableParents(each);
- }
- }
-
- private static 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;
- }
-
private static boolean hasAssignableTo(Set<Class<?>> assigns, Class<?> to) {
for (final Class<?> from : assigns) {
if (to.isAssignableFrom(from)) {
@@ -375,11 +348,28 @@ public class Categories extends Suite {
return false;
}
- private static Set<Class<?>> createSet(Class<?>... t) {
- final Set<Class<?>> set= new HashSet<Class<?>>();
- if (t != null) {
- Collections.addAll(set, t);
+ private static Set<Class<?>> createSet(Class<?>[] classes) {
+ // Not throwing a NPE if t is null is a bad idea, but it's the behavior from JUnit 4.12
+ // for include(boolean, Class<?>...) and exclude(boolean, Class<?>...)
+ if (classes == null || classes.length == 0) {
+ return Collections.emptySet();
+ }
+ for (Class<?> category : classes) {
+ if (category == null) {
+ throw new NullPointerException("has null category");
+ }
}
- return set;
+
+ return classes.length == 1
+ ? Collections.<Class<?>>singleton(classes[0])
+ : new LinkedHashSet<Class<?>>(Arrays.asList(classes));
+ }
+
+ private static Set<Class<?>> nullableClassToSet(Class<?> nullableClass) {
+ // Not throwing a NPE if t is null is a bad idea, but it's the behavior from JUnit 4.11
+ // for CategoryFilter(Class<?> includedCategory, Class<?> excludedCategory)
+ return nullableClass == null
+ ? Collections.<Class<?>>emptySet()
+ : Collections.<Class<?>>singleton(nullableClass);
}
}