Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

alpha-ready implementation of SuiteBuilder

  • Loading branch information...
commit f09cff79b941a525271f3f2838a9742b4c5c8d36 1 parent 3b7ab4a
dsaff authored
View
2  build.xml
@@ -5,7 +5,7 @@
<property name="src" value="src/main/java" />
<property name="target" location="target" />
<property name="bin" location="${target}/main" />
- <property name="version-base" value="4.8.2" />
+ <property name="version-base" value="4.9-SNAPSHOT-20100512-0041" />
<property name="version-status" value="" />
<property name="version" value="${version-base}${version-status}" />
<property name="dist" value="junit${version}" />
View
4 doc/ReleaseNotes4.9-SNAPSHOT-20100512-0041.html
@@ -0,0 +1,4 @@
+
+Can't open /Users/saff/Documents/git-repos/junit/doc/ReleaseNotes4.9-SNAPSHOT-20100512-0041.txt: No such file or directory at build/Markdown.pl line 218.
+Use of uninitialized value in substitution (s///) at build/Markdown.pl line 245.
+Use of uninitialized value in substitution (s///) at build/Markdown.pl line 246.
View
28 doc/ReleaseNotes4.9.html
@@ -0,0 +1,28 @@
+<h2>Summary of Changes in version 4.9</h2>
+
+<h3>SuiteBuilder</h3>
+
+<p>A new way of declaring suites to run. SuiteBuilder allows for flexible
+specification of where to find the classes containing tests, and how
+to filter the resulting runners. This suite class lists the
+explicit test classes to consider running, and then filters it down
+to only those tests or classes annotated with <code>@Category(Yes.class)</code>:</p>
+
+<pre><code>@RunWith(SuiteBuilder.class)
+public static class OnlyYes {
+ @Classes
+ public Listed classes= new Listed(Yes1.class, Yes2.class, No1.class);
+
+ @RunnerFilter
+ public CategoryFilter filter= CategoryFilter.include(Yes.class);
+}
+</code></pre>
+
+<p>We hope to soon include other implementations for the @Classes annotation,
+including a classpath-searching test gatherer.</p>
+
+<h3>Bug fixes</h3>
+
+<ul>
+<li>github#98: assumeTrue() does not work with expected exceptions</li>
+</ul>
View
20 doc/ReleaseNotes4.9.txt
@@ -1,5 +1,25 @@
## Summary of Changes in version 4.9 ##
+### SuiteBuilder ###
+
+A new way of declaring suites to run. SuiteBuilder allows for flexible
+specification of where to find the classes containing tests, and how
+to filter the resulting runners. This suite class lists the
+explicit test classes to consider running, and then filters it down
+to only those tests or classes annotated with `@Category(Yes.class)`:
+
+ @RunWith(SuiteBuilder.class)
+ public static class OnlyYes {
+ @Classes
+ public Listed classes= new Listed(Yes1.class, Yes2.class, No1.class);
+
+ @RunnerFilter
+ public CategoryFilter filter= CategoryFilter.include(Yes.class);
+ }
+
+We hope to soon include other implementations for the @Classes annotation,
+including a classpath-searching test gatherer.
+
### Bug fixes ###
- github#98: assumeTrue() does not work with expected exceptions
View
2  src/main/java/junit/runner/Version.java
@@ -9,7 +9,7 @@ private Version() {
}
public static String id() {
- return "4.8.2";
+ return "4.9-SNAPSHOT-20100512-0041";
}
public static void main(String[] args) {
View
4 src/main/java/org/junit/experimental/categories/CategoryFilter.java
@@ -8,10 +8,10 @@
import java.util.Arrays;
import java.util.List;
+import org.junit.experimental.runners.SuiteBuilder;
import org.junit.runner.Runner;
-import org.junit.tests.experimental.categories.SuiteBuilderTest.RunnerFilter;
-public class CategoryFilter implements RunnerFilter.Value {
+public class CategoryFilter implements SuiteBuilder.RunnerFilter.Value {
private final Class<?> fIncluded;
public CategoryFilter(Class<?> included) {
View
19 src/main/java/org/junit/experimental/runners/Listed.java
@@ -0,0 +1,19 @@
+/**
+ *
+ */
+package org.junit.experimental.runners;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class Listed implements SuiteBuilder.Classes.Value {
+ private final Class<?>[] fClasses;
+
+ public Listed(Class<?>... classes) {
+ fClasses= classes;
+ }
+
+ public List<? extends Class<?>> get() {
+ return Arrays.asList(fClasses);
+ }
+}
View
99 src/main/java/org/junit/experimental/runners/SuiteBuilder.java
@@ -0,0 +1,99 @@
+/**
+ *
+ */
+package org.junit.experimental.runners;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.junit.internal.builders.AllDefaultPossibilitiesBuilder;
+import org.junit.runner.Description;
+import org.junit.runner.Runner;
+import org.junit.runner.notification.RunNotifier;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.TestClass;
+
+public class SuiteBuilder extends Runner {
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface RunnerFilter {
+ public static interface Value {
+ public abstract List<Runner> matchingRunners(
+ List<Runner> allPossibleRunners);
+ }
+ }
+
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface Classes {
+ public static interface Value {
+ public abstract Collection<? extends Class<?>> get();
+ }
+ }
+
+ private final TestClass fTestClass;
+ private final Object fInstance;
+ private final List<Runner> fRunners;
+
+ public SuiteBuilder(Class<?> testClass) throws InitializationError {
+ fTestClass= new TestClass(testClass);
+ fInstance = createInstance();
+ fRunners= computeRunners();
+ }
+
+ private Object createInstance() throws InitializationError {
+ try {
+ return fTestClass.getOnlyConstructor().newInstance();
+ } catch (Exception e) {
+ throw new InitializationError(e);
+ }
+ }
+
+ @Override
+ public Description getDescription() {
+ Description description= Description.createSuiteDescription(fTestClass.getJavaClass());
+ for (Runner each : fRunners) {
+ description.addChild(each.getDescription());
+ }
+ return description;
+ }
+
+ @Override
+ public void run(RunNotifier notifier) {
+ for (Runner each : fRunners)
+ each.run(notifier);
+ }
+
+ private List<Runner> computeRunners() throws InitializationError {
+ List<Class<?>> allPossibleClasses= gatherClasses();
+ List<Runner> allPossibleRunners= runnersForClasses(allPossibleClasses);
+ return filterRunners(allPossibleRunners);
+ }
+
+ private List<Runner> filterRunners(List<Runner> allPossibleRunners) {
+ List<Runner> result= allPossibleRunners;
+ for (SuiteBuilder.RunnerFilter.Value each : getFilters())
+ result= each.matchingRunners(result);
+ return result;
+ }
+
+ private List<SuiteBuilder.RunnerFilter.Value> getFilters() {
+ return fTestClass.getAnnotatedFieldValues(fInstance,
+ SuiteBuilder.RunnerFilter.class, SuiteBuilder.RunnerFilter.Value.class);
+ }
+
+ private List<Runner> runnersForClasses(List<Class<?>> allPossibleClasses) throws InitializationError {
+ return new AllDefaultPossibilitiesBuilder(true).runners(fTestClass
+ .getJavaClass(), allPossibleClasses);
+ }
+
+ public List<Class<?>> gatherClasses() {
+ ArrayList<Class<?>> result= new ArrayList<Class<?>>();
+ List<SuiteBuilder.Classes.Value> classeses= fTestClass.getAnnotatedFieldValues(
+ fInstance, SuiteBuilder.Classes.class, SuiteBuilder.Classes.Value.class);
+ for (SuiteBuilder.Classes.Value each : classeses)
+ result.addAll(each.get());
+ return result;
+ }
+}
View
5 src/main/java/org/junit/runners/model/RunnerBuilder.java
@@ -87,6 +87,11 @@ void removeParent(Class<?> klass) {
}
}
+ public List<Runner> runners(Class<?> parent, List<Class<?>> children)
+ throws InitializationError {
+ return runners(parent, children.toArray(new Class<?>[0]));
+ }
+
private List<Runner> runners(Class<?>[] children) {
ArrayList<Runner> runners= new ArrayList<Runner>();
for (Class<?> each : children) {
View
124 src/test/java/org/junit/tests/experimental/categories/SuiteBuilderTest.java
@@ -5,138 +5,32 @@
import static org.junit.experimental.results.PrintableResult.testResult;
import static org.junit.experimental.results.ResultMatchers.isSuccessful;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.experimental.categories.CategoryFilter;
+import org.junit.experimental.runners.Listed;
+import org.junit.experimental.runners.SuiteBuilder;
+import org.junit.experimental.runners.SuiteBuilder.Classes;
+import org.junit.experimental.runners.SuiteBuilder.RunnerFilter;
import org.junit.runner.Description;
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.RunWith;
import org.junit.runner.Runner;
-import org.junit.runner.notification.RunNotifier;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.InitializationError;
-import org.junit.runners.model.TestClass;
public class SuiteBuilderTest {
- @Retention(RetentionPolicy.RUNTIME)
- public @interface RunnerFilter {
- public static interface Value {
- public abstract List<Runner> matchingRunners(
- List<Runner> allPossibleRunners);
- }
- }
-
- public static class Listed implements Classes.Value {
- private final Class<?>[] fClasses;
-
- public Listed(Class<?>... classes) {
- fClasses= classes;
- }
-
- public List<? extends Class<?>> get() {
- return Arrays.asList(fClasses);
- }
- }
-
- // Classes -> RunnerBuilder
-
- @Retention(RetentionPolicy.RUNTIME)
- public @interface Classes {
- public static interface Value {
- public abstract Collection<? extends Class<?>> get();
- }
- }
-
- public static class SuiteBuilder extends Runner {
- private final TestClass fTestClass;
-
- private final Object fInstance;
-
- private final List<Runner> fRunners;
-
- public SuiteBuilder(Class<?> testClass) throws InitializationError {
- fTestClass= new TestClass(testClass);
- // TODO: extract complexity
- try {
- fInstance= fTestClass.getOnlyConstructor().newInstance();
- } catch (Exception e) {
- throw new InitializationError(e);
- }
- fRunners= computeRunners();
- }
-
- @Override
- public Description getDescription() {
- Description description= Description.createSuiteDescription(fTestClass.getJavaClass());
- for (Runner each : fRunners) {
- description.addChild(each.getDescription());
- }
- return description;
- }
-
- // TODO: require an instance?
- @Override
- public void run(RunNotifier notifier) {
- for (Runner each : fRunners)
- each.run(notifier);
- }
-
- private List<Runner> computeRunners() {
- List<Class<?>> allPossibleClasses= gatherClasses();
- List<Runner> allPossibleRunners= runnersForClasses(allPossibleClasses);
- return filterRunners(allPossibleRunners);
- }
-
- private List<Runner> filterRunners(List<Runner> allPossibleRunners) {
- List<Runner> result= allPossibleRunners;
- for (RunnerFilter.Value each : getFilters())
- result= each.matchingRunners(result);
- return result;
- }
-
- private List<RunnerFilter.Value> getFilters() {
- return fTestClass.getAnnotatedFieldValues(fInstance,
- RunnerFilter.class, RunnerFilter.Value.class);
- }
-
- private List<Runner> runnersForClasses(List<Class<?>> allPossibleClasses) {
- // TODO: cheating
- ArrayList<Runner> result= new ArrayList<Runner>();
- for (Class<?> each : allPossibleClasses) {
- try {
- result.add(new BlockJUnit4ClassRunner(each));
- } catch (InitializationError e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- return result;
- }
-
- private List<Class<?>> gatherClasses() {
- ArrayList<Class<?>> result= new ArrayList<Class<?>>();
- List<Classes.Value> classeses= fTestClass.getAnnotatedFieldValues(
- fInstance, Classes.class, Classes.Value.class);
- for (Classes.Value each : classeses)
- result.addAll(each.get());
- return result;
- }
- }
-
static class Yes {
}
static class No {
}
+ // TODO: test multiple filters, multiple class sources
+
@Category(Yes.class)
public static class Yes1 {
@Test
@@ -168,7 +62,7 @@ public void no1() {
}
@RunWith(SuiteBuilder.class)
- public static class OnlyYesMaybeTwo {
+ public static class OnlyYes {
@Classes
public Listed classes= new Listed(Yes1.class, Yes2.class, No1.class);
@@ -212,9 +106,9 @@ public void onlyRunOne() {
@Test
public void runTwo() {
- Result result= new JUnitCore().run(OnlyYesMaybeTwo.class);
+ Result result= new JUnitCore().run(OnlyYes.class);
assertEquals(2, result.getRunCount());
- assertThat(testResult(OnlyYesMaybeTwo.class), isSuccessful());
+ assertThat(testResult(OnlyYes.class), isSuccessful());
}
@Test
Please sign in to comment.
Something went wrong with that request. Please try again.