diff --git a/.gitattributes b/.gitattributes index d643f847b4da..43cf4920bd13 100644 --- a/.gitattributes +++ b/.gitattributes @@ -3,6 +3,7 @@ *.GIF binary *.jar binary *.png binary +*.jpg binary *.svg text eol=lf # These files do not have unix line endings. Do not normalize them for now. diff --git a/.gitignore b/.gitignore index 50691cf3bd78..54f5aa75e33f 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ MaxCore.max *.iws out java.hprof.txt +.DS_Store diff --git a/.travis.settings.xml b/.travis.settings.xml new file mode 100644 index 000000000000..332f39daa17b --- /dev/null +++ b/.travis.settings.xml @@ -0,0 +1,22 @@ + + + + central + GCS Maven Central mirror + https://maven-central.storage-download.googleapis.com/maven2/ + google-maven-central + + + + + junit-snapshot-repo + ${env.OSSRH_USERNAME} + ${env.OSSRH_PASSWORD} + + + junit-releases-repo + ${env.OSSRH_USERNAME} + ${env.OSSRH_PASSWORD} + + + diff --git a/.travis.yml b/.travis.yml index 9c5ddddff2a6..3f44bc023143 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,23 +1,69 @@ +dist: trusty + language: java -install: - # Download dependencies with JDK 8 because Mave Central supports - # TLS 1.2 only but OpenJDK 6 does not. - - export ORIGINAL_JAVA_HOME=$JAVA_HOME - - jdk_switcher use oraclejdk8 - - ./mvnw test -DskipTests - # Delete all files created with JDK 8 - - ./mvnw clean - # Restore desired JDK - - export JAVA_HOME=$ORIGINAL_JAVA_HOME - # Run original install command but without GPG signing - - ./mvnw install -DskipTests + script: ./mvnw verify javadoc:javadoc site:site -addons: - apt: - packages: - - openjdk-6-jdk -jdk: - - oraclejdk9 - - oraclejdk8 - - openjdk7 - - openjdk6 + +install: +- ./mvnw --version + +stages: + - test + - name: deploy + if: (branch = master) AND (NOT type IN (pull_request)) + +jobs: + include: + - name: Java 6 + env: JDK=openjdk6 + addons: + apt: + packages: + - openjdk-6-jdk + install: + # Download dependencies with JDK 8 because Mave Central supports + # TLS 1.2 only but OpenJDK 6 does not. + - export ORIGINAL_JAVA_HOME=$JAVA_HOME + - jdk_switcher use oraclejdk8 + - ./mvnw test -DskipTests + # Delete all files created with JDK 8 + - ./mvnw clean + # Restore desired JDK + - export JAVA_HOME=$ORIGINAL_JAVA_HOME + - jdk_switcher use openjdk6 + - ./mvnw --version + - name: Java 7 + jdk: openjdk7 + - name: Java 8 + jdk: oraclejdk8 + - name: Java 9 + jdk: oraclejdk9 + - name: Java 10 + jdk: openjdk10 + - name: Java 11 + jdk: openjdk11 + - stage: deploy + name: "Publish snapshot artifacts" + addons: + apt: + packages: + - openjdk-6-jdk + install: + # Download dependencies with JDK 8 because Mave Central supports + # TLS 1.2 only but OpenJDK 6 does not. + - export ORIGINAL_JAVA_HOME=$JAVA_HOME + - jdk_switcher use oraclejdk8 + - ./mvnw test -DskipTests + # Delete all files created with JDK 8 + - ./mvnw clean + # Restore desired JDK + - export JAVA_HOME=$ORIGINAL_JAVA_HOME + - jdk_switcher use openjdk6 + - ./mvnw --version + env: + - JDK=openjdk6 + # OSSRH_USERNAME + - secure: griGZYDtqDMRUaYex/uAnpkWIQ/yodM6IOn4G8izWKpyGLeCxyXBG0FDcVo81xRq/9mMevj2idyW/xNP/HAQ45G4pyJUk/vTSMkNslzVjr7OBEtQQCN8XahSaOO0l0CJ5lzA6LdwWg7uDaf9znqZ0slt81u0S1NJmUZyYeUEim0= + # OSSRH_PASSWORD + - secure: EM7Z2M09HvLJXYJaeD/YmeF5A6tqavG2tBBeDcFZ7C6k0AI/wApe882pEMMoUG06xufKfSlt7WFJxoyU3M+fPOpeK5qZpJQxsHWnNJwbcbKzqMpM9mDsgIL9rtAvm9MuIIbIY2spiT0Cx3sHdh5qofaJHPL/u8Or5L9tE8FV1ew= + script: ./mvnw deploy --batch-mode --activate-profiles generate-docs --settings .travis.settings.xml diff --git a/BUILDING b/BUILDING index fa39b86e49cd..496eeb03b820 100644 --- a/BUILDING +++ b/BUILDING @@ -2,7 +2,7 @@ BUILDING FROM GITHUB: ===================== git clone https://github.com/junit-team/junit4.git -cd junit +cd junit4 mvn install BUILDING FROM JARS OR ZIPS: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 20ede553e241..8a327b77ddba 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -31,14 +31,13 @@ a good idea to add a comment to the bug to make sure that there's agreement on h ## Limitations -The JUnit team is not accepting changes to the code under the following paths : +The JUnit team is not accepting changes to the code under the following paths: * `src/main/java/junit` * `test/java/junit/tests/framework` * `test/java/junit/tests/extensions` -The reasoning is that the JUnit team feels that our users should focus on using either the JUnit4 APIs -or the soon-to-be-released JUnit4 APIs. +The reasoning is that the JUnit team feels that our users should focus on using either the JUnit4 or JUnit5 APIs. The team is also reluctant to accept changes that only update code from one code style to another. Generally the code in JUnit was approved by at least one person, so two people agreed that the style was reasonable. diff --git a/KEYS b/KEYS new file mode 100644 index 000000000000..0433e72f3343 --- /dev/null +++ b/KEYS @@ -0,0 +1,70 @@ +This file contains the PGP key that is used to sign releases. + +Importing: `pgp < KEYS` or `gpg --import KEYS` + +Adding a key: +`pgp -kxa >> KEYS`, +or `(pgpk -ll && pgpk -xa ) >> KEYS`, +or `(gpg --list-sigs && gpg --armor --export ) >> KEYS` + +================================ + +pub rsa4096 2018-04-08 [SC] + FF6E2C001948C5F2F38B0CC385911F425EC61B51 +uid [ unknown] Open Source Development +sig 3 85911F425EC61B51 2018-04-08 Open Source Development +sub rsa4096 2018-04-08 [E] +sig 85911F425EC61B51 2018-04-08 Open Source Development + +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQINBFrKW9IBEACkqUvM7hU1WqOOeb1gZ7pUsRliHuoUvYIrd+hdp+qhPmJ0NG0W +YhZK5UtJBmqvtHKRkbwYxUuya9zlBmCfQFf0GpFKJ65JSrPSkZADI3aZ4aUkxIUw +nIRoUHucmr10Xftpebr/zaJk5oR8RdaL5FapapmcZmAaHR9CDWB8XtI318u314jq +M5rKatnAZMERoPugOvvuAOz4bfZKwdfCmZKfYUM/TMSrSinXrGExSW6z4RhtqmpC +E5M/7OoVfvDynVJKqNazqgigpmMNhOyzAhQsiKh1K0akyxTZbjeZKsdYfhCXvq0q +k9+KM/cTllQ54MPnFWiObLkHeK0Waw8bI/vAJ4h4x/XM9iGYpkXv7F2/FVsHQdPe +YJcwD/CkD8KHyiPaRKMeApiUtZsdAHU0L4X/lNmcooea/7ipskruUgwcm+RdLhRZ +P949t1e7nqDZfpEHy90NiFxmlRAPSNqBLwefxY/hwBgog2jabDALJVcLCMosFWPj +MQhFlGSIODiVcW8folGIjzkyNZbNMWkwnl2QnWp/h2TAwYQJOMqcv2MG9o5pyzpx +97Iz1ngq1FlM/gJnGnNUydP2tAjT2L2U3MP1uX/EdRChdgPqdolqYhdFfwCr0Fpf +W527bUZpReHCEiQ29ABSnQ711mO+d9+qM6edRyHUoBWz89IHt8sCunuvNwARAQAB +tC1PcGVuIFNvdXJjZSBEZXZlbG9wbWVudCA8bWFpbEBtYXJjcGhpbGlwcC5kZT6J +Ak4EEwEIADgWIQT/biwAGUjF8vOLDMOFkR9CXsYbUQUCWspb0gIbAwULCQgHAgYV +CAkKCwIEFgIDAQIeAQIXgAAKCRCFkR9CXsYbUQyRD/9xm3BqdpWcRCE5UyB6nbwV +8TgzMmbOhpFhhcjzobly/pKAbcofKsjhreENJkfBVUo+zAFx21ToC5tbH20wRtIE +vQVCP6sAIzhYWU1ohafqVFP4+PztNBuYTnS6vGvSwzp0IXLIIoxSxo0IOED9uUS9 +DTxh1n9NnDLDe2pfjrXBblQtLSW3W5ISDoUvcoyO7Hk1OByW6MNsSoLvXIUNeVhB +ju9TfYxFACJSWBhUxJfgip9Y2GrNBJaYGLZrTAoW1Lh1H1DfLV3wHDClQ1+H+oyx +IOZULEGYY3MgZTd6Ner2yNAUCB7gVa50NiCZXCS74m+XzMrTEsdWjSMUaOe+dL0I +9MCrgi4ycUHWIfTKx9gGlIOo3hSDMN+8Nj33XPjLT8kcfoFeUX8jTOvC1HFfTuQJ +x2t/dKHizdrS3F6A/JQa7v8GNTrZFnEXkwgRTf3ccLoo3gPwzNJeCm2xNjvne1VH +fvxzwNmq8M05oicEigvEed2VMStMhvT7dSiMAf66rEJHjjaHAoNqbLDEATYrWUP2 +I52txHSSxSJohxVP6Ec6dERnqqYi0mVyzBPo7mmFFBisq74w8RvZXyzvXE3BTiDL +we1E/Z/AXbtJye9DickQ/G6RFtVLbUHQfzyRS/65JPtlH8rqJr58YWlylGImVLwE +OsKNQrwLZ0UkfaWV7wqr3rkCDQRaylvSARAAnQG636wliEOLkXN662OZS6Qz2+cF +ltCWboq9oX9FnA1PHnTY2cAtwS214RfWZxkjg6Stau+d1Wb8TsF/SUN3eKRSyrkA +xlX0v552vj3xmmfNsslQX47e6aEWZ0du0M8jw7/f7Qxp0InkBfpQwjSg4ECoH4cA +6dOFJIdxBv8dgS4K90HNuIHa+QYfVSVMjGwOjD9St6Pwkbg1sLedITRo59Bbv0J1 +4nE9LdWbCiwNrkDr24jTewdgrDaCpN6msUwcH1E0nYxuKAetHEi2OpgBhaY3RQ6Q +PQB6NywvmD0xRllMqu4hSp70pHFtm8LvJdWOsJ5we3KijHuZzEbBVTTl+2DhNMI0 +KMoh+P/OmyNOfWD8DL4NO3pVv+mPDZn82/eZ3XY1/oSQrpyJaCBjRKasVTtfiA/F +gYqTml6qZMjy6iywg84rLezELgcxHHvjhAKd4CfxyuCCgnGT0iRLFZKw44ZmOUqP +DkyvGRddIyHag1K7UaM/2UMn6iPMy7XWcaFiH5Huhz43SiOdsWGuwNk4dDxHdxmz +Sjps0H5dkfCciOFhEc54AFcGEXCWHXuxVqIq/hwqTmVl1RY+PTcQUIOfx36WW1ix +JQf8TpVxUbooK8vr1jOFF6khorDXoZDJNhI2VKomWp8Y38EPGyiUPZNcnmSiezx+ +MoQwAbeqjFMKG7UAEQEAAYkCNgQYAQgAIBYhBP9uLAAZSMXy84sMw4WRH0JexhtR +BQJaylvSAhsMAAoJEIWRH0JexhtR0LEP/RvYGlaokoosAYI5vNORAiYEc1Ow2McP +I1ZafHhcVxZhlwF48dAC2bYcasDX/PbEdcD6pwo8ZU8eI8Ht0VpRQxeV/sP01m2Y +EpAuyZ6jI7IQQCGcwQdN4qzQJxMAASl9JlplH2NniXV1/994FOtesT59ePMyexm5 +7lzhYXP1PGcdt8dH37r6z3XQu0lHRG/KBn7YhyA3zwJcno324KdBRJiynlc7uqQq ++ZptU9fR1+Nx0uoWZoFMsrQUmY34aAOPJu7jGMTG+VseMH6vDdNhhZs9JOlD/e/V +aF7NyadjOUD4j/ud7c0z2EwqjDKMFTHGbIdawT/7jartT+9yGUO+EmScBMiMuJUT +dCP4YDh3ExRdqefEBff3uE/rAP73ndNYdIVq9U0gY0uSNCD9JPfj4aCN52y9a2pS +7Dg7KB/Z8SH1R9IWP+t0HvVtAILdsLExNFTedJGHRh7uaC7pwRz01iivmtAKYICz +ruqlJie/IdEFFK/sus6fZek29odTrQxx42HGHO5GCNyEdK9jKVAeuZ10vcaNbuBp +iP7sf8/BsiEU4wHE8gjFeUPRiSjnERgXQwfJosLgf/K/SShQn2dCkYZRNF+SWJ6Z +2tQxcW5rpUjtclV/bRVkUX21EYfwA6SMB811mI7AVy8WPXCe8La72ukmaxEGbpJ8 +mdzS2PJko7mm +=l0XA +-----END PGP PUBLIC KEY BLOCK----- diff --git a/README.md b/README.md index 9ad06e6a4403..bb064a44714b 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,4 @@ For more information, please visit: * [Download and Install guide](https://github.com/junit-team/junit4/wiki/Download-and-Install) * [Getting Started](https://github.com/junit-team/junit4/wiki/Getting-started) -[![Latest Build Status](https://junit.ci.cloudbees.com/job/JUnit/badge/icon)](https://junit.ci.cloudbees.com/) - -[![Built on DEV@cloud](http://www.cloudbees.com/sites/default/files/Button-Built-on-CB-1.png)](http://www.cloudbees.com/foss/foss-dev.cb) - +[![Build Status](https://travis-ci.org/junit-team/junit4.svg?branch=master)](https://travis-ci.org/junit-team/junit4) diff --git a/acknowledgements.txt b/acknowledgements.txt index 832c0f005bd3..bbc24dfe041f 100644 --- a/acknowledgements.txt +++ b/acknowledgements.txt @@ -160,4 +160,4 @@ == NOTE: as of September 2011, we have stopped recording contributions here. For a full list of everyone who has contributed great bug reports and code, please see - http://github.com/junit-team/junit + http://github.com/junit-team/junit4 diff --git a/doc/ReleaseNotes4.12.md b/doc/ReleaseNotes4.12.md index 602d6bfa06e8..744ecf369062 100644 --- a/doc/ReleaseNotes4.12.md +++ b/doc/ReleaseNotes4.12.md @@ -155,7 +155,7 @@ thrown.reportMissingExceptionWithMessage("FAIL: Expected exception to be thrown" If a custom failure message is not provided, a default message is used. -### [Pull request #1013:](https://github.com/junit-team/junit/pull/1013) Make ErrorCollector#checkSucceeds generic +### [Pull request #1013:](https://github.com/junit-team/junit4/pull/1013) Make ErrorCollector#checkSucceeds generic The method `ErrorCollector.checkSucceeds()` is now generic. Previously, you could only pass in a `Callable` and it returned `Object`. You can now pass any `Callable` and the @@ -252,6 +252,8 @@ Each test is run in a new _daemon_ thread. If the specified timeout elapses befo ### [Pull request #876:](https://github.com/junit-team/junit4/pull/876) The timeout rule never times out if you pass in a timeout of zero. +A specified timeout of 0 will be interpreted as not set, however tests still launch from separate threads. This can be useful for disabling timeouts in environments where they are dynamically set based on some property. + # Parameterized Tests diff --git a/doc/ReleaseNotes4.13.md b/doc/ReleaseNotes4.13.md index f9dec0ab5925..1baf5b14ca32 100644 --- a/doc/ReleaseNotes4.13.md +++ b/doc/ReleaseNotes4.13.md @@ -1,6 +1,327 @@ -## Summary of changes in version 4.13 [unreleased!] +## Summary of changes in version 4.13 -We collect release notes in the wiki: -https://github.com/junit-team/junit4/wiki/4.13-release-notes +# Assertions -This file will be updated right before release. +### [Pull request #1054:](https://github.com/junit-team/junit/pull/1054) Improved error message for `assertArrayEquals` when multi-dimensional arrays have different lengths + +Previously, JUnit's assertion error message would indicate only that some array lengths _x_ and _y_ were unequal, without indicating whether this pertained to the outer array or some nested array. Now, in case of a length mismatch between two nested arrays, JUnit will tell at which indices they reside. + +### [Pull request #1154](https://github.com/junit-team/junit/pull/1154) and [#1504](https://github.com/junit-team/junit/pull/1504) Add `assertThrows` + +The `Assert` class now includes methods that can assert that a given function call (specified, for instance, as a lambda expression or method reference) results in a particular type of exception being thrown. In addition it returns the exception that was thrown, so that further assertions can be made (e.g. to verify that the message and cause are correct). + +### [Pull request #1300:](https://github.com/junit-team/junit/pull/1300) Show contents of actual array when array lengths differ + +Previously, when comparing two arrays which differ in length, `assertArrayEquals()` would only report that they differ in length. Now, it does the usual array comparison even when arrays differ in length, producing a failure message which combines the difference in length and the first difference in content. Where the content is another array, it is described by its type and length. + +### [Pull request #1315:](https://github.com/junit-team/junit4/pull/1315) `assertArrayEquals` shouldn't throw an NPE when test suites are compiled/run across versions of junit + +A redundant field, `fCause`, was removed on v4.12, and was seemingly harmless because `Throwable#initCause()` could directly initialize `cause` in the constructor. Unfortunately, this backwards incompatible change got aggravated when a test class, compiled with the latest (4.12+), ran with an older version that depended on fCause when building the assertion message[1](#1315-f1). + +This change adds back `fCause`, and overrides `getCause()` to handle forward compatibility[2](#1315-f2). + +To ensure serializability of further changes in `ArrayAssertionFailure` (until excising these fields by a major rev), a unit test now runs against v4.11, v4.12 failures, asserting around `#toString/getCause()`. + +[1] [Issue #1178](https://github.com/junit-team/junit4/issues/1178) details a particular case where gradle v2.2 is packaged with junit v4.11 and is used on running a test, generating test reports, despite specifying a particular version of junit (users would specify v4.12, or v4.+) in the test compile dependencies). + +[2] [Case](https://github.com/junit-team/junit4/pull/1315#issuecomment-222905229) if the test class is compiled with <= v4.11, where only `fCause` is initialized and not `Throwable#cause`, it can now fallback to the field, `fCause`, when building the message. + +### [Pull request #1150:](https://github.com/junit-team/junit4/pull/1150) Deprecate `Assert#assertThat` + +The method `assertThat` is used for writing assertions with Hamcrest. Hamcrest is an independent assertion library and contains an own `assertThat` method in the class `org.hamcrest.MatcherAssert`. It is available both in the old Hamcrest 1.3 release and in the current Hamcrest 2.1. Therefore the JUnit team recommends to use Hamcrest's own `assertThat` directly. + +# Test Runners + +### [Pull request #1037:](https://github.com/junit-team/junit/pull/1037) `BlockJUnit4ClassRunner#createTest` now accepts `FrameworkMethod` + +Subclasses of `BlockJUnit4ClassRunner` can now produce a custom test object based on the `FrameworkMethod` test being executed by implementing the new `createTest(FrameworkMethod)` method. The default implementation calls the existing `createTest()` method. + +### [Pull request #1082](https://github.com/junit-team/junit/pull/1082): Ensure exceptions from `BlockJUnit4ClassRunner.methodBlock()` don't result in unrooted tests + +The introduction of the `runLeaf()` method in `BlockJUnit4ClassRunner` in JUnit 4.9 introduced a regression with regard to exception handling. Specifically, in JUnit 4.9 through 4.12 the invocation of `methodBlock()` is no longer executed within a try-catch block as was the case in previous versions of JUnit. Custom modifications to `methodBlock()` or the methods it invokes may in fact throw exceptions, and such exceptions cause the current test execution to abort immediately. As a result, the failing test method is unrooted in test reports, and subsequent test methods are never invoked. Furthermore, any `RunListener` registered with JUnit is not notified. + +As of JUnit 4.13, the invocation of `methodBlock()` is once again wrapped within a try-catch block. If an exception is _not_ thrown, the resulting `Statement` is passed to `runLeaf()`. If an exception _is_ thrown, it is wrapped in a `Fail` statement which is passed to `runLeaf()`. + +### [Pull request #1286](https://github.com/junit-team/junit/pull/1286): Provide better feedback to the user in case of invalid test classes + +Only one exception per invalid test class is now thrown, rather than one per validation error. +The message of the exception includes all of the validation errors. + +Example: + + org.junit.runners.InvalidTestClassError: Invalid test class 'com.example.MyTest': + 1. Method staticAfterMethod() should not be static + 2. Method staticBeforeMethod() should not be static + +is the exception thrown when running the following test class with any kind of `ParentRunner`: + + public class MyTest { + + @Before + public static void staticBeforeMethod() { .. } + + @After + public static void staticAfterMethod() { .. } + + @Test + public void myTest() { .. } + } + +Validation errors for the same test class now count only once in the failure count. Therefore, in the example above, `Result#getFailureCount` will return 1. + +### [Pull request #1252](https://github.com/junit-team/junit4/pull/1252): Restore ability use ParentRunner lost in separate class loader + +`ParentRunner.getDescription()` now uses the class instance of the test class to create the description +(previously the class instance was loaded using the current classloader). + +### [Pull request #1377](https://github.com/junit-team/junit4/pull/1377): Description produced by Request.classes() shouldn't be null + +When obtaining a `Runner` via [Request.classes(Class... classes)](http://junit.org/junit4/javadoc/4.12/org/junit/runner/Request.html#classes(java.lang.Class...)), that Runner's `Description` will now print "classes" for the root item. This replaces the misleading output of String "null". + +### [Issue #1290](https://github.com/junit-team/junit4/issues/1290): Tests expecting AssumptionViolatedException are now correctly marked as passed + + @Test(expected = AssumptionViolatedException.class) + public void shouldThrowAssumptionViolatedException() { + throw new AssumptionViolatedException("expected"); + } + +This test would previously be marked as skipped; now will be marked as passed. + + +### [Pull request #1465](https://github.com/junit-team/junit/pull/1465): Provide helpful message if parameter cannot be set. + +JUnit throws an exception with a message like + + Cannot set parameter 'name'. Ensure that the the field 'name' is public. + +if a field of a parameterized test is annotated `@Parameter`, but its visibility is not public. Before an IllegalAccessException was thrown with a message like "Class ... can not access a member of class X with modifiers private". + + +### [Issue #1329](https://github.com/junit-team/junit4/issus/1329): Support assumptions in `@Parameters` method + +No test is run when an assumption in the `@Parameters` method fails. The test result for this test class contains one assumption failure and run count is zero. + + +### [Pull request #1449](https://github.com/junit-team/junit/pull/1449): Parameterized runner reuses TestClass instance + +Reduce memory consumption of parameterized tests by not creating a new instance of `TestClass` for every test. + +### [Pull request #1130](https://github.com/junit-team/junit/pull/1130): Add Ordering, Orderable and @OrderWith + +Test classes can now be annotated with `@OrderWith` to specify that the tests should execute in a particular +order. All runners extending `ParentRunner` support `@OrderWith`. Runners can also be ordered using +`Request.orderWith(Ordering)` + +Classes annotated with `@RunWith(Suite.class)` can also be ordered with `@OrderWith`. Note that if this is done, nested classes annotated with `@FixMethodOrder` will not be reordered (i.e. the `@FixMethodOrder` annotation is +always respected). Having a test class annotated with both `@OrderWith` and `@FixMethodOrder` will result in a +validation error (see +[pull request #1638](https://github.com/junit-team/junit4/pull/1638)). + +### [Pull request #1408](https://github.com/junit-team/junit/pull/1408): Suites don't have to be public + +Classes annotated with `@RunWith(Suite.class)` do not need to be public. This fixes a regression bug in JUnit 4.12. Suites didn't had to be public before 4.12. + +### [Pull request #1638](https://github.com/junit-team/junit4/pull/1638): Never reorder classes annotated with @FixMethodOrder + +Changing the order of a test run using `Request.sortWith()` no longer changes the order of test classes annotated +with `@FixMethodOrder`. The same holds true when you reorder tests with `Request.orderWith()` (`orderWith()` +was introduced in [Pull request #1130](https://github.com/junit-team/junit/pull/1130)). + +This was done because usually `@FixMethodOrder` is added to a class because the tests in the class they only pass +if run in a specific order. + +Test suites annotated with `@OrderWith` will also respect the `@FixMethodOrder` annotation. + +Having a test class annotated with both `@OrderWith` and `@FixMethodOrder` will result in a validation error. + +# Rules + +### [Pull request #1044:](https://github.com/junit-team/junit/pull/1044) Strict verification of resource deletion in `TemporaryFolder` rule + +Previously `TemporaryFolder` rule did not fail the test if some temporary resources could not be deleted. With this change a new `assuredDeletion` parameter is introduced which will fail the test with an `AssertionError`, if resource deletion fails. The default behavior of `TemporaryFolder` is unchanged. + +This feature must be enabled by creating a `TemporaryFolder` using the `TemporaryFolder.builder()` method: +```java +@Rule public TemporaryFolder folder = TemporaryFolder.builder().assureDeletion().build(); +``` + +### [Issue #1100:](https://github.com/junit-team/junit/issues/1110) StopWatch does not need to be abstract. + +Previously `StopWatch` was an abstract class, which means it cannot be used without extending it or using an anonymous class. The abstract modifier has been removed and StopWatch can be used easily now. + +### [Issue #1157:](https://github.com/junit-team/junit/issues/1157) TestName: Make 'name' field volatile + +The `name` field in the `TestName` rule was updated to be volatile. This should ensure that the name +is published even when tests are running in parallel. + +### [Issue #1223:](https://github.com/junit-team/junit/issues/1223) TemporaryFolder doesn't work for parallel test execution in several JVMs + +Previously `TemporaryFolder` rule silently succeeded if it failed to create a fresh temporary directory. With this change it will notice the failure, retry with a new name, and ultimately throw an `IOException` if all such attempts fail. + +### [Pull request #1305:](https://github.com/junit-team/junit/pull/1305) Add `ErrorCollector.checkThrows` + +The `ErrorCollector` class now has a `checkThrows` method that can assert that a given function call (specified, for instance, as a lambda expression or method reference) results in a particular type of exception being thrown. + +### [Issue #1303:](https://github.com/junit-team/junit/issues/1303) Prevent following symbolic links when deleting temporary directories + +Previously, `TemporaryFolder` would follow symbolic links; now it just deletes them. + +Following symbolic links when removing files can lead to the removal of files outside the directory structure rooted in the temporary folder, and it can lead to unbounded recursion if a symbolic link points to a directory where the link is directly reachable from. + +### [Issue #1295:](https://github.com/junit-team/junit/issues/1295) Javadoc for RuleChain contains errors + +Removed error from RuleChain Javadoc and clarified how it works with existing rules. Removed `static` modifier, added missing closing parenthesis of method calls and added clarification. + +### [Pull request #1313](https://github.com/junit-team/junit4/pull/1313): `RuleChain.around()` rejects null arguments +`RuleChain.around()` now implements a fail-fast strategy which also allows for better feedback to the final user, as the stacktrace will point to the exact line where the null rule is declared. + +### [Pull request #1397](https://github.com/junit-team/junit4/pull/1397): Change generics on `ExpectedException.expectCause()` +The signature of `ExpectedException.expectCause()` would not allow the caller to pass in a `Matcher` (which is returned by `CoreMatchers.notNullValue()`). This was fixed by changing the method to take in a +`Matcher` (ideally, the method should take in `Matcher` but there was concern that +changing the parameter type to `Matcher` would break some callers). + +### [Pull request #1443](https://github.com/junit-team/junit4/pull/1443): `ExpectedException.isAnyExceptionExpected()` is now public +The method `ExpectedException.isAnyExceptionExpected()` returns `true` if there is at least one expectation present for the `ExpectedException` rule. + +### [Pull request #1395](https://github.com/junit-team/junit4/pull/1395): Wrap assumption violations in ErrorCollector +Both `ErrorCollector.addError()` and `ErrorCollector.checkSucceeds()` now wrap `AssumptionViolatedException`. +In addition, `ErrorCollector.addError()` will throw a `NullPointerException` if you pass in a `null` value. + +### [Pull request #1402](https://github.com/junit-team/junit4/pull/1402): TemporaryFolder.newFolder(String) supports paths with slashes +There was a regression in JUnit 4.12 where `TemporaryFolder.newFolder(String)` no longer supported passing +in strings with separator characters. This has been fixed. he overload of newFolder() that +supports passing in multiple strings still does not allow path separators. + +### [Pull requests #1406 (part 1)](https://github.com/junit-team/junit4/pull/1406) and [#1568](https://github.com/junit-team/junit4/pull/1568): Improve error message when TemporaryFolder.newFolder(String) fails +When `newFolder(String path)` was not able to create the folder then it always failed with the error message "a folder with the name '``' already exists" although the reason for the failure could be something else. This message is now only used if the folder really exists. The message is "a file with the path '``' exists" if the whole path or a part of the path points to a file. In all other cases it fails now with the message "could not create a folder with the path '``'" + +### [Pull request #1406 (part 2)](https://github.com/junit-team/junit4/pull/1406): TemporaryFolder.newFolder(String...) supports path separator +You can now pass paths with path separators to `TemporaryFolder.newFolder(String...)`. E.g. + + tempFolder.newFolder("temp1", "temp2", "temp3/temp4") + +It creates a folder `temp1/temp2/temp3/temp4`. + + +### [Pull request #1406 (part 3)](https://github.com/junit-team/junit4/pull/1406): TemporaryFolder.newFolder(String...) fails for empty array + +When you call + + tempFolder.newFolder(new String[]) + +then it throws an `IllegalArgumentException` instead of returning an already existing folder. + + +### [Pull request #1335](https://github.com/junit-team/junit4/pull/1335): Fix ExternalResource: the test failure could be lost +When both the test failed and closing the resource failed, only the exception coming from the `after()` method was propagated, as per semantics of the try-finally (see also http://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.20.2). + +The new behavior is compatible with @After method semantics, as implemented in [RunAfters](https://github.com/junit-team/junit4/blob/master/src/main/java/org/junit/internal/runners/statements/RunAfters.java). + +### [Pull request #1435](https://github.com/junit-team/junit4/pull/1435): @BeforeParam/@AfterParam method annotations for Parameterized tests. +This allows having preparation and/or cleanup in tests for specific parameter values. + +### [Pull request #1460](https://github.com/junit-team/junit4/pull/1460): Handle assumption violations in the @Parameters method for Parameterized tests. +This allows skipping the whole test class when its assumptions are not met. + +### [Pull request #1445](https://github.com/junit-team/junit4/pull/1445) and [Pull request #1335](https://github.com/junit-team/junit4/pull/1501): Declarative ordering of rules. +The order in which rules are executed is specified by the annotation attribute: `@Rule(order = N)`, deprecating `RuleChain`. This may be used for avoiding some common pitfalls with `TestWatcher, `ErrorCollector` and `ExpectedException` for example. The Javadoc of `TestWatcher` was retrofitted accordingly. + +### [Pull request #1517](https://github.com/junit-team/junit4/pull/1517): Timeout rule destroys its ThreadGroups at the end +The `ThreadGroup` created for handling the timeout of tests is now destroyed, so the main thread group no longer keeps a reference to all timeout groups created during the tests. This caused the `threadGroup` to remain in memory, and all of its context along with it. + +### [Pull request #1633](https://github.com/junit-team/junit4/pull/1633): Deprecate ExpectedException.none() +The method Assert.assertThrows provides a nicer way for verifying exceptions. In addition the use of ExpectedException is error-prone when used with other rules like TestWatcher because the order of rules is important in that case. + +### [Pull request #1413](https://github.com/junit-team/junit4/pull/1413): Ignore bridge methods when scanning for annotated methods + +In a setup with a class hierarchy for test classes the order of rules (from methods), before methods, after methods and others depends on the class that contains these methods. Compilers can add bridge methods to child classes and therefore the order of the aforementioned methods can change in older JUnit releases. This is now fixed because bridge methods are ignored when scanning for annotated methods. + +### [Pull request #1612](https://github.com/junit-team/junit4/pull/1612): Make @ValidateWith only applicable to annotation types + +`@Target(ANNOTATION_TYPE)` has been added to `@ValidateWith` since it's only designed to be applied to another annotation. + +# Run Listener + +### [Pull request #1118:](https://github.com/junit-team/junit4/pull/1118) Add suite start/finish events to listener + +The `RunListener` class now has `fireTestSuiteStarted` and `fireTestSuiteFinished` methods that notify when test suites are about to be started/finished. + + +# Exception Testing + +### [Pull request #1359:](https://github.com/junit-team/junit4/pull/1359) Fixes how `MultipleFailureException` stack traces are printed + +Previously, calling `MultipleFailureException.printStackTrace()` only printed the stack trace for the `MultipleFailureException` itself. After this change, the stack trace for each exception caught in the `MultipleFailureException` is printed. + +### [Pull request #1376:](https://github.com/junit-team/junit4/pull/1376) Initializing MultipleFailureException with an empty list will now fail the test + +Previously, initializing `MultipleFailureException` with an empty list of contained Exceptions and throwing it in a test case wouldn't actually fail the test. Now an `IllegalArgumentException` will be raised in this situation and thus also fail the test. + +### [Pull request #1371:](https://github.com/junit-team/junit4/pull/1371) Update MultipleFailureException.assertEmpty() to wrap assumption failure + +`MultipleFailureException` will now wrap `MultipleFailureException` with `TestCouldNotBeSkippedException`. Previously, if you passed `MultipleFailureException` one `MultipleFailureException`--and no other exceptions-- +then the test would be skipped, otherwise it would fail. With the new behavior, it will always fail. + +### [Issue #1290:](https://github.com/junit-team/junit4/issues/1290) `@Test(expected = AssumptionViolatedException.class)` passes for AssumptionViolatedException + +Tests annotated with `@test(expected = AssumptionViolatedException.class)` +which throw AssumptionViolatedException had been marked as skipped. Now the are marked as successful tests. + + +# JUnit 3 Changes + +### [Pull request #1227:](https://github.com/junit-team/junit/pull/1227) Behave better if the `SecurityManager` denies access to `junit.properties` + +Previously, running tests with a `SecurityManager` would cause the test runner itself to throw an `AccessControlException` if the security policy didn't want it reading from `~/junit.properties`. This will now be treated the same as if the file does not exist. + +# Misc + +### [Pull request #1571:](https://github.com/junit-team/junit4/pull/1571) Set "junit" as "Automatic-Module-Name" + +For existing releases of JUnit the `Automatic-Module-Name` was derived from the name of the jar. In most cases it is already the name "junit". JUnit 4.13 explicitly sets the module name to "junit" so that it is independent from the jar's name. + + +### [Pull request #1028:](https://github.com/junit-team/junit4/pull/1028) Trim stack trace + +JUnit's command-line runner (`JUnitCore`) prints smaller stack traces. It skips all stack trace elements that come before the test method so that it starts at the test method. E.g. the output for the example from [Getting started](https://github.com/junit-team/junit4/wiki/Getting-started) page is now + + .E + Time: 0,006 + There was 1 failure: + 1) evaluatesExpression(CalculatorTest) + java.lang.AssertionError: expected:<6> but was:<-6> + at org.junit.Assert.fail(Assert.java:89) + at org.junit.Assert.failNotEquals(Assert.java:835) + at org.junit.Assert.assertEquals(Assert.java:647) + at org.junit.Assert.assertEquals(Assert.java:633) + at CalculatorTest.evaluatesExpression(CalculatorTest.java:9) + + FAILURES!!! + Tests run: 1, Failures: 1 + + +### [Pull request #1403:](https://github.com/junit-team/junit4/pull/1403) Restore CategoryFilter constructor + +The constructor `CategoryFilter(Class includedCategory, Class excludedCategory)` has been removed in JUnit 4.12. It is now available again. + + +### [Pull request #1530:](https://github.com/junit-team/junit4/pull/1530) Add Result#getAssumptionFailureCount + +Add method `getAssumptionFailureCount()` to `Result` which returns the number of assumption failures. + +### [Pull request #1292:](https://github.com/junit-team/junit4/pull/1292) Fix ResultMatchers#hasFailureContaining + +`ResultMatchers.hasFailureContaining()` should return `false` when the given `PrintableResult` has no failures. + +### [Pull request #1380:](https://github.com/junit-team/junit4/pull/1380) Fix Assume#assumeNotNull + +`Assume.assumeNotNull` should throw AssumptionViolatedException when called with a `null` array. + +### [Pull request #1557:](https://github.com/junit-team/junit4/pull/1380) MaxCore always closes stream of history file + +MaxCore didn't close the output stream of the history file when write failed. Now it does. + +### Signing + +The 4.13 release is signed with a new key (id 5EC61B51): +https://github.com/junit-team/junit4/blob/8c0df64ff17fead54c304a8b189da839084925c2/KEYS diff --git a/doc/building-junit.txt b/doc/building-junit.txt index 7f67e9731651..91169e3427b3 100644 --- a/doc/building-junit.txt +++ b/doc/building-junit.txt @@ -5,7 +5,7 @@ Steps to build junit: - Not too tedious: - Push to github (junit-team) - Run the ./mvnw clean install - - If not done, update src/main/config/settings.xml in /private/.../settings.xml on CloudBees' webdav share. + - If not done, update $M2_HOME/settings.xml - If not done, copy GnuPG keys in to ${gpg.homedir}. See settings.xml. - Perform Maven deployment of a snapshot or release version in Jenkins Remember that the version specified in the pom.xml indicates the version diff --git a/doc/homepage.html b/doc/homepage.html deleted file mode 100644 index 69c6248102e4..000000000000 --- a/doc/homepage.html +++ /dev/null @@ -1,115 +0,0 @@ - - -JUnit - - - - -

