-
Notifications
You must be signed in to change notification settings - Fork 3.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
--filter option implemented. #647
Changes from 15 commits
196c4ed
0a9a389
318adee
5edfb44
3433608
15c6048
74cab2d
5820172
9d9899b
aa7c75d
40b8761
b01900f
114025f
b1cf4b5
5619304
8265296
b0c0aaf
b5084eb
c85a267
ae1fc25
cfaceb6
fa5df4e
b026c08
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package org.junit.experimental.categories; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
import org.junit.internal.Classes; | ||
import org.junit.runner.FilterFactory; | ||
import org.junit.runner.FilterFactoryParams; | ||
import org.junit.runner.manipulation.Filter; | ||
|
||
/** | ||
* Implementation of FilterFactory for Category filtering. | ||
*/ | ||
public abstract class CategoryFilterFactory implements FilterFactory { | ||
/** | ||
* Creates a {@link org.junit.experimental.categories.Categories.CategoryFilter} given a | ||
* ${FilterFactoryParams} argument. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is ${} here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed. |
||
* | ||
* @param params Parameters needed to create the {@link Filter} | ||
* @throws FilterNotCreatedException | ||
*/ | ||
@Override | ||
public Filter createFilter(FilterFactoryParams params) throws FilterNotCreatedException { | ||
try { | ||
return createFilter(parseCategories(params.getArgs())); | ||
} catch (ClassNotFoundException e) { | ||
throw new FilterNotCreatedException(e); | ||
} | ||
} | ||
|
||
/** | ||
* Creates a {@link org.junit.experimental.categories.Categories.CategoryFilter} given an array of classes used as | ||
* {@link Category} values. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Strictly speaking, it takes Classes, which may be values of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
* | ||
* @param categories Category classes. | ||
*/ | ||
protected abstract Filter createFilter(Class<?>... categories); | ||
|
||
private Class<?>[] parseCategories(String categories) throws ClassNotFoundException { | ||
List<Class<?>> categoryClasses = new ArrayList<Class<?>>(); | ||
|
||
for (String category : categories.split(",")) { | ||
Class<?> categoryClass = Classes.getClass(category); | ||
|
||
categoryClasses.add(categoryClass); | ||
} | ||
|
||
return categoryClasses.toArray(new Class[]{}); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package org.junit.experimental.categories; | ||
|
||
import java.util.Arrays; | ||
import java.util.HashSet; | ||
import java.util.Set; | ||
|
||
import org.junit.runner.manipulation.Filter; | ||
|
||
import static org.junit.experimental.categories.Categories.CategoryFilter; | ||
|
||
/** | ||
* {@link org.junit.runner.FilterFactory} to exclude categories. | ||
* | ||
* The {@link Filter} that is created will filter out tests that are categorized with any of the | ||
* given categories. | ||
* | ||
* Usage from command line: | ||
* <code> | ||
* --filter=org.junit.experimental.categories.ExcludeCategories=pkg.of.Cat1,pkg.of.Cat2 | ||
* </code> | ||
* | ||
* Usage from API: | ||
* <code> | ||
* new ExcludeCategories().createFilter(Cat1.class, Cat2.class); | ||
* </code> | ||
*/ | ||
public final class ExcludeCategories extends CategoryFilterFactory { | ||
/** | ||
* Creates an {@link ExcludesAny} {@link CategoryFilter} given an array of classes used as | ||
* {@link Category} values. | ||
* | ||
* @param categories Category classes. | ||
* @return | ||
*/ | ||
@Override | ||
protected Filter createFilter(Class<?>... categories) { | ||
return new ExcludesAny(categories); | ||
} | ||
|
||
private static class ExcludesAny extends CategoryFilter { | ||
public ExcludesAny(Class<?>... categories) { | ||
this(new HashSet<Class<?>>(Arrays.asList(categories))); | ||
} | ||
|
||
public ExcludesAny(Set<Class<?>> categories) { | ||
super(true, null, true, categories); | ||
} | ||
|
||
@Override | ||
public String describe() { | ||
return "excludes " + super.describe(); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package org.junit.experimental.categories; | ||
|
||
import java.util.Arrays; | ||
import java.util.HashSet; | ||
import java.util.Set; | ||
|
||
import org.junit.runner.manipulation.Filter; | ||
|
||
import static org.junit.experimental.categories.Categories.CategoryFilter; | ||
|
||
/** | ||
* {@link org.junit.runner.FilterFactory} to include categories. | ||
* | ||
* The {@link Filter} that is created will filter out tests that are categorized with any of the | ||
* given categories. | ||
* | ||
* Usage from command line: | ||
* <code> | ||
* --filter=org.junit.experimental.categories.IncludeCategories=pkg.of.Cat1,pkg.of.Cat2 | ||
* </code> | ||
* | ||
* Usage from API: | ||
* <code> | ||
* new IncludeCategories().createFilter(Cat1.class, Cat2.class); | ||
* </code> | ||
*/ | ||
public final class IncludeCategories extends CategoryFilterFactory { | ||
/** | ||
* Creates an {@link IncludesAny} {@link CategoryFilter} given an array of classes used as | ||
* {@link Category} values. | ||
* | ||
* @param categories Category classes. | ||
* @return | ||
*/ | ||
@Override | ||
protected Filter createFilter(Class<?>... categories) { | ||
return new IncludesAny(categories); | ||
} | ||
|
||
private static class IncludesAny extends CategoryFilter { | ||
public IncludesAny(Class<?>... categories) { | ||
this(new HashSet<Class<?>>(Arrays.asList(categories))); | ||
} | ||
|
||
public IncludesAny(Set<Class<?>> categories) { | ||
super(true, categories, true, null); | ||
} | ||
|
||
@Override | ||
public String describe() { | ||
return "includes " + super.describe(); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package org.junit.internal; | ||
|
||
import static java.lang.Thread.currentThread; | ||
|
||
/** | ||
* Miscellaneous functions dealing with classes. | ||
*/ | ||
public class Classes { | ||
/** | ||
* Returns Class.forName for {@code className} using the current thread's class loader. | ||
* | ||
* @param className Name of the class. | ||
* @throws ClassNotFoundException | ||
*/ | ||
public static Class<?> getClass(String className) throws ClassNotFoundException { | ||
return Class.forName(className, true, currentThread().getContextClassLoader()); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -53,7 +53,7 @@ private List<Throwable> getCauses(Throwable cause) { | |
|
||
private Description describeCause(Throwable child) { | ||
return Description.createTestDescription(fTestClass, | ||
"initializationError"); | ||
"initializationError: " + child); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Spaces in descriptions give some frameworks fits. The throwable should be available in the stacktrace, can we leave it out of the description? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed. |
||
} | ||
|
||
private void runCause(Throwable child, RunNotifier notifier) { | ||
|
@@ -62,4 +62,4 @@ private void runCause(Throwable child, RunNotifier notifier) { | |
notifier.fireTestFailure(new Failure(description, child)); | ||
notifier.fireTestFinished(description); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
package org.junit.runner; | ||
|
||
import org.junit.internal.Classes; | ||
import org.junit.runner.manipulation.Filter; | ||
|
||
import static org.junit.runner.FilterFactory.FilterNotCreatedException; | ||
|
||
/** | ||
* Utility class whose methods create a {@link FilterFactory}. | ||
*/ | ||
public class FilterFactories { | ||
/** | ||
* Creates a {@link Filter}. | ||
* | ||
* A filter specification is of the form "package.of.FilterFactory=args-to-filter-factory" or | ||
* "package.of.FilterFactory". | ||
* | ||
* @param filterSpec The filter specification | ||
* @throws FilterFactoryNotCreatedException | ||
* @throws FilterNotCreatedException | ||
*/ | ||
public static Filter createFilterFromFilterSpec(Description description, String filterSpec) | ||
throws FilterFactoryNotCreatedException { | ||
|
||
if (filterSpec.contains("=")) { | ||
String[] tuple = filterSpec.split("=", 2); | ||
|
||
return createFilter(tuple[0], new FilterFactoryParams(description, tuple[1])); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @kcooney, is this how you were hoping to add descriptions, or would you rather Noel hold off and let you add descriptions when this is done? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @dsaff This isn't what I had in mind. I suggest removing the Description parameter from FilterFactoryParams for now. I can add it later; let's not add more things to go back and forth about in this change (it's actually pretty close iMHO) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
} else { | ||
return createFilter(filterSpec, new FilterFactoryParams(description)); | ||
} | ||
} | ||
|
||
/** | ||
* Creates a {@link Filter}. | ||
* | ||
* @param filterFactoryFqcn The fully qualified class name of the {@link FilterFactory} | ||
* @param params The arguments to the {@link FilterFactory} | ||
* @throws FilterNotCreatedException | ||
* @throws FilterFactoryNotCreatedException | ||
*/ | ||
public static Filter createFilter(String filterFactoryFqcn, FilterFactoryParams params) | ||
throws FilterFactoryNotCreatedException { | ||
FilterFactory filterFactory = createFilterFactory(filterFactoryFqcn); | ||
|
||
return filterFactory.createFilter(params); | ||
} | ||
|
||
/** | ||
* Creates a {@link Filter}. | ||
* | ||
* @param filterFactoryClass The class of the {@link FilterFactory} | ||
* @param params The arguments to the {@link FilterFactory} | ||
* @throws FilterNotCreatedException | ||
* @throws FilterFactoryNotCreatedException | ||
* | ||
*/ | ||
public static Filter createFilter(Class<? extends FilterFactory> filterFactoryClass, FilterFactoryParams params) | ||
throws FilterFactoryNotCreatedException { | ||
FilterFactory filterFactory = createFilterFactory(filterFactoryClass); | ||
|
||
return filterFactory.createFilter(params); | ||
} | ||
|
||
static FilterFactory createFilterFactory(String filterFactoryFqcn) throws FilterFactoryNotCreatedException { | ||
Class<? extends FilterFactory> filterFactoryClass; | ||
|
||
try { | ||
filterFactoryClass = Classes.getClass(filterFactoryFqcn).asSubclass(FilterFactory.class); | ||
} catch (Exception e) { | ||
throw new FilterFactoryNotCreatedException(e); | ||
} | ||
|
||
return createFilterFactory(filterFactoryClass); | ||
} | ||
|
||
static FilterFactory createFilterFactory(Class<? extends FilterFactory> filterFactoryClass) | ||
throws FilterFactoryNotCreatedException { | ||
try { | ||
return filterFactoryClass.getConstructor().newInstance(); | ||
} catch (Exception e) { | ||
throw new FilterFactoryNotCreatedException(e); | ||
} | ||
} | ||
|
||
/** | ||
* Exception thrown if the {@link FilterFactory} cannot be created. | ||
*/ | ||
public static class FilterFactoryNotCreatedException extends ClassNotFoundException { | ||
public FilterFactoryNotCreatedException(Exception exception) { | ||
super(exception.getMessage(), exception); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package org.junit.runner; | ||
|
||
import org.junit.runner.manipulation.Filter; | ||
|
||
/** | ||
* Extend this class to create a factory that creates {@link Filter}. | ||
*/ | ||
public interface FilterFactory { | ||
/** | ||
* Creates a {@link Filter} given a ${FilterFactoryParams} argument. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. $ -> @link There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
* | ||
* @param params Parameters needed to create the {@link Filter} | ||
* @throws FilterNotCreatedException | ||
*/ | ||
Filter createFilter(FilterFactoryParams params) throws FilterNotCreatedException; | ||
|
||
/** | ||
* Exception thrown if the {@link Filter} cannot be created. | ||
*/ | ||
static class FilterNotCreatedException extends FilterFactories.FilterFactoryNotCreatedException { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems odd that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hierarchy reversed. |
||
public FilterNotCreatedException(Exception exception) { | ||
super(exception); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package org.junit.runner; | ||
|
||
/** | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We'd be better off without any of the javadoc in this class. Better would be a brief class-level comment about why this exists (especially because it's taken @kcooney several times before I got my head around why this is a good idea). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @kcooney , preference for the class-level comment? |
||
* Parameters to a {@link FilterFactory}. | ||
*/ | ||
public final class FilterFactoryParams { | ||
private final Description description; | ||
private final String args; | ||
|
||
/** | ||
* Constructs a {@link FilterFactoryParams}. | ||
* | ||
* @param description {@link Description} | ||
*/ | ||
public FilterFactoryParams(Description description) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should javadoc where the FilterFactory can expect the Description and args to have come from. |
||
this(description, null); | ||
} | ||
|
||
/** | ||
* Constructs a {@link FilterFactoryParams}. | ||
* | ||
* @param description {@link Description} | ||
* @param args Arguments | ||
*/ | ||
public FilterFactoryParams(Description description, String args) { | ||
this.description = description; | ||
this.args = args; | ||
} | ||
|
||
/** | ||
* Returns the {@link Description}. | ||
*/ | ||
public Description getDescription() { | ||
return description; | ||
} | ||
|
||
/** | ||
* Returns the arguments. | ||
*/ | ||
public String getArgs() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you think this makes more sense as getArgs or getArg? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess it depends upon how one looks at it. The field can contain zero or more arguments depending upon how its user decides to parse it. @kcooney , opinions? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
return args; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this be package-scope?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.