Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Merging from remote

  • Loading branch information...
commit 45cee89178172749b7f75be3944d9aa367d97373 2 parents dcd07b1 + db9a456
Marcos Vinícius da Silva authored

Showing 74 changed files with 2,972 additions and 324 deletions. Show diff stats Hide diff stats

  1. +49 1 acknowledgements.txt
  2. +63 22 build.xml
  3. BIN  build/lib/ant-contrib-1.0b3.jar
  4. 0  { → build/maven}/pom-template.xml
  5. +49 0 build/maven/post_maven_tests.sh
  6. +61 0 build/maven/sample_project_template/pom.xml
  7. +33 0 build/maven/sample_project_template/src/test/java/JunitDependencyTest.java
  8. +36 0 build/run_tests.sh
  9. +1 34 build_tests.sh
  10. +93 0 doc/ReleaseNotes4.10.html
  11. +84 0 doc/ReleaseNotes4.10.txt
  12. +1 0  doc/ReleaseNotes4.11.html
  13. +1 0  doc/ReleaseNotes4.11.txt
  14. +14 0 doc/ReleaseNotes4.9.1.txt
  15. +1 1  doc/ReleaseNotes4.9.html
  16. +1 1  doc/ReleaseNotes4.9.txt
  17. +0 12 pom-template.xml.asc
  18. +5 1 src/main/java/junit/framework/AssertionFailedError.java
  19. +2 1  src/main/java/junit/framework/TestSuite.java
  20. +1 1  src/main/java/junit/runner/Version.java
  21. +14 4 src/main/java/org/junit/Assert.java
  22. +32 6 src/main/java/org/junit/ClassRule.java
  23. +29 6 src/main/java/org/junit/Rule.java
  24. +1 0  src/main/java/org/junit/experimental/theories/internal/AllMembersSupplier.java
  25. +35 0 src/main/java/org/junit/internal/MethodSorter.java
  26. +2 1  src/main/java/org/junit/internal/matchers/TypeSafeMatcher.java
  27. +2 1  src/main/java/org/junit/internal/runners/TestClass.java
  28. +112 0 src/main/java/org/junit/internal/runners/rules/RuleFieldValidator.java
  29. +47 22 src/main/java/org/junit/internal/runners/statements/FailOnTimeout.java
  30. +0 1  src/main/java/org/junit/internal/runners/statements/RunAfters.java
  31. +14 5 src/main/java/org/junit/rules/ErrorCollector.java
  32. +99 0 src/main/java/org/junit/rules/RuleChain.java
  33. +41 14 src/main/java/org/junit/rules/TemporaryFolder.java
  34. +3 0  src/main/java/org/junit/rules/TestWatcher.java
  35. +3 0  src/main/java/org/junit/rules/TestWatchman.java
  36. +4 2 src/main/java/org/junit/runner/Description.java
  37. +1 8 src/main/java/org/junit/runner/JUnitCore.java
  38. +3 1 src/main/java/org/junit/runner/Result.java
  39. +3 1 src/main/java/org/junit/runner/notification/Failure.java
  40. +36 37 src/main/java/org/junit/runners/BlockJUnit4ClassRunner.java
  41. +52 36 src/main/java/org/junit/runners/Parameterized.java
  42. +23 22 src/main/java/org/junit/runners/ParentRunner.java
  43. +20 1 src/main/java/org/junit/runners/model/FrameworkField.java
  44. +6 1 src/main/java/org/junit/runners/model/FrameworkMember.java
  45. +48 5 src/main/java/org/junit/runners/model/FrameworkMethod.java
  46. +53 0 src/main/java/org/junit/runners/model/NoGenericTypeParametersValidator.java
  47. +25 2 src/main/java/org/junit/runners/model/TestClass.java
  48. +3 1 src/test/java/junit/samples/SimpleTest.java
  49. +1 0  src/test/java/junit/tests/framework/AllTests.java
  50. +23 0 src/test/java/junit/tests/framework/AssertionFailedErrorTest.java
  51. +1 0  src/test/java/junit/tests/framework/TestListenerTest.java
  52. +2 1  src/test/java/junit/tests/runner/AllTests.java
  53. +37 0 src/test/java/junit/tests/runner/ResultTest.java
  54. +34 0 src/test/java/org/junit/internal/MethodSorterTest.java
  55. +3 1 src/test/java/org/junit/samples/SimpleTest.java
  56. +10 2 src/test/java/org/junit/tests/AllTests.java
  57. +32 16 src/test/java/org/junit/tests/experimental/categories/CategoriesAndParameterizedTest.java
  58. +0 2  src/test/java/org/junit/tests/experimental/categories/CategoryTest.java
  59. +137 1 src/test/java/org/junit/tests/experimental/rules/ClassRulesTest.java
  60. +32 0 src/test/java/org/junit/tests/experimental/rules/LoggingTestWatcher.java
  61. +60 0 src/test/java/org/junit/tests/experimental/rules/RuleChainTest.java
  62. +189 0 src/test/java/org/junit/tests/experimental/rules/RuleFieldValidatorTest.java
  63. +137 8 src/test/java/org/junit/tests/experimental/rules/TempFolderRuleTest.java
  64. +144 0 src/test/java/org/junit/tests/experimental/rules/TemporaryFolderUsageTest.java
  65. +378 26 src/test/java/org/junit/tests/experimental/rules/TestRuleTest.java
  66. +52 0 src/test/java/org/junit/tests/experimental/rules/TestWatcherTest.java
  67. +72 0 src/test/java/org/junit/tests/experimental/rules/TestWatchmanTest.java
  68. +8 0 src/test/java/org/junit/tests/experimental/rules/VerifierRuleTest.java
  69. +177 0 ...test/java/org/junit/tests/experimental/theories/runner/WithUnresolvedGenericTypeVariablesOnTheoryParms.java
  70. +110 0 src/test/java/org/junit/tests/internal/runners/statements/FailOnTimeoutTest.java
  71. +33 0 src/test/java/org/junit/tests/running/classes/BlockJUnit4ClassRunnerTest.java
  72. +32 15 src/test/java/org/junit/tests/running/classes/ParameterizedTestTest.java
  73. +27 1 src/test/java/org/junit/tests/running/classes/ParentRunnerTest.java
  74. +35 0 src/test/java/org/junit/tests/running/classes/TestClassTest.java
50 acknowledgements.txt
@@ -104,8 +104,56 @@
104 104 Samuel Le Berrigaud (sleberrigaud@github): Report for GH-248:
105 105 protected BlockJUnit4ClassRunner#rules method removed from 4.8.2
106 106
  107 +2011 Jun 24
  108 + Daniel Rothmaler (drothmaler@github):
  109 + #299: random temp file/folder creation
  110 + #300: ErrorCollector.checkThat overload
  111 +