JUnit

-

JUnit is a simple framework to write repeatable tests. It is an instance of -the xUnit architecture for unit testing frameworks. -

- -

-Getting Started

- -To get started with unit testing and JUnit read the article: -JUnit Cookbook. -
This article describes basic test writing using JUnit 4. -

You find additional samples in the org.junit.samples package: -

    -
  • -SimpleTest.java - some simple test cases
  • - -
  • -VectorTest.java - test cases for java.util.Vector
  • -
-

JUnit 4.x only comes with a textual TestRunner. For graphical feedback, -most major IDE's support -JUnit 4. If necessary, you can run JUnit 4 tests in a JUnit 3 -environment by adding the following method to each test class: -

-public static Test suite() {
-   return new JUnit4TestAdapter(ThisClass.class);
-} 
-
-
- -

-Documentation

- -
JUnit Cookbook -
    A cookbook for implementing tests with JUnit. -
Javadoc -
    API documentation generated with javadoc. -
Frequently asked questions -
    Some frequently asked questions about using JUnit. - -
Release notes -
    Latest JUnit release notes -
License -
    The terms of the common public license used for JUnit.
-
-The following documents still describe JUnit 3.8. -
-
The JUnit 3.8 version of this homepage -
Test Infected - Programmers -Love Writing Tests -
    An article demonstrating the development process -with JUnit. - -
JUnit - A cooks tour -
- -

JUnit Related Projects/Sites

-
    -
  • junit.org - a site for software - developers using JUnit. It provides instructions for how to integrate JUnit - with development tools like JBuilder and VisualAge/Java. As well as articles - about and extensions to JUnit.
  • -
  • XProgramming.com - - various implementations of the xUnit testing framework architecture. 
  • - -
-

Mailing Lists

-There are three junit mailing lists: - - -

Get Involved

- JUnit celebrates programmers testing their own software. As a result - bugs, patches, and feature requests which include JUnit TestCases have a - better - chance of being addressed than those without. - -
- JUnit is forged on - Sourceforge please use the tools provided for your submissions. - -
- JUnit source code is now hosted on GitHub. - -
- -hosted by SourceForge Logo - - - diff --git a/doc/index.htm b/doc/index.htm deleted file mode 100644 index dd19ff3383be..000000000000 --- a/doc/index.htm +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - JUnit Documentation - - - -

-JUnit Documentation

- -

-Kent Beck, Erich Gamma, David Saff

- -
-We have just begun documenting the new JUnit 4 architecture. The cookbook has already been updated. You can find the javadoc here. -The JUnit home page is here. -
- - diff --git a/doc/testinfected/testing.htm b/doc/testinfected/testing.htm index d11c11cd98d5..c5721e752b8d 100644 --- a/doc/testinfected/testing.htm +++ b/doc/testinfected/testing.htm @@ -181,14 +181,14 @@

result report. The value a string representation created by the toString converter method. There are -other asertXXXX variants not discussed here. +other assertXXXX variants not discussed here.

Now that we have implemented two test cases we notice some code duplication for setting-up the tests. It would be nice to reuse some of this test set-up code. In other words, we would like to have a common fixture for running the tests. With JUnit you can do so by storing the fixture's objects in instance variables of your TestCase -subclass and initialize them by overridding +subclass and initialize them by overriding the setUp method. The symmetric operation to setUp is tearDown which you can override to clean up the test fixture at the end of a test. Each test runs in its own fixture and JUnit calls setUp and tearDown for each test @@ -435,7 +435,7 @@