107 112 2011 Jul 06
108   - Stefan Birkner: Fixed wrong docomentation of ClassRule (github#254).
  113 + Stefan Birkner: Fixed wrong documentation of ClassRule (github#254).
  114 +
  115 +2011 Jul 08
  116 + Paul Holser (pholser@alumni.rice.edu): Beginnings of fix for GH-64:
  117 + Theories doesn't honor parameterized types
  118 +
  119 +2011 Jul 09
  120 + Nigel Charman: Reported Rules bugs github#257 and gihub#258.
  121 +
  122 +2011 Jul 09
  123 + Stefan Birkner: Fixed rules bugs (github#257, gihub#258, github#260).
  124 +
  125 +2011 Jul 09
  126 + Stefan Birkner: Fixed rules bugs (github#257, gihub#258, github#260).
  127 +
  128 +2011 Jul 16
  129 + Rob Dawson: Submitted a patch that makes Results serlializable.
  130 +
  131 +2011 Jul 20
  132 + Asaf Ary, Stefan Birkner: Fixed FailOnTimeout class (github#265).
109 133
110 134 2011 Jul 22
111 135 Andreas Köhler, Stefan Birkner: Fixed wrong documentation of Parameterized (github#89).
  136 +
  137 +2011 Jul 28
  138 + electrickery, Stefan Birkner: Fixed typo in JavaDoc (github#134).
  139 +
  140 +2011 Aug 07
  141 + Esko Luontola: Fixed TemporaryFolder creating files in the current working directory (github#278).
  142 +
  143 +2011 Aug 09
  144 + Stefan Birkner: Fixed JavaDoc links.
  145 +
  146 +2011 Aug 10
  147 + rodolfoliviero@github and JoseRibeiro@github: feature to create recursive temporary folders.
  148 +
  149 +2011 Aug 12
  150 + Esko Luontola: Fixed syntax error in Parameterized's usage example (github#285).
  151 +
  152 +2011 Sep 09
  153 + Robert Munteanu, Stefan Birkner:
  154 + TestWatcher and TestWatchman don't call failed when assumption is violated (github#296).
  155 + digulla@github, Stefan Birkner: Removed useless code (github#289).
  156 +
  157 +== NOTE: as of September 2011, we have stopped recording contributions here.
  158 + For a full list of everyone who has contributed great bug reports and code, please see
  159 + http://github.com/KentBeck/junit
85 build.xml
... ... @@ -1,13 +1,14 @@
1 1 <project name="junit" default="dist" basedir="."
2 2 xmlns:artifact="antlib:org.apache.maven.artifact.ant">
3 3 <tstamp />
  4 + <taskdef resource="net/sf/antcontrib/antcontrib.properties"/>
4 5
5 6 <property file="${user.home}/.junit.properties" />
6 7 <property name="src" value="src/main/java" />
7 8 <property name="target" location="target" />
8 9 <property name="bin" location="${target}/main" />
9   - <property name="version-base" value="4.9" />
10   - <property name="version-status" value="b3" />
  10 + <property name="version-base" value="4.11" />
  11 + <property name="version-status" value="-SNAPSHOT" />
11 12 <property name="version" value="${version-base}${version-status}" />
12 13 <property name="dist" value="junit${version}" />
13 14 <property name="versionfile" value="${src}/junit/runner/Version.java" />
@@ -67,6 +68,7 @@
67 68 debug="on"
68 69 classpath="@{classpath}"
69 70 includeantruntime="false"
  71 + source="1.5"
70 72 target="1.5"
71 73 >
72 74 <compilerarg value="-Xlint:unchecked" />
@@ -131,7 +133,8 @@
131 133
132 134 <target name="release-notes">
133 135 <property name="basename" value="doc/ReleaseNotes${version-base}" />
134   - <exec executable="build/Markdown.pl">
  136 + <exec executable="perl" failonerror="true">
  137 + <arg file="build/Markdown.pl"/>
135 138 <arg file="${basename}.txt"/>
136 139 <redirector output="${basename}.html" />
137 140 </exec>
@@ -217,19 +220,18 @@
217 220
218 221 <!-- to do automatic build upload, you need the maven ant tasks jar. -->
219 222 <!-- therefore, you must run ant as ant -lib build/lib stage.maven -->
220   - <macrodef name="stage.maven.jar">
  223 + <macrodef name="push.maven.jar">
221 224 <attribute name="jar" />
222 225 <attribute name="pom" />
  226 + <attribute name="url" />
  227 + <attribute name="repo.id" />
223 228 <element name="artifact.args" implicit="true" optional="true" />
224 229 <sequential>
225   - <property name="maven-repository-url"
226   - value="https://oss.sonatype.org/service/local/staging/deploy/maven2/" />
227   - <property name="maven-repository-id" value="sonatype-nexus-staging" />
228   - <echo message="Staging to maven: @{jar}" />
  230 + <echo message="Pushing to maven: @{jar} -> @{url}" />
229 231 <artifact:mvn failonerror="true">
230 232 <arg value="org.apache.maven.plugins:maven-gpg-plugin:1.1:sign-and-deploy-file" />
231   - <arg value="-Durl=${maven-repository-url}" />
232   - <arg value="-DrepositoryId=${maven-repository-id}" />
  233 + <arg value="-Durl=@{url}" />
  234 + <arg value="-DrepositoryId=@{repo.id}" />
233 235 <arg value="-DpomFile=@{pom}" />
234 236 <arg value="-Dfile=@{jar}" />
235 237 <artifact.args />
@@ -238,40 +240,79 @@
238 240 </sequential>
239 241 </macrodef>
240 242
241   - <macrodef name="stage.maven.artifactId">
  243 + <macrodef name="push.maven.artifact">
242 244 <attribute name="artifactId" />
  245 + <attribute name="url" />
  246 + <attribute name="repo.id" />
  247 + <attribute name="is.snapshot" default="false" />
243 248 <sequential>
  249 + <local name="m.prefix" />
244 250 <property name="m.prefix" value="${dist}/@{artifactId}-${version}" />
  251 + <local name="m.jar" />
245 252 <property name="m.jar" value="${m.prefix}.jar" />
  253 + <local name="m.sources.jar" />
246 254 <property name="m.sources.jar" value="${m.prefix}-src.jar" />
  255 + <local name="m.javadoc.jar" />
247 256 <property name="m.javadoc.jar" value="${m.prefix}-javadoc.jar" />
  257 + <local name="m.pom" />
248 258 <property name="m.pom" value="${dist}/pom-@{artifactId}.xml" />
249 259
250 260 <filter token="version" value="${version}" />
251 261 <filter token="artifactId" value="@{artifactId}" />
252 262
253 263 <copy
254   - file="pom-template.xml"
  264 + file="build/maven/pom-template.xml"
255 265 tofile="${m.pom}"
256 266 filtering="on"
257 267 overwrite="true"
258 268 />
259 269
260   - <stage.maven.jar jar="${m.jar}" pom="${m.pom}" />
261   -
262   - <stage.maven.jar jar="${m.sources.jar}" pom="${m.pom}" >
263   - <arg value="-Dclassifier=sources" />
264   - </stage.maven.jar>
  270 + <push.maven.jar jar="${m.jar}" pom="${m.pom}"
  271 + url="@{url}" repo.id="@{repo.id}" />
  272 +
  273 + <if>
  274 + <equals arg1="@{is.snapshot}" arg2="false" />
  275 + <then>
  276 + <push.maven.jar jar="${m.sources.jar}" pom="${m.pom}"
  277 + url="@{url}" repo.id="@{repo.id}">
  278 + <arg value="-Dclassifier=sources" />
  279 + </push.maven.jar>
265 280
266   - <stage.maven.jar jar="${m.javadoc.jar}" pom="${m.pom}" >
267   - <arg value="-Dclassifier=javadoc" />
268   - </stage.maven.jar>
  281 + <push.maven.jar jar="${m.javadoc.jar}" pom="${m.pom}"
  282 + url="@{url}" repo.id="@{repo.id}">
  283 + <arg value="-Dclassifier=javadoc" />
  284 + </push.maven.jar>
  285 + </then>
  286 + </if>
269 287 </sequential>
270 288 </macrodef>
271 289
272 290 <target name="stage.maven" depends="all.maven.jars">
273   - <stage.maven.artifactId artifactId="junit" />
274   - <stage.maven.artifactId artifactId="junit-dep" />
  291 + <property name="stage.url"
  292 + value="https://oss.sonatype.org/service/local/staging/deploy/maven2/" />
  293 + <property name="stage.repo.id" value="sonatype-nexus-staging" />
  294 +
  295 + <push.maven.artifact artifactId="junit"
  296 + url="${stage.url}"
  297 + repo.id="${stage.repo.id}"
  298 + is.snapshot="false" />
  299 + <push.maven.artifact artifactId="junit-dep"
  300 + url="${stage.url}"
  301 + repo.id="${stage.repo.id}"
  302 + is.snapshot="false" />
  303 + </target>
  304 +
  305 + <target name="snapshot.maven" depends="all.maven.jars">
  306 + <property name="snapshot.url"
  307 + value="https://oss.sonatype.org/content/repositories/snapshots/" />
  308 + <property name="snapshot.repo.id" value="sonatype-nexus-snapshots" />
  309 +
  310 + <push.maven.artifact artifactId="junit"
  311 + url="${snapshot.url}"
  312 + repo.id="${snapshot.repo.id}" />
  313 + <push.maven.artifact artifactId="junit-dep"
  314 + url="${snapshot.url}"
  315 + repo.id="${snapshot.repo.id}" />
275 316 </target>
276 317
277 318 <target name="print.version">
BIN  build/lib/ant-contrib-1.0b3.jar
Binary file not shown
0  pom-template.xml → build/maven/pom-template.xml
File renamed without changes
49 build/maven/post_maven_tests.sh
... ... @@ -0,0 +1,49 @@
  1 +set -e
  2 +set -o pipefail
  3 +
  4 +function TEST_junit_dep_49_plays_not_nicely_with_later_hamcrest {
  5 + # Make sure our system notices the bug (this broke because of a bad push)
  6 + ! runs_with_newer_hamcrest junit-dep 4.9
  7 +}
  8 +
  9 +function TEST_junit_dep_snapshot_plays_nicely_with_later_hamcrest {
  10 + runs_with_newer_hamcrest junit-dep LATEST
  11 +}
  12 +
  13 +function TEST_junit_snapshot_plays_not_nicely_with_later_hamcrest {
  14 + ! runs_with_newer_hamcrest junit LATEST
  15 +}
  16 +
  17 +function runs_with_newer_hamcrest {
  18 + local artifact_id=$1
  19 + local version=$2
  20 + rm -rf ~/.m2/repository/junit
  21 + rm -rf uses_junit
  22 + cp -r sample_project_template uses_junit
  23 + sed -i '' -e "s/___ARTIFACT_ID___/$artifact_id/" uses_junit/pom.xml
  24 + sed -i '' -e "s/___VERSION___/$version/" uses_junit/pom.xml
  25 + in_dir uses_junit mvn test
  26 + finally rm -rf uses_junit
  27 +}
  28 +
  29 +### <copied src="https://gist.github.com/1206506">
  30 +function in_dir {
  31 + local dir=$1
  32 + shift
  33 + if [ ! -e $dir ]; then
  34 + echo "$dir does not exist"
  35 + return 1
  36 + fi
  37 + pushd $dir >/dev/null
  38 + "$@"
  39 + finally popd >/dev/null
  40 +}
  41 +
  42 +function finally {
  43 + local return_this=$?
  44 + "$@"
  45 + return $return_this
  46 +}
  47 +### </copied>
  48 +
  49 +source ../run_tests.sh
61 build/maven/sample_project_template/pom.xml
... ... @@ -0,0 +1,61 @@
  1 +<project xmlns="http://maven.apache.org/POM/4.0.0"
  2 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  4 + <modelVersion>4.0.0</modelVersion>
  5 +
  6 + <groupId>com.example</groupId>
  7 + <artifactId>junit-dependency-test</artifactId>
  8 + <version>1.0-SNAPSHOT</version>
  9 +
  10 + <properties>
  11 + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  12 + <version.hamcrest>1.2.1</version.hamcrest>
  13 + </properties>
  14 +
  15 + <dependencies>
  16 + <dependency>
  17 + <groupId>junit</groupId>
  18 + <artifactId>___ARTIFACT_ID___</artifactId>
  19 + <version>___VERSION___</version>
  20 + </dependency>
  21 +
  22 + <!--
  23 + This dependency must be included *before* junit, because said JAR
  24 + contains an old hamcrest-core version. This is problematic at
  25 + runtime; see JunitDependencyTest.
  26 + If junit-dep has the right contents, the order should not matter.
  27 + -->
  28 + <dependency>
  29 + <groupId>org.hamcrest</groupId>
  30 + <artifactId>hamcrest-core</artifactId>
  31 + <version>${version.hamcrest}</version>
  32 + </dependency>
  33 +
  34 + <dependency>
  35 + <groupId>org.hamcrest</groupId>
  36 + <artifactId>hamcrest-library</artifactId>
  37 + <version>${version.hamcrest}</version>
  38 + </dependency>
  39 + </dependencies>
  40 +
  41 + <repositories>
  42 + <repository>
  43 + <id>Sonatype</id>
  44 + <url>https://oss.sonatype.org/content/groups/public</url>
  45 + <snapshots><enabled>true</enabled></snapshots>
  46 + <releases><enabled>true</enabled></releases>
  47 + </repository>
  48 + </repositories>
  49 +
  50 + <build>
  51 + <plugins>
  52 + <plugin>
  53 + <artifactId>maven-compiler-plugin</artifactId>
  54 + <configuration>
  55 + <source>1.5</source>
  56 + <target>1.5</target>
  57 + </configuration>
  58 + </plugin>
  59 + </plugins>
  60 + </build>
  61 +</project>
33 build/maven/sample_project_template/src/test/java/JunitDependencyTest.java
... ... @@ -0,0 +1,33 @@
  1 +import org.hamcrest.Matchers;
  2 +import org.junit.Test;
  3 +
  4 +public final class JunitDependencyTest {
  5 + /**
  6 + * JUnit dependency test.
  7 + *
  8 + * This class has three dependencies. These can be on the classpath in
  9 + * different orders. Of the two orderings below, the first one will cause a
  10 + * NoSuchMethodError, while the second one allows the test to pass
  11 + * successfully. See the explanation below for more information.
  12 + *
  13 + * Ordering 1: junit-4.9, hamcrest-core-1.2.1, hamcrest-library-1.2.1.
  14 + * Ordering 2: hamcrest-core-1.2.1, junit-4.9, hamcrest-library-1.2.1.
  15 + */
  16 + @Test
  17 + public void test() {
  18 + /*
  19 + * Note that we call Matchers#anyOf(Matcher<T>, Matcher<? super T>).
  20 + * This method is provided by hamcrest-library-1.2.1. Said module is
  21 + * compiled against hamcrest-core-1.2.1. Matchers#anyOf calls
  22 + * AnyOf#anyOf(Matcher<T>, Matcher<? super T>). The latter method is
  23 + * provided by hamcrest-core-1.2.1, but *not* by hamcrest-core-1.1.
  24 + *
  25 + * However, hamcrest-core-1.1 *does* contain a class called AnyOf. Now,
  26 + * since junit-4.9 incorporates hamcrest-core-1.1 we must make sure that
  27 + * hamcrest-core-1.2.1 is placed *before* junit-4.9 on the classpath.
  28 + * Failure to do so will cause the wrong AnyOf class to be used. The
  29 + * result is a NoSuchMethodError.
  30 + */
  31 + Matchers.anyOf(Matchers.nullValue(), Matchers.notNullValue());
  32 + }
  33 +}
36 build/run_tests.sh
... ... @@ -0,0 +1,36 @@
  1 +# See maven/post_maven_tests.sh for an example use
  2 +
  3 +SCRIPT_NAME=$0
  4 +TEST_NAME=${1:-ALL}
  5 +
  6 +function get_tests() {
  7 + if [ $TEST_NAME == "ALL" ]; then
  8 + part1=function
  9 + part2=TEST_
  10 + grep "$part1 $part2" $SCRIPT_NAME | sed 's/.*\(TEST_[A-Za-z0-9_]*\).*/\1/'
  11 + else
  12 + echo "TEST_${TEST_NAME}"
  13 + fi
  14 +}
  15 +
  16 +function run_tests() {
  17 + local exit_code=0
  18 +
  19 + for t in $(get_tests); do
  20 + echo "RUNNING: $t"
  21 + if "$t"; then
  22 + echo "PASSED: $t"
  23 + else
  24 + echo "FAILED: $t"
  25 + return 1
  26 + fi
  27 + done
  28 +}
  29 +
  30 +if run_tests; then
  31 + echo "ALL TESTS PASSED"
  32 + exit 0
  33 +else
  34 + echo "A TEST FAILED"
  35 + exit 1
  36 +fi
35 build_tests.sh
... ... @@ -1,9 +1,6 @@
1 1 set -e
2 2 set -o pipefail
3 3
4   -SCRIPT_NAME=$0
5   -TEST_NAME=${1:-ALL}
6   -
7 4 function TEST_BUILDING_in_zip {
8 5 version=$(get_junit_version)
9 6 ant zip
@@ -76,34 +73,4 @@ function get_junit_version {
76 73 ant print.version | grep echo | sed 's/.*echo..\([1-9].*\)/\1/'
77 74 }
78 75
79   -function get_tests() {
80   - if [ $TEST_NAME == "ALL" ]; then
81   - part1=function
82   - part2=TEST_
83   - grep "$part1 $part2" $SCRIPT_NAME | sed 's/.*\(TEST_[A-Za-z0-9_]*\).*/\1/'
84   - else
85   - echo "TEST_${TEST_NAME}"
86   - fi
87   -}
88   -
89   -function run_tests() {
90   - local exit_code=0
91   -
92   - for t in $(get_tests); do
93   - echo "RUNNING: $t"
94   - if "$t"; then
95   - echo "PASSED: $t"
96   - else
97   - echo "FAILED: $t"
98   - return 1
99   - fi
100   - done
101   -}
102   -
103   -if run_tests; then
104   - echo "ALL TESTS PASSED"
105   - exit 0
106   -else
107   - echo "A TEST FAILED"
108   - exit 1
109   -fi
  76 +source build/run_tests.sh
93 doc/ReleaseNotes4.10.html
... ... @@ -0,0 +1,93 @@
  1 +<h2>Summary of Changes in version 4.10 [unreleased!]</h2>
  2 +
  3 +<p>A full summary of commits between 4.9 and 4.10 is on <a href="https://github.com/KentBeck/junit/compare/r4.9...4.10">github</a></p>
  4 +
  5 +<h3>junit-dep has correct contents</h3>
  6 +
  7 +<p>junit-dep-4.9.jar incorrectly contained hamcrest classes, which could lead to version conflicts in projects that depend on hamcrest directly. This is fixed in 4.10 [@dsaff, closing gh-309]</p>
  8 +
  9 +<h3>RuleChain</h3>
  10 +
  11 +<p>The RuleChain rule allows ordering of TestRules:</p>
  12 +
  13 +<pre><code>public static class UseRuleChain {
  14 + @Rule
  15 + public TestRule chain= RuleChain
  16 + .outerRule(new LoggingRule("outer rule")
  17 + .around(new LoggingRule("middle rule")
  18 + .around(new LoggingRule("inner rule");
  19 +
  20 + @Test
  21 + public void example() {
  22 + assertTrue(true);
  23 + }
  24 +}
  25 +</code></pre>
  26 +
  27 +<p>writes the log</p>
  28 +
  29 +<pre><code>starting outer rule
  30 +starting middle rule
  31 +starting inner rule
  32 +finished inner rule
  33 +finished middle rule
  34 +finished outer rule
  35 +</code></pre>
  36 +
  37 +<h3>TemporaryFolder</h3>
  38 +
  39 +<ul>
  40 +<li><code>TemporaryFolder#newFolder(String... folderNames)</code> creates recursively deep temporary folders
  41 +[@rodolfoliviero, closing gh-283]</li>
  42 +<li><code>TemporaryFolder#newFile()</code> creates a randomly named new file, and <code>#newFolder()</code> creates a randomly named new folder
  43 +[@Daniel Rothmaler, closing gh-299]</li>
  44 +</ul>
  45 +
  46 +<h3>Theories</h3>
  47 +
  48 +<p>The <code>Theories</code> runner does not anticipate theory parameters that have generic
  49 +types, as reported by github#64. Fixing this won't happen until <code>Theories</code> is
  50 +moved to junit-contrib. In anticipation of this, 4.9.1 adds some of the
  51 +necessary machinery to the runner classes, and deprecates a method that only
  52 +the <code>Theories</code> runner uses, <code>FrameworkMethod</code>#producesType().
  53 +The Common Public License that JUnit is released under is now included
  54 +in the source repository.</p>
  55 +
  56 +<p>Thanks to <code>@pholser</code> for identifying a potential resolution for github#64
  57 +and initiating work on it.</p>
  58 +
  59 +<h3>Bug fixes</h3>
  60 +
  61 +<ul>
  62 +<li>Built-in Rules implementations
  63 +<ul>
  64 +<li>TemporaryFolder should not create files in the current working directory if applying the rule fails
  65 +[@orfjackal, fixing gh-278]</li>
  66 +<li>TestWatcher and TestWatchman should not call failed for AssumptionViolatedExceptions
  67 +[@stefanbirkner, fixing gh-296]</li>
  68 +</ul></li>
  69 +<li>Javadoc bugs
  70 +<ul>
  71 +<li>Assert documentation [@stefanbirkner, fixing gh-134]</li>
  72 +<li>ClassRule [@stefanbirkner, fixing gh-254]</li>
  73 +<li>Parameterized [@stefanbirkner, fixing gh-89]</li>
  74 +<li>Parameterized, again [@orfjackal, fixing gh-285]</li>
  75 +</ul></li>
  76 +<li>Miscellaneous
  77 +<ul>
  78 +<li>Useless code in RunAfters [@stefanbirkner, fixing gh-289]</li>
  79 +<li>Parameterized test classes should be able to have <code>@Category</code> annotations
  80 +[@dsaff, fixing gh-291]</li>
  81 +<li>Error count should be initialized in junit.tests.framework.TestListenerTest [@stefanbirkner, fixing gh-225]</li>
  82 +<li>AssertionFailedError constructor shouldn't call super with null message [@stefanbirkner, fixing gh-318]</li>
  83 +<li>Clearer error message for non-static inner test classes [@stefanbirkner, fixing gh-42]</li>
  84 +</ul></li>
  85 +</ul>
  86 +
  87 +<h3>Minor changes</h3>
  88 +
  89 +<ul>
  90 +<li>Description, Result and Failure are Serializable [@ephox-rob, closing gh-101]</li>
  91 +<li>FailOnTimeout is reusable, allowing for retrying Rules [@stefanbirkner, closing gh-265]</li>
  92 +<li>New <code>ErrorCollector.checkThat</code> overload, that allows you to specify a reason [@drothmaler, closing gh-300]</li>
  93 +</ul>
84 doc/ReleaseNotes4.10.txt
... ... @@ -0,0 +1,84 @@
  1 +## Summary of Changes in version 4.10 ##
  2 +
  3 +Thanks to a full cast of contributors of bug fixes and new features.
  4 +
  5 +A full summary of commits between 4.9 and 4.10 is on [github](https://github.com/KentBeck/junit/compare/r4.9...4.10)
  6 +
  7 +### junit-dep has correct contents ###
  8 +
  9 +junit-dep-4.9.jar incorrectly contained hamcrest classes, which could lead to version conflicts in projects that depend on hamcrest directly. This is fixed in 4.10 [@dsaff, closing gh-309]
  10 +
  11 +### RuleChain ###
  12 +
  13 +The RuleChain rule allows ordering of TestRules:
  14 +
  15 + public static class UseRuleChain {
  16 + @Rule
  17 + public TestRule chain= RuleChain
  18 + .outerRule(new LoggingRule("outer rule")
  19 + .around(new LoggingRule("middle rule")
  20 + .around(new LoggingRule("inner rule");
  21 +
  22 + @Test
  23 + public void example() {
  24 + assertTrue(true);
  25 + }
  26 + }
  27 +
  28 +writes the log
  29 +
  30 + starting outer rule
  31 + starting middle rule
  32 + starting inner rule
  33 + finished inner rule
  34 + finished middle rule
  35 + finished outer rule
  36 +
  37 +### TemporaryFolder ###
  38 +
  39 +- `TemporaryFolder#newFolder(String... folderNames)` creates recursively deep temporary folders
  40 + [@rodolfoliviero, closing gh-283]
  41 +- `TemporaryFolder#newFile()` creates a randomly named new file, and `#newFolder()` creates a randomly named new folder
  42 + [@Daniel Rothmaler, closing gh-299]
  43 +
  44 +### Theories ###
  45 +
  46 +The `Theories` runner does not anticipate theory parameters that have generic
  47 +types, as reported by github#64. Fixing this won't happen until `Theories` is
  48 +moved to junit-contrib. In anticipation of this, 4.9.1 adds some of the
  49 +necessary machinery to the runner classes, and deprecates a method that only
  50 +the `Theories` runner uses, `FrameworkMethod`#producesType().
  51 +The Common Public License that JUnit is released under is now included
  52 +in the source repository.
  53 +
  54 +Thanks to `@pholser` for identifying a potential resolution for github#64
  55 +and initiating work on it.
  56 +
  57 +### Bug fixes ###
  58 +
  59 +- Built-in Rules implementations
  60 + - TemporaryFolder should not create files in the current working directory if applying the rule fails
  61 + [@orfjackal, fixing gh-278]
  62 + - TestWatcher and TestWatchman should not call failed for AssumptionViolatedExceptions
  63 + [@stefanbirkner, fixing gh-296]
  64 +- Javadoc bugs
  65 + - Assert documentation [@stefanbirkner, fixing gh-134]
  66 + - ClassRule [@stefanbirkner, fixing gh-254]
  67 + - Parameterized [@stefanbirkner, fixing gh-89]
  68 + - Parameterized, again [@orfjackal, fixing gh-285]
  69 +- Miscellaneous
  70 + - Useless code in RunAfters [@stefanbirkner, fixing gh-289]
  71 + - Parameterized test classes should be able to have `@Category` annotations
  72 + [@dsaff, fixing gh-291]
  73 + - Error count should be initialized in junit.tests.framework.TestListenerTest [@stefanbirkner, fixing gh-225]
  74 + - AssertionFailedError constructor shouldn't call super with null message [@stefanbirkner, fixing gh-318]
  75 + - Clearer error message for non-static inner test classes [@stefanbirkner, fixing gh-42]
  76 +
  77 +### Minor changes ###
  78 +
  79 +- Description, Result and Failure are Serializable [@ephox-rob, closing gh-101]
  80 +- FailOnTimeout is reusable, allowing for retrying Rules [@stefanbirkner, closing gh-265]
  81 +- New `ErrorCollector.checkThat` overload, that allows you to specify a reason [@drothmaler, closing gh-300]
  82 +
  83 +
  84 +
1  doc/ReleaseNotes4.11.html
... ... @@ -0,0 +1 @@
  1 +<h2>Summary of Changes in version 4.11 [unreleased!]</h2>
1  doc/ReleaseNotes4.11.txt
... ... @@ -0,0 +1 @@
  1 +## Summary of Changes in version 4.11 [unreleased!] ##
14 doc/ReleaseNotes4.9.1.txt
... ... @@ -0,0 +1,14 @@
  1 +## Summary of Changes in version 4.9.1 [unreleased!] ##
  2 +
  3 +### Theories ###
  4 +
  5 +The `Theories` runner does not anticipate theory parameters that have generic
  6 +types, as reported by github#64. Fixing this won't happen until `Theories` is
  7 +moved to junit-contrib. In anticipation of this, 4.9.1 adds some of the
  8 +necessary machinery to the runner classes, and deprecates a method that only
  9 +the `Theories` runner uses, `FrameworkMethod`#producesType().
  10 +The Common Public License that JUnit is released under is now included
  11 +in the source repository.
  12 +
  13 +Thanks to `@pholser` for identifying a potential resolution for github#64
  14 +and initiating work on it.
2  doc/ReleaseNotes4.9.html
... ... @@ -1,4 +1,4 @@
1   -<h2>Summary of Changes in version 4.9 [unreleased!]</h2>
  1 +<h2>Summary of Changes in version 4.9, final</h2>
2 2
3 3 <p>Release theme: Test-class and suite level Rules.</p>
4 4
2  doc/ReleaseNotes4.9.txt
... ... @@ -1,4 +1,4 @@
1   -## Summary of Changes in version 4.9 [unreleased!] ##
  1 +## Summary of Changes in version 4.9, final ##
2 2
3 3 Release theme: Test-class and suite level Rules.
4 4
12 pom-template.xml.asc
Source Rendered
... ... @@ -1,12 +0,0 @@
1   ------BEGIN PGP SIGNATURE-----
2   -Version: GnuPG/MacGPG2 v2.0.17 (Darwin)
3   -Comment: GPGTools - http://gpgtools.org
4   -
5   -iQEcBAABAgAGBQJNmdc8AAoJEIiqH+6DGn6J1GwH/j7bKXkEJuzC3JfL8cE5WJSt
6   -5Ld7PP8QbXYB1Ko2X7o4cofWfaWDI8/j723LzKPW8UNs16m+jILMMvQXYY+VW/XV
7   -UVm/wRY+fjgjoYb2HrREKKP/M2bO4hSHjVQxPT6nga33kKCfoBQ27tVaWdQe01/Q
8   -siQfhKVekK21D+Odxd7TqDlSi1CN7M5HsLms6YufXwoJmjZdtiCrFlFlPBQy8vBA
9   -LwjmbDCpe85rWqwsOSUev5p2MA+IWX0OM6D2b1kOWYjhuGrpLg38lpcJm3yGILH/
10   -OewOxsvYOXoxjJ8eaEljvbW+E1+rBxwNbd24T7yRFDA/pUUx9Dz2YYtIo69NCSg=
11   -=wLGS
12   ------END PGP SIGNATURE-----
6 src/main/java/junit/framework/AssertionFailedError.java
@@ -11,6 +11,10 @@ public AssertionFailedError() {
11 11 }
12 12
13 13 public AssertionFailedError(String message) {
14   - super(message);
  14 + super(defaultString(message));
  15 + }
  16 +
  17 + private static String defaultString(String message) {
  18 + return message == null ? "" : message;
15 19 }
16 20 }
3  src/main/java/junit/framework/TestSuite.java
@@ -10,6 +10,7 @@
10 10 import java.util.Enumeration;
11 11 import java.util.List;
12 12 import java.util.Vector;
  13 +import org.junit.internal.MethodSorter;
13 14
14 15 /**
15 16 * <p>A <code>TestSuite</code> is a <code>Composite</code> of Tests.
@@ -146,7 +147,7 @@ private void addTestsFromTestCase(final Class<?> theClass) {
146 147 Class<?> superClass= theClass;
147 148 List<String> names= new ArrayList<String>();
148 149 while (Test.class.isAssignableFrom(superClass)) {
149   - for (Method each : superClass.getDeclaredMethods())
  150 + for (Method each : MethodSorter.getDeclaredMethods(superClass))
150 151 addTestMethod(each, names, theClass);
151 152 superClass= superClass.getSuperclass();
152 153 }
2  src/main/java/junit/runner/Version.java
@@ -9,7 +9,7 @@ private Version() {
9 9 }
10 10
11 11 public static String id() {
12   - return "4.9b3";
  12 + return "4.11-SNAPSHOT";
13 13 }
14 14
15 15 public static void main(String[] args) {
18 src/main/java/org/junit/Assert.java
@@ -474,7 +474,7 @@ static public void assertEquals(String message, long expected, long actual) {
474 474
475 475 /**
476 476 * @deprecated Use
477   - * <code>assertEquals(double expected, double actual, double epsilon)</code>
  477 + * <code>assertEquals(double expected, double actual, double delta)</code>
478 478 * instead
479 479 */
480 480 @Deprecated
@@ -484,7 +484,7 @@ static public void assertEquals(double expected, double actual) {
484 484
485 485 /**
486 486 * @deprecated Use
487   - * <code>assertEquals(String message, double expected, double actual, double epsilon)</code>
  487 + * <code>assertEquals(String message, double expected, double actual, double delta)</code>
488 488 * instead
489 489 */
490 490 @Deprecated
@@ -721,6 +721,11 @@ public static void assertEquals(Object[] expecteds, Object[] actuals) {
721 721 * // got value: &lt;0&gt;
722 722 * assertThat(0, is(not(1))) // passes
723 723 * </pre>
  724 + *
  725 + * <code>org.hamcrest.Matcher</code> does not currently document the meaning
  726 + * of its type parameter <code>T</code>. This method assumes that a matcher
  727 + * typed as <code>Matcher&lt;T&gt;</code> can be meaningfully applied only
  728 + * to values that could be assigned to a variable of type <code>T</code>.
724 729 *
725 730 * @param <T>
726 731 * the static type accepted by the matcher (this can flag obvious
@@ -734,7 +739,7 @@ public static void assertEquals(Object[] expecteds, Object[] actuals) {
734 739 * @see org.hamcrest.CoreMatchers
735 740 * @see org.junit.matchers.JUnitMatchers
736 741 */
737   - public static <T> void assertThat(T actual, Matcher<T> matcher) {
  742 + public static <T> void assertThat(T actual, Matcher<? super T> matcher) {
738 743 assertThat("", actual, matcher);
739 744 }
740 745
@@ -753,6 +758,11 @@ public static void assertEquals(Object[] expecteds, Object[] actuals) {
753 758 * assertThat(&quot;Zero is one&quot;, 0, is(not(1))) // passes
754 759 * </pre>
755 760 *
  761 + * <code>org.hamcrest.Matcher</code> does not currently document the meaning
  762 + * of its type parameter <code>T</code>. This method assumes that a matcher
  763 + * typed as <code>Matcher&lt;T&gt;</code> can be meaningfully applied only
  764 + * to values that could be assigned to a variable of type <code>T</code>.
  765 + *
756 766 * @param reason
757 767 * additional information about the error
758 768 * @param <T>
@@ -768,7 +778,7 @@ public static void assertEquals(Object[] expecteds, Object[] actuals) {
768 778 * @see org.junit.matchers.JUnitMatchers
769 779 */
770 780 public static <T> void assertThat(String reason, T actual,
771   - Matcher<T> matcher) {
  781 + Matcher<? super T> matcher) {
772 782 if (!matcher.matches(actual)) {
773 783 Description description= new StringDescription();
774 784 description.appendText(reason);
38 src/main/java/org/junit/ClassRule.java
@@ -6,8 +6,9 @@
6 6 import java.lang.annotation.Target;
7 7
8 8 /**
9   - * Annotates static fields that contain rules. Such a field must be public,
10   - * static, and a subtype of {@link org.junit.rules.TestRule}.
  9 + * Annotates static fields that contain rules or methods that return them. A field must be public,
  10 + * static, and a subtype of {@link org.junit.rules.TestRule}. A method must be public static, and return
  11 + * a subtype of {@link org.junit.rules.TestRule}
11 12 * The {@link org.junit.runners.model.Statement} passed
12 13 * to the {@link org.junit.rules.TestRule} will run any {@link BeforeClass} methods,
13 14 * then the entire body of the test class (all contained methods, if it is
@@ -25,13 +26,13 @@
25 26 * If there are multiple
26 27 * annotated {@link ClassRule}s on a class, they will be applied in an order
27 28 * that depends on your JVM's implementation of the reflection API, which is
28   - * undefined, in general.
  29 + * undefined, in general. However, Rules defined by fields will always be applied
  30 + * before Rules defined by methods.
29 31 *
30 32 * For example, here is a test suite that connects to a server once before
31 33 * all the test classes run, and disconnects after they are finished:
32 34 *
33 35 * <pre>
34   - *
35 36 * &#064;RunWith(Suite.class)
36 37 * &#064;SuiteClasses({A.class, B.class, C.class})
37 38 * public class UsesExternalResource {
@@ -52,9 +53,34 @@
52 53 * }
53 54 * </pre>
54 55 *
55   - * For more information and more examples, see {@link TestRule}.
  56 + * and the same using a method
  57 + *
  58 + * <pre>
  59 + * &#064;RunWith(Suite.class)
  60 + * &#064;SuiteClasses({A.class, B.class, C.class})
  61 + * public class UsesExternalResource {
  62 + * public static Server myServer= new Server();
  63 + *
  64 + * &#064;ClassRule
  65 + * public static ExternalResource getResource() {
  66 + * return new ExternalResource() {
  67 + * &#064;Override
  68 + * protected void before() throws Throwable {
  69 + * myServer.connect();
  70 + * }
  71 + *
  72 + * &#064;Override
  73 + * protected void after() {
  74 + * myServer.disconnect();
  75 + * }
  76 + * };
  77 + * }
  78 + * }
  79 + * </pre>
  80 + *
  81 + * For more information and more examples, see {@link org.junit.rules.TestRule}.
56 82 */
57 83 @Retention(RetentionPolicy.RUNTIME)
58   -@Target({ElementType.FIELD})
  84 +@Target({ElementType.FIELD, ElementType.METHOD})
59 85 public @interface ClassRule {
60 86 }
35 src/main/java/org/junit/Rule.java
@@ -6,15 +6,18 @@
6 6 import java.lang.annotation.Target;
7 7
8 8 /**
9   - * Annotates fields that contain rules. Such a field must be public, not
10   - * static, and a subtype of {@link org.junit.rules.TestRule}.
  9 + * Annotates fields that contain rules or methods that return a rule. A field must be public, not
  10 + * static, and a subtype of {@link org.junit.rules.TestRule}. A method must be public, not static
  11 + * and must return a subtype of {@link org.junit.rules.TestRule}.
11 12 * The {@link org.junit.runners.model.Statement} passed
12 13 * to the {@link org.junit.rules.TestRule} will run any {@link Before} methods,
13 14 * then the {@link Test} method, and finally any {@link After} methods,
14 15 * throwing an exception if any of these fail. If there are multiple
15   - * annotated {@link Rule}s on a class, they will be applied in an order
  16 + * annotated {@link Rule}s on a class, they will be applied in order of fields first, then methods.
  17 + * However, if there are mutliple fields (or methods) they will be applied in an order
16 18 * that depends on your JVM's implementation of the reflection API, which is
17   - * undefined, in general.
  19 + * undefined, in general. Rules defined by fields will always be applied
  20 + * before Rules defined by methods.
18 21 *
19 22 * For example, here is a test class that creates a temporary folder before
20 23 * each test method, and deletes it after each:
@@ -33,15 +36,35 @@
33 36 * }
34 37 * </pre>
35 38 *
  39 + * And the same using a method.
  40 + *
  41 + * <pre>
  42 + * public static class HasTempFolder {
  43 + * private TemporaryFolder folder= new TemporaryFolder();
  44 + *
  45 + * &#064;Rule
  46 + * public TemporaryFolder getFolder() {
  47 + * return folder;
  48 + * }
  49 + *
  50 + * &#064;Test
  51 + * public void testUsingTempFolder() throws IOException {
  52 + * File createdFile= folder.newFile(&quot;myfile.txt&quot;);
  53 + * File createdFolder= folder.newFolder(&quot;subfolder&quot;);
  54 + * // ...
  55 + * }
  56 + * }
  57 + * </pre>
  58 + *
36 59 * For more information and more examples, see
37 60 * {@link org.junit.rules.TestRule}.
38 61 *
39 62 * Note: for backwards compatibility, this annotation may also mark
40   - * fields of type {@link org.junit.rules.MethodRule}, which will be honored. However,
  63 + * fields or methods of type {@link org.junit.rules.MethodRule}, which will be honored. However,
41 64 * this is a deprecated interface and feature.
42 65 */
43 66 @Retention(RetentionPolicy.RUNTIME)
44   -@Target({ElementType.FIELD})
  67 +@Target({ElementType.FIELD, ElementType.METHOD})
45 68 public @interface Rule {
46 69
47 70 }
1  src/main/java/org/junit/experimental/theories/internal/AllMembersSupplier.java
@@ -80,6 +80,7 @@ private void addMultiPointMethods(List<PotentialAssignment> list) {
80 80 }
81 81 }
82 82
  83 + @SuppressWarnings("deprecation")
83 84 private void addSinglePointMethods(ParameterSignature sig,
84 85 List<PotentialAssignment> list) {
85 86 for (FrameworkMethod dataPointMethod : fClass
35 src/main/java/org/junit/internal/MethodSorter.java
... ... @@ -0,0 +1,35 @@
  1 +package org.junit.internal;
  2 +
  3 +import java.lang.reflect.Method;
  4 +import java.util.Arrays;
  5 +import java.util.Comparator;
  6 +
  7 +public class MethodSorter {
  8 +
  9 + /**
  10 + * Gets declared methods of a class in a predictable order.
  11 + * Using the JVM order is unwise since the Java platform does not
  12 + * specify any particular order, and in fact JDK 7 returns a more or less
  13 + * random order; well-written test code would not assume any order, but some
  14 + * does, and a predictable failure is better than a random failure on
  15 + * certain platforms. Uses an unspecified but deterministic order.
  16 + * @param clazz a class
  17 + * @return same as {@link Class#getDeclaredMethods} but sorted
  18 + * @see <a href="http://bugs.sun.com/view_bug.do?bug_id=7023180">JDK
  19 + * (non-)bug #7023180</a>
  20 + */
  21 + public static Method[] getDeclaredMethods(Class<?> clazz) {
  22 + Method[] methods = clazz.getDeclaredMethods();
  23 + Arrays.sort(methods, new Comparator<Method>() {
  24 + @Override public int compare(Method m1, Method m2) {
  25 + int i1 = m1.getName().hashCode();
  26 + int i2 = m2.getName().hashCode();
  27 + return i1 != i2 ? i1 - i2 : m1.toString().compareTo(m2.toString());
  28 + }
  29 + });
  30 + return methods;
  31 + }
  32 +
  33 + private MethodSorter() {}
  34 +
  35 +}
3  src/main/java/org/junit/internal/matchers/TypeSafeMatcher.java
@@ -3,6 +3,7 @@
3 3 import java.lang.reflect.Method;
4 4
5 5 import org.hamcrest.BaseMatcher;
  6 +import org.junit.internal.MethodSorter;
6 7
7 8 /**
8 9 * Convenient base class for Matchers that require a non-null value of a specific type.
@@ -26,7 +27,7 @@ protected TypeSafeMatcher() {
26 27
27 28 private static Class<?> findExpectedType(Class<?> fromClass) {
28 29 for (Class<?> c = fromClass; c != Object.class; c = c.getSuperclass()) {
29   - for (Method method : c.getDeclaredMethods()) {
  30 + for (Method method : MethodSorter.getDeclaredMethods(c)) {
30 31 if (isMatchesSafelyMethod(method)) {
31 32 return method.getParameterTypes()[0];
32 33 }
3  src/main/java/org/junit/internal/runners/TestClass.java
@@ -11,6 +11,7 @@
11 11 import org.junit.Before;
12 12 import org.junit.BeforeClass;
13 13 import org.junit.Test;
  14 +import org.junit.internal.MethodSorter;
14 15 import org.junit.runners.BlockJUnit4ClassRunner;
15 16
16 17 /**
@@ -41,7 +42,7 @@ public TestClass(Class<?> klass) {
41 42 public List<Method> getAnnotatedMethods(Class<? extends Annotation> annotationClass) {
42 43 List<Method> results= new ArrayList<Method>();
43 44 for (Class<?> eachClass : getSuperClasses(fClass)) {
44   - Method[] methods= eachClass.getDeclaredMethods();
  45 + Method[] methods= MethodSorter.getDeclaredMethods(eachClass);
45 46 for (Method eachMethod : methods) {
46 47 Annotation annotation= eachMethod.getAnnotation(annotationClass);
47 48 if (annotation != null && ! isShadowed(eachMethod, results))
112 src/main/java/org/junit/internal/runners/rules/RuleFieldValidator.java
... ... @@ -0,0 +1,112 @@
  1 +package org.junit.internal.runners.rules;
  2 +
  3 +import java.lang.annotation.Annotation;
  4 +import java.util.List;
  5 +
  6 +import org.junit.ClassRule;
  7 +import org.junit.Rule;
  8 +import org.junit.rules.MethodRule;
  9 +import org.junit.rules.TestRule;
  10 +import org.junit.runners.model.FrameworkMember;
  11 +import org.junit.runners.model.TestClass;
  12 +
  13 +/**
  14 + * A RuleFieldValidator validates the rule fields of a
  15 + * {@link org.junit.runners.model.TestClass}. All reasons for rejecting the
  16 + * {@code TestClass} are written to a list of errors.
  17 + *
  18 + * There are four slightly different validators. The {@link #CLASS_RULE_VALIDATOR}
  19 + * validates fields with a {@link ClassRule} annotation and the
  20 + * {@link #RULE_VALIDATOR} validates fields with a {@link Rule} annotation.
  21 + *
  22 + * The {@link #CLASS_RULE_METHOD_VALIDATOR}
  23 + * validates methods with a {@link ClassRule} annotation and the
  24 + * {@link #RULE_METHOD_VALIDATOR} validates methods with a {@link Rule} annotation.
  25 + */
  26 +public enum RuleFieldValidator {
  27 + /**
  28 + * Validates fields with a {@link ClassRule} annotation.
  29 + */
  30 + CLASS_RULE_VALIDATOR(ClassRule.class, false, true),
  31 + /**
  32 + * Validates fields with a {@link Rule} annotation.
  33 + */
  34 + RULE_VALIDATOR(Rule.class, false, false),
  35 + /**
  36 + * Validates methods with a {@link ClassRule} annotation.
  37 + */
  38 + CLASS_RULE_METHOD_VALIDATOR(ClassRule.class, true, true),
  39 + /**
  40 + * Validates methods with a {@link Rule} annotation.
  41 + */
  42 + RULE_METHOD_VALIDATOR(Rule.class, true, false);
  43 +
  44 + private final Class<? extends Annotation> fAnnotation;
  45 +
  46 + private final boolean fStaticMembers;
  47 + private final boolean fMethods;
  48 +
  49 + private RuleFieldValidator(Class<? extends Annotation> annotation,
  50 + boolean methods, boolean fStaticMembers) {
  51 + this.fAnnotation= annotation;
  52 + this.fStaticMembers= fStaticMembers;
  53 + this.fMethods= methods;
  54 + }
  55 +
  56 + /**
  57 + * Validate the {@link org.junit.runners.model.TestClass} and adds reasons
  58 + * for rejecting the class to a list of errors.
  59 + * @param target the {@code TestClass} to validate.
  60 + * @param errors the list of errors.
  61 + */
  62 + public void validate(TestClass target, List<Throwable> errors) {
  63 + List<? extends FrameworkMember<?>> members= fMethods ? target.getAnnotatedMethods(fAnnotation)
  64 + : target.getAnnotatedFields(fAnnotation);
  65 +
  66 + for (FrameworkMember<?> each : members)
  67 + validateMember(each, errors);
  68 + }
  69 +
  70 + private void validateMember(FrameworkMember<?> member, List<Throwable> errors) {
  71 + validateStatic(member, errors);
  72 + validatePublic(member, errors);
  73 + validateTestRuleOrMethodRule(member, errors);
  74 + }
  75 +
  76 + private void validateStatic(FrameworkMember<?> member,
  77 + List<Throwable> errors) {
  78 + if (fStaticMembers && !member.isStatic())
  79 + addError(errors, member, "must be static.");
  80 + if (!fStaticMembers && member.isStatic())
  81 + addError(errors, member, "must not be static.");
  82 + }
  83 +
  84 + private void validatePublic(FrameworkMember<?> member, List<Throwable> errors) {
  85 + if (!member.isPublic())
  86 + addError(errors, member, "must be public.");
  87 + }
  88 +
  89 + private void validateTestRuleOrMethodRule(FrameworkMember<?> member,
  90 + List<Throwable> errors) {
  91 + if (!isMethodRule(member) && !isTestRule(member))
  92 + addError(errors, member, fMethods ?
  93 + "must return an implementation of MethodRule or TestRule." :
  94 + "must implement MethodRule or TestRule.");
  95 + }
  96 +
  97 + private boolean isTestRule(FrameworkMember<?> member) {
  98 + return TestRule.class.isAssignableFrom(member.getType());
  99 + }
  100 +