public IMoney addMoneyBag(MoneyBag s) {     return s.addMoney(this); } -Here is the implemenation in MoneyBag which assumes additional constructors +Here is the implementation in MoneyBag which assumes additional constructors to create a MoneyBag from a Money and a MoneyBag and from two MoneyBags.
public IMoney addMoney(Money m) {
     return new MoneyBag(m, this);
diff --git a/pom.xml b/pom.xml
index 293cac1983d1..ec6284c6e2bb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
 
     junit
     junit
-    4.13-SNAPSHOT
+    4.14-SNAPSHOT
 
     JUnit
     JUnit is a unit testing framework for Java, created by Erich Gamma and Kent Beck.
@@ -48,7 +48,7 @@
         
             JUnit contributors
             JUnit
-            junit@yahoogroups.com
+            team@junit.org
             https://github.com/junit-team/junit4/graphs/contributors
             
                 developers
@@ -56,14 +56,6 @@
         
     
 
-    
-        
-            JUnit Mailing List
-            junit@yahoogroups.com
-            https://groups.yahoo.com/neo/groups/junit/info
-        
-    
-
     
         3.0.4
     
@@ -79,8 +71,8 @@
         https://github.com/junit-team/junit4/issues
     
     
-        jenkins
-        https://junit.ci.cloudbees.com/
+        travis
+        https://travis-ci.org/junit-team/junit4
     
     
         https://github.com/junit-team/junit4/wiki/Download-and-Install
@@ -360,6 +352,9 @@
                         
                             true
                         
+                        
+                            junit
+                                                
                     
                 
             
@@ -413,7 +408,7 @@
             
             
                 maven-javadoc-plugin
-                2.10.1
+                2.10.3
                 
                     javadoc/latest
                     ${basedir}/src/main/javadoc/stylesheet.css
@@ -567,6 +562,26 @@
                 
                 1.6
             
+            
+                
+                    
+                        maven-javadoc-plugin
+                        
+                            1.6
+                        
+                    
+                
+            
+            
+                
+                    
+                        maven-javadoc-plugin
+                        
+                            1.6
+                        
+                    
+                
+            
         
     
 
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
deleted file mode 100644
index e2631b19f28b..000000000000
--- a/src/changes/changes.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-
-  
-    
-    
-
-    
-    
-
-    
-    
-
-    
-    
-
-    
-    
-
-    
-    
-
-    
-    
-
-    
-    
-
-    
-    
-
-    
-    
-
-    
-    
-  
-
\ No newline at end of file
diff --git a/src/main/java/junit/framework/JUnit4TestAdapter.java b/src/main/java/junit/framework/JUnit4TestAdapter.java
index 13e478efc3e9..9d32031e4eba 100644
--- a/src/main/java/junit/framework/JUnit4TestAdapter.java
+++ b/src/main/java/junit/framework/JUnit4TestAdapter.java
@@ -9,8 +9,10 @@
 import org.junit.runner.Runner;
 import org.junit.runner.manipulation.Filter;
 import org.junit.runner.manipulation.Filterable;
+import org.junit.runner.manipulation.Orderer;
+import org.junit.runner.manipulation.InvalidOrderingException;
 import org.junit.runner.manipulation.NoTestsRemainException;
-import org.junit.runner.manipulation.Sortable;
+import org.junit.runner.manipulation.Orderable;
 import org.junit.runner.manipulation.Sorter;
 
 /**
@@ -23,7 +25,7 @@ public static Test suite() {
       }
 
*/ -public class JUnit4TestAdapter implements Test, Filterable, Sortable, Describable { +public class JUnit4TestAdapter implements Test, Filterable, Orderable, Describable { private final Class fNewTestClass; private final Runner fRunner; @@ -93,4 +95,13 @@ public void filter(Filter filter) throws NoTestsRemainException { public void sort(Sorter sorter) { sorter.apply(fRunner); } + + /** + * {@inheritDoc} + * + * @since 4.13 + */ + public void order(Orderer orderer) throws InvalidOrderingException { + orderer.apply(fRunner); + } } \ No newline at end of file diff --git a/src/main/java/org/junit/Assert.java b/src/main/java/org/junit/Assert.java index a3d7905e6d24..3221f29e56b1 100644 --- a/src/main/java/org/junit/Assert.java +++ b/src/main/java/org/junit/Assert.java @@ -923,8 +923,7 @@ public static void assertEquals(Object[] expecteds, Object[] actuals) { * @param matcher an expression, built of {@link Matcher}s, specifying allowed * values * @see org.hamcrest.CoreMatchers - * @see org.hamcrest.MatcherAssert - * @deprecated use {@code org.hamcrest.junit.MatcherAssert.assertThat()} + * @deprecated use {@code org.hamcrest.MatcherAssert.assertThat()} */ @Deprecated public static void assertThat(T actual, Matcher matcher) { @@ -957,8 +956,7 @@ public static void assertThat(T actual, Matcher matcher) { * @param matcher an expression, built of {@link Matcher}s, specifying allowed * values * @see org.hamcrest.CoreMatchers - * @see org.hamcrest.MatcherAssert - * @deprecated use {@code org.hamcrest.junit.MatcherAssert.assertThat()} + * @deprecated use {@code org.hamcrest.MatcherAssert.assertThat()} */ @Deprecated public static void assertThat(String reason, T actual, diff --git a/src/main/java/org/junit/Assume.java b/src/main/java/org/junit/Assume.java index 0e42ff95ae8b..29b705be6988 100644 --- a/src/main/java/org/junit/Assume.java +++ b/src/main/java/org/junit/Assume.java @@ -54,7 +54,7 @@ public static void assumeTrue(boolean b) { * The inverse of {@link #assumeTrue(boolean)}. */ public static void assumeFalse(boolean b) { - assumeTrue(!b); + assumeThat(b, is(false)); } /** @@ -100,9 +100,7 @@ public static void assumeNotNull(Object... objects) { * @param matcher an expression, built of {@link Matcher}s, specifying allowed values * @see org.hamcrest.CoreMatchers * @see org.junit.matchers.JUnitMatchers - * @deprecated use {@code org.hamcrest.junit.MatcherAssume.assumeThat()} */ - @Deprecated public static void assumeThat(T actual, Matcher matcher) { if (!matcher.matches(actual)) { throw new AssumptionViolatedException(actual, matcher); @@ -125,9 +123,7 @@ public static void assumeThat(T actual, Matcher matcher) { * @param matcher an expression, built of {@link Matcher}s, specifying allowed values * @see org.hamcrest.CoreMatchers * @see org.junit.matchers.JUnitMatchers - * @deprecated use {@code org.hamcrest.junit.MatcherAssume.assumeThat()} */ - @Deprecated public static void assumeThat(String message, T actual, Matcher matcher) { if (!matcher.matches(actual)) { throw new AssumptionViolatedException(message, actual, matcher); diff --git a/src/main/java/org/junit/AssumptionViolatedException.java b/src/main/java/org/junit/AssumptionViolatedException.java index a0cd9e533a75..1d62190a2315 100644 --- a/src/main/java/org/junit/AssumptionViolatedException.java +++ b/src/main/java/org/junit/AssumptionViolatedException.java @@ -18,7 +18,6 @@ public class AssumptionViolatedException extends org.junit.internal.AssumptionVi * An assumption exception with the given actual value and a matcher describing * the expectation that failed. */ - @Deprecated public AssumptionViolatedException(T actual, Matcher matcher) { super(actual, matcher); } @@ -27,9 +26,8 @@ public AssumptionViolatedException(T actual, Matcher matcher) { * An assumption exception with a message with the given actual value and a * matcher describing the expectation that failed. */ - @Deprecated - public AssumptionViolatedException(String message, T actual, Matcher matcher) { - super(message, actual, matcher); + public AssumptionViolatedException(String message, T expected, Matcher matcher) { + super(message, expected, matcher); } /** diff --git a/src/main/java/org/junit/ClassRule.java b/src/main/java/org/junit/ClassRule.java index 75c9c8d94e8f..94ee29f9f51d 100644 --- a/src/main/java/org/junit/ClassRule.java +++ b/src/main/java/org/junit/ClassRule.java @@ -30,6 +30,8 @@ * undefined, in general. However, Rules defined by fields will always be applied * after Rules defined by methods, i.e. the Statements returned by the former will * be executed around those returned by the latter. + * + *

Usage

*

* For example, here is a test suite that connects to a server once before * all the test classes run, and disconnects after they are finished: @@ -80,6 +82,26 @@ *

* For more information and more examples, see {@link org.junit.rules.TestRule}. * + *

Ordering

+ *

+ * You can use {@link #order()} if you want to have control over the order in + * which the Rules are applied. + * + *

+ * public class ThreeClassRules {
+ *     @ClassRule(order = 0)
+ *     public static LoggingRule outer = new LoggingRule("outer rule");
+ *
+ *     @ClassRule(order = 1)
+ *     public static LoggingRule middle = new LoggingRule("middle rule");
+ *
+ *     @ClassRule(order = 2)
+ *     public static LoggingRule inner = new LoggingRule("inner rule");
+ *
+ *     // ...
+ * }
+ * 
+ * * @since 4.9 */ @Retention(RetentionPolicy.RUNTIME) diff --git a/src/main/java/org/junit/Rule.java b/src/main/java/org/junit/Rule.java index bae47a256996..9370e94f51fc 100644 --- a/src/main/java/org/junit/Rule.java +++ b/src/main/java/org/junit/Rule.java @@ -21,9 +21,9 @@ * that depends on your JVM's implementation of the reflection API, which is * undefined, in general. Rules defined by fields will always be applied * after Rules defined by methods, i.e. the Statements returned by the former will - * be executed around those returned by the latter. You can use a {@link org.junit.rules.RuleChain} - * if you want to have control over the order in which the Rules are applied. + * be executed around those returned by the latter. * + *

Usage

*

* For example, here is a test class that creates a temporary folder before * each test method, and deletes it after each: @@ -63,6 +63,26 @@ * For more information and more examples, see * {@link org.junit.rules.TestRule}. * + *

Ordering

+ *

+ * You can use {@link #order()} if you want to have control over the order in + * which the Rules are applied. + * + *

+ * public class ThreeRules {
+ *     @Rule(order = 0)
+ *     public LoggingRule outer = new LoggingRule("outer rule");
+ *
+ *     @Rule(order = 1)
+ *     public LoggingRule middle = new LoggingRule("middle rule");
+ *
+ *     @Rule(order = 2)
+ *     public LoggingRule inner = new LoggingRule("inner rule");
+ *
+ *     // ...
+ * }
+ * 
+ * * @since 4.7 */ @Retention(RetentionPolicy.RUNTIME) diff --git a/src/main/java/org/junit/experimental/max/MaxHistory.java b/src/main/java/org/junit/experimental/max/MaxHistory.java index 273b07947553..ab7443f38535 100644 --- a/src/main/java/org/junit/experimental/max/MaxHistory.java +++ b/src/main/java/org/junit/experimental/max/MaxHistory.java @@ -75,10 +75,15 @@ private MaxHistory(File storedResults) { } private void save() throws IOException { - ObjectOutputStream stream = new ObjectOutputStream(new FileOutputStream( - fHistoryStore)); - stream.writeObject(this); - stream.close(); + ObjectOutputStream stream = null; + try { + stream = new ObjectOutputStream(new FileOutputStream(fHistoryStore)); + stream.writeObject(this); + } finally { + if (stream != null) { + stream.close(); + } + } } Long getFailureTimestamp(Description key) { diff --git a/src/main/java/org/junit/experimental/theories/ParametersSuppliedBy.java b/src/main/java/org/junit/experimental/theories/ParametersSuppliedBy.java index 15b5d9518d8a..846a39e46339 100644 --- a/src/main/java/org/junit/experimental/theories/ParametersSuppliedBy.java +++ b/src/main/java/org/junit/experimental/theories/ParametersSuppliedBy.java @@ -17,7 +17,7 @@ * * In addition, annotations themselves can be annotated with * @ParametersSuppliedBy, and then used similarly. ParameterSuppliedBy - * annotations on parameters are detected by searching up this heirarchy such + * annotations on parameters are detected by searching up this hierarchy such * that these act as syntactic sugar, making: * *
diff --git a/src/main/java/org/junit/internal/matchers/StacktracePrintingMatcher.java b/src/main/java/org/junit/internal/matchers/StacktracePrintingMatcher.java
index 9e9505da075f..93a6827678d0 100644
--- a/src/main/java/org/junit/internal/matchers/StacktracePrintingMatcher.java
+++ b/src/main/java/org/junit/internal/matchers/StacktracePrintingMatcher.java
@@ -9,11 +9,7 @@
 /**
  * A matcher that delegates to throwableMatcher and in addition appends the
  * stacktrace of the actual Throwable in case of a mismatch.
- *
- * @deprecated use {@code org.hamcrest.junit.JunitMatchers.isThrowable()}
- * or {@code org.hamcrest.junit.JunitMatchers.isException()}
  */
-@Deprecated
 public class StacktracePrintingMatcher extends
         org.hamcrest.TypeSafeMatcher {
 
diff --git a/src/main/java/org/junit/internal/matchers/ThrowableCauseMatcher.java b/src/main/java/org/junit/internal/matchers/ThrowableCauseMatcher.java
index a8d9cefd932d..6e2ff5e3d565 100644
--- a/src/main/java/org/junit/internal/matchers/ThrowableCauseMatcher.java
+++ b/src/main/java/org/junit/internal/matchers/ThrowableCauseMatcher.java
@@ -10,9 +10,7 @@
  * match.
  *
  * @param  the type of the throwable being matched
- * @deprecated use {@code org.hamcrest.junit.ExpectedException}
  */
-@Deprecated
 public class ThrowableCauseMatcher extends
         TypeSafeMatcher {
 
diff --git a/src/main/java/org/junit/internal/requests/ClassRequest.java b/src/main/java/org/junit/internal/requests/ClassRequest.java
index acc9c90aebe9..d60e36062d81 100644
--- a/src/main/java/org/junit/internal/requests/ClassRequest.java
+++ b/src/main/java/org/junit/internal/requests/ClassRequest.java
@@ -1,17 +1,11 @@
 package org.junit.internal.requests;
 
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-
 import org.junit.internal.builders.AllDefaultPossibilitiesBuilder;
 import org.junit.internal.builders.SuiteMethodBuilder;
-import org.junit.runner.Request;
 import org.junit.runner.Runner;
 import org.junit.runners.model.RunnerBuilder;
 
-public class ClassRequest extends Request {
-    private final Lock runnerLock = new ReentrantLock();
-
+public class ClassRequest extends MemoizingRequest {
     /*
      * We have to use the f prefix, because IntelliJ's JUnit4IdeaTestRunner uses
      * reflection to access this field. See
@@ -19,7 +13,6 @@ public class ClassRequest extends Request {
      */
     private final Class fTestClass;
     private final boolean canUseSuiteMethod;
-    private volatile Runner runner;
 
     public ClassRequest(Class testClass, boolean canUseSuiteMethod) {
         this.fTestClass = testClass;
@@ -31,18 +24,8 @@ public ClassRequest(Class testClass) {
     }
 
     @Override
-    public Runner getRunner() {
-        if (runner == null) {
-            runnerLock.lock();
-            try {
-                if (runner == null) {
-                    runner = new CustomAllDefaultPossibilitiesBuilder().safeRunnerForClass(fTestClass);
-                }
-            } finally {
-                runnerLock.unlock();
-            }
-        }
-        return runner;
+    protected Runner createRunner() {
+        return new CustomAllDefaultPossibilitiesBuilder().safeRunnerForClass(fTestClass);
     }
 
     private class CustomAllDefaultPossibilitiesBuilder extends AllDefaultPossibilitiesBuilder {
diff --git a/src/main/java/org/junit/internal/requests/MemoizingRequest.java b/src/main/java/org/junit/internal/requests/MemoizingRequest.java
new file mode 100644
index 000000000000..191c23022536
--- /dev/null
+++ b/src/main/java/org/junit/internal/requests/MemoizingRequest.java
@@ -0,0 +1,30 @@
+package org.junit.internal.requests;
+
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.junit.runner.Request;
+import org.junit.runner.Runner;
+
+abstract class MemoizingRequest extends Request {
+    private final Lock runnerLock = new ReentrantLock();
+    private volatile Runner runner;
+
+    @Override
+    public final Runner getRunner() {
+        if (runner == null) {
+            runnerLock.lock();
+            try {
+                if (runner == null) {
+                    runner = createRunner();
+                }
+            } finally {
+                runnerLock.unlock();
+            }
+        }
+        return runner;
+    }
+
+    /** Creates the {@link Runner} to return from {@link #getRunner()}. Called at most once. */
+    protected abstract Runner createRunner();
+}
diff --git a/src/main/java/org/junit/internal/requests/OrderingRequest.java b/src/main/java/org/junit/internal/requests/OrderingRequest.java
new file mode 100644
index 000000000000..441e595a3680
--- /dev/null
+++ b/src/main/java/org/junit/internal/requests/OrderingRequest.java
@@ -0,0 +1,29 @@
+package org.junit.internal.requests;
+
+import org.junit.internal.runners.ErrorReportingRunner;
+import org.junit.runner.Request;
+import org.junit.runner.Runner;
+import org.junit.runner.manipulation.InvalidOrderingException;
+import org.junit.runner.manipulation.Ordering;
+
+/** @since 4.13 */
+public class OrderingRequest extends MemoizingRequest {
+    private final Request request;
+    private final Ordering ordering;
+
+    public OrderingRequest(Request request, Ordering ordering) {
+        this.request = request;
+        this.ordering = ordering;
+    }
+
+    @Override
+    protected Runner createRunner() {
+        Runner runner = request.getRunner();
+        try {
+            ordering.apply(runner);
+        } catch (InvalidOrderingException e) {
+            return new ErrorReportingRunner(ordering.getClass(), e);
+        }
+        return runner;
+    }
+}
diff --git a/src/main/java/org/junit/internal/runners/JUnit38ClassRunner.java b/src/main/java/org/junit/internal/runners/JUnit38ClassRunner.java
index 631fcf2e5904..0d51541adcf8 100644
--- a/src/main/java/org/junit/internal/runners/JUnit38ClassRunner.java
+++ b/src/main/java/org/junit/internal/runners/JUnit38ClassRunner.java
@@ -1,5 +1,8 @@
 package org.junit.internal.runners;
 
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+
 import junit.extensions.TestDecorator;
 import junit.framework.AssertionFailedError;
 import junit.framework.Test;
@@ -12,15 +15,16 @@
 import org.junit.runner.Runner;
 import org.junit.runner.manipulation.Filter;
 import org.junit.runner.manipulation.Filterable;
+import org.junit.runner.manipulation.Orderer;
+import org.junit.runner.manipulation.InvalidOrderingException;
 import org.junit.runner.manipulation.NoTestsRemainException;
+import org.junit.runner.manipulation.Orderable;
 import org.junit.runner.manipulation.Sortable;
 import org.junit.runner.manipulation.Sorter;
 import org.junit.runner.notification.Failure;
 import org.junit.runner.notification.RunNotifier;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Method;
 
-public class JUnit38ClassRunner extends Runner implements Filterable, Sortable {
+public class JUnit38ClassRunner extends Runner implements Filterable, Orderable {
     private static final class OldTestClassAdaptingListener implements
             TestListener {
         private final RunNotifier notifier;
@@ -170,6 +174,18 @@ public void sort(Sorter sorter) {
         }
     }
 
+    /**
+     * {@inheritDoc}
+     *
+     * @since 4.13
+     */
+    public void order(Orderer orderer) throws InvalidOrderingException {
+        if (getTest() instanceof Orderable) {
+            Orderable adapter = (Orderable) getTest();
+            adapter.order(orderer);
+        }
+    }
+
     private void setTest(Test test) {
         this.test = test;
     }
diff --git a/src/main/java/org/junit/matchers/JUnitMatchers.java b/src/main/java/org/junit/matchers/JUnitMatchers.java
index 47897c5ae044..13407cc05217 100644
--- a/src/main/java/org/junit/matchers/JUnitMatchers.java
+++ b/src/main/java/org/junit/matchers/JUnitMatchers.java
@@ -11,9 +11,7 @@
  * not currently included in the basic CoreMatchers class from hamcrest.
  *
  * @since 4.4
- * @deprecated use {@code org.hamcrest.junit.JUnitMatchers}
  */
-@Deprecated
 public class JUnitMatchers {
     /**
      * @return A matcher matching any collection containing element
diff --git a/src/main/java/org/junit/rules/DisableOnDebug.java b/src/main/java/org/junit/rules/DisableOnDebug.java
index eed841c7a3c4..3bca103ed5a4 100644
--- a/src/main/java/org/junit/rules/DisableOnDebug.java
+++ b/src/main/java/org/junit/rules/DisableOnDebug.java
@@ -103,9 +103,7 @@ public Statement apply(Statement base, Description description) {
      */
     private static boolean isDebugging(List arguments) {
         for (final String argument : arguments) {
-            if ("-Xdebug".equals(argument)) {
-                return true;
-            } else if (argument.startsWith("-agentlib:jdwp")) {
+            if ("-Xdebug".equals(argument) || argument.startsWith("-agentlib:jdwp")) {
                 return true;
             }
         }
diff --git a/src/main/java/org/junit/rules/ErrorCollector.java b/src/main/java/org/junit/rules/ErrorCollector.java
index 80a7c12712ef..9711e50358f7 100644
--- a/src/main/java/org/junit/rules/ErrorCollector.java
+++ b/src/main/java/org/junit/rules/ErrorCollector.java
@@ -61,10 +61,7 @@ public void addError(Throwable error) {
     /**
      * Adds a failure to the table if {@code matcher} does not match {@code value}.
      * Execution continues, but the test will fail at the end if the match fails.
-     *
-     * @deprecated use {@code org.hamcrest.junit.ErrorCollector.checkThat()}
      */
-    @Deprecated
     public  void checkThat(final T value, final Matcher matcher) {
         checkThat("", value, matcher);
     }
@@ -73,10 +70,7 @@ public  void checkThat(final T value, final Matcher matcher) {
      * Adds a failure with the given {@code reason}
      * to the table if {@code matcher} does not match {@code value}.
      * Execution continues, but the test will fail at the end if the match fails.
-     *
-     * @deprecated use {@code org.hamcrest.junit.ErrorCollector.checkThat()}
      */
-    @Deprecated
     public  void checkThat(final String reason, final T value, final Matcher matcher) {
         checkSucceeds(new Callable() {
             public Object call() throws Exception {
diff --git a/src/main/java/org/junit/rules/ExpectedException.java b/src/main/java/org/junit/rules/ExpectedException.java
index 82936aa93c40..431ad495b12f 100644
--- a/src/main/java/org/junit/rules/ExpectedException.java
+++ b/src/main/java/org/junit/rules/ExpectedException.java
@@ -106,17 +106,19 @@
  * exception. E.g. "Test doesn't throw %s." will fail with the error message
  * "Test doesn't throw an instance of foo.".
  *
- * @deprecated Since 4.13
- * {@link org.junit.Assert#assertThrows(Class, org.junit.function.ThrowingRunnable)
- * Assert.assertThrows} can be used to verify that your code throws a specific
- * exception.
  * @since 4.7
  */
 public class ExpectedException implements TestRule {
     /**
      * Returns a {@linkplain TestRule rule} that expects no exception to
      * be thrown (identical to behavior without this rule).
+     *
+     * @deprecated Since 4.13
+     * {@link org.junit.Assert#assertThrows(Class, org.junit.function.ThrowingRunnable)
+     * Assert.assertThrows} can be used to verify that your code throws a specific
+     * exception.
      */
+    @Deprecated
     public static ExpectedException none() {
         return new ExpectedException();
     }
@@ -177,10 +179,7 @@ public Statement apply(Statement base,
      *     thrown.expect(is(e));
      *     throw e;
      * }
-     *
-     * @deprecated use {@code org.hamcrest.junit.ExpectedException.expect()}
      */
-    @Deprecated
     public void expect(Matcher matcher) {
         matcherBuilder.add(matcher);
     }
@@ -219,10 +218,7 @@ public void expectMessage(String substring) {
      *     thrown.expectMessage(startsWith("What"));
      *     throw new NullPointerException("What happened?");
      * }
-     *
-     * @deprecated use {@code org.hamcrest.junit.ExpectedException.expectMessage()}
      */
-    @Deprecated
     public void expectMessage(Matcher matcher) {
         expect(hasMessage(matcher));
     }
@@ -236,10 +232,7 @@ public void expectMessage(Matcher matcher) {
      *     thrown.expectCause(is(expectedCause));
      *     throw new IllegalArgumentException("What happened?", cause);
      * }
-     *
-     * @deprecated use {@code org.hamcrest.junit.ExpectedException.expectCause()}
      */
-    @Deprecated
     public void expectCause(Matcher expectedCause) {
         expect(hasCause(expectedCause));
     }
diff --git a/src/main/java/org/junit/rules/ExternalResource.java b/src/main/java/org/junit/rules/ExternalResource.java
index c7c0102c9efa..71fc84294308 100644
--- a/src/main/java/org/junit/rules/ExternalResource.java
+++ b/src/main/java/org/junit/rules/ExternalResource.java
@@ -77,10 +77,8 @@ protected void before() throws Throwable {
 
     /**
      * Override to tear down your specific external resource.
-     *
-     * @throws Throwable if teardown fails
      */
-    protected void after() throws Throwable {
+    protected void after() {
         // do nothing
     }
 }
diff --git a/src/main/java/org/junit/rules/RuleChain.java b/src/main/java/org/junit/rules/RuleChain.java
index 0ed497339ddd..bf93aae1f318 100644
--- a/src/main/java/org/junit/rules/RuleChain.java
+++ b/src/main/java/org/junit/rules/RuleChain.java
@@ -4,26 +4,34 @@
 import java.util.Collections;
 import java.util.List;
 
+import org.junit.Rule;
 import org.junit.runner.Description;
 import org.junit.runners.model.Statement;
 
 /**
- * The RuleChain rule allows ordering of TestRules. You create a
+ * The {@code RuleChain} can be used for creating composite rules. You create a
  * {@code RuleChain} with {@link #outerRule(TestRule)} and subsequent calls of
  * {@link #around(TestRule)}:
  *
  * 
+ * public abstract class CompositeRules {
+ *   public static TestRule extendedLogging() {
+ *     return RuleChain.outerRule(new LoggingRule("outer rule"))
+ *                     .around(new LoggingRule("middle rule"))
+ *                     .around(new LoggingRule("inner rule"));
+ *   }
+ * }
+ * 
+ * + *
  * public class UseRuleChain {
- * 	@Rule
- * 	public RuleChain chain= RuleChain
- * 	                       .outerRule(new LoggingRule("outer rule"))
- * 	                       .around(new LoggingRule("middle rule"))
- * 	                       .around(new LoggingRule("inner rule"));
+ *   @Rule
+ *   public final TestRule extendedLogging = CompositeRules.extendedLogging();
  *
- * 	@Test
- * 	public void example() {
- * 		assertTrue(true);
- *     }
+ *   @Test
+ *   public void example() {
+ *     assertTrue(true);
+ *   }
  * }
  * 
* @@ -37,28 +45,16 @@ * finished middle rule * finished outer rule * - * - * {@code RuleChain} cannot be used to define the order of existing rules. - * For example in the below snippet the LoggingRule {@code middle} would be - * executed outside as well as inside the {@code RuleChain}: * - *
- * @Rule
- * public LoggingRule middle = new LoggingRule("middle rule");
- * 
- * @Rule
- * public RuleChain chain = RuleChain
- *                          .outerRule(new LoggingRule("outer rule"))
- *                          .around(middle)
- *                          .around(new LoggingRule("inner rule"));
- * 
+ * In older versions of JUnit (before 4.13) {@code RuleChain} was used for + * ordering rules. We recommend to not use it for this purpose anymore. You can + * use the attribute {@code order} of the annotation {@link Rule#order() Rule} + * or {@link org.junit.ClassRule#order() ClassRule} for ordering rules. * - * @deprecated Since 4.13 ordering of rules can be naturally specified with an annotation attribute. * @see org.junit.Rule#order() * @see org.junit.ClassRule#order() * @since 4.10 */ -@Deprecated public class RuleChain implements TestRule { private static final RuleChain EMPTY_CHAIN = new RuleChain( Collections.emptyList()); diff --git a/src/main/java/org/junit/rules/TemporaryFolder.java b/src/main/java/org/junit/rules/TemporaryFolder.java index ca84a721fa77..1a6a77060805 100644 --- a/src/main/java/org/junit/rules/TemporaryFolder.java +++ b/src/main/java/org/junit/rules/TemporaryFolder.java @@ -200,14 +200,19 @@ public File newFolder(String... paths) throws IOException { File relativePath = null; File file = root; boolean lastMkdirsCallSuccessful = true; - for (int i = 0; i < paths.length; i++) { - relativePath = new File(relativePath, paths[i]); + for (String path : paths) { + relativePath = new File(relativePath, path); file = new File(root, relativePath.getPath()); lastMkdirsCallSuccessful = file.mkdirs(); if (!lastMkdirsCallSuccessful && !file.isDirectory()) { - throw new IOException( - "could not create a folder with the path \'" + relativePath.getPath() + "\'"); + if (file.exists()) { + throw new IOException( + "a file with the path \'" + relativePath.getPath() + "\' exists"); + } else { + throw new IOException( + "could not create a folder with the path \'" + relativePath.getPath() + "\'"); + } } } if (!lastMkdirsCallSuccessful) { @@ -278,7 +283,7 @@ public void delete() { * @return {@code true} if all resources are deleted successfully, * {@code false} otherwise. */ - protected boolean tryDelete() { + private boolean tryDelete() { if (folder == null) { return true; } diff --git a/src/main/java/org/junit/runner/OrderWith.java b/src/main/java/org/junit/runner/OrderWith.java new file mode 100644 index 000000000000..e8470c9dd1c8 --- /dev/null +++ b/src/main/java/org/junit/runner/OrderWith.java @@ -0,0 +1,28 @@ +package org.junit.runner; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.junit.runner.manipulation.Ordering; +import org.junit.validator.ValidateWith; + +/** + * When a test class is annotated with @OrderWith or extends a class annotated + * with @OrderWith, JUnit will order the tests in the test class (and child + * test classes, if any) using the ordering defined by the {@link Ordering} class. + * + * @since 4.13 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +@Inherited +@ValidateWith(OrderWithValidator.class) +public @interface OrderWith { + /** + * Gets a class that extends {@link Ordering}. The class must have a public no-arg constructor. + */ + Class value(); +} diff --git a/src/main/java/org/junit/runner/OrderWithValidator.java b/src/main/java/org/junit/runner/OrderWithValidator.java new file mode 100644 index 000000000000..f8eab2523c16 --- /dev/null +++ b/src/main/java/org/junit/runner/OrderWithValidator.java @@ -0,0 +1,38 @@ +package org.junit.runner; + +import static java.util.Collections.emptyList; +import static java.util.Collections.singletonList; + +import java.util.List; + +import org.junit.FixMethodOrder; +import org.junit.runners.model.TestClass; +import org.junit.validator.AnnotationValidator; + +/** + * Validates that there are no errors in the use of the {@code OrderWith} + * annotation. If there is, a {@code Throwable} object will be added to the list + * of errors. + * + * @since 4.13 + */ +public final class OrderWithValidator extends AnnotationValidator { + + /** + * Adds to {@code errors} a throwable for each problem detected. Looks for + * {@code FixMethodOrder} annotations. + * + * @param testClass that is being validated + * @return A list of exceptions detected + * + * @since 4.13 + */ + @Override + public List validateAnnotatedClass(TestClass testClass) { + if (testClass.getAnnotation(FixMethodOrder.class) != null) { + return singletonList( + new Exception("@FixMethodOrder cannot be combined with @OrderWith")); + } + return emptyList(); + } +} diff --git a/src/main/java/org/junit/runner/Request.java b/src/main/java/org/junit/runner/Request.java index 264489217f74..7b9a99003b47 100644 --- a/src/main/java/org/junit/runner/Request.java +++ b/src/main/java/org/junit/runner/Request.java @@ -5,9 +5,11 @@ import org.junit.internal.builders.AllDefaultPossibilitiesBuilder; import org.junit.internal.requests.ClassRequest; import org.junit.internal.requests.FilterRequest; +import org.junit.internal.requests.OrderingRequest; import org.junit.internal.requests.SortingRequest; import org.junit.internal.runners.ErrorReportingRunner; import org.junit.runner.manipulation.Filter; +import org.junit.runner.manipulation.Ordering; import org.junit.runners.model.InitializationError; /** @@ -151,15 +153,15 @@ public Request filterWith(Description desiredDescription) { * For example, here is code to run a test suite in alphabetical order: *
      * private static Comparator<Description> forward() {
-     * return new Comparator<Description>() {
-     * public int compare(Description o1, Description o2) {
-     * return o1.getDisplayName().compareTo(o2.getDisplayName());
-     * }
-     * };
+     *   return new Comparator<Description>() {
+     *     public int compare(Description o1, Description o2) {
+     *       return o1.getDisplayName().compareTo(o2.getDisplayName());
+     *     }
+     *   };
      * }
      *
      * public static main() {
-     * new JUnitCore().run(Request.aClass(AllTests.class).sortWith(forward()));
+     *   new JUnitCore().run(Request.aClass(AllTests.class).sortWith(forward()));
      * }
      * 
* @@ -169,4 +171,32 @@ public Request filterWith(Description desiredDescription) { public Request sortWith(Comparator comparator) { return new SortingRequest(this, comparator); } + + /** + * Returns a Request whose Tests can be run in a certain order, defined by + * ordering + *

+ * For example, here is code to run a test suite in reverse order: + *

+     * private static Ordering reverse() {
+     *   return new Ordering() {
+     *     public List<Description> orderItems(Collection<Description> descriptions) {
+     *       List<Description> ordered = new ArrayList<>(descriptions);
+     *       Collections.reverse(ordered);
+     *       return ordered;
+     *     }
+     *   }
+     * }
+     *     
+     * public static main() {
+     *   new JUnitCore().run(Request.aClass(AllTests.class).orderWith(reverse()));
+     * }
+     * 
+ * + * @return a Request with ordered Tests + * @since 4.13 + */ + public Request orderWith(Ordering ordering) { + return new OrderingRequest(this, ordering); + } } diff --git a/src/main/java/org/junit/runner/manipulation/Alphanumeric.java b/src/main/java/org/junit/runner/manipulation/Alphanumeric.java new file mode 100644 index 000000000000..8388d21eb804 --- /dev/null +++ b/src/main/java/org/junit/runner/manipulation/Alphanumeric.java @@ -0,0 +1,27 @@ +package org.junit.runner.manipulation; + +import java.util.Comparator; + +import org.junit.runner.Description; + +/** + * A sorter that orders tests alphanumerically by test name. + * + * @since 4.13 + */ +public final class Alphanumeric extends Sorter implements Ordering.Factory { + + public Alphanumeric() { + super(COMPARATOR); + } + + public Ordering create(Context context) { + return this; + } + + private static final Comparator COMPARATOR = new Comparator() { + public int compare(Description o1, Description o2) { + return o1.getDisplayName().compareTo(o2.getDisplayName()); + } + }; +} diff --git a/src/main/java/org/junit/runner/manipulation/InvalidOrderingException.java b/src/main/java/org/junit/runner/manipulation/InvalidOrderingException.java new file mode 100644 index 000000000000..d9d60f778b62 --- /dev/null +++ b/src/main/java/org/junit/runner/manipulation/InvalidOrderingException.java @@ -0,0 +1,21 @@ +package org.junit.runner.manipulation; + +/** + * Thrown when an ordering does something invalid (like remove or add children) + * + * @since 4.13 + */ +public class InvalidOrderingException extends Exception { + private static final long serialVersionUID = 1L; + + public InvalidOrderingException() { + } + + public InvalidOrderingException(String message) { + super(message); + } + + public InvalidOrderingException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/main/java/org/junit/runner/manipulation/Orderable.java b/src/main/java/org/junit/runner/manipulation/Orderable.java new file mode 100644 index 000000000000..9a12a3bc1ef2 --- /dev/null +++ b/src/main/java/org/junit/runner/manipulation/Orderable.java @@ -0,0 +1,21 @@ +package org.junit.runner.manipulation; + +/** + * Interface for runners that allow ordering of tests. + * + *

Beware of using this interface to cope with order dependencies between tests. + * Tests that are isolated from each other are less expensive to maintain and + * can be run individually. + * + * @since 4.13 + */ +public interface Orderable extends Sortable { + + /** + * Orders the tests using orderer + * + * @throws InvalidOrderingException if orderer does something invalid (like remove or add + * children) + */ + void order(Orderer orderer) throws InvalidOrderingException; +} diff --git a/src/main/java/org/junit/runner/manipulation/Orderer.java b/src/main/java/org/junit/runner/manipulation/Orderer.java new file mode 100644 index 000000000000..eb1305437076 --- /dev/null +++ b/src/main/java/org/junit/runner/manipulation/Orderer.java @@ -0,0 +1,62 @@ +package org.junit.runner.manipulation; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.junit.runner.Description; + +/** + * Orders tests. + * + * @since 4.13 + */ +public final class Orderer { + private final Ordering ordering; + + Orderer(Ordering delegate) { + this.ordering = delegate; + } + + /** + * Orders the descriptions. + * + * @return descriptions in order + */ + public List order(Collection descriptions) + throws InvalidOrderingException { + List inOrder = ordering.orderItems( + Collections.unmodifiableCollection(descriptions)); + if (!ordering.validateOrderingIsCorrect()) { + return inOrder; + } + + Set uniqueDescriptions = new HashSet(descriptions); + if (!uniqueDescriptions.containsAll(inOrder)) { + throw new InvalidOrderingException("Ordering added items"); + } + Set resultAsSet = new HashSet(inOrder); + if (resultAsSet.size() != inOrder.size()) { + throw new InvalidOrderingException("Ordering duplicated items"); + } else if (!resultAsSet.containsAll(uniqueDescriptions)) { + throw new InvalidOrderingException("Ordering removed items"); + } + + return inOrder; + } + + /** + * Order the tests in target. + * + * @throws InvalidOrderingException if ordering does something invalid (like remove or add + * children) + */ + public void apply(Object target) throws InvalidOrderingException { + if (target instanceof Orderable) { + Orderable orderable = (Orderable) target; + orderable.order(this); + } + } +} diff --git a/src/main/java/org/junit/runner/manipulation/Ordering.java b/src/main/java/org/junit/runner/manipulation/Ordering.java new file mode 100644 index 000000000000..0d0ce93780e6 --- /dev/null +++ b/src/main/java/org/junit/runner/manipulation/Ordering.java @@ -0,0 +1,172 @@ +package org.junit.runner.manipulation; + +import java.lang.reflect.Constructor; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Random; + +import org.junit.runner.Description; +import org.junit.runner.OrderWith; + +/** + * Reorders tests. An {@code Ordering} can reverse the order of tests, sort the + * order or even shuffle the order. + * + *

In general you will not need to use a Ordering directly. + * Instead, use {@link org.junit.runner.Request#orderWith(Ordering)}. + * + * @since 4.13 + */ +public abstract class Ordering { + private static final String CONSTRUCTOR_ERROR_FORMAT + = "Ordering class %s should have a public constructor with signature " + + "%s(Ordering.Context context)"; + + /** + * Creates an {@link Ordering} that shuffles the items using the given + * {@link Random} instance. + */ + public static Ordering shuffledBy(final Random random) { + return new Ordering() { + @Override + boolean validateOrderingIsCorrect() { + return false; + } + + @Override + protected List orderItems(Collection descriptions) { + List shuffled = new ArrayList(descriptions); + Collections.shuffle(shuffled, random); + return shuffled; + } + }; + } + + /** + * Creates an {@link Ordering} from the given factory class. The class must have a public no-arg + * constructor. + * + * @param factoryClass class to use to create the ordering + * @param annotatedTestClass test class that is annotated with {@link OrderWith}. + * @throws InvalidOrderingException if the instance could not be created + */ + public static Ordering definedBy( + Class factoryClass, Description annotatedTestClass) + throws InvalidOrderingException { + if (factoryClass == null) { + throw new NullPointerException("factoryClass cannot be null"); + } + if (annotatedTestClass == null) { + throw new NullPointerException("annotatedTestClass cannot be null"); + } + + Ordering.Factory factory; + try { + Constructor constructor = factoryClass.getConstructor(); + factory = constructor.newInstance(); + } catch (NoSuchMethodException e) { + throw new InvalidOrderingException(String.format( + CONSTRUCTOR_ERROR_FORMAT, + getClassName(factoryClass), + factoryClass.getSimpleName())); + } catch (Exception e) { + throw new InvalidOrderingException( + "Could not create ordering for " + annotatedTestClass, e); + } + return definedBy(factory, annotatedTestClass); + } + + /** + * Creates an {@link Ordering} from the given factory. + * + * @param factory factory to use to create the ordering + * @param annotatedTestClass test class that is annotated with {@link OrderWith}. + * @throws InvalidOrderingException if the instance could not be created + */ + public static Ordering definedBy( + Ordering.Factory factory, Description annotatedTestClass) + throws InvalidOrderingException { + if (factory == null) { + throw new NullPointerException("factory cannot be null"); + } + if (annotatedTestClass == null) { + throw new NullPointerException("annotatedTestClass cannot be null"); + } + + return factory.create(new Ordering.Context(annotatedTestClass)); + } + + private static String getClassName(Class clazz) { + String name = clazz.getCanonicalName(); + if (name == null) { + return clazz.getName(); + } + return name; + } + + /** + * Order the tests in target using this ordering. + * + * @throws InvalidOrderingException if ordering does something invalid (like remove or add + * children) + */ + public void apply(Object target) throws InvalidOrderingException { + /* + * Note that some subclasses of Ordering override apply(). The Sorter + * subclass of Ordering overrides apply() to apply the sort (this is + * done because sorting is more efficient than ordering). + */ + if (target instanceof Orderable) { + Orderable orderable = (Orderable) target; + orderable.order(new Orderer(this)); + } + } + + /** + * Returns {@code true} if this ordering could produce invalid results (i.e. + * if it could add or remove values). + */ + boolean validateOrderingIsCorrect() { + return true; + } + + /** + * Implemented by sub-classes to order the descriptions. + * + * @return descriptions in order + */ + protected abstract List orderItems(Collection descriptions); + + /** Context about the ordering being applied. */ + public static class Context { + private final Description description; + + /** + * Gets the description for the top-level target being ordered. + */ + public Description getTarget() { + return description; + } + + private Context(Description description) { + this.description = description; + } + } + + /** + * Factory for creating {@link Ordering} instances. + * + *

For a factory to be used with {@code @OrderWith} it needs to have a public no-arg + * constructor. + */ + public interface Factory { + /** + * Creates an Ordering instance using the given context. Implementations + * of this method that do not need to use the context can return the + * same instance every time. + */ + Ordering create(Context context); + } +} diff --git a/src/main/java/org/junit/runner/manipulation/Sorter.java b/src/main/java/org/junit/runner/manipulation/Sorter.java index 20192d0c96e8..4b5274c31012 100644 --- a/src/main/java/org/junit/runner/manipulation/Sorter.java +++ b/src/main/java/org/junit/runner/manipulation/Sorter.java @@ -1,16 +1,21 @@ package org.junit.runner.manipulation; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; import java.util.Comparator; +import java.util.List; import org.junit.runner.Description; /** * A Sorter orders tests. In general you will not need - * to use a Sorter directly. Instead, use {@link org.junit.runner.Request#sortWith(Comparator)}. + * to use a Sorter directly. Instead, use + * {@link org.junit.runner.Request#sortWith(Comparator)}. * * @since 4.0 */ -public class Sorter implements Comparator { +public class Sorter extends Ordering implements Comparator { /** * NULL is a Sorter that leaves elements in an undefined order */ @@ -27,17 +32,26 @@ public int compare(Description o1, Description o2) { * to sort tests * * @param comparator the {@link Comparator} to use when sorting tests + * @since 4.0 */ public Sorter(Comparator comparator) { this.comparator = comparator; } /** - * Sorts the test in runner using comparator + * Sorts the tests in target using comparator. + * + * @since 4.0 */ - public void apply(Object object) { - if (object instanceof Sortable) { - Sortable sortable = (Sortable) object; + @Override + public void apply(Object target) { + /* + * Note that all runners that are Orderable are also Sortable (because + * Orderable extends Sortable). Sorting is more efficient than ordering, + * so we override the parent behavior so we sort instead. + */ + if (target instanceof Sortable) { + Sortable sortable = (Sortable) target; sortable.sort(this); } } @@ -45,4 +59,32 @@ public void apply(Object object) { public int compare(Description o1, Description o2) { return comparator.compare(o1, o2); } + + /** + * {@inheritDoc} + * + * @since 4.13 + */ + @Override + protected final List orderItems(Collection descriptions) { + /* + * In practice, we will never get here--Sorters do their work in the + * compare() method--but the Liskov substitution principle demands that + * we obey the general contract of Orderable. Luckily, it's trivial to + * implement. + */ + List sorted = new ArrayList(descriptions); + Collections.sort(sorted, this); // Note: it would be incorrect to pass in "comparator" + return sorted; + } + + /** + * {@inheritDoc} + * + * @since 4.13 + */ + @Override + boolean validateOrderingIsCorrect() { + return false; + } } diff --git a/src/main/java/org/junit/runner/notification/RunListener.java b/src/main/java/org/junit/runner/notification/RunListener.java index 9048c5016f37..d7cac003f1c6 100644 --- a/src/main/java/org/junit/runner/notification/RunListener.java +++ b/src/main/java/org/junit/runner/notification/RunListener.java @@ -76,7 +76,7 @@ public void testRunFinished(Result result) throws Exception { * *

Note that not all runners will call this method, so runners should * be prepared to handle {@link #testStarted(Description)} calls for tests - * where there was no cooresponding {@code testSuiteStarted()} call for + * where there was no corresponding {@code testSuiteStarted()} call for * the parent {@code Description}. * * @param description the description of the test suite that is about to be run diff --git a/src/main/java/org/junit/runner/notification/SynchronizedRunListener.java b/src/main/java/org/junit/runner/notification/SynchronizedRunListener.java index 0cd2f49444d7..400fed8fcebf 100644 --- a/src/main/java/org/junit/runner/notification/SynchronizedRunListener.java +++ b/src/main/java/org/junit/runner/notification/SynchronizedRunListener.java @@ -10,7 +10,7 @@ *

This class synchronizes all listener calls on a RunNotifier instance. This is done because * prior to JUnit 4.12, all listeners were called in a synchronized block in RunNotifier, * so no two listeners were ever called concurrently. If we instead made the methods here - * sychronized, clients that added multiple listeners that called common code might see + * synchronized, clients that added multiple listeners that called common code might see * issues due to the reduced synchronization. * * @author Tibor Digana (tibor17) diff --git a/src/main/java/org/junit/runners/BlockJUnit4ClassRunner.java b/src/main/java/org/junit/runners/BlockJUnit4ClassRunner.java index 8ce14d95ea07..455341aa0cb9 100644 --- a/src/main/java/org/junit/runners/BlockJUnit4ClassRunner.java +++ b/src/main/java/org/junit/runners/BlockJUnit4ClassRunner.java @@ -319,6 +319,7 @@ protected Object runReflectiveCall() throws Throwable { statement = withBefores(method, test, statement); statement = withAfters(method, test, statement); statement = withRules(method, test, statement); + statement = withInterruptIsolation(statement); return statement; } @@ -458,7 +459,7 @@ private long getTimeout(Test annotation) { private static class RuleCollector implements MemberValueConsumer { final List result = new ArrayList(); - public void accept(FrameworkMember member, T value) { + public void accept(FrameworkMember member, T value) { Rule rule = member.getAnnotation(Rule.class); if (rule != null) { RuleContainer container = CURRENT_RULE_CONTAINER.get(); diff --git a/src/main/java/org/junit/runners/Parameterized.java b/src/main/java/org/junit/runners/Parameterized.java index 9dffb54b853b..d11b66a2d0c3 100644 --- a/src/main/java/org/junit/runners/Parameterized.java +++ b/src/main/java/org/junit/runners/Parameterized.java @@ -15,6 +15,7 @@ import org.junit.internal.AssumptionViolatedException; import org.junit.runner.Description; +import org.junit.runner.Result; import org.junit.runner.Runner; import org.junit.runner.notification.Failure; import org.junit.runner.notification.RunNotifier; @@ -184,6 +185,21 @@ * } * * + *

Avoid creating parameters

+ *

With {@link org.junit.Assume assumptions} you can dynamically skip tests. + * Assumptions are also supported by the @Parameters method. + * Creating parameters is stopped when the assumption fails and none of the + * tests in the test class is executed. JUnit reports a + * {@link Result#getAssumptionFailureCount() single assumption failure} for the + * whole test class in this case. + *

+ * @Parameters
+ * public static Iterable<? extends Object> data() {
+ * 	String os = System.getProperty("os.name").toLowerCase()
+ * 	Assume.assumeTrue(os.contains("win"));
+ * 	return Arrays.asList("first test", "second test");
+ * }
+ * 
* @since 4.0 */ public class Parameterized extends Suite { diff --git a/src/main/java/org/junit/runners/ParentRunner.java b/src/main/java/org/junit/runners/ParentRunner.java index 4949c242e5b2..0a0e7cb6a583 100644 --- a/src/main/java/org/junit/runners/ParentRunner.java +++ b/src/main/java/org/junit/runners/ParentRunner.java @@ -7,18 +7,19 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.ClassRule; +import org.junit.FixMethodOrder; import org.junit.Ignore; import org.junit.Rule; import org.junit.internal.AssumptionViolatedException; @@ -31,8 +32,10 @@ import org.junit.runner.Runner; import org.junit.runner.manipulation.Filter; import org.junit.runner.manipulation.Filterable; +import org.junit.runner.manipulation.Orderer; +import org.junit.runner.manipulation.InvalidOrderingException; import org.junit.runner.manipulation.NoTestsRemainException; -import org.junit.runner.manipulation.Sortable; +import org.junit.runner.manipulation.Orderable; import org.junit.runner.manipulation.Sorter; import org.junit.runner.notification.RunNotifier; import org.junit.runner.notification.StoppedByUserException; @@ -61,15 +64,15 @@ * @since 4.5 */ public abstract class ParentRunner extends Runner implements Filterable, - Sortable { - private static final List VALIDATORS = Arrays.asList( + Orderable { + private static final List VALIDATORS = Collections.singletonList( new AnnotationsValidator()); private final Lock childrenLock = new ReentrantLock(); private final TestClass testClass; // Guarded by childrenLock - private volatile Collection filteredChildren = null; + private volatile List filteredChildren = null; private volatile RunnerScheduler scheduler = new RunnerScheduler() { public void schedule(Runnable childStatement) { @@ -212,6 +215,7 @@ protected Statement classBlock(final RunNotifier notifier) { statement = withBeforeClasses(statement); statement = withAfterClasses(statement); statement = withClassRules(statement); + statement = withInterruptIsolation(statement); } return statement; } @@ -291,6 +295,22 @@ public void evaluate() { }; } + /** + * @return a {@link Statement}: clears interrupt status of current thread after execution of statement + */ + protected final Statement withInterruptIsolation(final Statement statement) { + return new Statement() { + @Override + public void evaluate() throws Throwable { + try { + statement.evaluate(); + } finally { + Thread.interrupted(); // clearing thread interrupted status for isolation + } + } + }; + } + /** * Evaluates whether a child is ignored. The default implementation always * returns false. @@ -422,7 +442,7 @@ public void filter(Filter filter) throws NoTestsRemainException { iter.remove(); } } - filteredChildren = Collections.unmodifiableCollection(children); + filteredChildren = Collections.unmodifiableList(children); if (filteredChildren.isEmpty()) { throw new NoTestsRemainException(); } @@ -432,6 +452,10 @@ public void filter(Filter filter) throws NoTestsRemainException { } public void sort(Sorter sorter) { + if (shouldNotReorder()) { + return; + } + childrenLock.lock(); try { for (T each : getFilteredChildren()) { @@ -439,7 +463,47 @@ public void sort(Sorter sorter) { } List sortedChildren = new ArrayList(getFilteredChildren()); Collections.sort(sortedChildren, comparator(sorter)); - filteredChildren = Collections.unmodifiableCollection(sortedChildren); + filteredChildren = Collections.unmodifiableList(sortedChildren); + } finally { + childrenLock.unlock(); + } + } + + /** + * Implementation of {@link Orderable#order(Orderer)}. + * + * @since 4.13 + */ + public void order(Orderer orderer) throws InvalidOrderingException { + if (shouldNotReorder()) { + return; + } + + childrenLock.lock(); + try { + List children = getFilteredChildren(); + // In theory, we could have duplicate Descriptions. De-dup them before ordering, + // and add them back at the end. + Map> childMap = new LinkedHashMap>( + children.size()); + for (T child : children) { + Description description = describeChild(child); + List childrenWithDescription = childMap.get(description); + if (childrenWithDescription == null) { + childrenWithDescription = new ArrayList(1); + childMap.put(description, childrenWithDescription); + } + childrenWithDescription.add(child); + orderer.apply(child); + } + + List inOrder = orderer.order(childMap.keySet()); + + children = new ArrayList(children.size()); + for (Description description : inOrder) { + children.addAll(childMap.get(description)); + } + filteredChildren = Collections.unmodifiableList(children); } finally { childrenLock.unlock(); } @@ -449,6 +513,11 @@ public void sort(Sorter sorter) { // Private implementation // + private boolean shouldNotReorder() { + // If the test specifies a specific order, do not reorder. + return getDescription().getAnnotation(FixMethodOrder.class) != null; + } + private void validate() throws InitializationError { List errors = new ArrayList(); collectInitializationErrors(errors); @@ -457,12 +526,13 @@ private void validate() throws InitializationError { } } - private Collection getFilteredChildren() { + private List getFilteredChildren() { if (filteredChildren == null) { childrenLock.lock(); try { if (filteredChildren == null) { - filteredChildren = Collections.unmodifiableCollection(getChildren()); + filteredChildren = Collections.unmodifiableList( + new ArrayList(getChildren())); } } finally { childrenLock.unlock(); @@ -494,16 +564,13 @@ public void setScheduler(RunnerScheduler scheduler) { private static class ClassRuleCollector implements MemberValueConsumer { final List entries = new ArrayList(); - public void accept(FrameworkMember member, TestRule value) { + public void accept(FrameworkMember member, TestRule value) { ClassRule rule = member.getAnnotation(ClassRule.class); entries.add(new RuleContainer.RuleEntry(value, RuleContainer.RuleEntry.TYPE_TEST_RULE, rule != null ? rule.order() : null)); } public List getOrderedRules() { - if (entries.isEmpty()) { - return Collections.emptyList(); - } Collections.sort(entries, RuleContainer.ENTRY_COMPARATOR); List result = new ArrayList(entries.size()); for (RuleContainer.RuleEntry entry : entries) { diff --git a/src/main/java/org/junit/runners/model/FrameworkField.java b/src/main/java/org/junit/runners/model/FrameworkField.java index 9065d8324e08..e99d05b46312 100644 --- a/src/main/java/org/junit/runners/model/FrameworkField.java +++ b/src/main/java/org/junit/runners/model/FrameworkField.java @@ -47,7 +47,7 @@ public T getAnnotation(Class annotationType) { @Override public boolean isShadowedBy(FrameworkField otherMember) { - return isStatic() && otherMember.getName().equals(getName()); + return otherMember.getName().equals(getName()); } @Override diff --git a/src/main/java/org/junit/runners/model/FrameworkMember.java b/src/main/java/org/junit/runners/model/FrameworkMember.java index 19e35f454591..5634b3f0ca98 100644 --- a/src/main/java/org/junit/runners/model/FrameworkMember.java +++ b/src/main/java/org/junit/runners/model/FrameworkMember.java @@ -12,13 +12,7 @@ public abstract class FrameworkMember> implements Annotatable { abstract boolean isShadowedBy(T otherMember); - /** - * Check if this member is shadowed by any of the given members. If it - * is, the other member is removed. - * - * @return member that should be used, or {@code null} if no member should be used. - */ - final T handlePossibleShadowedMember(List members) { + T handlePossibleBridgeMethod(List members) { for (int i = members.size() - 1; i >=0; i--) { T otherMember = members.get(i); if (isShadowedBy(otherMember)) { @@ -36,11 +30,6 @@ final T handlePossibleShadowedMember(List members) { } } // No shadow or bridge method found. The caller should add *this* member. - return self(); - } - - @SuppressWarnings("unchecked") - private T self() { return (T) this; } diff --git a/src/main/java/org/junit/runners/model/MemberValueConsumer.java b/src/main/java/org/junit/runners/model/MemberValueConsumer.java index 351b23ef7889..a6157bf3be72 100644 --- a/src/main/java/org/junit/runners/model/MemberValueConsumer.java +++ b/src/main/java/org/junit/runners/model/MemberValueConsumer.java @@ -11,8 +11,8 @@ public interface MemberValueConsumer { /** * Receives the next value and its declaring member. * - * @param member declaring member ({@link FrameworkMethod or {@link FrameworkField}} + * @param member declaring member ({@link FrameworkMethod} or {@link FrameworkField}) * @param value the value of the next member */ - void accept(FrameworkMember member, T value); + void accept(FrameworkMember member, T value); } diff --git a/src/main/java/org/junit/runners/model/RunnerBuilder.java b/src/main/java/org/junit/runners/model/RunnerBuilder.java index bc6f85f04813..ba7c9e24d6ba 100644 --- a/src/main/java/org/junit/runners/model/RunnerBuilder.java +++ b/src/main/java/org/junit/runners/model/RunnerBuilder.java @@ -6,7 +6,11 @@ import java.util.Set; import org.junit.internal.runners.ErrorReportingRunner; +import org.junit.runner.Description; +import org.junit.runner.OrderWith; import org.junit.runner.Runner; +import org.junit.runner.manipulation.InvalidOrderingException; +import org.junit.runner.manipulation.Ordering; /** * A RunnerBuilder is a strategy for constructing runners for classes. @@ -63,12 +67,25 @@ public abstract class RunnerBuilder { */ public Runner safeRunnerForClass(Class testClass) { try { - return runnerForClass(testClass); + Runner runner = runnerForClass(testClass); + if (runner != null) { + configureRunner(runner); + } + return runner; } catch (Throwable e) { return new ErrorReportingRunner(testClass, e); } } + private void configureRunner(Runner runner) throws InvalidOrderingException { + Description description = runner.getDescription(); + OrderWith orderWith = description.getAnnotation(OrderWith.class); + if (orderWith != null) { + Ordering ordering = Ordering.definedBy(orderWith.value(), description); + ordering.apply(runner); + } + } + Class addParent(Class parent) throws InitializationError { if (!parents.add(parent)) { throw new InitializationError(String.format("class '%s' (possibly indirectly) contains itself as a SuiteClass", parent.getName())); diff --git a/src/main/java/org/junit/runners/model/TestClass.java b/src/main/java/org/junit/runners/model/TestClass.java index 55b3e3b3e808..5962c2b478dc 100644 --- a/src/main/java/org/junit/runners/model/TestClass.java +++ b/src/main/java/org/junit/runners/model/TestClass.java @@ -84,7 +84,7 @@ protected static > void addToAnnotationLists(T memb for (Annotation each : member.getAnnotations()) { Class type = each.annotationType(); List members = getAnnotatedMembers(map, type, true); - T memberToAdd = member.handlePossibleShadowedMember(members); + T memberToAdd = member.handlePossibleBridgeMethod(members); if (memberToAdd == null) { return; } @@ -228,7 +228,7 @@ public List getAnnotatedFieldValues(Object test, final List results = new ArrayList(); collectAnnotatedFieldValues(test, annotationClass, valueClass, new MemberValueConsumer() { - public void accept(FrameworkMember member, T value) { + public void accept(FrameworkMember member, T value) { results.add(value); } }); @@ -262,7 +262,7 @@ public List getAnnotatedMethodValues(Object test, final List results = new ArrayList(); collectAnnotatedMethodValues(test, annotationClass, valueClass, new MemberValueConsumer() { - public void accept(FrameworkMember member, T value) { + public void accept(FrameworkMember member, T value) { results.add(value); } }); diff --git a/src/main/java/org/junit/validator/ValidateWith.java b/src/main/java/org/junit/validator/ValidateWith.java index 03d790670f75..3725db81f954 100644 --- a/src/main/java/org/junit/validator/ValidateWith.java +++ b/src/main/java/org/junit/validator/ValidateWith.java @@ -1,8 +1,10 @@ package org.junit.validator; +import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; /** * Allows for an {@link AnnotationValidator} to be attached to an annotation. @@ -13,6 +15,7 @@ * @since 4.12 */ @Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.ANNOTATION_TYPE) @Inherited public @interface ValidateWith { Class value(); diff --git a/src/site/fml/faq.fml b/src/site/fml/faq.fml index b5a6bdddc792..bb8fe5e37cc3 100644 --- a/src/site/fml/faq.fml +++ b/src/site/fml/faq.fml @@ -128,15 +128,6 @@ - -Where can I find articles on - JUnit? -

- The JUnit home page maintains a list - of JUnit - articles. -

-
How is JUnit licensed? @@ -315,7 +306,7 @@

Please stick to technical issues on the discussion forum and mailing lists. Keep in mind that these are public, so - do not include any confidental information in your + do not include any confidential information in your questions!

@@ -346,7 +337,7 @@

JUnit is hosted on GitHub. + href="http://github/junit-team/junit4">GitHub. Please use the tools provided by GitHub for your submissions.

@@ -1060,7 +1051,7 @@ oneTimeTearDown() (Submitted by: Eric Armstrong)

- To run your JUnit tests, you'll need the following elemements in + To run your JUnit tests, you'll need the following elements in your CLASSPATH:

    @@ -1252,7 +1243,7 @@ oneTimeTearDown()

    -DparameterName=parameterValue

    - If the number of parameters on the command line gets unweildy, + If the number of parameters on the command line gets unwieldy, pass in the location of a property file that defines a set of parameters. Alternatively, the JUnit-addons package @@ -1375,7 +1366,7 @@ excluded.8=net.jini.* now you can have the reverse problem where the JUnit loader will load a host of org.w3c.dom/org.xml.sax classes, and then the system loader violates the loader - contraints at some point when it tries to do exactly what I + constraints at some point when it tries to do exactly what I described above with JAXP because it doesn't ever delegate to its logical child (the JUnit loader). Inevitably, if your test cases use many JAXP and related XML classes, one or the other @@ -1472,7 +1463,7 @@ a test failure, rather than the source file's line number?

    DirectorySuiteBuilder builder = new DirectorySuiteBuilder();
     builder.setSuffix("Test");
    -Test suite = builer.suite("/home/project/myproject/tests");
    +Test suite = builder.suite("/home/project/myproject/tests");

    Documentation and examples are at http://junit-addons.sourceforge.net. @@ -1708,14 +1699,6 @@ end Miscellaneous - - How do I integrate JUnit with my IDE? -

    - The JUnit home page maintains a list of IDE integration - instructions. -

    - How do I launch a debugger when a test fails?

    diff --git a/src/site/resources/css/carousel.css b/src/site/resources/css/carousel.css new file mode 100644 index 000000000000..bc63d46add7c --- /dev/null +++ b/src/site/resources/css/carousel.css @@ -0,0 +1,13 @@ +.carousel-content { + height: 20em; +} +.carousel-caption a { + color: #ffffff; +} +#junit-lambda-teaser { + background: url(../images/junit-lambda/background.png); + text-align: center; +} +#junit-lambda-teaser p { + padding-top: 25px; +} \ No newline at end of file diff --git a/src/site/resources/css/junit-lambda.css b/src/site/resources/css/junit-lambda.css new file mode 100644 index 000000000000..fbcb1feb0242 --- /dev/null +++ b/src/site/resources/css/junit-lambda.css @@ -0,0 +1,69 @@ +ul.inline { + margin-left: 0; + list-style: none; +} +.inline li { + display: inline-block; + margin-right: 10px; + margin-bottom: 10px; +} + +.sponsors li { + border: 1px solid #e3e3e3; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.sponsors li:hover { + border-color: #c5c5c5; +} +.sponsors li { + text-align: center; + padding: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); +} +.sponsors li a { + display: block; + padding: 0 10px !important; +} + +.sponsors-small li a img { + max-height: 100px; + max-width: 200px; +} + +.sponsors-small li a { + width: 200px; + height: 120px; + line-height: 120px; +} +.sponsors-medium li a { + width: 278px; + height: 141px; + line-height: 141px; +} +.sponsors-large li a { + width: 435px; + height: 237px; + line-height: 237px; +} + +ul.people { + margin-left: 7px; + margin-right: 7px; +} +.people li { + display: block; + width: 170px; + margin: 0; + padding: 0 15px 0 0; + float: left; + text-align: center; +} +.people img.avatar { + display: block; + width: 100%; + margin: 0 0 10px 0; +} diff --git a/src/site/resources/images/junit-lambda/background.png b/src/site/resources/images/junit-lambda/background.png new file mode 100644 index 000000000000..ff8b1be8654c Binary files /dev/null and b/src/site/resources/images/junit-lambda/background.png differ diff --git a/src/site/resources/images/junit-lambda/contributors/42talents.png b/src/site/resources/images/junit-lambda/contributors/42talents.png new file mode 100644 index 000000000000..cddcae9b5bfd Binary files /dev/null and b/src/site/resources/images/junit-lambda/contributors/42talents.png differ diff --git a/src/site/resources/images/junit-lambda/contributors/adnovum.png b/src/site/resources/images/junit-lambda/contributors/adnovum.png new file mode 100644 index 000000000000..0743bed58bc2 Binary files /dev/null and b/src/site/resources/images/junit-lambda/contributors/adnovum.png differ diff --git a/src/site/resources/images/junit-lambda/contributors/arcbees.png b/src/site/resources/images/junit-lambda/contributors/arcbees.png new file mode 100755 index 000000000000..943325e0bf1a Binary files /dev/null and b/src/site/resources/images/junit-lambda/contributors/arcbees.png differ diff --git a/src/site/resources/images/junit-lambda/contributors/autotrader.jpg b/src/site/resources/images/junit-lambda/contributors/autotrader.jpg new file mode 100644 index 000000000000..a20a8d69c11f Binary files /dev/null and b/src/site/resources/images/junit-lambda/contributors/autotrader.jpg differ diff --git a/src/site/resources/images/junit-lambda/contributors/bol.jpg b/src/site/resources/images/junit-lambda/contributors/bol.jpg new file mode 100644 index 000000000000..ba0a4f73202e Binary files /dev/null and b/src/site/resources/images/junit-lambda/contributors/bol.jpg differ diff --git a/src/site/resources/images/junit-lambda/contributors/bouvet.png b/src/site/resources/images/junit-lambda/contributors/bouvet.png new file mode 100644 index 000000000000..9f239ca57c93 Binary files /dev/null and b/src/site/resources/images/junit-lambda/contributors/bouvet.png differ diff --git a/src/site/resources/images/junit-lambda/contributors/devnexus.png b/src/site/resources/images/junit-lambda/contributors/devnexus.png new file mode 100644 index 000000000000..fa6d6ea25885 Binary files /dev/null and b/src/site/resources/images/junit-lambda/contributors/devnexus.png differ diff --git a/src/site/resources/images/junit-lambda/contributors/diffplug.png b/src/site/resources/images/junit-lambda/contributors/diffplug.png new file mode 100644 index 000000000000..e663310f72f4 Binary files /dev/null and b/src/site/resources/images/junit-lambda/contributors/diffplug.png differ diff --git a/src/site/resources/images/junit-lambda/contributors/disy.jpg b/src/site/resources/images/junit-lambda/contributors/disy.jpg new file mode 100644 index 000000000000..99210e522eab Binary files /dev/null and b/src/site/resources/images/junit-lambda/contributors/disy.jpg differ diff --git a/src/site/resources/images/junit-lambda/contributors/eclipse.png b/src/site/resources/images/junit-lambda/contributors/eclipse.png new file mode 100755 index 000000000000..47db56d82ac3 Binary files /dev/null and b/src/site/resources/images/junit-lambda/contributors/eclipse.png differ diff --git a/src/site/resources/images/junit-lambda/contributors/ergon.png b/src/site/resources/images/junit-lambda/contributors/ergon.png new file mode 100644 index 000000000000..70c2014ba387 Binary files /dev/null and b/src/site/resources/images/junit-lambda/contributors/ergon.png differ diff --git a/src/site/resources/images/junit-lambda/contributors/gradle.png b/src/site/resources/images/junit-lambda/contributors/gradle.png new file mode 100644 index 000000000000..ed603e574563 Binary files /dev/null and b/src/site/resources/images/junit-lambda/contributors/gradle.png differ diff --git a/src/site/resources/images/junit-lambda/contributors/intellijidea.png b/src/site/resources/images/junit-lambda/contributors/intellijidea.png new file mode 100644 index 000000000000..5d9edbf29a2d Binary files /dev/null and b/src/site/resources/images/junit-lambda/contributors/intellijidea.png differ diff --git a/src/site/resources/images/junit-lambda/contributors/klarna.png b/src/site/resources/images/junit-lambda/contributors/klarna.png new file mode 100644 index 000000000000..9122da6b4c76 Binary files /dev/null and b/src/site/resources/images/junit-lambda/contributors/klarna.png differ diff --git a/src/site/resources/images/junit-lambda/contributors/klosebrothers.png b/src/site/resources/images/junit-lambda/contributors/klosebrothers.png new file mode 100644 index 000000000000..6ff579789d33 Binary files /dev/null and b/src/site/resources/images/junit-lambda/contributors/klosebrothers.png differ diff --git a/src/site/resources/images/junit-lambda/contributors/msgsystems.png b/src/site/resources/images/junit-lambda/contributors/msgsystems.png new file mode 100644 index 000000000000..68850ccc202e Binary files /dev/null and b/src/site/resources/images/junit-lambda/contributors/msgsystems.png differ diff --git a/src/site/resources/images/junit-lambda/contributors/murex.jpg b/src/site/resources/images/junit-lambda/contributors/murex.jpg new file mode 100644 index 000000000000..a86019ff4b1c Binary files /dev/null and b/src/site/resources/images/junit-lambda/contributors/murex.jpg differ diff --git a/src/site/resources/images/junit-lambda/contributors/netcetera.png b/src/site/resources/images/junit-lambda/contributors/netcetera.png new file mode 100644 index 000000000000..8520f90efe1b Binary files /dev/null and b/src/site/resources/images/junit-lambda/contributors/netcetera.png differ diff --git a/src/site/resources/images/junit-lambda/contributors/novatec.png b/src/site/resources/images/junit-lambda/contributors/novatec.png new file mode 100644 index 000000000000..b5a6ee3b1c18 Binary files /dev/null and b/src/site/resources/images/junit-lambda/contributors/novatec.png differ diff --git a/src/site/resources/images/junit-lambda/contributors/ociweb.png b/src/site/resources/images/junit-lambda/contributors/ociweb.png new file mode 100644 index 000000000000..36cb8d92106f Binary files /dev/null and b/src/site/resources/images/junit-lambda/contributors/ociweb.png differ diff --git a/src/site/resources/images/junit-lambda/contributors/oio.png b/src/site/resources/images/junit-lambda/contributors/oio.png new file mode 100644 index 000000000000..66ce7e397287 Binary files /dev/null and b/src/site/resources/images/junit-lambda/contributors/oio.png differ diff --git a/src/site/resources/images/junit-lambda/contributors/red6-es.jpg b/src/site/resources/images/junit-lambda/contributors/red6-es.jpg new file mode 100644 index 000000000000..f4bdb869e696 Binary files /dev/null and b/src/site/resources/images/junit-lambda/contributors/red6-es.jpg differ diff --git a/src/site/resources/images/junit-lambda/contributors/samuraism.png b/src/site/resources/images/junit-lambda/contributors/samuraism.png new file mode 100644 index 000000000000..fa804899097b Binary files /dev/null and b/src/site/resources/images/junit-lambda/contributors/samuraism.png differ diff --git a/src/site/resources/images/junit-lambda/contributors/siili.png b/src/site/resources/images/junit-lambda/contributors/siili.png new file mode 100644 index 000000000000..a757885fb660 Binary files /dev/null and b/src/site/resources/images/junit-lambda/contributors/siili.png differ diff --git a/src/site/resources/images/junit-lambda/contributors/sipgate.png b/src/site/resources/images/junit-lambda/contributors/sipgate.png new file mode 100644 index 000000000000..31cc742527fb Binary files /dev/null and b/src/site/resources/images/junit-lambda/contributors/sipgate.png differ diff --git a/src/site/resources/images/junit-lambda/contributors/six.gif b/src/site/resources/images/junit-lambda/contributors/six.gif new file mode 100644 index 000000000000..19f111831ba1 Binary files /dev/null and b/src/site/resources/images/junit-lambda/contributors/six.gif differ diff --git a/src/site/resources/images/junit-lambda/contributors/sonrisa.png b/src/site/resources/images/junit-lambda/contributors/sonrisa.png new file mode 100644 index 000000000000..350e0df1042d Binary files /dev/null and b/src/site/resources/images/junit-lambda/contributors/sonrisa.png differ diff --git a/src/site/resources/images/junit-lambda/contributors/squeed.png b/src/site/resources/images/junit-lambda/contributors/squeed.png new file mode 100644 index 000000000000..275f663c8795 Binary files /dev/null and b/src/site/resources/images/junit-lambda/contributors/squeed.png differ diff --git a/src/site/resources/images/junit-lambda/contributors/structure101.png b/src/site/resources/images/junit-lambda/contributors/structure101.png new file mode 100644 index 000000000000..f57ece9ae304 Binary files /dev/null and b/src/site/resources/images/junit-lambda/contributors/structure101.png differ diff --git a/src/site/resources/images/junit-lambda/contributors/synyx.jpg b/src/site/resources/images/junit-lambda/contributors/synyx.jpg new file mode 100755 index 000000000000..5143a738fec8 Binary files /dev/null and b/src/site/resources/images/junit-lambda/contributors/synyx.jpg differ diff --git a/src/site/resources/images/junit-lambda/contributors/tng.png b/src/site/resources/images/junit-lambda/contributors/tng.png new file mode 100644 index 000000000000..94db5512ebd2 Binary files /dev/null and b/src/site/resources/images/junit-lambda/contributors/tng.png differ diff --git a/src/site/resources/images/junit-lambda/contributors/topdesk.png b/src/site/resources/images/junit-lambda/contributors/topdesk.png new file mode 100644 index 000000000000..2a1d50c5767f Binary files /dev/null and b/src/site/resources/images/junit-lambda/contributors/topdesk.png differ diff --git a/src/site/resources/images/junit-lambda/contributors/vaddy.png b/src/site/resources/images/junit-lambda/contributors/vaddy.png new file mode 100644 index 000000000000..b595aef46558 Binary files /dev/null and b/src/site/resources/images/junit-lambda/contributors/vaddy.png differ diff --git a/src/site/resources/images/junit-lambda/contributors/zenika.png b/src/site/resources/images/junit-lambda/contributors/zenika.png new file mode 100644 index 000000000000..a83250c36573 Binary files /dev/null and b/src/site/resources/images/junit-lambda/contributors/zenika.png differ diff --git a/src/site/resources/images/junit-lambda/junit-lambda-logo.png b/src/site/resources/images/junit-lambda/junit-lambda-logo.png new file mode 100644 index 000000000000..d14a985e9f64 Binary files /dev/null and b/src/site/resources/images/junit-lambda/junit-lambda-logo.png differ diff --git a/src/site/resources/images/junit-lambda/sponsors/amex.png b/src/site/resources/images/junit-lambda/sponsors/amex.png new file mode 100644 index 000000000000..8f9d2f3c5a0c Binary files /dev/null and b/src/site/resources/images/junit-lambda/sponsors/amex.png differ diff --git a/src/site/resources/images/junit-lambda/sponsors/andrena.png b/src/site/resources/images/junit-lambda/sponsors/andrena.png new file mode 100644 index 000000000000..bd3663c5cc47 Binary files /dev/null and b/src/site/resources/images/junit-lambda/sponsors/andrena.png differ diff --git a/src/site/resources/images/junit-lambda/sponsors/heidelberg-mobil.png b/src/site/resources/images/junit-lambda/sponsors/heidelberg-mobil.png new file mode 100644 index 000000000000..2e3046a8f8eb Binary files /dev/null and b/src/site/resources/images/junit-lambda/sponsors/heidelberg-mobil.png differ diff --git a/src/site/resources/images/junit-lambda/sponsors/namics.png b/src/site/resources/images/junit-lambda/sponsors/namics.png new file mode 100644 index 000000000000..3a30b5205a30 Binary files /dev/null and b/src/site/resources/images/junit-lambda/sponsors/namics.png differ diff --git a/src/site/resources/images/junit-lambda/sponsors/pivotal.png b/src/site/resources/images/junit-lambda/sponsors/pivotal.png new file mode 100644 index 000000000000..1ee4d0c8eeee Binary files /dev/null and b/src/site/resources/images/junit-lambda/sponsors/pivotal.png differ diff --git a/src/site/resources/images/junit5-banner.png b/src/site/resources/images/junit5-banner.png new file mode 100644 index 000000000000..76a1243ddc28 Binary files /dev/null and b/src/site/resources/images/junit5-banner.png differ diff --git a/src/site/resources/scripts/index.js b/src/site/resources/scripts/index.js index 9e1486ec601c..043f1df72734 100644 --- a/src/site/resources/scripts/index.js +++ b/src/site/resources/scripts/index.js @@ -1,6 +1,6 @@ $(document).ready(function(){ $('#main-carousel').carousel({ - interval:5000 + interval:10000 }); $('#main-carousel-prev').on("click", function () { diff --git a/src/site/site.xml b/src/site/site.xml index 323f6eb065f6..89d1463a000f 100644 --- a/src/site/site.xml +++ b/src/site/site.xml @@ -3,7 +3,7 @@ xsi:schemaLocation="http://maven.apache.org/DECORATION/1.1.0 http://maven.apache.org/xsd/decoration-1.1.0.xsd"> ${project.name} - http://junit.org/images/junit-logo.png + ./images/junit-logo.png http://junit.org/ @@ -12,7 +12,6 @@ - @@ -24,18 +23,20 @@ + + - + -

    + - + @@ -45,7 +46,7 @@ false true - junit-team/junit + junit-team/junit4 right diff --git a/src/site/xdoc/index.xml b/src/site/xdoc/index.xml index d50b470a3360..dc13888e2408 100644 --- a/src/site/xdoc/index.xml +++ b/src/site/xdoc/index.xml @@ -14,8 +14,17 @@