From 2a0687c8905d9f9d1c8d4e1dee255a8ceabba5e5 Mon Sep 17 00:00:00 2001 From: David Srbecky Date: Wed, 24 Feb 2021 15:52:50 +0000 Subject: Revert "Remove support for stuck threads" Revert submission 1601635 Reason for revert: b/181123058 Reverted Changes: I8f5cd1266:Remove support for stuck threads Ifdb59336d:Remove DisableOnDebug (new in 4.12) as it is not s... I6abae5aed:Extra generic type information to aid certain java... I5ec909df6:Upgrade external/junit to 4.13.2 Change-Id: Icf0a7b88b0004e60cd4139cb10be62af5bdc68d2 --- .../internal/runners/statements/FailOnTimeout.java | 155 ++++++++++++++++++++- src/main/java/org/junit/rules/Timeout.java | 33 +++++ 2 files changed, 186 insertions(+), 2 deletions(-) (limited to 'src/main') diff --git a/src/main/java/org/junit/internal/runners/statements/FailOnTimeout.java b/src/main/java/org/junit/internal/runners/statements/FailOnTimeout.java index 9fad35b..9362cc1 100644 --- a/src/main/java/org/junit/internal/runners/statements/FailOnTimeout.java +++ b/src/main/java/org/junit/internal/runners/statements/FailOnTimeout.java @@ -1,5 +1,8 @@ package org.junit.internal.runners.statements; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; @@ -7,6 +10,9 @@ import java.util.concurrent.FutureTask; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import org.junit.internal.management.ManagementFactory; +import org.junit.internal.management.ThreadMXBean; +import org.junit.runners.model.MultipleFailureException; import org.junit.runners.model.Statement; import org.junit.runners.model.TestTimedOutException; @@ -14,6 +20,7 @@ public class FailOnTimeout extends Statement { private final Statement originalStatement; private final TimeUnit timeUnit; private final long timeout; + private final boolean lookForStuckThread; /** * Returns a new builder for building an instance. @@ -40,6 +47,7 @@ public class FailOnTimeout extends Statement { originalStatement = statement; timeout = builder.timeout; timeUnit = builder.unit; + lookForStuckThread = builder.lookForStuckThread; } /** @@ -48,6 +56,7 @@ public class FailOnTimeout extends Statement { * @since 4.12 */ public static class Builder { + private boolean lookForStuckThread = false; private long timeout = 0; private TimeUnit unit = TimeUnit.SECONDS; @@ -79,6 +88,20 @@ public class FailOnTimeout extends Statement { return this; } + /** + * Specifies whether to look for a stuck thread. If a timeout occurs and this + * feature is enabled, the test will look for a thread that appears to be stuck + * and dump its backtrace. This feature is experimental. Behavior may change + * after the 4.12 release in response to feedback. + * + * @param enable {@code true} to enable the feature + * @return {@code this} for method chaining. + */ + public Builder withLookingForStuckThread(boolean enable) { + this.lookForStuckThread = enable; + return this; + } + /** * Builds a {@link FailOnTimeout} instance using the values in this builder, * wrapping the given statement. @@ -97,7 +120,8 @@ public class FailOnTimeout extends Statement { public void evaluate() throws Throwable { CallableStatement callable = new CallableStatement(); FutureTask task = new FutureTask(callable); - Thread thread = new Thread(task, "Time-limited test"); + ThreadGroup threadGroup = threadGroupForNewThread(); + Thread thread = new Thread(threadGroup, task, "Time-limited test"); thread.setDaemon(true); thread.start(); callable.awaitStarted(); @@ -107,6 +131,31 @@ public class FailOnTimeout extends Statement { } } + private ThreadGroup threadGroupForNewThread() { + if (!lookForStuckThread) { + // Use the default ThreadGroup (usually the one from the current + // thread). + return null; + } + + // Create the thread in a new ThreadGroup, so if the time-limited thread + // becomes stuck, getStuckThread() can find the thread likely to be the + // culprit. + ThreadGroup threadGroup = new ThreadGroup("FailOnTimeoutGroup"); + if (!threadGroup.isDaemon()) { + // Mark the new ThreadGroup as a daemon thread group, so it will be + // destroyed after the time-limited thread completes. By ensuring the + // ThreadGroup is destroyed, any data associated with the ThreadGroup + // (ex: via java.beans.ThreadGroupContext) is destroyed. + try { + threadGroup.setDaemon(true); + } catch (SecurityException e) { + // Swallow the exception to keep the same behavior as in JUnit 4.12. + } + } + return threadGroup; + } + /** * Wait for the test task, returning the exception thrown by the test if the * test failed, an exception indicating a timeout if the test timed out, or @@ -131,12 +180,114 @@ public class FailOnTimeout extends Statement { private Exception createTimeoutException(Thread thread) { StackTraceElement[] stackTrace = thread.getStackTrace(); + final Thread stuckThread = lookForStuckThread ? getStuckThread(thread) : null; Exception currThreadException = new TestTimedOutException(timeout, timeUnit); if (stackTrace != null) { currThreadException.setStackTrace(stackTrace); thread.interrupt(); } - return currThreadException; + if (stuckThread != null) { + Exception stuckThreadException = + new Exception("Appears to be stuck in thread " + + stuckThread.getName()); + stuckThreadException.setStackTrace(getStackTrace(stuckThread)); + return new MultipleFailureException( + Arrays.asList(currThreadException, stuckThreadException)); + } else { + return currThreadException; + } + } + + /** + * Retrieves the stack trace for a given thread. + * @param thread The thread whose stack is to be retrieved. + * @return The stack trace; returns a zero-length array if the thread has + * terminated or the stack cannot be retrieved for some other reason. + */ + private StackTraceElement[] getStackTrace(Thread thread) { + try { + return thread.getStackTrace(); + } catch (SecurityException e) { + return new StackTraceElement[0]; + } + } + + /** + * Determines whether the test appears to be stuck in some thread other than + * the "main thread" (the one created to run the test). This feature is experimental. + * Behavior may change after the 4.12 release in response to feedback. + * @param mainThread The main thread created by {@code evaluate()} + * @return The thread which appears to be causing the problem, if different from + * {@code mainThread}, or {@code null} if the main thread appears to be the + * problem or if the thread cannot be determined. The return value is never equal + * to {@code mainThread}. + */ + private Thread getStuckThread(Thread mainThread) { + List threadsInGroup = getThreadsInGroup(mainThread.getThreadGroup()); + if (threadsInGroup.isEmpty()) { + return null; + } + + // Now that we have all the threads in the test's thread group: Assume that + // any thread we're "stuck" in is RUNNABLE. Look for all RUNNABLE threads. + // If just one, we return that (unless it equals threadMain). If there's more + // than one, pick the one that's using the most CPU time, if this feature is + // supported. + Thread stuckThread = null; + long maxCpuTime = 0; + for (Thread thread : threadsInGroup) { + if (thread.getState() == Thread.State.RUNNABLE) { + long threadCpuTime = cpuTime(thread); + if (stuckThread == null || threadCpuTime > maxCpuTime) { + stuckThread = thread; + maxCpuTime = threadCpuTime; + } + } + } + return (stuckThread == mainThread) ? null : stuckThread; + } + + /** + * Returns all active threads belonging to a thread group. + * @param group The thread group. + * @return The active threads in the thread group. The result should be a + * complete list of the active threads at some point in time. Returns an empty list + * if this cannot be determined, e.g. because new threads are being created at an + * extremely fast rate. + */ + private List getThreadsInGroup(ThreadGroup group) { + final int activeThreadCount = group.activeCount(); // this is just an estimate + int threadArraySize = Math.max(activeThreadCount * 2, 100); + for (int loopCount = 0; loopCount < 5; loopCount++) { + Thread[] threads = new Thread[threadArraySize]; + int enumCount = group.enumerate(threads); + if (enumCount < threadArraySize) { + return Arrays.asList(threads).subList(0, enumCount); + } + // if there are too many threads to fit into the array, enumerate's result + // is >= the array's length; therefore we can't trust that it returned all + // the threads. Try again. + threadArraySize += 100; + } + // threads are proliferating too fast for us. Bail before we get into + // trouble. + return Collections.emptyList(); + } + + /** + * Returns the CPU time used by a thread, if possible. + * @param thr The thread to query. + * @return The CPU time used by {@code thr}, or 0 if it cannot be determined. + */ + private long cpuTime(Thread thr) { + ThreadMXBean mxBean = ManagementFactory.getThreadMXBean(); + if (mxBean.isThreadCpuTimeSupported()) { + try { + return mxBean.getThreadCpuTime(thr.getId()); + } catch (UnsupportedOperationException e) { + } + } + return 0; } private class CallableStatement implements Callable { diff --git a/src/main/java/org/junit/rules/Timeout.java b/src/main/java/org/junit/rules/Timeout.java index 5cf905a..334a923 100644 --- a/src/main/java/org/junit/rules/Timeout.java +++ b/src/main/java/org/junit/rules/Timeout.java @@ -40,6 +40,7 @@ import java.util.concurrent.TimeUnit; public class Timeout implements TestRule { private final long timeout; private final TimeUnit timeUnit; + private final boolean lookForStuckThread; /** * Returns a new builder for building an instance. @@ -79,6 +80,7 @@ public class Timeout implements TestRule { public Timeout(long timeout, TimeUnit timeUnit) { this.timeout = timeout; this.timeUnit = timeUnit; + lookForStuckThread = false; } /** @@ -90,6 +92,7 @@ public class Timeout implements TestRule { protected Timeout(Builder builder) { timeout = builder.getTimeout(); timeUnit = builder.getTimeUnit(); + lookForStuckThread = builder.getLookingForStuckThread(); } /** @@ -121,6 +124,16 @@ public class Timeout implements TestRule { return unit.convert(timeout, timeUnit); } + /** + * Gets whether this {@code Timeout} will look for a stuck thread + * when the test times out. + * + * @since 4.12 + */ + protected final boolean getLookingForStuckThread() { + return lookForStuckThread; + } + /** * Creates a {@link Statement} that will run the given * {@code statement}, and timeout the operation based @@ -133,6 +146,7 @@ public class Timeout implements TestRule { Statement statement) throws Exception { return FailOnTimeout.builder() .withTimeout(timeout, timeUnit) + .withLookingForStuckThread(lookForStuckThread) .build(statement); } @@ -190,6 +204,25 @@ public class Timeout implements TestRule { return timeUnit; } + /** + * Specifies whether to look for a stuck thread. If a timeout occurs and this + * feature is enabled, the rule will look for a thread that appears to be stuck + * and dump its backtrace. This feature is experimental. Behavior may change + * after the 4.12 release in response to feedback. + * + * @param enable {@code true} to enable the feature + * @return {@code this} for method chaining. + */ + public Builder withLookingForStuckThread(boolean enable) { + this.lookForStuckThread = enable; + return this; + } + + protected boolean getLookingForStuckThread() { + return lookForStuckThread; + } + + /** * Builds a {@link Timeout} instance using the values in this builder., */ -- cgit v1.2.3 From d2b8e1f0634a7e5de2e5fcd5c9ca51c06e8a318c Mon Sep 17 00:00:00 2001 From: David Srbecky Date: Wed, 24 Feb 2021 15:52:50 +0000 Subject: Revert "Remove DisableOnDebug (new in 4.12) as it is not support..." Revert submission 1601635 Reason for revert: b/181123058 Reverted Changes: I8f5cd1266:Remove support for stuck threads Ifdb59336d:Remove DisableOnDebug (new in 4.12) as it is not s... I6abae5aed:Extra generic type information to aid certain java... I5ec909df6:Upgrade external/junit to 4.13.2 Change-Id: I464bf4512b5e19f37ba69ac42a5e9c22f61bc7d1 --- src/main/java/org/junit/rules/DisableOnDebug.java | 125 ++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 src/main/java/org/junit/rules/DisableOnDebug.java (limited to 'src/main') diff --git a/src/main/java/org/junit/rules/DisableOnDebug.java b/src/main/java/org/junit/rules/DisableOnDebug.java new file mode 100644 index 0000000..3bca103 --- /dev/null +++ b/src/main/java/org/junit/rules/DisableOnDebug.java @@ -0,0 +1,125 @@ +package org.junit.rules; + +import java.util.List; + +import org.junit.internal.management.ManagementFactory; +import org.junit.internal.management.RuntimeMXBean; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +/** + * The {@code DisableOnDebug} Rule allows you to label certain rules to be + * disabled when debugging. + *

+ * The most illustrative use case is for tests that make use of the + * {@link Timeout} rule, when ran in debug mode the test may terminate on + * timeout abruptly during debugging. Developers may disable the timeout, or + * increase the timeout by making a code change on tests that need debugging and + * remember revert the change afterwards or rules such as {@link Timeout} that + * may be disabled during debugging may be wrapped in a {@code DisableOnDebug}. + *

+ * The important benefit of this feature is that you can disable such rules + * without any making any modifications to your test class to remove them during + * debugging. + *

+ * This does nothing to tackle timeouts or time sensitive code under test when + * debugging and may make this less useful in such circumstances. + *

+ * Example usage: + * + *

+ * public static class DisableTimeoutOnDebugSampleTest {
+ * 
+ *     @Rule
+ *     public TestRule timeout = new DisableOnDebug(new Timeout(20));
+ * 
+ *     @Test
+ *     public void myTest() {
+ *         int i = 0;
+ *         assertEquals(0, i); // suppose you had a break point here to inspect i
+ *     }
+ * }
+ * 
+ * + * @since 4.12 + */ +public class DisableOnDebug implements TestRule { + private final TestRule rule; + private final boolean debugging; + + /** + * Create a {@code DisableOnDebug} instance with the timeout specified in + * milliseconds. + * + * @param rule to disable during debugging + */ + public DisableOnDebug(TestRule rule) { + this(rule, ManagementFactory.getRuntimeMXBean() + .getInputArguments()); + } + + /** + * Visible for testing purposes only. + * + * @param rule the rule to disable during debugging + * @param inputArguments + * arguments provided to the Java runtime + */ + DisableOnDebug(TestRule rule, List inputArguments) { + this.rule = rule; + debugging = isDebugging(inputArguments); + } + + /** + * @see TestRule#apply(Statement, Description) + */ + public Statement apply(Statement base, Description description) { + if (debugging) { + return base; + } else { + return rule.apply(base, description); + } + } + + /** + * Parses arguments passed to the runtime environment for debug flags + *

+ * Options specified in: + *

    + *
  • + * javase-6
  • + *
  • javase-7
  • + *
  • javase-8
  • + * + * + * @param arguments + * the arguments passed to the runtime environment, usually this + * will be {@link RuntimeMXBean#getInputArguments()} + * @return true if the current JVM was started in debug mode, false + * otherwise. + */ + private static boolean isDebugging(List arguments) { + for (final String argument : arguments) { + if ("-Xdebug".equals(argument) || argument.startsWith("-agentlib:jdwp")) { + return true; + } + } + return false; + } + + /** + * Returns {@code true} if the JVM is in debug mode. This method may be used + * by test classes to take additional action to disable code paths that + * interfere with debugging if required. + * + * @return {@code true} if the current JVM is in debug mode, {@code false} + * otherwise + */ + public boolean isDebugging() { + return debugging; + } + +} -- cgit v1.2.3 From 6a658e7a4df0cc8ea6465da46fcf1a823cb0d491 Mon Sep 17 00:00:00 2001 From: David Srbecky Date: Wed, 24 Feb 2021 15:52:50 +0000 Subject: Revert "Extra generic type information to aid certain javacs." Revert submission 1601635 Reason for revert: b/181123058 Reverted Changes: I8f5cd1266:Remove support for stuck threads Ifdb59336d:Remove DisableOnDebug (new in 4.12) as it is not s... I6abae5aed:Extra generic type information to aid certain java... I5ec909df6:Upgrade external/junit to 4.13.2 Change-Id: Ic641a09a2f6e661e2f466941123e74aba0ac4dac --- src/main/java/org/junit/matchers/JUnitMatchers.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/main') diff --git a/src/main/java/org/junit/matchers/JUnitMatchers.java b/src/main/java/org/junit/matchers/JUnitMatchers.java index 37e3d68..13407cc 100644 --- a/src/main/java/org/junit/matchers/JUnitMatchers.java +++ b/src/main/java/org/junit/matchers/JUnitMatchers.java @@ -48,7 +48,7 @@ public class JUnitMatchers { */ @Deprecated public static Matcher> hasItems(Matcher... elementMatchers) { - return CoreMatchers.hasItems(elementMatchers); + return CoreMatchers.hasItems(elementMatchers); } /** @@ -57,7 +57,7 @@ public class JUnitMatchers { */ @Deprecated public static Matcher> everyItem(final Matcher elementMatcher) { - return CoreMatchers.everyItem((Matcher) elementMatcher); + return CoreMatchers.everyItem(elementMatcher); } /** -- cgit v1.2.3 From 08a6d4b74555db6d01048fc7065eb1e2bfaf33bc Mon Sep 17 00:00:00 2001 From: David Srbecky Date: Wed, 24 Feb 2021 15:52:50 +0000 Subject: Revert "Upgrade external/junit to 4.13.2" Revert submission 1601635 Reason for revert: b/181123058 Reverted Changes: I8f5cd1266:Remove support for stuck threads Ifdb59336d:Remove DisableOnDebug (new in 4.12) as it is not s... I6abae5aed:Extra generic type information to aid certain java... I5ec909df6:Upgrade external/junit to 4.13.2 Change-Id: Idaddfc2039816a8d7b12c91fdd540b801ab854ff --- .../java/junit/extensions/ActiveTestSuite.java | 2 +- src/main/java/junit/extensions/TestDecorator.java | 1 - src/main/java/junit/framework/Assert.java | 78 ++-- .../java/junit/framework/ComparisonCompactor.java | 1 - .../java/junit/framework/JUnit4TestAdapter.java | 25 +- src/main/java/junit/framework/Protectable.java | 4 +- src/main/java/junit/framework/TestCase.java | 47 ++- src/main/java/junit/framework/TestFailure.java | 8 +- src/main/java/junit/framework/TestResult.java | 10 +- src/main/java/junit/framework/TestSuite.java | 29 +- src/main/java/junit/runner/BaseTestRunner.java | 9 +- src/main/java/junit/runner/TestRunListener.java | 16 +- src/main/java/junit/runner/Version.java | 2 +- src/main/java/junit/textui/TestRunner.java | 4 +- src/main/java/org/junit/Assert.java | 170 +++------ src/main/java/org/junit/Assume.java | 19 +- .../org/junit/AssumptionViolatedException.java | 4 +- src/main/java/org/junit/ClassRule.java | 33 +- src/main/java/org/junit/ComparisonFailure.java | 2 +- src/main/java/org/junit/Rule.java | 39 +- src/main/java/org/junit/Test.java | 39 +- .../org/junit/TestCouldNotBeSkippedException.java | 19 - .../junit/experimental/categories/Categories.java | 108 +++--- .../categories/CategoryFilterFactory.java | 6 +- .../org/junit/experimental/max/MaxHistory.java | 15 +- .../experimental/results/PrintableResult.java | 9 - .../junit/experimental/results/ResultMatchers.java | 35 +- .../theories/ParametersSuppliedBy.java | 2 +- .../org/junit/experimental/theories/Theories.java | 11 +- .../theories/internal/Assignments.java | 11 +- .../java/org/junit/function/ThrowingRunnable.java | 14 - .../org/junit/internal/ArrayComparisonFailure.java | 13 +- .../internal/AssumptionViolatedException.java | 30 +- src/main/java/org/junit/internal/Checks.java | 37 -- src/main/java/org/junit/internal/Classes.java | 28 +- .../org/junit/internal/ComparisonCriteria.java | 89 +---- .../internal/SerializableMatcherDescription.java | 47 --- .../internal/SerializableValueDescription.java | 38 -- src/main/java/org/junit/internal/TextListener.java | 4 +- src/main/java/org/junit/internal/Throwables.java | 231 ------------ .../builders/AllDefaultPossibilitiesBuilder.java | 11 - .../org/junit/internal/builders/JUnit4Builder.java | 6 +- .../internal/management/FakeRuntimeMXBean.java | 21 -- .../internal/management/FakeThreadMXBean.java | 27 -- .../internal/management/ManagementFactory.java | 77 ---- .../management/ReflectiveRuntimeMXBean.java | 61 ---- .../management/ReflectiveThreadMXBean.java | 92 ----- .../junit/internal/management/RuntimeMXBean.java | 14 - .../junit/internal/management/ThreadMXBean.java | 17 - .../matchers/StacktracePrintingMatcher.java | 9 +- .../internal/matchers/ThrowableCauseMatcher.java | 6 +- .../junit/internal/matchers/TypeSafeMatcher.java | 2 +- .../org/junit/internal/requests/ClassRequest.java | 41 +-- .../org/junit/internal/requests/FilterRequest.java | 2 +- .../junit/internal/requests/MemoizingRequest.java | 30 -- .../junit/internal/requests/OrderingRequest.java | 29 -- .../internal/runners/ErrorReportingRunner.java | 50 +-- .../internal/runners/InitializationError.java | 2 +- .../junit/internal/runners/JUnit38ClassRunner.java | 22 +- .../junit/internal/runners/MethodValidator.java | 2 +- .../java/org/junit/internal/runners/TestClass.java | 2 +- .../internal/runners/model/EachTestNotifier.java | 23 -- .../internal/runners/rules/ValidationError.java | 3 - .../runners/statements/ExpectException.java | 4 +- .../internal/runners/statements/FailOnTimeout.java | 155 +------- .../internal/runners/statements/RunAfters.java | 9 +- .../internal/runners/statements/RunBefores.java | 9 +- .../java/org/junit/matchers/JUnitMatchers.java | 4 +- src/main/java/org/junit/rules/DisableOnDebug.java | 125 ------- src/main/java/org/junit/rules/ErrorCollector.java | 38 +- .../java/org/junit/rules/ExpectedException.java | 57 ++- .../java/org/junit/rules/ExternalResource.java | 15 +- src/main/java/org/junit/rules/MethodRule.java | 16 +- src/main/java/org/junit/rules/RuleChain.java | 50 +-- src/main/java/org/junit/rules/Stopwatch.java | 2 +- src/main/java/org/junit/rules/TemporaryFolder.java | 277 +++----------- src/main/java/org/junit/rules/TestName.java | 2 +- src/main/java/org/junit/rules/TestWatcher.java | 12 +- src/main/java/org/junit/rules/Timeout.java | 37 +- src/main/java/org/junit/runner/Computer.java | 12 +- src/main/java/org/junit/runner/Describable.java | 2 +- src/main/java/org/junit/runner/Description.java | 13 +- src/main/java/org/junit/runner/FilterFactory.java | 3 +- .../junit/runner/JUnitCommandLineParseResult.java | 8 +- src/main/java/org/junit/runner/OrderWith.java | 28 -- .../java/org/junit/runner/OrderWithValidator.java | 38 -- src/main/java/org/junit/runner/Request.java | 58 +-- src/main/java/org/junit/runner/Result.java | 31 +- .../junit/runner/manipulation/Alphanumeric.java | 27 -- .../manipulation/InvalidOrderingException.java | 21 -- .../org/junit/runner/manipulation/Orderable.java | 21 -- .../org/junit/runner/manipulation/Orderer.java | 62 ---- .../org/junit/runner/manipulation/Ordering.java | 172 --------- .../org/junit/runner/manipulation/Sortable.java | 2 +- .../java/org/junit/runner/manipulation/Sorter.java | 54 +-- .../org/junit/runner/notification/Failure.java | 23 +- .../org/junit/runner/notification/RunListener.java | 28 -- .../org/junit/runner/notification/RunNotifier.java | 41 +-- .../notification/SynchronizedRunListener.java | 33 +- .../org/junit/runners/BlockJUnit4ClassRunner.java | 172 ++++----- src/main/java/org/junit/runners/JUnit4.java | 3 +- src/main/java/org/junit/runners/Parameterized.java | 405 +++++++-------------- src/main/java/org/junit/runners/ParentRunner.java | 176 ++------- src/main/java/org/junit/runners/RuleContainer.java | 113 ------ src/main/java/org/junit/runners/Suite.java | 4 +- .../org/junit/runners/model/FrameworkField.java | 21 +- .../org/junit/runners/model/FrameworkMember.java | 24 +- .../org/junit/runners/model/FrameworkMethod.java | 14 - .../junit/runners/model/InitializationError.java | 2 +- .../junit/runners/model/InvalidTestClassError.java | 39 -- .../junit/runners/model/MemberValueConsumer.java | 18 - .../runners/model/MultipleFailureException.java | 41 +-- .../org/junit/runners/model/RunnerBuilder.java | 30 +- .../java/org/junit/runners/model/TestClass.java | 57 +-- .../BlockJUnit4ClassRunnerWithParameters.java | 94 +---- .../parameterized/ParametersRunnerFactory.java | 2 +- .../runners/parameterized/TestWithParameters.java | 7 +- .../validator/AnnotationValidatorFactory.java | 3 + .../org/junit/validator/AnnotationsValidator.java | 4 +- .../org/junit/validator/TestClassValidator.java | 2 +- .../java/org/junit/validator/ValidateWith.java | 3 - 121 files changed, 784 insertions(+), 3777 deletions(-) mode change 100644 => 100755 src/main/java/org/junit/Assert.java delete mode 100644 src/main/java/org/junit/TestCouldNotBeSkippedException.java delete mode 100644 src/main/java/org/junit/function/ThrowingRunnable.java delete mode 100644 src/main/java/org/junit/internal/Checks.java delete mode 100644 src/main/java/org/junit/internal/SerializableMatcherDescription.java delete mode 100644 src/main/java/org/junit/internal/SerializableValueDescription.java delete mode 100644 src/main/java/org/junit/internal/management/FakeRuntimeMXBean.java delete mode 100644 src/main/java/org/junit/internal/management/FakeThreadMXBean.java delete mode 100644 src/main/java/org/junit/internal/management/ManagementFactory.java delete mode 100644 src/main/java/org/junit/internal/management/ReflectiveRuntimeMXBean.java delete mode 100644 src/main/java/org/junit/internal/management/ReflectiveThreadMXBean.java delete mode 100644 src/main/java/org/junit/internal/management/RuntimeMXBean.java delete mode 100644 src/main/java/org/junit/internal/management/ThreadMXBean.java delete mode 100644 src/main/java/org/junit/internal/requests/MemoizingRequest.java delete mode 100644 src/main/java/org/junit/internal/requests/OrderingRequest.java delete mode 100644 src/main/java/org/junit/rules/DisableOnDebug.java delete mode 100644 src/main/java/org/junit/runner/OrderWith.java delete mode 100644 src/main/java/org/junit/runner/OrderWithValidator.java delete mode 100644 src/main/java/org/junit/runner/manipulation/Alphanumeric.java delete mode 100644 src/main/java/org/junit/runner/manipulation/InvalidOrderingException.java delete mode 100644 src/main/java/org/junit/runner/manipulation/Orderable.java delete mode 100644 src/main/java/org/junit/runner/manipulation/Orderer.java delete mode 100644 src/main/java/org/junit/runner/manipulation/Ordering.java mode change 100644 => 100755 src/main/java/org/junit/runners/ParentRunner.java delete mode 100644 src/main/java/org/junit/runners/RuleContainer.java delete mode 100644 src/main/java/org/junit/runners/model/InvalidTestClassError.java delete mode 100644 src/main/java/org/junit/runners/model/MemberValueConsumer.java mode change 100644 => 100755 src/main/java/org/junit/runners/model/TestClass.java (limited to 'src/main') diff --git a/src/main/java/junit/extensions/ActiveTestSuite.java b/src/main/java/junit/extensions/ActiveTestSuite.java index 6f0f99d..95c5e2e 100644 --- a/src/main/java/junit/extensions/ActiveTestSuite.java +++ b/src/main/java/junit/extensions/ActiveTestSuite.java @@ -63,7 +63,7 @@ public class ActiveTestSuite extends TestSuite { } } - public synchronized void runFinished() { + synchronized public void runFinished() { fActiveTestDeathCount++; notifyAll(); } diff --git a/src/main/java/junit/extensions/TestDecorator.java b/src/main/java/junit/extensions/TestDecorator.java index a3c5e08..2b74f30 100644 --- a/src/main/java/junit/extensions/TestDecorator.java +++ b/src/main/java/junit/extensions/TestDecorator.java @@ -9,7 +9,6 @@ import junit.framework.TestResult; * test decorators. Test decorator subclasses can be introduced to add behaviour * before or after a test is run. */ -@SuppressWarnings("deprecation") public class TestDecorator extends Assert implements Test { protected Test fTest; diff --git a/src/main/java/junit/framework/Assert.java b/src/main/java/junit/framework/Assert.java index 43482a1..663461c 100644 --- a/src/main/java/junit/framework/Assert.java +++ b/src/main/java/junit/framework/Assert.java @@ -17,7 +17,7 @@ public class Assert { * Asserts that a condition is true. If it isn't it throws * an AssertionFailedError with the given message. */ - public static void assertTrue(String message, boolean condition) { + static public void assertTrue(String message, boolean condition) { if (!condition) { fail(message); } @@ -27,7 +27,7 @@ public class Assert { * Asserts that a condition is true. If it isn't it throws * an AssertionFailedError. */ - public static void assertTrue(boolean condition) { + static public void assertTrue(boolean condition) { assertTrue(null, condition); } @@ -35,7 +35,7 @@ public class Assert { * Asserts that a condition is false. If it isn't it throws * an AssertionFailedError with the given message. */ - public static void assertFalse(String message, boolean condition) { + static public void assertFalse(String message, boolean condition) { assertTrue(message, !condition); } @@ -43,14 +43,14 @@ public class Assert { * Asserts that a condition is false. If it isn't it throws * an AssertionFailedError. */ - public static void assertFalse(boolean condition) { + static public void assertFalse(boolean condition) { assertFalse(null, condition); } /** * Fails a test with the given message. */ - public static void fail(String message) { + static public void fail(String message) { if (message == null) { throw new AssertionFailedError(); } @@ -60,7 +60,7 @@ public class Assert { /** * Fails a test with no message. */ - public static void fail() { + static public void fail() { fail(null); } @@ -68,7 +68,7 @@ public class Assert { * Asserts that two objects are equal. If they are not * an AssertionFailedError is thrown with the given message. */ - public static void assertEquals(String message, Object expected, Object actual) { + static public void assertEquals(String message, Object expected, Object actual) { if (expected == null && actual == null) { return; } @@ -82,14 +82,14 @@ public class Assert { * Asserts that two objects are equal. If they are not * an AssertionFailedError is thrown. */ - public static void assertEquals(Object expected, Object actual) { + static public void assertEquals(Object expected, Object actual) { assertEquals(null, expected, actual); } /** * Asserts that two Strings are equal. */ - public static void assertEquals(String message, String expected, String actual) { + static public void assertEquals(String message, String expected, String actual) { if (expected == null && actual == null) { return; } @@ -103,7 +103,7 @@ public class Assert { /** * Asserts that two Strings are equal. */ - public static void assertEquals(String expected, String actual) { + static public void assertEquals(String expected, String actual) { assertEquals(null, expected, actual); } @@ -112,12 +112,12 @@ public class Assert { * an AssertionFailedError is thrown with the given message. If the expected * value is infinity then the delta value is ignored. */ - public static void assertEquals(String message, double expected, double actual, double delta) { + static public void assertEquals(String message, double expected, double actual, double delta) { if (Double.compare(expected, actual) == 0) { return; } if (!(Math.abs(expected - actual) <= delta)) { - failNotEquals(message, Double.valueOf(expected), Double.valueOf(actual)); + failNotEquals(message, new Double(expected), new Double(actual)); } } @@ -125,7 +125,7 @@ public class Assert { * Asserts that two doubles are equal concerning a delta. If the expected * value is infinity then the delta value is ignored. */ - public static void assertEquals(double expected, double actual, double delta) { + static public void assertEquals(double expected, double actual, double delta) { assertEquals(null, expected, actual, delta); } @@ -134,12 +134,12 @@ public class Assert { * are not an AssertionFailedError is thrown with the given message. If the * expected value is infinity then the delta value is ignored. */ - public static void assertEquals(String message, float expected, float actual, float delta) { + static public void assertEquals(String message, float expected, float actual, float delta) { if (Float.compare(expected, actual) == 0) { return; } if (!(Math.abs(expected - actual) <= delta)) { - failNotEquals(message, Float.valueOf(expected), Float.valueOf(actual)); + failNotEquals(message, new Float(expected), new Float(actual)); } } @@ -147,7 +147,7 @@ public class Assert { * Asserts that two floats are equal concerning a delta. If the expected * value is infinity then the delta value is ignored. */ - public static void assertEquals(float expected, float actual, float delta) { + static public void assertEquals(float expected, float actual, float delta) { assertEquals(null, expected, actual, delta); } @@ -155,14 +155,14 @@ public class Assert { * Asserts that two longs are equal. If they are not * an AssertionFailedError is thrown with the given message. */ - public static void assertEquals(String message, long expected, long actual) { + static public void assertEquals(String message, long expected, long actual) { assertEquals(message, Long.valueOf(expected), Long.valueOf(actual)); } /** * Asserts that two longs are equal. */ - public static void assertEquals(long expected, long actual) { + static public void assertEquals(long expected, long actual) { assertEquals(null, expected, actual); } @@ -170,14 +170,14 @@ public class Assert { * Asserts that two booleans are equal. If they are not * an AssertionFailedError is thrown with the given message. */ - public static void assertEquals(String message, boolean expected, boolean actual) { + static public void assertEquals(String message, boolean expected, boolean actual) { assertEquals(message, Boolean.valueOf(expected), Boolean.valueOf(actual)); } /** * Asserts that two booleans are equal. */ - public static void assertEquals(boolean expected, boolean actual) { + static public void assertEquals(boolean expected, boolean actual) { assertEquals(null, expected, actual); } @@ -185,14 +185,14 @@ public class Assert { * Asserts that two bytes are equal. If they are not * an AssertionFailedError is thrown with the given message. */ - public static void assertEquals(String message, byte expected, byte actual) { + static public void assertEquals(String message, byte expected, byte actual) { assertEquals(message, Byte.valueOf(expected), Byte.valueOf(actual)); } /** * Asserts that two bytes are equal. */ - public static void assertEquals(byte expected, byte actual) { + static public void assertEquals(byte expected, byte actual) { assertEquals(null, expected, actual); } @@ -200,14 +200,14 @@ public class Assert { * Asserts that two chars are equal. If they are not * an AssertionFailedError is thrown with the given message. */ - public static void assertEquals(String message, char expected, char actual) { + static public void assertEquals(String message, char expected, char actual) { assertEquals(message, Character.valueOf(expected), Character.valueOf(actual)); } /** * Asserts that two chars are equal. */ - public static void assertEquals(char expected, char actual) { + static public void assertEquals(char expected, char actual) { assertEquals(null, expected, actual); } @@ -215,14 +215,14 @@ public class Assert { * Asserts that two shorts are equal. If they are not * an AssertionFailedError is thrown with the given message. */ - public static void assertEquals(String message, short expected, short actual) { + static public void assertEquals(String message, short expected, short actual) { assertEquals(message, Short.valueOf(expected), Short.valueOf(actual)); } /** * Asserts that two shorts are equal. */ - public static void assertEquals(short expected, short actual) { + static public void assertEquals(short expected, short actual) { assertEquals(null, expected, actual); } @@ -230,21 +230,21 @@ public class Assert { * Asserts that two ints are equal. If they are not * an AssertionFailedError is thrown with the given message. */ - public static void assertEquals(String message, int expected, int actual) { + static public void assertEquals(String message, int expected, int actual) { assertEquals(message, Integer.valueOf(expected), Integer.valueOf(actual)); } /** * Asserts that two ints are equal. */ - public static void assertEquals(int expected, int actual) { + static public void assertEquals(int expected, int actual) { assertEquals(null, expected, actual); } /** * Asserts that an object isn't null. */ - public static void assertNotNull(Object object) { + static public void assertNotNull(Object object) { assertNotNull(null, object); } @@ -252,7 +252,7 @@ public class Assert { * Asserts that an object isn't null. If it is * an AssertionFailedError is thrown with the given message. */ - public static void assertNotNull(String message, Object object) { + static public void assertNotNull(String message, Object object) { assertTrue(message, object != null); } @@ -263,7 +263,7 @@ public class Assert { * * @param object Object to check or null */ - public static void assertNull(Object object) { + static public void assertNull(Object object) { if (object != null) { assertNull("Expected: but was: " + object.toString(), object); } @@ -273,7 +273,7 @@ public class Assert { * Asserts that an object is null. If it is not * an AssertionFailedError is thrown with the given message. */ - public static void assertNull(String message, Object object) { + static public void assertNull(String message, Object object) { assertTrue(message, object == null); } @@ -281,7 +281,7 @@ public class Assert { * Asserts that two objects refer to the same object. If they are not * an AssertionFailedError is thrown with the given message. */ - public static void assertSame(String message, Object expected, Object actual) { + static public void assertSame(String message, Object expected, Object actual) { if (expected == actual) { return; } @@ -292,7 +292,7 @@ public class Assert { * Asserts that two objects refer to the same object. If they are not * the same an AssertionFailedError is thrown. */ - public static void assertSame(Object expected, Object actual) { + static public void assertSame(Object expected, Object actual) { assertSame(null, expected, actual); } @@ -301,7 +301,7 @@ public class Assert { * refer to the same object an AssertionFailedError is thrown with the * given message. */ - public static void assertNotSame(String message, Object expected, Object actual) { + static public void assertNotSame(String message, Object expected, Object actual) { if (expected == actual) { failSame(message); } @@ -311,21 +311,21 @@ public class Assert { * Asserts that two objects do not refer to the same object. If they do * refer to the same object an AssertionFailedError is thrown. */ - public static void assertNotSame(Object expected, Object actual) { + static public void assertNotSame(Object expected, Object actual) { assertNotSame(null, expected, actual); } - public static void failSame(String message) { + static public void failSame(String message) { String formatted = (message != null) ? message + " " : ""; fail(formatted + "expected not same"); } - public static void failNotSame(String message, Object expected, Object actual) { + static public void failNotSame(String message, Object expected, Object actual) { String formatted = (message != null) ? message + " " : ""; fail(formatted + "expected same:<" + expected + "> was not:<" + actual + ">"); } - public static void failNotEquals(String message, Object expected, Object actual) { + static public void failNotEquals(String message, Object expected, Object actual) { fail(format(message, expected, actual)); } diff --git a/src/main/java/junit/framework/ComparisonCompactor.java b/src/main/java/junit/framework/ComparisonCompactor.java index 81ddd5b..fa20a8e 100644 --- a/src/main/java/junit/framework/ComparisonCompactor.java +++ b/src/main/java/junit/framework/ComparisonCompactor.java @@ -18,7 +18,6 @@ public class ComparisonCompactor { fActual = actual; } - @SuppressWarnings("deprecation") public String compact(String message) { if (fExpected == null || fActual == null || areStringsEqual()) { return Assert.format(message, fExpected, fActual); diff --git a/src/main/java/junit/framework/JUnit4TestAdapter.java b/src/main/java/junit/framework/JUnit4TestAdapter.java index 9d32031..cbb66db 100644 --- a/src/main/java/junit/framework/JUnit4TestAdapter.java +++ b/src/main/java/junit/framework/JUnit4TestAdapter.java @@ -9,23 +9,11 @@ import org.junit.runner.Request; 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; -/** - * The JUnit4TestAdapter enables running JUnit-4-style tests using a JUnit-3-style test runner. - * - *

    To use it, add the following to a test class: - *

    -      public static Test suite() {
    -        return new JUnit4TestAdapter(YourJUnit4TestClass.class);
    -      }
    -
    - */ -public class JUnit4TestAdapter implements Test, Filterable, Orderable, Describable { +public class JUnit4TestAdapter implements Test, Filterable, Sortable, Describable { private final Class fNewTestClass; private final Runner fRunner; @@ -95,13 +83,4 @@ public class JUnit4TestAdapter implements Test, Filterable, Orderable, Describab 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/junit/framework/Protectable.java b/src/main/java/junit/framework/Protectable.java index c5ceb16..9f30b10 100644 --- a/src/main/java/junit/framework/Protectable.java +++ b/src/main/java/junit/framework/Protectable.java @@ -8,7 +8,7 @@ package junit.framework; public interface Protectable { /** - * Run the following method protected. + * Run the the following method protected. */ public abstract void protect() throws Throwable; -} +} \ No newline at end of file diff --git a/src/main/java/junit/framework/TestCase.java b/src/main/java/junit/framework/TestCase.java index e474a64..b89ce71 100644 --- a/src/main/java/junit/framework/TestCase.java +++ b/src/main/java/junit/framework/TestCase.java @@ -73,7 +73,6 @@ import java.lang.reflect.Modifier; * @see TestResult * @see TestSuite */ -@SuppressWarnings("deprecation") public abstract class TestCase extends Assert implements Test { /** * the name of the test case @@ -103,7 +102,7 @@ public abstract class TestCase extends Assert implements Test { } /** - * Creates a default TestResult object. + * Creates a default TestResult object * * @see TestResult */ @@ -188,6 +187,7 @@ public abstract class TestCase extends Assert implements Test { * Asserts that a condition is true. If it isn't it throws * an AssertionFailedError with the given message. */ + @SuppressWarnings("deprecation") public static void assertTrue(String message, boolean condition) { Assert.assertTrue(message, condition); } @@ -196,6 +196,7 @@ public abstract class TestCase extends Assert implements Test { * Asserts that a condition is true. If it isn't it throws * an AssertionFailedError. */ + @SuppressWarnings("deprecation") public static void assertTrue(boolean condition) { Assert.assertTrue(condition); } @@ -204,6 +205,7 @@ public abstract class TestCase extends Assert implements Test { * Asserts that a condition is false. If it isn't it throws * an AssertionFailedError with the given message. */ + @SuppressWarnings("deprecation") public static void assertFalse(String message, boolean condition) { Assert.assertFalse(message, condition); } @@ -212,6 +214,7 @@ public abstract class TestCase extends Assert implements Test { * Asserts that a condition is false. If it isn't it throws * an AssertionFailedError. */ + @SuppressWarnings("deprecation") public static void assertFalse(boolean condition) { Assert.assertFalse(condition); } @@ -219,6 +222,7 @@ public abstract class TestCase extends Assert implements Test { /** * Fails a test with the given message. */ + @SuppressWarnings("deprecation") public static void fail(String message) { Assert.fail(message); } @@ -226,6 +230,7 @@ public abstract class TestCase extends Assert implements Test { /** * Fails a test with no message. */ + @SuppressWarnings("deprecation") public static void fail() { Assert.fail(); } @@ -234,6 +239,7 @@ public abstract class TestCase extends Assert implements Test { * Asserts that two objects are equal. If they are not * an AssertionFailedError is thrown with the given message. */ + @SuppressWarnings("deprecation") public static void assertEquals(String message, Object expected, Object actual) { Assert.assertEquals(message, expected, actual); } @@ -242,6 +248,7 @@ public abstract class TestCase extends Assert implements Test { * Asserts that two objects are equal. If they are not * an AssertionFailedError is thrown. */ + @SuppressWarnings("deprecation") public static void assertEquals(Object expected, Object actual) { Assert.assertEquals(expected, actual); } @@ -249,6 +256,7 @@ public abstract class TestCase extends Assert implements Test { /** * Asserts that two Strings are equal. */ + @SuppressWarnings("deprecation") public static void assertEquals(String message, String expected, String actual) { Assert.assertEquals(message, expected, actual); } @@ -256,6 +264,7 @@ public abstract class TestCase extends Assert implements Test { /** * Asserts that two Strings are equal. */ + @SuppressWarnings("deprecation") public static void assertEquals(String expected, String actual) { Assert.assertEquals(expected, actual); } @@ -265,6 +274,7 @@ public abstract class TestCase extends Assert implements Test { * an AssertionFailedError is thrown with the given message. If the expected * value is infinity then the delta value is ignored. */ + @SuppressWarnings("deprecation") public static void assertEquals(String message, double expected, double actual, double delta) { Assert.assertEquals(message, expected, actual, delta); } @@ -273,6 +283,7 @@ public abstract class TestCase extends Assert implements Test { * Asserts that two doubles are equal concerning a delta. If the expected * value is infinity then the delta value is ignored. */ + @SuppressWarnings("deprecation") public static void assertEquals(double expected, double actual, double delta) { Assert.assertEquals(expected, actual, delta); } @@ -282,6 +293,7 @@ public abstract class TestCase extends Assert implements Test { * are not an AssertionFailedError is thrown with the given message. If the * expected value is infinity then the delta value is ignored. */ + @SuppressWarnings("deprecation") public static void assertEquals(String message, float expected, float actual, float delta) { Assert.assertEquals(message, expected, actual, delta); } @@ -290,6 +302,7 @@ public abstract class TestCase extends Assert implements Test { * Asserts that two floats are equal concerning a delta. If the expected * value is infinity then the delta value is ignored. */ + @SuppressWarnings("deprecation") public static void assertEquals(float expected, float actual, float delta) { Assert.assertEquals(expected, actual, delta); } @@ -298,6 +311,7 @@ public abstract class TestCase extends Assert implements Test { * Asserts that two longs are equal. If they are not * an AssertionFailedError is thrown with the given message. */ + @SuppressWarnings("deprecation") public static void assertEquals(String message, long expected, long actual) { Assert.assertEquals(message, expected, actual); } @@ -305,6 +319,7 @@ public abstract class TestCase extends Assert implements Test { /** * Asserts that two longs are equal. */ + @SuppressWarnings("deprecation") public static void assertEquals(long expected, long actual) { Assert.assertEquals(expected, actual); } @@ -313,6 +328,7 @@ public abstract class TestCase extends Assert implements Test { * Asserts that two booleans are equal. If they are not * an AssertionFailedError is thrown with the given message. */ + @SuppressWarnings("deprecation") public static void assertEquals(String message, boolean expected, boolean actual) { Assert.assertEquals(message, expected, actual); } @@ -320,6 +336,7 @@ public abstract class TestCase extends Assert implements Test { /** * Asserts that two booleans are equal. */ + @SuppressWarnings("deprecation") public static void assertEquals(boolean expected, boolean actual) { Assert.assertEquals(expected, actual); } @@ -328,6 +345,7 @@ public abstract class TestCase extends Assert implements Test { * Asserts that two bytes are equal. If they are not * an AssertionFailedError is thrown with the given message. */ + @SuppressWarnings("deprecation") public static void assertEquals(String message, byte expected, byte actual) { Assert.assertEquals(message, expected, actual); } @@ -335,6 +353,7 @@ public abstract class TestCase extends Assert implements Test { /** * Asserts that two bytes are equal. */ + @SuppressWarnings("deprecation") public static void assertEquals(byte expected, byte actual) { Assert.assertEquals(expected, actual); } @@ -343,6 +362,7 @@ public abstract class TestCase extends Assert implements Test { * Asserts that two chars are equal. If they are not * an AssertionFailedError is thrown with the given message. */ + @SuppressWarnings("deprecation") public static void assertEquals(String message, char expected, char actual) { Assert.assertEquals(message, expected, actual); } @@ -350,6 +370,7 @@ public abstract class TestCase extends Assert implements Test { /** * Asserts that two chars are equal. */ + @SuppressWarnings("deprecation") public static void assertEquals(char expected, char actual) { Assert.assertEquals(expected, actual); } @@ -358,6 +379,7 @@ public abstract class TestCase extends Assert implements Test { * Asserts that two shorts are equal. If they are not * an AssertionFailedError is thrown with the given message. */ + @SuppressWarnings("deprecation") public static void assertEquals(String message, short expected, short actual) { Assert.assertEquals(message, expected, actual); } @@ -365,6 +387,7 @@ public abstract class TestCase extends Assert implements Test { /** * Asserts that two shorts are equal. */ + @SuppressWarnings("deprecation") public static void assertEquals(short expected, short actual) { Assert.assertEquals(expected, actual); } @@ -373,6 +396,7 @@ public abstract class TestCase extends Assert implements Test { * Asserts that two ints are equal. If they are not * an AssertionFailedError is thrown with the given message. */ + @SuppressWarnings("deprecation") public static void assertEquals(String message, int expected, int actual) { Assert.assertEquals(message, expected, actual); } @@ -380,6 +404,7 @@ public abstract class TestCase extends Assert implements Test { /** * Asserts that two ints are equal. */ + @SuppressWarnings("deprecation") public static void assertEquals(int expected, int actual) { Assert.assertEquals(expected, actual); } @@ -387,6 +412,7 @@ public abstract class TestCase extends Assert implements Test { /** * Asserts that an object isn't null. */ + @SuppressWarnings("deprecation") public static void assertNotNull(Object object) { Assert.assertNotNull(object); } @@ -395,6 +421,7 @@ public abstract class TestCase extends Assert implements Test { * Asserts that an object isn't null. If it is * an AssertionFailedError is thrown with the given message. */ + @SuppressWarnings("deprecation") public static void assertNotNull(String message, Object object) { Assert.assertNotNull(message, object); } @@ -406,6 +433,7 @@ public abstract class TestCase extends Assert implements Test { * * @param object Object to check or null */ + @SuppressWarnings("deprecation") public static void assertNull(Object object) { Assert.assertNull(object); } @@ -414,6 +442,7 @@ public abstract class TestCase extends Assert implements Test { * Asserts that an object is null. If it is not * an AssertionFailedError is thrown with the given message. */ + @SuppressWarnings("deprecation") public static void assertNull(String message, Object object) { Assert.assertNull(message, object); } @@ -422,6 +451,7 @@ public abstract class TestCase extends Assert implements Test { * Asserts that two objects refer to the same object. If they are not * an AssertionFailedError is thrown with the given message. */ + @SuppressWarnings("deprecation") public static void assertSame(String message, Object expected, Object actual) { Assert.assertSame(message, expected, actual); } @@ -430,6 +460,7 @@ public abstract class TestCase extends Assert implements Test { * Asserts that two objects refer to the same object. If they are not * the same an AssertionFailedError is thrown. */ + @SuppressWarnings("deprecation") public static void assertSame(Object expected, Object actual) { Assert.assertSame(expected, actual); } @@ -439,6 +470,7 @@ public abstract class TestCase extends Assert implements Test { * refer to the same object an AssertionFailedError is thrown with the * given message. */ + @SuppressWarnings("deprecation") public static void assertNotSame(String message, Object expected, Object actual) { Assert.assertNotSame(message, expected, actual); } @@ -447,22 +479,27 @@ public abstract class TestCase extends Assert implements Test { * Asserts that two objects do not refer to the same object. If they do * refer to the same object an AssertionFailedError is thrown. */ + @SuppressWarnings("deprecation") public static void assertNotSame(Object expected, Object actual) { Assert.assertNotSame(expected, actual); } + @SuppressWarnings("deprecation") public static void failSame(String message) { Assert.failSame(message); } + @SuppressWarnings("deprecation") public static void failNotSame(String message, Object expected, Object actual) { Assert.failNotSame(message, expected, actual); } + @SuppressWarnings("deprecation") public static void failNotEquals(String message, Object expected, Object actual) { Assert.failNotEquals(message, expected, actual); } + @SuppressWarnings("deprecation") public static String format(String message, Object expected, Object actual) { return Assert.format(message, expected, actual); } @@ -482,7 +519,7 @@ public abstract class TestCase extends Assert implements Test { } /** - * Returns a string representation of the test case. + * Returns a string representation of the test case */ @Override public String toString() { @@ -490,7 +527,7 @@ public abstract class TestCase extends Assert implements Test { } /** - * Gets the name of a TestCase. + * Gets the name of a TestCase * * @return the name of the TestCase */ @@ -499,7 +536,7 @@ public abstract class TestCase extends Assert implements Test { } /** - * Sets the name of a TestCase. + * Sets the name of a TestCase * * @param name the name to set */ diff --git a/src/main/java/junit/framework/TestFailure.java b/src/main/java/junit/framework/TestFailure.java index d1ddfbc..6168b58 100644 --- a/src/main/java/junit/framework/TestFailure.java +++ b/src/main/java/junit/framework/TestFailure.java @@ -1,6 +1,7 @@ package junit.framework; -import org.junit.internal.Throwables; +import java.io.PrintWriter; +import java.io.StringWriter; /** @@ -48,7 +49,10 @@ public class TestFailure { * thrown by TestFailure. */ public String trace() { - return Throwables.getStacktrace(thrownException()); + StringWriter stringWriter = new StringWriter(); + PrintWriter writer = new PrintWriter(stringWriter); + thrownException().printStackTrace(writer); + return stringWriter.toString(); } /** diff --git a/src/main/java/junit/framework/TestResult.java b/src/main/java/junit/framework/TestResult.java index e01a2b0..8332542 100644 --- a/src/main/java/junit/framework/TestResult.java +++ b/src/main/java/junit/framework/TestResult.java @@ -52,14 +52,14 @@ public class TestResult { } /** - * Registers a TestListener. + * Registers a TestListener */ public synchronized void addListener(TestListener listener) { fListeners.add(listener); } /** - * Unregisters a TestListener. + * Unregisters a TestListener */ public synchronized void removeListener(TestListener listener) { fListeners.remove(listener); @@ -91,7 +91,7 @@ public class TestResult { } /** - * Returns an Enumeration for the errors. + * Returns an Enumeration for the errors */ public synchronized Enumeration errors() { return Collections.enumeration(fErrors); @@ -106,7 +106,7 @@ public class TestResult { } /** - * Returns an Enumeration for the failures. + * Returns an Enumeration for the failures */ public synchronized Enumeration failures() { return Collections.enumeration(fFailures); @@ -150,7 +150,7 @@ public class TestResult { } /** - * Checks whether the test run should stop. + * Checks whether the test run should stop */ public synchronized boolean shouldStop() { return fStop; diff --git a/src/main/java/junit/framework/TestSuite.java b/src/main/java/junit/framework/TestSuite.java index 50cd5f8..366f1cf 100644 --- a/src/main/java/junit/framework/TestSuite.java +++ b/src/main/java/junit/framework/TestSuite.java @@ -1,5 +1,7 @@ package junit.framework; +import java.io.PrintWriter; +import java.io.StringWriter; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -10,7 +12,6 @@ import java.util.List; import java.util.Vector; import org.junit.internal.MethodSorter; -import org.junit.internal.Throwables; /** * A TestSuite is a Composite of Tests. @@ -34,7 +35,7 @@ import org.junit.internal.Throwables; *

    * A final option is to do the same for a large array of test classes. *

    - * Class[] testClasses = { MathTest.class, AnotherTest.class };
    + * Class[] testClasses = { MathTest.class, AnotherTest.class }
      * TestSuite suite= new TestSuite(testClasses);
      * 
    * @@ -64,11 +65,11 @@ public class TestSuite implements Test { test = constructor.newInstance(new Object[]{name}); } } catch (InstantiationException e) { - return (warning("Cannot instantiate test case: " + name + " (" + Throwables.getStacktrace(e) + ")")); + return (warning("Cannot instantiate test case: " + name + " (" + exceptionToString(e) + ")")); } catch (InvocationTargetException e) { - return (warning("Exception in constructor: " + name + " (" + Throwables.getStacktrace(e.getTargetException()) + ")")); + return (warning("Exception in constructor: " + name + " (" + exceptionToString(e.getTargetException()) + ")")); } catch (IllegalAccessException e) { - return (warning("Cannot access test case: " + name + " (" + Throwables.getStacktrace(e) + ")")); + return (warning("Cannot access test case: " + name + " (" + exceptionToString(e) + ")")); } return (Test) test; } @@ -98,6 +99,16 @@ public class TestSuite implements Test { }; } + /** + * Converts the stack trace into a string + */ + private static String exceptionToString(Throwable e) { + StringWriter stringWriter = new StringWriter(); + PrintWriter writer = new PrintWriter(stringWriter); + e.printStackTrace(writer); + return stringWriter.toString(); + } + private String fName; private Vector fTests = new Vector(10); // Cannot convert this to List because it is used directly by some test runners @@ -199,7 +210,7 @@ public class TestSuite implements Test { } /** - * Adds the tests from the given class to the suite. + * Adds the tests from the given class to the suite */ public void addTestSuite(Class testClass) { addTest(new TestSuite(testClass)); @@ -251,21 +262,21 @@ public class TestSuite implements Test { } /** - * Returns the test at the given index. + * Returns the test at the given index */ public Test testAt(int index) { return fTests.get(index); } /** - * Returns the number of tests in this suite. + * Returns the number of tests in this suite */ public int testCount() { return fTests.size(); } /** - * Returns the tests as an enumeration. + * Returns the tests as an enumeration */ public Enumeration tests() { return fTests.elements(); diff --git a/src/main/java/junit/runner/BaseTestRunner.java b/src/main/java/junit/runner/BaseTestRunner.java index d63fae7..8268323 100644 --- a/src/main/java/junit/runner/BaseTestRunner.java +++ b/src/main/java/junit/runner/BaseTestRunner.java @@ -20,8 +20,6 @@ import junit.framework.Test; import junit.framework.TestListener; import junit.framework.TestSuite; -import org.junit.internal.Throwables; - /** * Base class for all test runners. * This class was born live on stage in Sardinia during XP2000. @@ -235,7 +233,6 @@ public abstract class BaseTestRunner implements TestListener { setPreferences(new Properties(getPreferences())); getPreferences().load(is); } catch (IOException ignored) { - } catch (SecurityException ignored) { } finally { try { if (is != null) { @@ -267,7 +264,11 @@ public abstract class BaseTestRunner implements TestListener { * Returns a filtered stack trace */ public static String getFilteredTrace(Throwable e) { - return BaseTestRunner.getFilteredTrace(Throwables.getStacktrace(e)); + StringWriter stringWriter = new StringWriter(); + PrintWriter writer = new PrintWriter(stringWriter); + e.printStackTrace(writer); + String trace = stringWriter.toString(); + return BaseTestRunner.getFilteredTrace(trace); } /** diff --git a/src/main/java/junit/runner/TestRunListener.java b/src/main/java/junit/runner/TestRunListener.java index ce5b3d5..b5e22f5 100644 --- a/src/main/java/junit/runner/TestRunListener.java +++ b/src/main/java/junit/runner/TestRunListener.java @@ -8,18 +8,18 @@ package junit.runner; */ public interface TestRunListener { /* test status constants*/ - int STATUS_ERROR = 1; - int STATUS_FAILURE = 2; + public static final int STATUS_ERROR = 1; + public static final int STATUS_FAILURE = 2; - void testRunStarted(String testSuiteName, int testCount); + public void testRunStarted(String testSuiteName, int testCount); - void testRunEnded(long elapsedTime); + public void testRunEnded(long elapsedTime); - void testRunStopped(long elapsedTime); + public void testRunStopped(long elapsedTime); - void testStarted(String testName); + public void testStarted(String testName); - void testEnded(String testName); + public void testEnded(String testName); - void testFailed(int status, String testName, String trace); + public void testFailed(int status, String testName, String trace); } diff --git a/src/main/java/junit/runner/Version.java b/src/main/java/junit/runner/Version.java index 6c7862e..eaf3db7 100644 --- a/src/main/java/junit/runner/Version.java +++ b/src/main/java/junit/runner/Version.java @@ -9,7 +9,7 @@ public class Version { } public static String id() { - return "4.13.3-SNAPSHOT"; + return "4.12-SNAPSHOT"; } public static void main(String[] args) { diff --git a/src/main/java/junit/textui/TestRunner.java b/src/main/java/junit/textui/TestRunner.java index 913020a..4d78f77 100644 --- a/src/main/java/junit/textui/TestRunner.java +++ b/src/main/java/junit/textui/TestRunner.java @@ -131,7 +131,7 @@ public class TestRunner extends BaseTestRunner { } } - public static void main(String[] args) { + public static void main(String args[]) { TestRunner aTestRunner = new TestRunner(); try { TestResult r = aTestRunner.start(args); @@ -149,7 +149,7 @@ public class TestRunner extends BaseTestRunner { * Starts a test run. Analyzes the command line arguments and runs the given * test suite. */ - public TestResult start(String[] args) throws Exception { + public TestResult start(String args[]) throws Exception { String testCase = ""; String method = ""; boolean wait = false; diff --git a/src/main/java/org/junit/Assert.java b/src/main/java/org/junit/Assert.java old mode 100644 new mode 100755 index 65bbc9d..d7deb06 --- a/src/main/java/org/junit/Assert.java +++ b/src/main/java/org/junit/Assert.java @@ -2,7 +2,6 @@ package org.junit; import org.hamcrest.Matcher; import org.hamcrest.MatcherAssert; -import org.junit.function.ThrowingRunnable; import org.junit.internal.ArrayComparisonFailure; import org.junit.internal.ExactComparisonCriteria; import org.junit.internal.InexactComparisonCriteria; @@ -37,7 +36,7 @@ public class Assert { * okay) * @param condition condition to be checked */ - public static void assertTrue(String message, boolean condition) { + static public void assertTrue(String message, boolean condition) { if (!condition) { fail(message); } @@ -49,7 +48,7 @@ public class Assert { * * @param condition condition to be checked */ - public static void assertTrue(boolean condition) { + static public void assertTrue(boolean condition) { assertTrue(null, condition); } @@ -61,7 +60,7 @@ public class Assert { * okay) * @param condition condition to be checked */ - public static void assertFalse(String message, boolean condition) { + static public void assertFalse(String message, boolean condition) { assertTrue(message, !condition); } @@ -71,7 +70,7 @@ public class Assert { * * @param condition condition to be checked */ - public static void assertFalse(boolean condition) { + static public void assertFalse(boolean condition) { assertFalse(null, condition); } @@ -82,7 +81,7 @@ public class Assert { * okay) * @see AssertionError */ - public static void fail(String message) { + static public void fail(String message) { if (message == null) { throw new AssertionError(); } @@ -92,7 +91,7 @@ public class Assert { /** * Fails a test with no message. */ - public static void fail() { + static public void fail() { fail(null); } @@ -107,12 +106,11 @@ public class Assert { * @param expected expected value * @param actual actual value */ - public static void assertEquals(String message, Object expected, + static public void assertEquals(String message, Object expected, Object actual) { if (equalsRegardingNull(expected, actual)) { return; - } - if (expected instanceof String && actual instanceof String) { + } else if (expected instanceof String && actual instanceof String) { String cleanMessage = message == null ? "" : message; throw new ComparisonFailure(cleanMessage, (String) expected, (String) actual); @@ -142,7 +140,7 @@ public class Assert { * @param expected expected value * @param actual the value to check against expected */ - public static void assertEquals(Object expected, Object actual) { + static public void assertEquals(Object expected, Object actual) { assertEquals(null, expected, actual); } @@ -157,7 +155,7 @@ public class Assert { * @param unexpected unexpected value to check * @param actual the value to check against unexpected */ - public static void assertNotEquals(String message, Object unexpected, + static public void assertNotEquals(String message, Object unexpected, Object actual) { if (equalsRegardingNull(unexpected, actual)) { failEquals(message, actual); @@ -173,7 +171,7 @@ public class Assert { * @param unexpected unexpected value to check * @param actual the value to check against unexpected */ - public static void assertNotEquals(Object unexpected, Object actual) { + static public void assertNotEquals(Object unexpected, Object actual) { assertNotEquals(null, unexpected, actual); } @@ -196,7 +194,7 @@ public class Assert { * @param unexpected unexpected value to check * @param actual the value to check against unexpected */ - public static void assertNotEquals(String message, long unexpected, long actual) { + static public void assertNotEquals(String message, long unexpected, long actual) { if (unexpected == actual) { failEquals(message, Long.valueOf(actual)); } @@ -209,7 +207,7 @@ public class Assert { * @param unexpected unexpected value to check * @param actual the value to check against unexpected */ - public static void assertNotEquals(long unexpected, long actual) { + static public void assertNotEquals(long unexpected, long actual) { assertNotEquals(null, unexpected, actual); } @@ -228,7 +226,7 @@ public class Assert { * actual for which both numbers are still * considered equal. */ - public static void assertNotEquals(String message, double unexpected, + static public void assertNotEquals(String message, double unexpected, double actual, double delta) { if (!doubleIsDifferent(unexpected, actual, delta)) { failEquals(message, Double.valueOf(actual)); @@ -247,7 +245,7 @@ public class Assert { * actual for which both numbers are still * considered equal. */ - public static void assertNotEquals(double unexpected, double actual, double delta) { + static public void assertNotEquals(double unexpected, double actual, double delta) { assertNotEquals(null, unexpected, actual, delta); } @@ -263,7 +261,7 @@ public class Assert { * actual for which both numbers are still * considered equal. */ - public static void assertNotEquals(float unexpected, float actual, float delta) { + static public void assertNotEquals(float unexpected, float actual, float delta) { assertNotEquals(null, unexpected, actual, delta); } @@ -299,7 +297,7 @@ public class Assert { public static void assertArrayEquals(Object[] expecteds, Object[] actuals) { assertArrayEquals(null, expecteds, actuals); } - + /** * Asserts that two boolean arrays are equal. If they are not, an * {@link AssertionError} is thrown with the given message. If @@ -314,8 +312,8 @@ public class Assert { public static void assertArrayEquals(String message, boolean[] expecteds, boolean[] actuals) throws ArrayComparisonFailure { internalArrayEquals(message, expecteds, actuals); - } - + } + /** * Asserts that two boolean arrays are equal. If they are not, an * {@link AssertionError} is thrown. If expected and @@ -549,7 +547,7 @@ public class Assert { * actual for which both numbers are still * considered equal. */ - public static void assertEquals(String message, double expected, + static public void assertEquals(String message, double expected, double actual, double delta) { if (doubleIsDifferent(expected, actual, delta)) { failNotEquals(message, Double.valueOf(expected), Double.valueOf(actual)); @@ -571,7 +569,7 @@ public class Assert { * actual for which both numbers are still * considered equal. */ - public static void assertEquals(String message, float expected, + static public void assertEquals(String message, float expected, float actual, float delta) { if (floatIsDifferent(expected, actual, delta)) { failNotEquals(message, Float.valueOf(expected), Float.valueOf(actual)); @@ -593,14 +591,14 @@ public class Assert { * actual for which both numbers are still * considered equal. */ - public static void assertNotEquals(String message, float unexpected, + static public void assertNotEquals(String message, float unexpected, float actual, float delta) { if (!floatIsDifferent(unexpected, actual, delta)) { failEquals(message, Float.valueOf(actual)); } } - private static boolean doubleIsDifferent(double d1, double d2, double delta) { + static private boolean doubleIsDifferent(double d1, double d2, double delta) { if (Double.compare(d1, d2) == 0) { return false; } @@ -611,7 +609,7 @@ public class Assert { return true; } - private static boolean floatIsDifferent(float f1, float f2, float delta) { + static private boolean floatIsDifferent(float f1, float f2, float delta) { if (Float.compare(f1, f2) == 0) { return false; } @@ -629,7 +627,7 @@ public class Assert { * @param expected expected long value. * @param actual actual long value */ - public static void assertEquals(long expected, long actual) { + static public void assertEquals(long expected, long actual) { assertEquals(null, expected, actual); } @@ -642,7 +640,7 @@ public class Assert { * @param expected long expected value. * @param actual long actual value */ - public static void assertEquals(String message, long expected, long actual) { + static public void assertEquals(String message, long expected, long actual) { if (expected != actual) { failNotEquals(message, Long.valueOf(expected), Long.valueOf(actual)); } @@ -654,7 +652,7 @@ public class Assert { * instead */ @Deprecated - public static void assertEquals(double expected, double actual) { + static public void assertEquals(double expected, double actual) { assertEquals(null, expected, actual); } @@ -664,7 +662,7 @@ public class Assert { * instead */ @Deprecated - public static void assertEquals(String message, double expected, + static public void assertEquals(String message, double expected, double actual) { fail("Use assertEquals(expected, actual, delta) to compare floating-point numbers"); } @@ -681,7 +679,7 @@ public class Assert { * actual for which both numbers are still * considered equal. */ - public static void assertEquals(double expected, double actual, double delta) { + static public void assertEquals(double expected, double actual, double delta) { assertEquals(null, expected, actual, delta); } @@ -697,7 +695,8 @@ public class Assert { * actual for which both numbers are still * considered equal. */ - public static void assertEquals(float expected, float actual, float delta) { + + static public void assertEquals(float expected, float actual, float delta) { assertEquals(null, expected, actual, delta); } @@ -709,7 +708,7 @@ public class Assert { * okay) * @param object Object to check or null */ - public static void assertNotNull(String message, Object object) { + static public void assertNotNull(String message, Object object) { assertTrue(message, object != null); } @@ -719,7 +718,7 @@ public class Assert { * * @param object Object to check or null */ - public static void assertNotNull(Object object) { + static public void assertNotNull(Object object) { assertNotNull(null, object); } @@ -731,7 +730,7 @@ public class Assert { * okay) * @param object Object to check or null */ - public static void assertNull(String message, Object object) { + static public void assertNull(String message, Object object) { if (object == null) { return; } @@ -744,11 +743,11 @@ public class Assert { * * @param object Object to check or null */ - public static void assertNull(Object object) { + static public void assertNull(Object object) { assertNull(null, object); } - private static void failNotNull(String message, Object actual) { + static private void failNotNull(String message, Object actual) { String formatted = ""; if (message != null) { formatted = message + " "; @@ -765,7 +764,7 @@ public class Assert { * @param expected the expected object * @param actual the object to compare to expected */ - public static void assertSame(String message, Object expected, Object actual) { + static public void assertSame(String message, Object expected, Object actual) { if (expected == actual) { return; } @@ -779,7 +778,7 @@ public class Assert { * @param expected the expected object * @param actual the object to compare to expected */ - public static void assertSame(Object expected, Object actual) { + static public void assertSame(Object expected, Object actual) { assertSame(null, expected, actual); } @@ -793,7 +792,7 @@ public class Assert { * @param unexpected the object you don't expect * @param actual the object to compare to unexpected */ - public static void assertNotSame(String message, Object unexpected, + static public void assertNotSame(String message, Object unexpected, Object actual) { if (unexpected == actual) { failSame(message); @@ -808,11 +807,11 @@ public class Assert { * @param unexpected the object you don't expect * @param actual the object to compare to unexpected */ - public static void assertNotSame(Object unexpected, Object actual) { + static public void assertNotSame(Object unexpected, Object actual) { assertNotSame(null, unexpected, actual); } - private static void failSame(String message) { + static private void failSame(String message) { String formatted = ""; if (message != null) { formatted = message + " "; @@ -820,7 +819,7 @@ public class Assert { fail(formatted + "expected not same"); } - private static void failNotSame(String message, Object expected, + static private void failNotSame(String message, Object expected, Object actual) { String formatted = ""; if (message != null) { @@ -830,19 +829,19 @@ public class Assert { + ">"); } - private static void failNotEquals(String message, Object expected, + static private void failNotEquals(String message, Object expected, Object actual) { fail(format(message, expected, actual)); } static String format(String message, Object expected, Object actual) { String formatted = ""; - if (message != null && !"".equals(message)) { + if (message != null && !message.equals("")) { formatted = message + " "; } String expectedString = String.valueOf(expected); String actualString = String.valueOf(actual); - if (equalsRegardingNull(expectedString, actualString)) { + if (expectedString.equals(actualString)) { return formatted + "expected: " + formatClassAndValue(expected, expectedString) + " but was: " + formatClassAndValue(actual, actualString); @@ -852,11 +851,6 @@ public class Assert { } } - private static String formatClass(Class value) { - String className = value.getCanonicalName(); - return className == null ? value.getName() : className; - } - private static String formatClassAndValue(Object value, String valueString) { String className = value == null ? "null" : value.getClass().getName(); return className + "<" + valueString + ">"; @@ -923,9 +917,8 @@ public class Assert { * @param matcher an expression, built of {@link Matcher}s, specifying allowed * values * @see org.hamcrest.CoreMatchers - * @deprecated use {@code org.hamcrest.MatcherAssert.assertThat()} + * @see org.hamcrest.MatcherAssert */ - @Deprecated public static void assertThat(T actual, Matcher matcher) { assertThat("", actual, matcher); } @@ -956,79 +949,10 @@ public class Assert { * @param matcher an expression, built of {@link Matcher}s, specifying allowed * values * @see org.hamcrest.CoreMatchers - * @deprecated use {@code org.hamcrest.MatcherAssert.assertThat()} + * @see org.hamcrest.MatcherAssert */ - @Deprecated public static void assertThat(String reason, T actual, Matcher matcher) { MatcherAssert.assertThat(reason, actual, matcher); } - - /** - * Asserts that {@code runnable} throws an exception of type {@code expectedThrowable} when - * executed. If it does, the exception object is returned. If it does not throw an exception, an - * {@link AssertionError} is thrown. If it throws the wrong type of exception, an {@code - * AssertionError} is thrown describing the mismatch; the exception that was actually thrown can - * be obtained by calling {@link AssertionError#getCause}. - * - * @param expectedThrowable the expected type of the exception - * @param runnable a function that is expected to throw an exception when executed - * @return the exception thrown by {@code runnable} - * @since 4.13 - */ - public static T assertThrows(Class expectedThrowable, - ThrowingRunnable runnable) { - return assertThrows(null, expectedThrowable, runnable); - } - - /** - * Asserts that {@code runnable} throws an exception of type {@code expectedThrowable} when - * executed. If it does, the exception object is returned. If it does not throw an exception, an - * {@link AssertionError} is thrown. If it throws the wrong type of exception, an {@code - * AssertionError} is thrown describing the mismatch; the exception that was actually thrown can - * be obtained by calling {@link AssertionError#getCause}. - * - * @param message the identifying message for the {@link AssertionError} (null - * okay) - * @param expectedThrowable the expected type of the exception - * @param runnable a function that is expected to throw an exception when executed - * @return the exception thrown by {@code runnable} - * @since 4.13 - */ - public static T assertThrows(String message, Class expectedThrowable, - ThrowingRunnable runnable) { - try { - runnable.run(); - } catch (Throwable actualThrown) { - if (expectedThrowable.isInstance(actualThrown)) { - @SuppressWarnings("unchecked") T retVal = (T) actualThrown; - return retVal; - } else { - String expected = formatClass(expectedThrowable); - Class actualThrowable = actualThrown.getClass(); - String actual = formatClass(actualThrowable); - if (expected.equals(actual)) { - // There must be multiple class loaders. Add the identity hash code so the message - // doesn't say "expected: java.lang.String ..." - expected += "@" + Integer.toHexString(System.identityHashCode(expectedThrowable)); - actual += "@" + Integer.toHexString(System.identityHashCode(actualThrowable)); - } - String mismatchMessage = buildPrefix(message) - + format("unexpected exception type thrown;", expected, actual); - - // The AssertionError(String, Throwable) ctor is only available on JDK7. - AssertionError assertionError = new AssertionError(mismatchMessage); - assertionError.initCause(actualThrown); - throw assertionError; - } - } - String notThrownMessage = buildPrefix(message) + String - .format("expected %s to be thrown, but nothing was thrown", - formatClass(expectedThrowable)); - throw new AssertionError(notThrownMessage); - } - - private static String buildPrefix(String message) { - return message != null && message.length() != 0 ? message + ": " : ""; - } } diff --git a/src/main/java/org/junit/Assume.java b/src/main/java/org/junit/Assume.java index 29b705b..b7687f7 100644 --- a/src/main/java/org/junit/Assume.java +++ b/src/main/java/org/junit/Assume.java @@ -14,7 +14,7 @@ import org.hamcrest.Matcher; * basically means "don't run this test if these conditions don't apply". The default JUnit runner skips tests with * failing assumptions. Custom runners may behave differently. *

    - * A good example of using assumptions is in Theories where they are needed to exclude certain datapoints that aren't suitable or allowed for a certain test case. + * A good example of using assumptions is in Theories where they are needed to exclude certain datapoints that aren't suitable or allowed for a certain test case. *

    * Failed assumptions are usually not logged, because there may be many tests that don't apply to certain * configurations. @@ -29,20 +29,11 @@ import org.hamcrest.Matcher; * *

    * - * @see Theories + * @see Theories * * @since 4.4 */ public class Assume { - - /** - * Do not instantiate. - * @deprecated since 4.13. - */ - @Deprecated - public Assume() { - } - /** * If called with an expression evaluating to {@code false}, the test will halt and be ignored. */ @@ -54,7 +45,7 @@ public class Assume { * The inverse of {@link #assumeTrue(boolean)}. */ public static void assumeFalse(boolean b) { - assumeThat(b, is(false)); + assumeTrue(!b); } /** @@ -76,11 +67,9 @@ public class Assume { } /** - * If called with a {@code null} array or one or more {@code null} elements in {@code objects}, - * the test will halt and be ignored. + * If called with one or more null elements in objects, the test will halt and be ignored. */ public static void assumeNotNull(Object... objects) { - assumeThat(objects, notNullValue()); assumeThat(asList(objects), everyItem(notNullValue())); } diff --git a/src/main/java/org/junit/AssumptionViolatedException.java b/src/main/java/org/junit/AssumptionViolatedException.java index 1d62190..e48ddf0 100644 --- a/src/main/java/org/junit/AssumptionViolatedException.java +++ b/src/main/java/org/junit/AssumptionViolatedException.java @@ -40,7 +40,7 @@ public class AssumptionViolatedException extends org.junit.internal.AssumptionVi /** * An assumption exception with the given message and a cause. */ - public AssumptionViolatedException(String message, Throwable t) { - super(message, t); + public AssumptionViolatedException(String assumption, Throwable t) { + super(assumption, t); } } diff --git a/src/main/java/org/junit/ClassRule.java b/src/main/java/org/junit/ClassRule.java index 94ee29f..02c40a7 100644 --- a/src/main/java/org/junit/ClassRule.java +++ b/src/main/java/org/junit/ClassRule.java @@ -28,10 +28,7 @@ import java.lang.annotation.Target; * annotated {@link ClassRule}s on a class, they will be applied in an order * that depends on your JVM's implementation of the reflection API, which is * 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

    + * before Rules defined by methods. *

    * 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: @@ -82,37 +79,9 @@ import java.lang.annotation.Target; *

    * 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) @Target({ElementType.FIELD, ElementType.METHOD}) public @interface ClassRule { - - /** - * Specifies the order in which rules are applied. The rules with a higher value are inner. - * - * @since 4.13 - */ - int order() default Rule.DEFAULT_ORDER; - } diff --git a/src/main/java/org/junit/ComparisonFailure.java b/src/main/java/org/junit/ComparisonFailure.java index d1daa86..9563e61 100644 --- a/src/main/java/org/junit/ComparisonFailure.java +++ b/src/main/java/org/junit/ComparisonFailure.java @@ -21,7 +21,7 @@ public class ComparisonFailure extends AssertionError { /* * We have to use the f prefix until the next major release to ensure * serialization compatibility. - * See https://github.com/junit-team/junit4/issues/976 + * See https://github.com/junit-team/junit/issues/976 */ private String fExpected; private String fActual; diff --git a/src/main/java/org/junit/Rule.java b/src/main/java/org/junit/Rule.java index 9370e94..711235c 100644 --- a/src/main/java/org/junit/Rule.java +++ b/src/main/java/org/junit/Rule.java @@ -16,14 +16,12 @@ import java.lang.annotation.Target; * to the {@link org.junit.rules.TestRule} will run any {@link Before} methods, * then the {@link Test} method, and finally any {@link After} methods, * throwing an exception if any of these fail. If there are multiple - * annotated {@link Rule}s on a class, they will be applied in order of methods first, then fields. + * annotated {@link Rule}s on a class, they will be applied in order of fields first, then methods. * However, if there are multiple fields (or methods) they will be applied in an order * 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. - * - *

    Usage

    + * before Rules defined by methods. You can use a {@link org.junit.rules.RuleChain} if you want + * to have control over the order in which the Rules are applied. *

    * For example, here is a test class that creates a temporary folder before * each test method, and deletes it after each: @@ -63,39 +61,10 @@ import java.lang.annotation.Target; * 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) @Target({ElementType.FIELD, ElementType.METHOD}) public @interface Rule { - int DEFAULT_ORDER = -1; - - /** - * Specifies the order in which rules are applied. The rules with a higher value are inner. - * - * @since 4.13 - */ - int order() default DEFAULT_ORDER; - -} +} \ No newline at end of file diff --git a/src/main/java/org/junit/Test.java b/src/main/java/org/junit/Test.java index 1db6fc7..71ac428 100644 --- a/src/main/java/org/junit/Test.java +++ b/src/main/java/org/junit/Test.java @@ -1,7 +1,5 @@ package org.junit; -import org.junit.function.ThrowingRunnable; - import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -25,40 +23,24 @@ import java.lang.annotation.Target; * } * *

    - * The Test annotation supports two optional parameters for - * exception testing and for limiting test execution time. - * - *

    Exception Testing

    - *

    - * The parameter expected declares that a test method should throw + * The Test annotation supports two optional parameters. + * The first, expected, declares that a test method should throw * an exception. If it doesn't throw an exception or if it throws a different exception * than the one declared, the test fails. For example, the following test succeeds: *

    - *    @Test(expected=IndexOutOfBoundsException.class)
    - *    public void outOfBounds() {
    + *    @Test(expected=IndexOutOfBoundsException.class) public void outOfBounds() {
      *       new ArrayList<Object>().get(1);
      *    }
      * 
    - * - * Using the parameter expected for exception testing comes with - * some limitations: only the exception's type can be checked and it is not - * possible to precisely specify the code that throws the exception. Therefore - * JUnit 4 has improved its support for exception testing with - * {@link Assert#assertThrows(Class, ThrowingRunnable)} and the - * {@link org.junit.rules.ExpectedException ExpectedException} rule. - * With assertThrows the code that throws the exception can be - * precisely specified. If the exception's message or one of its properties - * should be verified, the ExpectedException rule can be used. Further + * If the exception's message or one of its properties should be verified, the + * {@link org.junit.rules.ExpectedException ExpectedException} rule can be used. Further * information about exception testing can be found at the - * JUnit Wiki. - * - *

    Timeout

    + * JUnit Wiki. *

    - * The parameter timeout causes a test to fail if it takes + * The second optional parameter, timeout, causes a test to fail if it takes * longer than a specified amount of clock time (measured in milliseconds). The following test fails: *

    - *    @Test(timeout=100)
    - *    public void infinity() {
    + *    @Test(timeout=100) public void infinity() {
      *       while(true);
      *    }
      * 
    @@ -67,8 +49,7 @@ import java.lang.annotation.Target; * following test may or may not fail depending on how the operating system * schedules threads: *
    - *    @Test(timeout=100)
    - *    public void sleep100() {
    + *    @Test(timeout=100) public void sleep100() {
      *       Thread.sleep(100);
      *    }
      * 
    @@ -85,7 +66,7 @@ import java.lang.annotation.Target; public @interface Test { /** - * Default empty exception. + * Default empty exception */ static class None extends Throwable { private static final long serialVersionUID = 1L; diff --git a/src/main/java/org/junit/TestCouldNotBeSkippedException.java b/src/main/java/org/junit/TestCouldNotBeSkippedException.java deleted file mode 100644 index 4804493..0000000 --- a/src/main/java/org/junit/TestCouldNotBeSkippedException.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.junit; - -/** - * Indicates that a test that indicated that it should be skipped could not be skipped. - * This can be thrown if a test uses the methods in {@link Assume} to indicate that - * it should be skipped, but before processing of the test was completed, other failures - * occured. - * - * @see org.junit.Assume - * @since 4.13 - */ -public class TestCouldNotBeSkippedException extends RuntimeException { - private static final long serialVersionUID = 1L; - - /** Creates an instance using the given assumption failure. */ - public TestCouldNotBeSkippedException(org.junit.internal.AssumptionViolatedException cause) { - super("Test could not be skipped due to other failures", cause); - } -} diff --git a/src/main/java/org/junit/experimental/categories/Categories.java b/src/main/java/org/junit/experimental/categories/Categories.java index 0c73ed8..290c180 100644 --- a/src/main/java/org/junit/experimental/categories/Categories.java +++ b/src/main/java/org/junit/experimental/categories/Categories.java @@ -2,10 +2,8 @@ package org.junit.experimental.categories; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import java.util.Arrays; import java.util.Collections; import java.util.HashSet; -import java.util.LinkedHashSet; import java.util.Set; import org.junit.runner.Description; @@ -78,7 +76,7 @@ import org.junit.runners.model.RunnerBuilder; * * * @version 4.12 - * @see Categories at JUnit wiki + * @see Categories at JUnit wiki */ public class Categories extends Suite { @@ -88,13 +86,13 @@ public class Categories extends Suite { * Determines the tests to run that are annotated with categories specified in * the value of this annotation or their subtypes unless excluded with {@link ExcludeCategory}. */ - Class[] value() default {}; + public Class[] value() default {}; /** * If true, runs tests annotated with any of the categories in * {@link IncludeCategory#value()}. Otherwise, runs tests only if annotated with all of the categories. */ - boolean matchAny() default true; + public boolean matchAny() default true; } @Retention(RetentionPolicy.RUNTIME) @@ -103,13 +101,13 @@ public class Categories extends Suite { * Determines the tests which do not run if they are annotated with categories specified in the * value of this annotation or their subtypes regardless of being included in {@link IncludeCategory#value()}. */ - Class[] value() default {}; + public Class[] value() default {}; /** * If true, the tests annotated with any of the categories in {@link ExcludeCategory#value()} * do not run. Otherwise, the tests do not run if and only if annotated with all categories. */ - boolean matchAny() default true; + public boolean matchAny() default true; } public static class CategoryFilter extends Filter { @@ -119,7 +117,10 @@ public class Categories extends Suite { private final boolean excludedAny; public static CategoryFilter include(boolean matchAny, Class... categories) { - return new CategoryFilter(matchAny, categories, true, null); + if (hasNull(categories)) { + throw new NullPointerException("has null category"); + } + return categoryFilter(matchAny, createSet(categories), true, null); } public static CategoryFilter include(Class category) { @@ -131,7 +132,10 @@ public class Categories extends Suite { } public static CategoryFilter exclude(boolean matchAny, Class... categories) { - return new CategoryFilter(true, null, matchAny, categories); + if (hasNull(categories)) { + throw new NullPointerException("has null category"); + } + return categoryFilter(true, null, matchAny, createSet(categories)); } public static CategoryFilter exclude(Class category) { @@ -147,30 +151,14 @@ public class Categories extends Suite { return new CategoryFilter(matchAnyInclusions, inclusions, matchAnyExclusions, exclusions); } - @Deprecated - public CategoryFilter(Class includedCategory, Class excludedCategory) { - includedAny = true; - excludedAny = true; - included = nullableClassToSet(includedCategory); - excluded = nullableClassToSet(excludedCategory); - } - protected CategoryFilter(boolean matchAnyIncludes, Set> includes, - boolean matchAnyExcludes, Set> excludes) { + boolean matchAnyExcludes, Set> excludes) { includedAny = matchAnyIncludes; excludedAny = matchAnyExcludes; included = copyAndRefine(includes); excluded = copyAndRefine(excludes); } - private CategoryFilter(boolean matchAnyIncludes, Class[] inclusions, - boolean matchAnyExcludes, Class[] exclusions) { - includedAny = matchAnyIncludes; - excludedAny = matchAnyExcludes; - included = createSet(inclusions); - excluded = createSet(exclusions); - } - /** * @see #toString() */ @@ -296,13 +284,23 @@ public class Categories extends Suite { } private static Set> copyAndRefine(Set> classes) { - Set> c= new LinkedHashSet>(); + HashSet> c= new HashSet>(); if (classes != null) { c.addAll(classes); } c.remove(null); return c; } + + private static boolean hasNull(Class... classes) { + if (classes == null) return false; + for (Class clazz : classes) { + if (clazz == null) { + return true; + } + } + return false; + } } public Categories(Class klass, RunnerBuilder builder) throws InitializationError { @@ -317,6 +315,7 @@ public class Categories extends Suite { } catch (NoTestsRemainException e) { throw new InitializationError(e); } + assertNoCategorizedDescendentsOfUncategorizeableParents(getDescription()); } private static Set> getIncludedCategory(Class klass) { @@ -339,6 +338,34 @@ public class Categories extends Suite { return annotation == null || annotation.matchAny(); } + private static void assertNoCategorizedDescendentsOfUncategorizeableParents(Description description) throws InitializationError { + if (!canHaveCategorizedChildren(description)) { + assertNoDescendantsHaveCategoryAnnotations(description); + } + for (Description each : description.getChildren()) { + assertNoCategorizedDescendentsOfUncategorizeableParents(each); + } + } + + private static void assertNoDescendantsHaveCategoryAnnotations(Description description) throws InitializationError { + for (Description each : description.getChildren()) { + if (each.getAnnotation(Category.class) != null) { + throw new InitializationError("Category annotations on Parameterized classes are not supported on individual methods."); + } + assertNoDescendantsHaveCategoryAnnotations(each); + } + } + + // If children have names like [0], our current magical category code can't determine their parentage. + private static boolean canHaveCategorizedChildren(Description description) { + for (Description each : description.getChildren()) { + if (each.getTestClass() == null) { + return false; + } + } + return true; + } + private static boolean hasAssignableTo(Set> assigns, Class to) { for (final Class from : assigns) { if (to.isAssignableFrom(from)) { @@ -348,28 +375,11 @@ public class Categories extends Suite { return false; } - private static Set> createSet(Class[] classes) { - // Not throwing a NPE if t is null is a bad idea, but it's the behavior from JUnit 4.12 - // for include(boolean, Class...) and exclude(boolean, Class...) - if (classes == null || classes.length == 0) { - return Collections.emptySet(); - } - for (Class category : classes) { - if (category == null) { - throw new NullPointerException("has null category"); - } + private static Set> createSet(Class... t) { + final Set> set= new HashSet>(); + if (t != null) { + Collections.addAll(set, t); } - - return classes.length == 1 - ? Collections.>singleton(classes[0]) - : new LinkedHashSet>(Arrays.asList(classes)); - } - - private static Set> nullableClassToSet(Class nullableClass) { - // Not throwing a NPE if t is null is a bad idea, but it's the behavior from JUnit 4.11 - // for CategoryFilter(Class includedCategory, Class excludedCategory) - return nullableClass == null - ? Collections.>emptySet() - : Collections.>singleton(nullableClass); + return set; } } diff --git a/src/main/java/org/junit/experimental/categories/CategoryFilterFactory.java b/src/main/java/org/junit/experimental/categories/CategoryFilterFactory.java index e9bdab7..cee1ae7 100644 --- a/src/main/java/org/junit/experimental/categories/CategoryFilterFactory.java +++ b/src/main/java/org/junit/experimental/categories/CategoryFilterFactory.java @@ -37,11 +37,7 @@ abstract class CategoryFilterFactory implements FilterFactory { List> categoryClasses = new ArrayList>(); for (String category : categories.split(",")) { - /* - * Load the category class using the context class loader. - * If there is no context class loader, use the class loader for this class. - */ - Class categoryClass = Classes.getClass(category, getClass()); + Class categoryClass = Classes.getClass(category); categoryClasses.add(categoryClass); } diff --git a/src/main/java/org/junit/experimental/max/MaxHistory.java b/src/main/java/org/junit/experimental/max/MaxHistory.java index ab7443f..45a4033 100644 --- a/src/main/java/org/junit/experimental/max/MaxHistory.java +++ b/src/main/java/org/junit/experimental/max/MaxHistory.java @@ -64,7 +64,7 @@ public class MaxHistory implements Serializable { /* * We have to use the f prefix until the next major release to ensure * serialization compatibility. - * See https://github.com/junit-team/junit4/issues/976 + * See https://github.com/junit-team/junit/issues/976 */ private final Map fDurations = new HashMap(); private final Map fFailureTimestamps = new HashMap(); @@ -75,15 +75,10 @@ public class MaxHistory implements Serializable { } private void save() throws IOException { - ObjectOutputStream stream = null; - try { - stream = new ObjectOutputStream(new FileOutputStream(fHistoryStore)); - stream.writeObject(this); - } finally { - if (stream != null) { - stream.close(); - } - } + ObjectOutputStream stream = new ObjectOutputStream(new FileOutputStream( + fHistoryStore)); + stream.writeObject(this); + stream.close(); } Long getFailureTimestamp(Description key) { diff --git a/src/main/java/org/junit/experimental/results/PrintableResult.java b/src/main/java/org/junit/experimental/results/PrintableResult.java index 0f67766..ffe22f0 100644 --- a/src/main/java/org/junit/experimental/results/PrintableResult.java +++ b/src/main/java/org/junit/experimental/results/PrintableResult.java @@ -54,15 +54,6 @@ public class PrintableResult { return result.getFailures().size(); } - /** - * Returns the failures in this result. - * - * @since 4.13 - */ - public List failures() { - return result.getFailures(); - } - @Override public String toString() { ByteArrayOutputStream stream = new ByteArrayOutputStream(); diff --git a/src/main/java/org/junit/experimental/results/ResultMatchers.java b/src/main/java/org/junit/experimental/results/ResultMatchers.java index 92f2e6b..cf58f1b 100644 --- a/src/main/java/org/junit/experimental/results/ResultMatchers.java +++ b/src/main/java/org/junit/experimental/results/ResultMatchers.java @@ -14,15 +14,6 @@ import org.hamcrest.TypeSafeMatcher; * */ public class ResultMatchers { - - /** - * Do not instantiate. - * @deprecated will be private soon. - */ - @Deprecated - public ResultMatchers() { - } - /** * Matches if the tests are all successful */ @@ -61,34 +52,14 @@ public class ResultMatchers { }; } - /** - * Matches if the result has exactly one failure matching the given matcher. - * - * @since 4.13 - */ - public static Matcher hasSingleFailureMatching(final Matcher matcher) { - return new TypeSafeMatcher() { - @Override - public boolean matchesSafely(PrintableResult item) { - return item.failureCount() == 1 && matcher.matches(item.failures().get(0).getException()); - } - - public void describeTo(Description description) { - description.appendText("has failure with exception matching "); - matcher.describeTo(description); - } - }; - } - /** * Matches if the result has one or more failures, and at least one of them * contains {@code string} */ public static Matcher hasFailureContaining(final String string) { - return new TypeSafeMatcher() { - @Override - public boolean matchesSafely(PrintableResult item) { - return item.failureCount() > 0 && item.toString().contains(string); + return new BaseMatcher() { + public boolean matches(Object item) { + return item.toString().contains(string); } public void describeTo(Description description) { diff --git a/src/main/java/org/junit/experimental/theories/ParametersSuppliedBy.java b/src/main/java/org/junit/experimental/theories/ParametersSuppliedBy.java index 846a39e..15b5d95 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 @@ import java.lang.annotation.Target; * * In addition, annotations themselves can be annotated with * @ParametersSuppliedBy, and then used similarly. ParameterSuppliedBy - * annotations on parameters are detected by searching up this hierarchy such + * annotations on parameters are detected by searching up this heirarchy such * that these act as syntactic sugar, making: * *
    diff --git a/src/main/java/org/junit/experimental/theories/Theories.java b/src/main/java/org/junit/experimental/theories/Theories.java
    index ac88a36..817f553 100644
    --- a/src/main/java/org/junit/experimental/theories/Theories.java
    +++ b/src/main/java/org/junit/experimental/theories/Theories.java
    @@ -51,11 +51,11 @@ import org.junit.runners.model.TestClass;
      *      }
      * }
      * 
    - * This makes it clear that the username should be included in the config file name, + * This makes it clear that the user's filename should be included in the config file name, * only if it doesn't contain a slash. Another test or theory might define what happens when a username does contain * a slash. UserTest will attempt to run filenameIncludesUsername on every compatible data * point defined in the class. If any of the assumptions fail, the data point is silently ignored. If all of the - * assumptions pass, but an assertion fails, the test fails. If no parameters can be found that satisfy all assumptions, the test fails. + * assumptions pass, but an assertion fails, the test fails. *

    * Defining general statements as theories allows data point reuse across a bunch of functionality tests and also * allows automated tools to search for new, unexpected data points that expose bugs. @@ -73,11 +73,6 @@ public class Theories extends BlockJUnit4ClassRunner { super(klass); } - /** @since 4.13 */ - protected Theories(TestClass testClass) throws InitializationError { - super(testClass); - } - @Override protected void collectInitializationErrors(List errors) { super.collectInitializationErrors(errors); @@ -220,7 +215,7 @@ public class Theories extends BlockJUnit4ClassRunner { protected void runWithCompleteAssignment(final Assignments complete) throws Throwable { - new BlockJUnit4ClassRunner(getTestClass()) { + new BlockJUnit4ClassRunner(getTestClass().getJavaClass()) { @Override protected void collectInitializationErrors( List errors) { diff --git a/src/main/java/org/junit/experimental/theories/internal/Assignments.java b/src/main/java/org/junit/experimental/theories/internal/Assignments.java index 6626797..a94c8a5 100644 --- a/src/main/java/org/junit/experimental/theories/internal/Assignments.java +++ b/src/main/java/org/junit/experimental/theories/internal/Assignments.java @@ -47,7 +47,7 @@ public class Assignments { } public boolean isComplete() { - return unassigned.isEmpty(); + return unassigned.size() == 0; } public ParameterSignature nextUnassigned() { @@ -55,10 +55,11 @@ public class Assignments { } public Assignments assignNext(PotentialAssignment source) { - List potentialAssignments = new ArrayList(assigned); - potentialAssignments.add(source); + List assigned = new ArrayList( + this.assigned); + assigned.add(source); - return new Assignments(potentialAssignments, unassigned.subList(1, + return new Assignments(assigned, unassigned.subList(1, unassigned.size()), clazz); } @@ -76,7 +77,7 @@ public class Assignments { ParameterSignature unassigned = nextUnassigned(); List assignments = getSupplier(unassigned).getValueSources(unassigned); - if (assignments.isEmpty()) { + if (assignments.size() == 0) { assignments = generateAssignmentsFromTypeAlone(unassigned); } diff --git a/src/main/java/org/junit/function/ThrowingRunnable.java b/src/main/java/org/junit/function/ThrowingRunnable.java deleted file mode 100644 index d0eb782..0000000 --- a/src/main/java/org/junit/function/ThrowingRunnable.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.junit.function; - -/** - * This interface facilitates the use of - * {@link org.junit.Assert#assertThrows(Class, ThrowingRunnable)} from Java 8. It allows method - * references to void methods (that declare checked exceptions) to be passed directly into - * {@code assertThrows} - * without wrapping. It is not meant to be implemented directly. - * - * @since 4.13 - */ -public interface ThrowingRunnable { - void run() throws Throwable; -} diff --git a/src/main/java/org/junit/internal/ArrayComparisonFailure.java b/src/main/java/org/junit/internal/ArrayComparisonFailure.java index d300e7e..8627d6e 100644 --- a/src/main/java/org/junit/internal/ArrayComparisonFailure.java +++ b/src/main/java/org/junit/internal/ArrayComparisonFailure.java @@ -16,12 +16,11 @@ public class ArrayComparisonFailure extends AssertionError { /* * We have to use the f prefix until the next major release to ensure - * serialization compatibility. - * See https://github.com/junit-team/junit4/issues/976 + * serialization compatibility. + * See https://github.com/junit-team/junit/issues/976 */ private final List fIndices = new ArrayList(); private final String fMessage; - private final AssertionError fCause; /** * Construct a new ArrayComparisonFailure with an error text and the array's @@ -33,8 +32,7 @@ public class ArrayComparisonFailure extends AssertionError { */ public ArrayComparisonFailure(String message, AssertionError cause, int index) { this.fMessage = message; - this.fCause = cause; - initCause(fCause); + initCause(cause); addDimension(index); } @@ -42,11 +40,6 @@ public class ArrayComparisonFailure extends AssertionError { fIndices.add(0, index); } - @Override - public synchronized Throwable getCause() { - return super.getCause() == null ? fCause : super.getCause(); - } - @Override public String getMessage() { StringBuilder sb = new StringBuilder(); diff --git a/src/main/java/org/junit/internal/AssumptionViolatedException.java b/src/main/java/org/junit/internal/AssumptionViolatedException.java index 0e79b56..880d73f 100644 --- a/src/main/java/org/junit/internal/AssumptionViolatedException.java +++ b/src/main/java/org/junit/internal/AssumptionViolatedException.java @@ -1,8 +1,5 @@ package org.junit.internal; -import java.io.IOException; -import java.io.ObjectOutputStream; - import org.hamcrest.Description; import org.hamcrest.Matcher; import org.hamcrest.SelfDescribing; @@ -21,7 +18,7 @@ public class AssumptionViolatedException extends RuntimeException implements Sel /* * We have to use the f prefix until the next major release to ensure * serialization compatibility. - * See https://github.com/junit-team/junit4/issues/976 + * See https://github.com/junit-team/junit/issues/976 */ private final String fAssumption; private final boolean fValueMatcher; @@ -111,29 +108,4 @@ public class AssumptionViolatedException extends RuntimeException implements Sel } } } - - /** - * Override default Java object serialization to correctly deal with potentially unserializable matchers or values. - * By not implementing readObject, we assure ourselves of backwards compatibility and compatibility with the - * standard way of Java serialization. - * - * @param objectOutputStream The outputStream to write our representation to - * @throws IOException When serialization fails - */ - private void writeObject(ObjectOutputStream objectOutputStream) throws IOException { - ObjectOutputStream.PutField putField = objectOutputStream.putFields(); - putField.put("fAssumption", fAssumption); - putField.put("fValueMatcher", fValueMatcher); - - // We have to wrap the matcher into a serializable form. - putField.put("fMatcher", SerializableMatcherDescription.asSerializableMatcher(fMatcher)); - - // We have to wrap the value inside a non-String class (instead of serializing the String value directly) as - // A Description will handle a String and non-String object differently (1st is surrounded by '"' while the - // latter will be surrounded by '<' '>'. Wrapping it makes sure that the description of a serialized and - // non-serialized instance produce the exact same description - putField.put("fValue", SerializableValueDescription.asSerializableValue(fValue)); - - objectOutputStream.writeFields(); - } } diff --git a/src/main/java/org/junit/internal/Checks.java b/src/main/java/org/junit/internal/Checks.java deleted file mode 100644 index 9724947..0000000 --- a/src/main/java/org/junit/internal/Checks.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.junit.internal; - -/** @since 4.13 */ -public final class Checks { - - private Checks() {} - - /** - * Checks that the given value is not {@code null}. - * - * @param value object reference to check - * @return the passed-in value, if not {@code null} - * @throws NullPointerException if {@code value} is {@code null} - */ - public static T notNull(T value) { - if (value == null) { - throw new NullPointerException(); - } - return value; - } - - /** - * Checks that the given value is not {@code null}, using the given message - * as the exception message if an exception is thrown. - * - * @param value object reference to check - * @param message message to use if {@code value} is {@code null} - * @return the passed-in value, if not {@code null} - * @throws NullPointerException if {@code value} is {@code null} - */ - public static T notNull(T value, String message) { - if (value == null) { - throw new NullPointerException(message); - } - return value; - } -} diff --git a/src/main/java/org/junit/internal/Classes.java b/src/main/java/org/junit/internal/Classes.java index e8404f6..154603d 100644 --- a/src/main/java/org/junit/internal/Classes.java +++ b/src/main/java/org/junit/internal/Classes.java @@ -6,39 +6,13 @@ import static java.lang.Thread.currentThread; * Miscellaneous functions dealing with classes. */ public class Classes { - - /** - * Do not instantiate. - * @deprecated will be private soon. - */ - @Deprecated - public Classes() { - } - /** * Returns Class.forName for {@code className} using the current thread's class loader. - * If the current thread does not have a class loader, falls back to the class loader for - * {@link Classes}. * * @param className Name of the class. * @throws ClassNotFoundException */ public static Class getClass(String className) throws ClassNotFoundException { - return getClass(className, Classes.class); - } - - /** - * Returns Class.forName for {@code className} using the current thread's class loader. - * If the current thread does not have a class loader, falls back to the class loader for the - * passed-in class. - * - * @param className Name of the class. - * @param callingClass Class that is requesting a the class - * @throws ClassNotFoundException - * @since 4.13 - */ - public static Class getClass(String className, Class callingClass) throws ClassNotFoundException { - ClassLoader classLoader = currentThread().getContextClassLoader(); - return Class.forName(className, true, classLoader == null ? callingClass.getClassLoader() : classLoader); + return Class.forName(className, true, currentThread().getContextClassLoader()); } } diff --git a/src/main/java/org/junit/internal/ComparisonCriteria.java b/src/main/java/org/junit/internal/ComparisonCriteria.java index ed1c674..e6d49a4 100644 --- a/src/main/java/org/junit/internal/ComparisonCriteria.java +++ b/src/main/java/org/junit/internal/ComparisonCriteria.java @@ -25,11 +25,6 @@ public abstract class ComparisonCriteria { */ public void arrayEquals(String message, Object expecteds, Object actuals) throws ArrayComparisonFailure { - arrayEquals(message, expecteds, actuals, true); - } - - private void arrayEquals(String message, Object expecteds, Object actuals, boolean outer) - throws ArrayComparisonFailure { if (expecteds == actuals || Arrays.deepEquals(new Object[] {expecteds}, new Object[] {actuals})) { // The reflection-based loop below is potentially very slow, especially for primitive @@ -39,37 +34,19 @@ public abstract class ComparisonCriteria { } String header = message == null ? "" : message + ": "; - // Only include the user-provided message in the outer exception. - String exceptionMessage = outer ? header : ""; - - if (expecteds == null) { - Assert.fail(exceptionMessage + "expected array was null"); - } - if (actuals == null) { - Assert.fail(exceptionMessage + "actual array was null"); - } - - int actualsLength = Array.getLength(actuals); - int expectedsLength = Array.getLength(expecteds); - if (actualsLength != expectedsLength) { - header += "array lengths differed, expected.length=" - + expectedsLength + " actual.length=" + actualsLength + "; "; - } - int prefixLength = Math.min(actualsLength, expectedsLength); + int expectedsLength = assertArraysAreSameLength(expecteds, + actuals, header); - for (int i = 0; i < prefixLength; i++) { + for (int i = 0; i < expectedsLength; i++) { Object expected = Array.get(expecteds, i); Object actual = Array.get(actuals, i); if (isArray(expected) && isArray(actual)) { try { - arrayEquals(message, expected, actual, false); + arrayEquals(message, expected, actual); } catch (ArrayComparisonFailure e) { e.addDimension(i); throw e; - } catch (AssertionError e) { - // Array lengths differed. - throw new ArrayComparisonFailure(header, e, i); } } else { try { @@ -79,53 +56,27 @@ public abstract class ComparisonCriteria { } } } - - if (actualsLength != expectedsLength) { - Object expected = getToStringableArrayElement(expecteds, expectedsLength, prefixLength); - Object actual = getToStringableArrayElement(actuals, actualsLength, prefixLength); - try { - Assert.assertEquals(expected, actual); - } catch (AssertionError e) { - throw new ArrayComparisonFailure(header, e, prefixLength); - } - } } - private static final Object END_OF_ARRAY_SENTINEL = objectWithToString("end of array"); - - private Object getToStringableArrayElement(Object array, int length, int index) { - if (index < length) { - Object element = Array.get(array, index); - if (isArray(element)) { - return objectWithToString(componentTypeName(element.getClass()) + "[" + Array.getLength(element) + "]"); - } else { - return element; - } - } else { - return END_OF_ARRAY_SENTINEL; - } - } - - private static Object objectWithToString(final String string) { - return new Object() { - @Override - public String toString() { - return string; - } - }; + private boolean isArray(Object expected) { + return expected != null && expected.getClass().isArray(); } - private String componentTypeName(Class arrayClass) { - Class componentType = arrayClass.getComponentType(); - if (componentType.isArray()) { - return componentTypeName(componentType) + "[]"; - } else { - return componentType.getName(); + private int assertArraysAreSameLength(Object expecteds, + Object actuals, String header) { + if (expecteds == null) { + Assert.fail(header + "expected array was null"); } - } - - private boolean isArray(Object expected) { - return expected != null && expected.getClass().isArray(); + if (actuals == null) { + Assert.fail(header + "actual array was null"); + } + int actualsLength = Array.getLength(actuals); + int expectedsLength = Array.getLength(expecteds); + if (actualsLength != expectedsLength) { + Assert.fail(header + "array lengths differed, expected.length=" + + expectedsLength + " actual.length=" + actualsLength); + } + return expectedsLength; } protected abstract void assertElementsEqual(Object expected, Object actual); diff --git a/src/main/java/org/junit/internal/SerializableMatcherDescription.java b/src/main/java/org/junit/internal/SerializableMatcherDescription.java deleted file mode 100644 index e036557..0000000 --- a/src/main/java/org/junit/internal/SerializableMatcherDescription.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.junit.internal; - -import java.io.Serializable; - -import org.hamcrest.BaseMatcher; -import org.hamcrest.Description; -import org.hamcrest.Matcher; -import org.hamcrest.StringDescription; - -/** - * This class exists solely to provide a serializable description of a matcher to be serialized as a field in - * {@link AssumptionViolatedException}. Being a {@link Throwable}, it is required to be {@link Serializable}, but most - * implementations of {@link Matcher} are not. This class works around that limitation as - * {@link AssumptionViolatedException} only every uses the description of the {@link Matcher}, while still retaining - * backwards compatibility with classes compiled against its class signature before 4.14 and/or deserialization of - * previously serialized instances. - */ -class SerializableMatcherDescription extends BaseMatcher implements Serializable { - - private final String matcherDescription; - - private SerializableMatcherDescription(Matcher matcher) { - matcherDescription = StringDescription.asString(matcher); - } - - public boolean matches(Object o) { - throw new UnsupportedOperationException("This Matcher implementation only captures the description"); - } - - public void describeTo(Description description) { - description.appendText(matcherDescription); - } - - /** - * Factory method that checks to see if the matcher is already serializable. - * @param matcher the matcher to make serializable - * @return The provided matcher if it is null or already serializable, - * the SerializableMatcherDescription representation of it if it is not. - */ - static Matcher asSerializableMatcher(Matcher matcher) { - if (matcher == null || matcher instanceof Serializable) { - return matcher; - } else { - return new SerializableMatcherDescription(matcher); - } - } -} diff --git a/src/main/java/org/junit/internal/SerializableValueDescription.java b/src/main/java/org/junit/internal/SerializableValueDescription.java deleted file mode 100644 index 4d055d7..0000000 --- a/src/main/java/org/junit/internal/SerializableValueDescription.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.junit.internal; - -import java.io.Serializable; - -/** - * This class exists solely to provide a serializable description of a value to be serialized as a field in - * {@link AssumptionViolatedException}. Being a {@link Throwable}, it is required to be {@link Serializable}, but a - * value of type Object provides no guarantee to be serializable. This class works around that limitation as - * {@link AssumptionViolatedException} only every uses the string representation of the value, while still retaining - * backwards compatibility with classes compiled against its class signature before 4.14 and/or deserialization of - * previously serialized instances. - */ -class SerializableValueDescription implements Serializable { - private final String value; - - private SerializableValueDescription(Object value) { - this.value = String.valueOf(value); - } - - /** - * Factory method that checks to see if the value is already serializable. - * @param value the value to make serializable - * @return The provided value if it is null or already serializable, - * the SerializableValueDescription representation of it if it is not. - */ - static Object asSerializableValue(Object value) { - if (value == null || value instanceof Serializable) { - return value; - } else { - return new SerializableValueDescription(value); - } - } - - @Override - public String toString() { - return value; - } -} diff --git a/src/main/java/org/junit/internal/TextListener.java b/src/main/java/org/junit/internal/TextListener.java index d548aeb..9aa56c7 100644 --- a/src/main/java/org/junit/internal/TextListener.java +++ b/src/main/java/org/junit/internal/TextListener.java @@ -58,7 +58,7 @@ public class TextListener extends RunListener { protected void printFailures(Result result) { List failures = result.getFailures(); - if (failures.isEmpty()) { + if (failures.size() == 0) { return; } if (failures.size() == 1) { @@ -74,7 +74,7 @@ public class TextListener extends RunListener { protected void printFailure(Failure each, String prefix) { getWriter().println(prefix + ") " + each.getTestHeader()); - getWriter().print(each.getTrimmedTrace()); + getWriter().print(each.getTrace()); } protected void printFooter(Result result) { diff --git a/src/main/java/org/junit/internal/Throwables.java b/src/main/java/org/junit/internal/Throwables.java index 3f0f7a3..86dceef 100644 --- a/src/main/java/org/junit/internal/Throwables.java +++ b/src/main/java/org/junit/internal/Throwables.java @@ -1,17 +1,5 @@ package org.junit.internal; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.PrintWriter; -import java.io.StringReader; -import java.io.StringWriter; -import java.lang.reflect.Method; -import java.util.AbstractList; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - /** * Miscellaneous functions dealing with {@code Throwable}. * @@ -51,223 +39,4 @@ public final class Throwables { private static void rethrow(Throwable e) throws T { throw (T) e; } - - /** - * Returns the stacktrace of the given Throwable as a String. - * - * @since 4.13 - */ - public static String getStacktrace(Throwable exception) { - StringWriter stringWriter = new StringWriter(); - PrintWriter writer = new PrintWriter(stringWriter); - exception.printStackTrace(writer); - return stringWriter.toString(); - } - - /** - * Gets a trimmed version of the stack trace of the given exception. Stack trace - * elements that are below the test method are filtered out. - * - * @return a trimmed stack trace, or the original trace if trimming wasn't possible - */ - public static String getTrimmedStackTrace(Throwable exception) { - List trimmedStackTraceLines = getTrimmedStackTraceLines(exception); - if (trimmedStackTraceLines.isEmpty()) { - return getFullStackTrace(exception); - } - - StringBuilder result = new StringBuilder(exception.toString()); - appendStackTraceLines(trimmedStackTraceLines, result); - appendStackTraceLines(getCauseStackTraceLines(exception), result); - return result.toString(); - } - - private static List getTrimmedStackTraceLines(Throwable exception) { - List stackTraceElements = Arrays.asList(exception.getStackTrace()); - int linesToInclude = stackTraceElements.size(); - - State state = State.PROCESSING_OTHER_CODE; - for (StackTraceElement stackTraceElement : asReversedList(stackTraceElements)) { - state = state.processStackTraceElement(stackTraceElement); - if (state == State.DONE) { - List trimmedLines = new ArrayList(linesToInclude + 2); - trimmedLines.add(""); - for (StackTraceElement each : stackTraceElements.subList(0, linesToInclude)) { - trimmedLines.add("\tat " + each); - } - if (exception.getCause() != null) { - trimmedLines.add("\t... " + (stackTraceElements.size() - trimmedLines.size()) + " trimmed"); - } - return trimmedLines; - } - linesToInclude--; - } - return Collections.emptyList(); - } - - private static final Method getSuppressed = initGetSuppressed(); - - private static Method initGetSuppressed() { - try { - return Throwable.class.getMethod("getSuppressed"); - } catch (Throwable e) { - return null; - } - } - - private static boolean hasSuppressed(Throwable exception) { - if (getSuppressed == null) { - return false; - } - try { - Throwable[] suppressed = (Throwable[]) getSuppressed.invoke(exception); - return suppressed.length != 0; - } catch (Throwable e) { - return false; - } - } - - private static List getCauseStackTraceLines(Throwable exception) { - if (exception.getCause() != null || hasSuppressed(exception)) { - String fullTrace = getFullStackTrace(exception); - BufferedReader reader = new BufferedReader( - new StringReader(fullTrace.substring(exception.toString().length()))); - List causedByLines = new ArrayList(); - - try { - String line; - while ((line = reader.readLine()) != null) { - if (line.startsWith("Caused by: ") || line.trim().startsWith("Suppressed: ")) { - causedByLines.add(line); - while ((line = reader.readLine()) != null) { - causedByLines.add(line); - } - return causedByLines; - } - } - } catch (IOException e) { - // We should never get here, because we are reading from a StringReader - } - } - - return Collections.emptyList(); - } - - private static String getFullStackTrace(Throwable exception) { - StringWriter stringWriter = new StringWriter(); - PrintWriter writer = new PrintWriter(stringWriter); - exception.printStackTrace(writer); - return stringWriter.toString(); - } - - private static void appendStackTraceLines( - List stackTraceLines, StringBuilder destBuilder) { - for (String stackTraceLine : stackTraceLines) { - destBuilder.append(String.format("%s%n", stackTraceLine)); - } - } - - private static List asReversedList(final List list) { - return new AbstractList() { - - @Override - public T get(int index) { - return list.get(list.size() - index - 1); - } - - @Override - public int size() { - return list.size(); - } - }; - } - - private enum State { - PROCESSING_OTHER_CODE { - @Override public State processLine(String methodName) { - if (isTestFrameworkMethod(methodName)) { - return PROCESSING_TEST_FRAMEWORK_CODE; - } - return this; - } - }, - PROCESSING_TEST_FRAMEWORK_CODE { - @Override public State processLine(String methodName) { - if (isReflectionMethod(methodName)) { - return PROCESSING_REFLECTION_CODE; - } else if (isTestFrameworkMethod(methodName)) { - return this; - } - return PROCESSING_OTHER_CODE; - } - }, - PROCESSING_REFLECTION_CODE { - @Override public State processLine(String methodName) { - if (isReflectionMethod(methodName)) { - return this; - } else if (isTestFrameworkMethod(methodName)) { - // This is here to handle TestCase.runBare() calling TestCase.runTest(). - return PROCESSING_TEST_FRAMEWORK_CODE; - } - return DONE; - } - }, - DONE { - @Override public State processLine(String methodName) { - return this; - } - }; - - /** Processes a stack trace element method name, possibly moving to a new state. */ - protected abstract State processLine(String methodName); - - /** Processes a stack trace element, possibly moving to a new state. */ - public final State processStackTraceElement(StackTraceElement element) { - return processLine(element.getClassName() + "." + element.getMethodName() + "()"); - } - } - - private static final String[] TEST_FRAMEWORK_METHOD_NAME_PREFIXES = { - "org.junit.runner.", - "org.junit.runners.", - "org.junit.experimental.runners.", - "org.junit.internal.", - "junit.extensions", - "junit.framework", - "junit.runner", - "junit.textui", - }; - - private static final String[] TEST_FRAMEWORK_TEST_METHOD_NAME_PREFIXES = { - "org.junit.internal.StackTracesTest", - }; - - private static boolean isTestFrameworkMethod(String methodName) { - return isMatchingMethod(methodName, TEST_FRAMEWORK_METHOD_NAME_PREFIXES) && - !isMatchingMethod(methodName, TEST_FRAMEWORK_TEST_METHOD_NAME_PREFIXES); - } - - private static final String[] REFLECTION_METHOD_NAME_PREFIXES = { - "sun.reflect.", - "java.lang.reflect.", - "jdk.internal.reflect.", - "org.junit.rules.RunRules.(", - "org.junit.rules.RunRules.applyAll(", // calls TestRules - "org.junit.runners.RuleContainer.apply(", // calls MethodRules & TestRules - "junit.framework.TestCase.runBare(", // runBare() directly calls setUp() and tearDown() - }; - - private static boolean isReflectionMethod(String methodName) { - return isMatchingMethod(methodName, REFLECTION_METHOD_NAME_PREFIXES); - } - - private static boolean isMatchingMethod(String methodName, String[] methodNamePrefixes) { - for (String methodNamePrefix : methodNamePrefixes) { - if (methodName.startsWith(methodNamePrefix)) { - return true; - } - } - - return false; - } } diff --git a/src/main/java/org/junit/internal/builders/AllDefaultPossibilitiesBuilder.java b/src/main/java/org/junit/internal/builders/AllDefaultPossibilitiesBuilder.java index 8704a54..d86ec95 100644 --- a/src/main/java/org/junit/internal/builders/AllDefaultPossibilitiesBuilder.java +++ b/src/main/java/org/junit/internal/builders/AllDefaultPossibilitiesBuilder.java @@ -9,17 +9,6 @@ import org.junit.runners.model.RunnerBuilder; public class AllDefaultPossibilitiesBuilder extends RunnerBuilder { private final boolean canUseSuiteMethod; - /** - * @since 4.13 - */ - public AllDefaultPossibilitiesBuilder() { - canUseSuiteMethod = true; - } - - /** - * @deprecated used {@link #AllDefaultPossibilitiesBuilder()}. - */ - @Deprecated public AllDefaultPossibilitiesBuilder(boolean canUseSuiteMethod) { this.canUseSuiteMethod = canUseSuiteMethod; } diff --git a/src/main/java/org/junit/internal/builders/JUnit4Builder.java b/src/main/java/org/junit/internal/builders/JUnit4Builder.java index 7959e75..6a00678 100644 --- a/src/main/java/org/junit/internal/builders/JUnit4Builder.java +++ b/src/main/java/org/junit/internal/builders/JUnit4Builder.java @@ -1,12 +1,12 @@ package org.junit.internal.builders; import org.junit.runner.Runner; -import org.junit.runners.JUnit4; +import org.junit.runners.BlockJUnit4ClassRunner; import org.junit.runners.model.RunnerBuilder; public class JUnit4Builder extends RunnerBuilder { @Override public Runner runnerForClass(Class testClass) throws Throwable { - return new JUnit4(testClass); + return new BlockJUnit4ClassRunner(testClass); } -} +} \ No newline at end of file diff --git a/src/main/java/org/junit/internal/management/FakeRuntimeMXBean.java b/src/main/java/org/junit/internal/management/FakeRuntimeMXBean.java deleted file mode 100644 index 477b150..0000000 --- a/src/main/java/org/junit/internal/management/FakeRuntimeMXBean.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.junit.internal.management; - -import java.util.Collections; -import java.util.List; - -/** - * No-op implementation of RuntimeMXBean when the platform doesn't provide it. - */ -class FakeRuntimeMXBean implements RuntimeMXBean { - - /** - * {@inheritDoc} - * - *

    Always returns an empty list. - */ - public List getInputArguments() { - return Collections.emptyList(); - } - -} - diff --git a/src/main/java/org/junit/internal/management/FakeThreadMXBean.java b/src/main/java/org/junit/internal/management/FakeThreadMXBean.java deleted file mode 100644 index 893f2e3..0000000 --- a/src/main/java/org/junit/internal/management/FakeThreadMXBean.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.junit.internal.management; - -/** - * No-op implementation of ThreadMXBean when the platform doesn't provide it. - */ -final class FakeThreadMXBean implements ThreadMXBean { - - /** - * {@inheritDoc} - * - *

    Always throws an {@link UnsupportedOperationException} - */ - public long getThreadCpuTime(long id) { - throw new UnsupportedOperationException(); - } - - /** - * {@inheritDoc} - * - *

    Always returns false. - */ - public boolean isThreadCpuTimeSupported() { - return false; - } - -} - diff --git a/src/main/java/org/junit/internal/management/ManagementFactory.java b/src/main/java/org/junit/internal/management/ManagementFactory.java deleted file mode 100644 index 5be1447..0000000 --- a/src/main/java/org/junit/internal/management/ManagementFactory.java +++ /dev/null @@ -1,77 +0,0 @@ -package org.junit.internal.management; - -import org.junit.internal.Classes; - -import java.lang.reflect.InvocationTargetException; - -/** - * Reflective wrapper around {@link java.lang.management.ManagementFactory} - */ -public class ManagementFactory { - private static final class FactoryHolder { - private static final Class MANAGEMENT_FACTORY_CLASS; - - static { - Class managementFactoryClass = null; - try { - managementFactoryClass = Classes.getClass("java.lang.management.ManagementFactory"); - } catch (ClassNotFoundException e) { - // do nothing, managementFactoryClass will be none on failure - } - MANAGEMENT_FACTORY_CLASS = managementFactoryClass; - } - - static Object getBeanObject(String methodName) { - if (MANAGEMENT_FACTORY_CLASS != null) { - try { - return MANAGEMENT_FACTORY_CLASS.getMethod(methodName).invoke(null); - } catch (IllegalAccessException e) { - // fallthrough - } catch (IllegalArgumentException e) { - // fallthrough - } catch (InvocationTargetException e) { - // fallthrough - } catch (NoSuchMethodException e) { - // fallthrough - } catch (SecurityException e) { - // fallthrough - } - } - return null; - } - } - - private static final class RuntimeHolder { - private static final RuntimeMXBean RUNTIME_MX_BEAN = - getBean(FactoryHolder.getBeanObject("getRuntimeMXBean")); - - private static final RuntimeMXBean getBean(Object runtimeMxBean) { - return runtimeMxBean != null - ? new ReflectiveRuntimeMXBean(runtimeMxBean) : new FakeRuntimeMXBean(); - } - } - - private static final class ThreadHolder { - private static final ThreadMXBean THREAD_MX_BEAN = - getBean(FactoryHolder.getBeanObject("getThreadMXBean")); - - private static final ThreadMXBean getBean(Object threadMxBean) { - return threadMxBean != null - ? new ReflectiveThreadMXBean(threadMxBean) : new FakeThreadMXBean(); - } - } - - /** - * @see java.lang.management.ManagementFactory#getRuntimeMXBean() - */ - public static RuntimeMXBean getRuntimeMXBean() { - return RuntimeHolder.RUNTIME_MX_BEAN; - } - - /** - * @see java.lang.management.ManagementFactory#getThreadMXBean() - */ - public static ThreadMXBean getThreadMXBean() { - return ThreadHolder.THREAD_MX_BEAN; - } -} diff --git a/src/main/java/org/junit/internal/management/ReflectiveRuntimeMXBean.java b/src/main/java/org/junit/internal/management/ReflectiveRuntimeMXBean.java deleted file mode 100644 index 289587a..0000000 --- a/src/main/java/org/junit/internal/management/ReflectiveRuntimeMXBean.java +++ /dev/null @@ -1,61 +0,0 @@ -package org.junit.internal.management; - -import org.junit.internal.Classes; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Collections; -import java.util.List; - -/** - * Implementation of {@link RuntimeMXBean} using the JVM reflectively. - */ -final class ReflectiveRuntimeMXBean implements RuntimeMXBean { - private final Object runtimeMxBean; - - private static final class Holder { - private static final Method getInputArgumentsMethod; - static { - Method inputArguments = null; - try { - Class threadMXBeanClass = Classes.getClass("java.lang.management.RuntimeMXBean"); - inputArguments = threadMXBeanClass.getMethod("getInputArguments"); - } catch (ClassNotFoundException e) { - // do nothing, input arguments will be null on failure - } catch (NoSuchMethodException e) { - // do nothing, input arguments will be null on failure - } catch (SecurityException e) { - // do nothing, input arguments will be null on failure - } - getInputArgumentsMethod = inputArguments; - } - } - - ReflectiveRuntimeMXBean(Object runtimeMxBean) { - super(); - this.runtimeMxBean = runtimeMxBean; - } - - /** - * {@inheritDoc} - */ - @SuppressWarnings("unchecked") - public List getInputArguments() { - if (Holder.getInputArgumentsMethod != null) { - try { - return (List) Holder.getInputArgumentsMethod.invoke(runtimeMxBean); - } catch (ClassCastException e) { // no multi-catch with source level 6 - // fallthrough - } catch (IllegalAccessException e) { - // fallthrough - } catch (IllegalArgumentException e) { - // fallthrough - } catch (InvocationTargetException e) { - // fallthrough - } - } - return Collections.emptyList(); - } - -} - diff --git a/src/main/java/org/junit/internal/management/ReflectiveThreadMXBean.java b/src/main/java/org/junit/internal/management/ReflectiveThreadMXBean.java deleted file mode 100644 index bc741be..0000000 --- a/src/main/java/org/junit/internal/management/ReflectiveThreadMXBean.java +++ /dev/null @@ -1,92 +0,0 @@ -package org.junit.internal.management; - -import org.junit.internal.Classes; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -/** - * Implementation of {@link ThreadMXBean} using the JVM reflectively. - */ -final class ReflectiveThreadMXBean implements ThreadMXBean { - private final Object threadMxBean; - - - private static final class Holder { - static final Method getThreadCpuTimeMethod; - static final Method isThreadCpuTimeSupportedMethod; - - private static final String FAILURE_MESSAGE = "Unable to access ThreadMXBean"; - - static { - Method threadCpuTime = null; - Method threadCpuTimeSupported = null; - try { - Class threadMXBeanClass = Classes.getClass("java.lang.management.ThreadMXBean"); - threadCpuTime = threadMXBeanClass.getMethod("getThreadCpuTime", long.class); - threadCpuTimeSupported = threadMXBeanClass.getMethod("isThreadCpuTimeSupported"); - } catch (ClassNotFoundException e) { - // do nothing, the methods will be null on failure - } catch (NoSuchMethodException e) { - // do nothing, the methods will be null on failure - } catch (SecurityException e) { - // do nothing, the methods will be null on failure - } - getThreadCpuTimeMethod = threadCpuTime; - isThreadCpuTimeSupportedMethod = threadCpuTimeSupported; - } - } - - ReflectiveThreadMXBean(Object threadMxBean) { - super(); - this.threadMxBean = threadMxBean; - } - - /** - * {@inheritDoc} - */ - public long getThreadCpuTime(long id) { - if (Holder.getThreadCpuTimeMethod != null) { - Exception error = null; - try { - return (Long) Holder.getThreadCpuTimeMethod.invoke(threadMxBean, id); - } catch (ClassCastException e) { - error = e; - // fallthrough - } catch (IllegalAccessException e) { - error = e; - // fallthrough - } catch (IllegalArgumentException e) { - error = e; - // fallthrough - } catch (InvocationTargetException e) { - error = e; - // fallthrough - } - throw new UnsupportedOperationException(Holder.FAILURE_MESSAGE, error); - } - throw new UnsupportedOperationException(Holder.FAILURE_MESSAGE); - } - - /** - * {@inheritDoc} - */ - public boolean isThreadCpuTimeSupported() { - if (Holder.isThreadCpuTimeSupportedMethod != null) { - try { - return (Boolean) Holder.isThreadCpuTimeSupportedMethod.invoke(threadMxBean); - } catch (ClassCastException e) { - // fallthrough - } catch (IllegalAccessException e) { - // fallthrough - } catch (IllegalArgumentException e) { - // fallthrough - } catch (InvocationTargetException e) { - // fallthrough - } - } - return false; - } - -} - diff --git a/src/main/java/org/junit/internal/management/RuntimeMXBean.java b/src/main/java/org/junit/internal/management/RuntimeMXBean.java deleted file mode 100644 index 84f8861..0000000 --- a/src/main/java/org/junit/internal/management/RuntimeMXBean.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.junit.internal.management; - -import java.util.List; - -/** - * Wrapper for {@link java.lang.management.RuntimeMXBean}. - */ -public interface RuntimeMXBean { - - /** - * @see java.lang.management.RuntimeMXBean#getInputArguments() - */ - List getInputArguments(); -} diff --git a/src/main/java/org/junit/internal/management/ThreadMXBean.java b/src/main/java/org/junit/internal/management/ThreadMXBean.java deleted file mode 100644 index f9225c9..0000000 --- a/src/main/java/org/junit/internal/management/ThreadMXBean.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.junit.internal.management; - -/** - * Wrapper for {@link java.lang.management.ThreadMXBean}. - */ -public interface ThreadMXBean { - /** - * @see java.lang.management.ThreadMXBean#getThreadCpuTime(long) - */ - long getThreadCpuTime(long id); - - /** - * @see java.lang.management.ThreadMXBean#isThreadCpuTimeSupported() - */ - boolean isThreadCpuTimeSupported(); -} - diff --git a/src/main/java/org/junit/internal/matchers/StacktracePrintingMatcher.java b/src/main/java/org/junit/internal/matchers/StacktracePrintingMatcher.java index 93a6827..5d45ba3 100644 --- a/src/main/java/org/junit/internal/matchers/StacktracePrintingMatcher.java +++ b/src/main/java/org/junit/internal/matchers/StacktracePrintingMatcher.java @@ -1,11 +1,12 @@ package org.junit.internal.matchers; +import java.io.PrintWriter; +import java.io.StringWriter; + import org.hamcrest.Description; import org.hamcrest.Factory; import org.hamcrest.Matcher; -import org.junit.internal.Throwables; - /** * A matcher that delegates to throwableMatcher and in addition appends the * stacktrace of the actual Throwable in case of a mismatch. @@ -36,7 +37,9 @@ public class StacktracePrintingMatcher extends } private String readStacktrace(Throwable throwable) { - return Throwables.getStacktrace(throwable); + StringWriter stringWriter = new StringWriter(); + throwable.printStackTrace(new PrintWriter(stringWriter)); + return stringWriter.toString(); } @Factory diff --git a/src/main/java/org/junit/internal/matchers/ThrowableCauseMatcher.java b/src/main/java/org/junit/internal/matchers/ThrowableCauseMatcher.java index 6e2ff5e..22ce8bd 100644 --- a/src/main/java/org/junit/internal/matchers/ThrowableCauseMatcher.java +++ b/src/main/java/org/junit/internal/matchers/ThrowableCauseMatcher.java @@ -14,9 +14,9 @@ import org.hamcrest.TypeSafeMatcher; public class ThrowableCauseMatcher extends TypeSafeMatcher { - private final Matcher causeMatcher; + private final Matcher causeMatcher; - public ThrowableCauseMatcher(Matcher causeMatcher) { + public ThrowableCauseMatcher(Matcher causeMatcher) { this.causeMatcher = causeMatcher; } @@ -44,7 +44,7 @@ public class ThrowableCauseMatcher extends * @param type of the outer exception */ @Factory - public static Matcher hasCause(final Matcher matcher) { + public static Matcher hasCause(final Matcher matcher) { return new ThrowableCauseMatcher(matcher); } } \ No newline at end of file diff --git a/src/main/java/org/junit/internal/matchers/TypeSafeMatcher.java b/src/main/java/org/junit/internal/matchers/TypeSafeMatcher.java index fb25982..4e2cc12 100644 --- a/src/main/java/org/junit/internal/matchers/TypeSafeMatcher.java +++ b/src/main/java/org/junit/internal/matchers/TypeSafeMatcher.java @@ -40,7 +40,7 @@ public abstract class TypeSafeMatcher extends BaseMatcher { } private static boolean isMatchesSafelyMethod(Method method) { - return "matchesSafely".equals(method.getName()) + return method.getName().equals("matchesSafely") && method.getParameterTypes().length == 1 && !method.isSynthetic(); } diff --git a/src/main/java/org/junit/internal/requests/ClassRequest.java b/src/main/java/org/junit/internal/requests/ClassRequest.java index d60e360..3d6b100 100644 --- a/src/main/java/org/junit/internal/requests/ClassRequest.java +++ b/src/main/java/org/junit/internal/requests/ClassRequest.java @@ -1,18 +1,20 @@ package org.junit.internal.requests; 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 MemoizingRequest { +public class ClassRequest extends Request { + private final Object runnerLock = new Object(); + /* * We have to use the f prefix, because IntelliJ's JUnit4IdeaTestRunner uses * reflection to access this field. See - * https://github.com/junit-team/junit4/issues/960 + * https://github.com/junit-team/junit/issues/960 */ private final Class fTestClass; private final boolean canUseSuiteMethod; + private volatile Runner runner; public ClassRequest(Class testClass, boolean canUseSuiteMethod) { this.fTestClass = testClass; @@ -24,31 +26,14 @@ public class ClassRequest extends MemoizingRequest { } @Override - protected Runner createRunner() { - return new CustomAllDefaultPossibilitiesBuilder().safeRunnerForClass(fTestClass); - } - - private class CustomAllDefaultPossibilitiesBuilder extends AllDefaultPossibilitiesBuilder { - - @Override - protected RunnerBuilder suiteMethodBuilder() { - return new CustomSuiteMethodBuilder(); - } - } - - /* - * Customization of {@link SuiteMethodBuilder} that prevents use of the - * suite method when creating a runner for fTestClass when canUseSuiteMethod - * is false. - */ - private class CustomSuiteMethodBuilder extends SuiteMethodBuilder { - - @Override - public Runner runnerForClass(Class testClass) throws Throwable { - if (testClass == fTestClass && !canUseSuiteMethod) { - return null; + public Runner getRunner() { + if (runner == null) { + synchronized (runnerLock) { + if (runner == null) { + runner = new AllDefaultPossibilitiesBuilder(canUseSuiteMethod).safeRunnerForClass(fTestClass); + } } - return super.runnerForClass(testClass); } + return runner; } } \ No newline at end of file diff --git a/src/main/java/org/junit/internal/requests/FilterRequest.java b/src/main/java/org/junit/internal/requests/FilterRequest.java index 5f00399..066cba3 100644 --- a/src/main/java/org/junit/internal/requests/FilterRequest.java +++ b/src/main/java/org/junit/internal/requests/FilterRequest.java @@ -14,7 +14,7 @@ public final class FilterRequest extends Request { /* * We have to use the f prefix, because IntelliJ's JUnit4IdeaTestRunner uses * reflection to access this field. See - * https://github.com/junit-team/junit4/issues/960 + * https://github.com/junit-team/junit/issues/960 */ private final Filter fFilter; diff --git a/src/main/java/org/junit/internal/requests/MemoizingRequest.java b/src/main/java/org/junit/internal/requests/MemoizingRequest.java deleted file mode 100644 index 191c230..0000000 --- a/src/main/java/org/junit/internal/requests/MemoizingRequest.java +++ /dev/null @@ -1,30 +0,0 @@ -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 deleted file mode 100644 index 441e595..0000000 --- a/src/main/java/org/junit/internal/requests/OrderingRequest.java +++ /dev/null @@ -1,29 +0,0 @@ -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/ErrorReportingRunner.java b/src/main/java/org/junit/internal/runners/ErrorReportingRunner.java index f52abab..1d32beb 100644 --- a/src/main/java/org/junit/internal/runners/ErrorReportingRunner.java +++ b/src/main/java/org/junit/internal/runners/ErrorReportingRunner.java @@ -1,44 +1,33 @@ package org.junit.internal.runners; import java.lang.reflect.InvocationTargetException; +import java.util.Arrays; import java.util.List; import org.junit.runner.Description; import org.junit.runner.Runner; import org.junit.runner.notification.Failure; import org.junit.runner.notification.RunNotifier; -import org.junit.runners.model.InvalidTestClassError; import org.junit.runners.model.InitializationError; -import static java.util.Collections.singletonList; - public class ErrorReportingRunner extends Runner { private final List causes; - private final String classNames; + private final Class testClass; public ErrorReportingRunner(Class testClass, Throwable cause) { - this(cause, testClass); - } - - public ErrorReportingRunner(Throwable cause, Class... testClasses) { - if (testClasses == null || testClasses.length == 0) { - throw new NullPointerException("Test classes cannot be null or empty"); + if (testClass == null) { + throw new NullPointerException("Test class cannot be null"); } - for (Class testClass : testClasses) { - if (testClass == null) { - throw new NullPointerException("Test class cannot be null"); - } - } - classNames = getClassNames(testClasses); + this.testClass = testClass; causes = getCauses(cause); } - + @Override public Description getDescription() { - Description description = Description.createSuiteDescription(classNames); + Description description = Description.createSuiteDescription(testClass); for (Throwable each : causes) { - description.addChild(describeCause()); + description.addChild(describeCause(each)); } return description; } @@ -50,25 +39,11 @@ public class ErrorReportingRunner extends Runner { } } - private String getClassNames(Class... testClasses) { - final StringBuilder builder = new StringBuilder(); - for (Class testClass : testClasses) { - if (builder.length() != 0) { - builder.append(", "); - } - builder.append(testClass.getName()); - } - return builder.toString(); - } - @SuppressWarnings("deprecation") private List getCauses(Throwable cause) { if (cause instanceof InvocationTargetException) { return getCauses(cause.getCause()); } - if (cause instanceof InvalidTestClassError) { - return singletonList(cause); - } if (cause instanceof InitializationError) { return ((InitializationError) cause).getCauses(); } @@ -76,15 +51,16 @@ public class ErrorReportingRunner extends Runner { return ((org.junit.internal.runners.InitializationError) cause) .getCauses(); } - return singletonList(cause); + return Arrays.asList(cause); } - private Description describeCause() { - return Description.createTestDescription(classNames, "initializationError"); + private Description describeCause(Throwable child) { + return Description.createTestDescription(testClass, + "initializationError"); } private void runCause(Throwable child, RunNotifier notifier) { - Description description = describeCause(); + Description description = describeCause(child); notifier.fireTestStarted(description); notifier.fireTestFailure(new Failure(description, child)); notifier.fireTestFinished(description); diff --git a/src/main/java/org/junit/internal/runners/InitializationError.java b/src/main/java/org/junit/internal/runners/InitializationError.java index 484f58d..52065ec 100644 --- a/src/main/java/org/junit/internal/runners/InitializationError.java +++ b/src/main/java/org/junit/internal/runners/InitializationError.java @@ -15,7 +15,7 @@ public class InitializationError extends Exception { /* * We have to use the f prefix until the next major release to ensure * serialization compatibility. - * See https://github.com/junit-team/junit4/issues/976 + * See https://github.com/junit-team/junit/issues/976 */ private final List fErrors; diff --git a/src/main/java/org/junit/internal/runners/JUnit38ClassRunner.java b/src/main/java/org/junit/internal/runners/JUnit38ClassRunner.java index 0d51541..631fcf2 100644 --- a/src/main/java/org/junit/internal/runners/JUnit38ClassRunner.java +++ b/src/main/java/org/junit/internal/runners/JUnit38ClassRunner.java @@ -1,8 +1,5 @@ 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; @@ -15,16 +12,15 @@ import org.junit.runner.Description; 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, Orderable { +public class JUnit38ClassRunner extends Runner implements Filterable, Sortable { private static final class OldTestClassAdaptingListener implements TestListener { private final RunNotifier notifier; @@ -174,18 +170,6 @@ public class JUnit38ClassRunner extends Runner implements Filterable, Orderable } } - /** - * {@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/internal/runners/MethodValidator.java b/src/main/java/org/junit/internal/runners/MethodValidator.java index e656ee5..ba9c9d1 100644 --- a/src/main/java/org/junit/internal/runners/MethodValidator.java +++ b/src/main/java/org/junit/internal/runners/MethodValidator.java @@ -86,7 +86,7 @@ public class MethodValidator { } if (each.getReturnType() != Void.TYPE) { errors.add(new Exception("Method " + each.getName() - + "should have a return type of void")); + + " should be void")); } if (each.getParameterTypes().length != 0) { errors.add(new Exception("Method " + each.getName() diff --git a/src/main/java/org/junit/internal/runners/TestClass.java b/src/main/java/org/junit/internal/runners/TestClass.java index 6d24f4f..1abaeea 100644 --- a/src/main/java/org/junit/internal/runners/TestClass.java +++ b/src/main/java/org/junit/internal/runners/TestClass.java @@ -85,7 +85,7 @@ public class TestClass { } private List> getSuperClasses(Class testClass) { - List> results = new ArrayList>(); + ArrayList> results = new ArrayList>(); Class current = testClass; while (current != null) { results.add(current); diff --git a/src/main/java/org/junit/internal/runners/model/EachTestNotifier.java b/src/main/java/org/junit/internal/runners/model/EachTestNotifier.java index c5a0764..e094809 100644 --- a/src/main/java/org/junit/internal/runners/model/EachTestNotifier.java +++ b/src/main/java/org/junit/internal/runners/model/EachTestNotifier.java @@ -45,27 +45,4 @@ public class EachTestNotifier { public void fireTestIgnored() { notifier.fireTestIgnored(description); } - - /** - * Calls {@link RunNotifier#fireTestSuiteStarted(Description)}, passing the - * {@link Description} that was passed to the {@code EachTestNotifier} constructor. - * This should be called when a test suite is about to be started. - * @see RunNotifier#fireTestSuiteStarted(Description) - * @since 4.13 - */ - public void fireTestSuiteStarted() { - notifier.fireTestSuiteStarted(description); - } - - /** - * Calls {@link RunNotifier#fireTestSuiteFinished(Description)}, passing the - * {@link Description} that was passed to the {@code EachTestNotifier} constructor. - * This should be called when a test suite has finished, whether the test suite succeeds - * or fails. - * @see RunNotifier#fireTestSuiteFinished(Description) - * @since 4.13 - */ - public void fireTestSuiteFinished() { - notifier.fireTestSuiteFinished(description); - } } \ No newline at end of file diff --git a/src/main/java/org/junit/internal/runners/rules/ValidationError.java b/src/main/java/org/junit/internal/runners/rules/ValidationError.java index 31bd660..d1af8ae 100644 --- a/src/main/java/org/junit/internal/runners/rules/ValidationError.java +++ b/src/main/java/org/junit/internal/runners/rules/ValidationError.java @@ -5,9 +5,6 @@ import org.junit.runners.model.FrameworkMember; import java.lang.annotation.Annotation; class ValidationError extends Exception { - - private static final long serialVersionUID = 3176511008672645574L; - public ValidationError(FrameworkMember member, Class annotation, String suffix) { super(String.format("The @%s '%s' %s", annotation.getSimpleName(), member.getName(), suffix)); } diff --git a/src/main/java/org/junit/internal/runners/statements/ExpectException.java b/src/main/java/org/junit/internal/runners/statements/ExpectException.java index 9a2a952..d0636bd 100644 --- a/src/main/java/org/junit/internal/runners/statements/ExpectException.java +++ b/src/main/java/org/junit/internal/runners/statements/ExpectException.java @@ -19,9 +19,7 @@ public class ExpectException extends Statement { next.evaluate(); complete = true; } catch (AssumptionViolatedException e) { - if (!expected.isAssignableFrom(e.getClass())) { - throw e; - } + throw e; } catch (Throwable e) { if (!expected.isAssignableFrom(e.getClass())) { String message = "Unexpected exception, expected<" diff --git a/src/main/java/org/junit/internal/runners/statements/FailOnTimeout.java b/src/main/java/org/junit/internal/runners/statements/FailOnTimeout.java index 9362cc1..9fad35b 100644 --- a/src/main/java/org/junit/internal/runners/statements/FailOnTimeout.java +++ b/src/main/java/org/junit/internal/runners/statements/FailOnTimeout.java @@ -1,8 +1,5 @@ package org.junit.internal.runners.statements; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; @@ -10,9 +7,6 @@ import java.util.concurrent.FutureTask; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import org.junit.internal.management.ManagementFactory; -import org.junit.internal.management.ThreadMXBean; -import org.junit.runners.model.MultipleFailureException; import org.junit.runners.model.Statement; import org.junit.runners.model.TestTimedOutException; @@ -20,7 +14,6 @@ public class FailOnTimeout extends Statement { private final Statement originalStatement; private final TimeUnit timeUnit; private final long timeout; - private final boolean lookForStuckThread; /** * Returns a new builder for building an instance. @@ -47,7 +40,6 @@ public class FailOnTimeout extends Statement { originalStatement = statement; timeout = builder.timeout; timeUnit = builder.unit; - lookForStuckThread = builder.lookForStuckThread; } /** @@ -56,7 +48,6 @@ public class FailOnTimeout extends Statement { * @since 4.12 */ public static class Builder { - private boolean lookForStuckThread = false; private long timeout = 0; private TimeUnit unit = TimeUnit.SECONDS; @@ -88,20 +79,6 @@ public class FailOnTimeout extends Statement { return this; } - /** - * Specifies whether to look for a stuck thread. If a timeout occurs and this - * feature is enabled, the test will look for a thread that appears to be stuck - * and dump its backtrace. This feature is experimental. Behavior may change - * after the 4.12 release in response to feedback. - * - * @param enable {@code true} to enable the feature - * @return {@code this} for method chaining. - */ - public Builder withLookingForStuckThread(boolean enable) { - this.lookForStuckThread = enable; - return this; - } - /** * Builds a {@link FailOnTimeout} instance using the values in this builder, * wrapping the given statement. @@ -120,8 +97,7 @@ public class FailOnTimeout extends Statement { public void evaluate() throws Throwable { CallableStatement callable = new CallableStatement(); FutureTask task = new FutureTask(callable); - ThreadGroup threadGroup = threadGroupForNewThread(); - Thread thread = new Thread(threadGroup, task, "Time-limited test"); + Thread thread = new Thread(task, "Time-limited test"); thread.setDaemon(true); thread.start(); callable.awaitStarted(); @@ -131,31 +107,6 @@ public class FailOnTimeout extends Statement { } } - private ThreadGroup threadGroupForNewThread() { - if (!lookForStuckThread) { - // Use the default ThreadGroup (usually the one from the current - // thread). - return null; - } - - // Create the thread in a new ThreadGroup, so if the time-limited thread - // becomes stuck, getStuckThread() can find the thread likely to be the - // culprit. - ThreadGroup threadGroup = new ThreadGroup("FailOnTimeoutGroup"); - if (!threadGroup.isDaemon()) { - // Mark the new ThreadGroup as a daemon thread group, so it will be - // destroyed after the time-limited thread completes. By ensuring the - // ThreadGroup is destroyed, any data associated with the ThreadGroup - // (ex: via java.beans.ThreadGroupContext) is destroyed. - try { - threadGroup.setDaemon(true); - } catch (SecurityException e) { - // Swallow the exception to keep the same behavior as in JUnit 4.12. - } - } - return threadGroup; - } - /** * Wait for the test task, returning the exception thrown by the test if the * test failed, an exception indicating a timeout if the test timed out, or @@ -180,114 +131,12 @@ public class FailOnTimeout extends Statement { private Exception createTimeoutException(Thread thread) { StackTraceElement[] stackTrace = thread.getStackTrace(); - final Thread stuckThread = lookForStuckThread ? getStuckThread(thread) : null; Exception currThreadException = new TestTimedOutException(timeout, timeUnit); if (stackTrace != null) { currThreadException.setStackTrace(stackTrace); thread.interrupt(); } - if (stuckThread != null) { - Exception stuckThreadException = - new Exception("Appears to be stuck in thread " + - stuckThread.getName()); - stuckThreadException.setStackTrace(getStackTrace(stuckThread)); - return new MultipleFailureException( - Arrays.asList(currThreadException, stuckThreadException)); - } else { - return currThreadException; - } - } - - /** - * Retrieves the stack trace for a given thread. - * @param thread The thread whose stack is to be retrieved. - * @return The stack trace; returns a zero-length array if the thread has - * terminated or the stack cannot be retrieved for some other reason. - */ - private StackTraceElement[] getStackTrace(Thread thread) { - try { - return thread.getStackTrace(); - } catch (SecurityException e) { - return new StackTraceElement[0]; - } - } - - /** - * Determines whether the test appears to be stuck in some thread other than - * the "main thread" (the one created to run the test). This feature is experimental. - * Behavior may change after the 4.12 release in response to feedback. - * @param mainThread The main thread created by {@code evaluate()} - * @return The thread which appears to be causing the problem, if different from - * {@code mainThread}, or {@code null} if the main thread appears to be the - * problem or if the thread cannot be determined. The return value is never equal - * to {@code mainThread}. - */ - private Thread getStuckThread(Thread mainThread) { - List threadsInGroup = getThreadsInGroup(mainThread.getThreadGroup()); - if (threadsInGroup.isEmpty()) { - return null; - } - - // Now that we have all the threads in the test's thread group: Assume that - // any thread we're "stuck" in is RUNNABLE. Look for all RUNNABLE threads. - // If just one, we return that (unless it equals threadMain). If there's more - // than one, pick the one that's using the most CPU time, if this feature is - // supported. - Thread stuckThread = null; - long maxCpuTime = 0; - for (Thread thread : threadsInGroup) { - if (thread.getState() == Thread.State.RUNNABLE) { - long threadCpuTime = cpuTime(thread); - if (stuckThread == null || threadCpuTime > maxCpuTime) { - stuckThread = thread; - maxCpuTime = threadCpuTime; - } - } - } - return (stuckThread == mainThread) ? null : stuckThread; - } - - /** - * Returns all active threads belonging to a thread group. - * @param group The thread group. - * @return The active threads in the thread group. The result should be a - * complete list of the active threads at some point in time. Returns an empty list - * if this cannot be determined, e.g. because new threads are being created at an - * extremely fast rate. - */ - private List getThreadsInGroup(ThreadGroup group) { - final int activeThreadCount = group.activeCount(); // this is just an estimate - int threadArraySize = Math.max(activeThreadCount * 2, 100); - for (int loopCount = 0; loopCount < 5; loopCount++) { - Thread[] threads = new Thread[threadArraySize]; - int enumCount = group.enumerate(threads); - if (enumCount < threadArraySize) { - return Arrays.asList(threads).subList(0, enumCount); - } - // if there are too many threads to fit into the array, enumerate's result - // is >= the array's length; therefore we can't trust that it returned all - // the threads. Try again. - threadArraySize += 100; - } - // threads are proliferating too fast for us. Bail before we get into - // trouble. - return Collections.emptyList(); - } - - /** - * Returns the CPU time used by a thread, if possible. - * @param thr The thread to query. - * @return The CPU time used by {@code thr}, or 0 if it cannot be determined. - */ - private long cpuTime(Thread thr) { - ThreadMXBean mxBean = ManagementFactory.getThreadMXBean(); - if (mxBean.isThreadCpuTimeSupported()) { - try { - return mxBean.getThreadCpuTime(thr.getId()); - } catch (UnsupportedOperationException e) { - } - } - return 0; + return currThreadException; } private class CallableStatement implements Callable { diff --git a/src/main/java/org/junit/internal/runners/statements/RunAfters.java b/src/main/java/org/junit/internal/runners/statements/RunAfters.java index 5e56c33..7512a7d 100644 --- a/src/main/java/org/junit/internal/runners/statements/RunAfters.java +++ b/src/main/java/org/junit/internal/runners/statements/RunAfters.java @@ -30,7 +30,7 @@ public class RunAfters extends Statement { } finally { for (FrameworkMethod each : afters) { try { - invokeMethod(each); + each.invokeExplosively(target); } catch (Throwable e) { errors.add(e); } @@ -38,11 +38,4 @@ public class RunAfters extends Statement { } MultipleFailureException.assertEmpty(errors); } - - /** - * @since 4.13 - */ - protected void invokeMethod(FrameworkMethod method) throws Throwable { - method.invokeExplosively(target); - } } \ No newline at end of file diff --git a/src/main/java/org/junit/internal/runners/statements/RunBefores.java b/src/main/java/org/junit/internal/runners/statements/RunBefores.java index bd835c7..238fbe7 100644 --- a/src/main/java/org/junit/internal/runners/statements/RunBefores.java +++ b/src/main/java/org/junit/internal/runners/statements/RunBefores.java @@ -21,15 +21,8 @@ public class RunBefores extends Statement { @Override public void evaluate() throws Throwable { for (FrameworkMethod before : befores) { - invokeMethod(before); + before.invokeExplosively(target); } next.evaluate(); } - - /** - * @since 4.13 - */ - protected void invokeMethod(FrameworkMethod method) throws Throwable { - method.invokeExplosively(target); - } } \ No newline at end of file diff --git a/src/main/java/org/junit/matchers/JUnitMatchers.java b/src/main/java/org/junit/matchers/JUnitMatchers.java index 13407cc..5bb48d7 100644 --- a/src/main/java/org/junit/matchers/JUnitMatchers.java +++ b/src/main/java/org/junit/matchers/JUnitMatchers.java @@ -48,7 +48,7 @@ public class JUnitMatchers { */ @Deprecated public static Matcher> hasItems(Matcher... elementMatchers) { - return CoreMatchers.hasItems(elementMatchers); + return CoreMatchers.hasItems(elementMatchers); } /** @@ -57,7 +57,7 @@ public class JUnitMatchers { */ @Deprecated public static Matcher> everyItem(final Matcher elementMatcher) { - return CoreMatchers.everyItem(elementMatcher); + return CoreMatchers.everyItem((Matcher) elementMatcher); } /** diff --git a/src/main/java/org/junit/rules/DisableOnDebug.java b/src/main/java/org/junit/rules/DisableOnDebug.java deleted file mode 100644 index 3bca103..0000000 --- a/src/main/java/org/junit/rules/DisableOnDebug.java +++ /dev/null @@ -1,125 +0,0 @@ -package org.junit.rules; - -import java.util.List; - -import org.junit.internal.management.ManagementFactory; -import org.junit.internal.management.RuntimeMXBean; -import org.junit.runner.Description; -import org.junit.runners.model.Statement; - -/** - * The {@code DisableOnDebug} Rule allows you to label certain rules to be - * disabled when debugging. - *

    - * The most illustrative use case is for tests that make use of the - * {@link Timeout} rule, when ran in debug mode the test may terminate on - * timeout abruptly during debugging. Developers may disable the timeout, or - * increase the timeout by making a code change on tests that need debugging and - * remember revert the change afterwards or rules such as {@link Timeout} that - * may be disabled during debugging may be wrapped in a {@code DisableOnDebug}. - *

    - * The important benefit of this feature is that you can disable such rules - * without any making any modifications to your test class to remove them during - * debugging. - *

    - * This does nothing to tackle timeouts or time sensitive code under test when - * debugging and may make this less useful in such circumstances. - *

    - * Example usage: - * - *

    - * public static class DisableTimeoutOnDebugSampleTest {
    - * 
    - *     @Rule
    - *     public TestRule timeout = new DisableOnDebug(new Timeout(20));
    - * 
    - *     @Test
    - *     public void myTest() {
    - *         int i = 0;
    - *         assertEquals(0, i); // suppose you had a break point here to inspect i
    - *     }
    - * }
    - * 
    - * - * @since 4.12 - */ -public class DisableOnDebug implements TestRule { - private final TestRule rule; - private final boolean debugging; - - /** - * Create a {@code DisableOnDebug} instance with the timeout specified in - * milliseconds. - * - * @param rule to disable during debugging - */ - public DisableOnDebug(TestRule rule) { - this(rule, ManagementFactory.getRuntimeMXBean() - .getInputArguments()); - } - - /** - * Visible for testing purposes only. - * - * @param rule the rule to disable during debugging - * @param inputArguments - * arguments provided to the Java runtime - */ - DisableOnDebug(TestRule rule, List inputArguments) { - this.rule = rule; - debugging = isDebugging(inputArguments); - } - - /** - * @see TestRule#apply(Statement, Description) - */ - public Statement apply(Statement base, Description description) { - if (debugging) { - return base; - } else { - return rule.apply(base, description); - } - } - - /** - * Parses arguments passed to the runtime environment for debug flags - *

    - * Options specified in: - *

      - *
    • - * javase-6
    • - *
    • javase-7
    • - *
    • javase-8
    • - * - * - * @param arguments - * the arguments passed to the runtime environment, usually this - * will be {@link RuntimeMXBean#getInputArguments()} - * @return true if the current JVM was started in debug mode, false - * otherwise. - */ - private static boolean isDebugging(List arguments) { - for (final String argument : arguments) { - if ("-Xdebug".equals(argument) || argument.startsWith("-agentlib:jdwp")) { - return true; - } - } - return false; - } - - /** - * Returns {@code true} if the JVM is in debug mode. This method may be used - * by test classes to take additional action to disable code paths that - * interfere with debugging if required. - * - * @return {@code true} if the current JVM is in debug mode, {@code false} - * otherwise - */ - public boolean isDebugging() { - return debugging; - } - -} diff --git a/src/main/java/org/junit/rules/ErrorCollector.java b/src/main/java/org/junit/rules/ErrorCollector.java index 9711e50..8c6600e 100644 --- a/src/main/java/org/junit/rules/ErrorCollector.java +++ b/src/main/java/org/junit/rules/ErrorCollector.java @@ -1,14 +1,11 @@ package org.junit.rules; import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertThrows; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; -import org.junit.function.ThrowingRunnable; -import org.junit.internal.AssumptionViolatedException; import org.hamcrest.Matcher; import org.junit.runners.model.MultipleFailureException; @@ -46,16 +43,7 @@ public class ErrorCollector extends Verifier { * Adds a Throwable to the table. Execution continues, but the test will fail at the end. */ public void addError(Throwable error) { - if (error == null) { - throw new NullPointerException("Error cannot be null"); - } - if (error instanceof AssumptionViolatedException) { - AssertionError e = new AssertionError(error.getMessage()); - e.initCause(error); - errors.add(e); - } else { - errors.add(error); - } + errors.add(error); } /** @@ -88,33 +76,9 @@ public class ErrorCollector extends Verifier { public T checkSucceeds(Callable callable) { try { return callable.call(); - } catch (AssumptionViolatedException e) { - AssertionError error = new AssertionError("Callable threw AssumptionViolatedException"); - error.initCause(e); - addError(error); - return null; } catch (Throwable e) { addError(e); return null; } } - - /** - * Adds a failure to the table if {@code runnable} does not throw an - * exception of type {@code expectedThrowable} when executed. - * Execution continues, but the test will fail at the end if the runnable - * does not throw an exception, or if it throws a different exception. - * - * @param expectedThrowable the expected type of the exception - * @param runnable a function that is expected to throw an exception when executed - * @since 4.13 - */ - public void checkThrows(Class expectedThrowable, ThrowingRunnable runnable) { - try { - assertThrows(expectedThrowable, runnable); - } catch (AssertionError e) { - addError(e); - } - } - } diff --git a/src/main/java/org/junit/rules/ExpectedException.java b/src/main/java/org/junit/rules/ExpectedException.java index 431ad49..4d61712 100644 --- a/src/main/java/org/junit/rules/ExpectedException.java +++ b/src/main/java/org/junit/rules/ExpectedException.java @@ -7,6 +7,7 @@ import static org.junit.Assert.assertThat; import static org.junit.Assert.fail; import static org.junit.internal.matchers.ThrowableCauseMatcher.hasCause; import static org.junit.internal.matchers.ThrowableMessageMatcher.hasMessage; + import org.hamcrest.Matcher; import org.hamcrest.StringDescription; import org.junit.AssumptionViolatedException; @@ -20,7 +21,7 @@ import org.junit.runners.model.Statement; * *
       public class SimpleExpectedExceptionTest {
        *     @Rule
      - *     public ExpectedException thrown = ExpectedException.none();
      + *     public ExpectedException thrown= ExpectedException.none();
        *
        *     @Test
        *     public void throwsNothing() {
      @@ -34,19 +35,16 @@ import org.junit.runners.model.Statement;
        *     }
        * }
      * - *

      You have to add the {@code ExpectedException} rule to your test. + *

      + * You have to add the {@code ExpectedException} rule to your test. * This doesn't affect your existing tests (see {@code throwsNothing()}). - * After specifying the type of the expected exception your test is + * After specifiying the type of the expected exception your test is * successful when such an exception is thrown and it fails if a * different or no exception is thrown. * - *

      This rule does not perform any special magic to make execution continue - * as if the exception had not been thrown. So it is nearly always a mistake - * for a test method to have statements after the one that is expected to - * throw the exception. - * - *

      Instead of specifying the exception's type you can characterize the - * expected exception based on other criteria, too: + *

      + * Instead of specifying the exception's type you can characterize the + * expected exception based on other criterias, too: * *

        *
      • The exception's message contains a specific text: {@link #expectMessage(String)}
      • @@ -55,7 +53,8 @@ import org.junit.runners.model.Statement; *
      • The exception itself complies with a Hamcrest matcher: {@link #expect(Matcher)}
      • *
      * - *

      You can combine any of the presented expect-methods. The test is + *

      + * You can combine any of the presented expect-methods. The test is * successful if all specifications are met. *

       @Test
        * public void throwsException() {
      @@ -64,15 +63,9 @@ import org.junit.runners.model.Statement;
        *     throw new NullPointerException("What happened?");
        * }
      * - *

      It is recommended to set the {@link org.junit.Rule#order() order} of the - * {@code ExpectedException} to {@code Integer.MAX_VALUE} if it is used together - * with another rule that handles exceptions, e.g. {@link ErrorCollector}. - * Otherwise failing tests may be successful. - *

       @Rule(order = Integer.MAX_VALUE)
      - * public ExpectedException thrown = ExpectedException.none();
      - * *

      AssumptionViolatedExceptions

      - *

      JUnit uses {@link AssumptionViolatedException}s for indicating that a test + *

      + * JUnit uses {@link AssumptionViolatedException}s for indicating that a test * provides no useful information. (See {@link org.junit.Assume} for more * information.) You have to call {@code assume} methods before you set * expectations of the {@code ExpectedException} rule. In this case the rule @@ -87,7 +80,8 @@ import org.junit.runners.model.Statement; * *

      AssertionErrors

      * - *

      JUnit uses {@link AssertionError}s for indicating that a test is failing. You + *

      + * JUnit uses {@link AssertionError}s for indicating that a test is failing. You * have to call {@code assert} methods before you set expectations of the * {@code ExpectedException} rule, if they should be handled by the framework. * E.g. the following test fails because of the {@code assertTrue} statement. @@ -99,7 +93,8 @@ import org.junit.runners.model.Statement; * } * *

      Missing Exceptions

      - *

      By default missing exceptions are reported with an error message + *

      + * By default missing exceptions are reported with an error message * like "Expected test to throw an instance of foo". You can configure a different * message by means of {@link #reportMissingExceptionWithMessage(String)}. You * can use a {@code %s} placeholder for the description of the expected @@ -112,13 +107,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(); } @@ -233,18 +222,10 @@ public class ExpectedException implements TestRule { * throw new IllegalArgumentException("What happened?", cause); * } */ - public void expectCause(Matcher expectedCause) { + public void expectCause(Matcher expectedCause) { expect(hasCause(expectedCause)); } - /** - * Check if any Exception is expected. - * @since 4.13 - */ - public final boolean isAnyExceptionExpected() { - return matcherBuilder.expectsThrowable(); - } - private class ExpectedExceptionStatement extends Statement { private final Statement next; @@ -274,6 +255,10 @@ public class ExpectedException implements TestRule { } } + private boolean isAnyExceptionExpected() { + return matcherBuilder.expectsThrowable(); + } + private void failDueToMissingException() throws AssertionError { fail(missingExceptionMessage()); } diff --git a/src/main/java/org/junit/rules/ExternalResource.java b/src/main/java/org/junit/rules/ExternalResource.java index 71fc842..71ca287 100644 --- a/src/main/java/org/junit/rules/ExternalResource.java +++ b/src/main/java/org/junit/rules/ExternalResource.java @@ -1,10 +1,6 @@ package org.junit.rules; -import java.util.ArrayList; -import java.util.List; - import org.junit.runner.Description; -import org.junit.runners.model.MultipleFailureException; import org.junit.runners.model.Statement; /** @@ -48,20 +44,11 @@ public abstract class ExternalResource implements TestRule { @Override public void evaluate() throws Throwable { before(); - - List errors = new ArrayList(); try { base.evaluate(); - } catch (Throwable t) { - errors.add(t); } finally { - try { - after(); - } catch (Throwable t) { - errors.add(t); - } + after(); } - MultipleFailureException.assertEmpty(errors); } }; } diff --git a/src/main/java/org/junit/rules/MethodRule.java b/src/main/java/org/junit/rules/MethodRule.java index 94608f5..823ee78 100644 --- a/src/main/java/org/junit/rules/MethodRule.java +++ b/src/main/java/org/junit/rules/MethodRule.java @@ -10,9 +10,21 @@ import org.junit.runners.model.Statement; * {@link Statement} that executes the method is passed to each annotated * {@link Rule} in turn, and each may return a substitute or modified * {@link Statement}, which is passed to the next {@link Rule}, if any. For - * an example of how this can be useful, see {@link TestWatchman}. + * examples of how this can be useful, see these provided MethodRules, + * or write your own: * - *

      Note that {@link MethodRule} has been replaced by {@link TestRule}, + *

        + *
      • {@link ErrorCollector}: collect multiple errors in one test method
      • + *
      • {@link ExpectedException}: make flexible assertions about thrown exceptions
      • + *
      • {@link ExternalResource}: start and stop a server, for example
      • + *
      • {@link TemporaryFolder}: create fresh files, and delete after test
      • + *
      • {@link TestName}: remember the test name for use during the method
      • + *
      • {@link TestWatchman}: add logic at events during method execution
      • + *
      • {@link Timeout}: cause test to fail after a set time
      • + *
      • {@link Verifier}: fail test if object state ends up incorrect
      • + *
      + * + * Note that {@link MethodRule} has been replaced by {@link TestRule}, * which has the added benefit of supporting class rules. * * @since 4.7 diff --git a/src/main/java/org/junit/rules/RuleChain.java b/src/main/java/org/junit/rules/RuleChain.java index bf93aae..f43d8f5 100644 --- a/src/main/java/org/junit/rules/RuleChain.java +++ b/src/main/java/org/junit/rules/RuleChain.java @@ -4,34 +4,26 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import org.junit.Rule; import org.junit.runner.Description; import org.junit.runners.model.Statement; /** - * The {@code RuleChain} can be used for creating composite rules. You create a + * The RuleChain rule allows ordering of TestRules. 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 final TestRule extendedLogging = CompositeRules.extendedLogging();
      + * public static class UseRuleChain {
      + * 	@Rule
      + * 	public RuleChain chain= RuleChain
      + * 	                       .outerRule(new LoggingRule("outer rule")
      + * 	                       .around(new LoggingRule("middle rule")
      + * 	                       .around(new LoggingRule("inner rule");
        *
      - *   @Test
      - *   public void example() {
      - *     assertTrue(true);
      - *   }
      + * 	@Test
      + * 	public void example() {
      + * 		assertTrue(true);
      + *     }
        * }
        * 
      * @@ -46,13 +38,6 @@ import org.junit.runners.model.Statement; * finished outer 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. - * - * @see org.junit.Rule#order() - * @see org.junit.ClassRule#order() * @since 4.10 */ public class RuleChain implements TestRule { @@ -87,17 +72,13 @@ public class RuleChain implements TestRule { } /** - * Create a new {@code RuleChain}, which encloses the given {@link TestRule} with + * Create a new {@code RuleChain}, which encloses the {@code nextRule} with * the rules of the current {@code RuleChain}. * - * @param enclosedRule the rule to enclose; must not be {@code null}. + * @param enclosedRule the rule to enclose. * @return a new {@code RuleChain}. - * @throws NullPointerException if the argument {@code enclosedRule} is {@code null} */ public RuleChain around(TestRule enclosedRule) { - if (enclosedRule == null) { - throw new NullPointerException("The enclosed rule must not be null"); - } List rulesOfNewChain = new ArrayList(); rulesOfNewChain.add(enclosedRule); rulesOfNewChain.addAll(rulesStartingWithInnerMost); @@ -108,6 +89,9 @@ public class RuleChain implements TestRule { * {@inheritDoc} */ public Statement apply(Statement base, Description description) { - return new RunRules(base, rulesStartingWithInnerMost, description); + for (TestRule each : rulesStartingWithInnerMost) { + base = each.apply(base, description); + } + return base; } } \ No newline at end of file diff --git a/src/main/java/org/junit/rules/Stopwatch.java b/src/main/java/org/junit/rules/Stopwatch.java index 6900a48..5d34e7f 100644 --- a/src/main/java/org/junit/rules/Stopwatch.java +++ b/src/main/java/org/junit/rules/Stopwatch.java @@ -76,7 +76,7 @@ import java.util.concurrent.TimeUnit; * @author tibor17 * @since 4.12 */ -public class Stopwatch implements TestRule { +public abstract class Stopwatch implements TestRule { private final Clock clock; private volatile long startNanos; private volatile long endNanos; diff --git a/src/main/java/org/junit/rules/TemporaryFolder.java b/src/main/java/org/junit/rules/TemporaryFolder.java index a726c66..dc75c93 100644 --- a/src/main/java/org/junit/rules/TemporaryFolder.java +++ b/src/main/java/org/junit/rules/TemporaryFolder.java @@ -1,20 +1,15 @@ package org.junit.rules; -import static org.junit.Assert.fail; - import java.io.File; import java.io.IOException; -import java.lang.reflect.Array; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import org.junit.Rule; /** * The TemporaryFolder Rule allows creation of files and folders that should * be deleted when the test method finishes (whether it passes or - * fails). - * By default no exception will be thrown in case the deletion fails. + * fails). Whether the deletion is successful or not is not checked by this rule. + * No exception will be thrown in case the deletion fails. * *

      Example of usage: *

      @@ -31,104 +26,18 @@ import org.junit.Rule;
        * }
        * 
      * - *

      TemporaryFolder rule supports assured deletion mode, which - * will fail the test in case deletion fails with {@link AssertionError}. - * - *

      Creating TemporaryFolder with assured deletion: - *

      - *  @Rule
      - *  public TemporaryFolder folder= TemporaryFolder.builder().assureDeletion().build();
      - * 
      - * * @since 4.7 */ public class TemporaryFolder extends ExternalResource { private final File parentFolder; - private final boolean assureDeletion; private File folder; - private static final int TEMP_DIR_ATTEMPTS = 10000; - private static final String TMP_PREFIX = "junit"; - - /** - * Create a temporary folder which uses system default temporary-file - * directory to create temporary resources. - */ public TemporaryFolder() { - this((File) null); + this(null); } - /** - * Create a temporary folder which uses the specified directory to create - * temporary resources. - * - * @param parentFolder folder where temporary resources will be created. - * If {@code null} then system default temporary-file directory is used. - */ public TemporaryFolder(File parentFolder) { this.parentFolder = parentFolder; - this.assureDeletion = false; - } - - /** - * Create a {@link TemporaryFolder} initialized with - * values from a builder. - */ - protected TemporaryFolder(Builder builder) { - this.parentFolder = builder.parentFolder; - this.assureDeletion = builder.assureDeletion; - } - - /** - * Returns a new builder for building an instance of {@link TemporaryFolder}. - * - * @since 4.13 - */ - public static Builder builder() { - return new Builder(); - } - - /** - * Builds an instance of {@link TemporaryFolder}. - * - * @since 4.13 - */ - public static class Builder { - private File parentFolder; - private boolean assureDeletion; - - protected Builder() {} - - /** - * Specifies which folder to use for creating temporary resources. - * If {@code null} then system default temporary-file directory is - * used. - * - * @return this - */ - public Builder parentFolder(File parentFolder) { - this.parentFolder = parentFolder; - return this; - } - - /** - * Setting this flag assures that no resources are left undeleted. Failure - * to fulfill the assurance results in failure of tests with an - * {@link AssertionError}. - * - * @return this - */ - public Builder assureDeletion() { - this.assureDeletion = true; - return this; - } - - /** - * Builds a {@link TemporaryFolder} instance using the values in this builder. - */ - public TemporaryFolder build() { - return new TemporaryFolder(this); - } } @Override @@ -166,129 +75,66 @@ public class TemporaryFolder extends ExternalResource { * Returns a new fresh file with a random name under the temporary folder. */ public File newFile() throws IOException { - return File.createTempFile(TMP_PREFIX, null, getRoot()); + return File.createTempFile("junit", null, getRoot()); } /** - * Returns a new fresh folder with the given path under the temporary + * Returns a new fresh folder with the given name under the temporary * folder. */ - public File newFolder(String path) throws IOException { - return newFolder(new String[]{path}); + public File newFolder(String folder) throws IOException { + return newFolder(new String[]{folder}); } /** - * Returns a new fresh folder with the given paths under the temporary - * folder. For example, if you pass in the strings {@code "parent"} and {@code "child"} - * then a directory named {@code "parent"} will be created under the temporary folder - * and a directory named {@code "child"} will be created under the newly-created - * {@code "parent"} directory. + * Returns a new fresh folder with the given name(s) under the temporary + * folder. */ - public File newFolder(String... paths) throws IOException { - if (paths.length == 0) { - throw new IllegalArgumentException("must pass at least one path"); - } - - /* - * Before checking if the paths are absolute paths, check if create() was ever called, - * and if it wasn't, throw IllegalStateException. - */ - File root = getRoot(); - for (String path : paths) { - if (new File(path).isAbsolute()) { - throw new IOException("folder path \'" + path + "\' is not a relative path"); - } - } - - File relativePath = null; - File file = root; - boolean lastMkdirsCallSuccessful = true; - for (String path : paths) { - relativePath = new File(relativePath, path); - file = new File(root, relativePath.getPath()); - - lastMkdirsCallSuccessful = file.mkdirs(); - if (!lastMkdirsCallSuccessful && !file.isDirectory()) { - 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() + "\'"); - } + public File newFolder(String... folderNames) throws IOException { + File file = getRoot(); + for (int i = 0; i < folderNames.length; i++) { + String folderName = folderNames[i]; + validateFolderName(folderName); + file = new File(file, folderName); + if (!file.mkdir() && isLastElementInArray(i, folderNames)) { + throw new IOException( + "a folder with the name \'" + folderName + "\' already exists"); } } - if (!lastMkdirsCallSuccessful) { - throw new IOException( - "a folder with the path \'" + relativePath.getPath() + "\' already exists"); - } return file; } - + /** - * Returns a new fresh folder with a random name under the temporary folder. + * Validates if multiple path components were used while creating a folder. + * + * @param folderName + * Name of the folder being created */ - public File newFolder() throws IOException { - return createTemporaryFolderIn(getRoot()); + private void validateFolderName(String folderName) throws IOException { + File tempFile = new File(folderName); + if (tempFile.getParent() != null) { + String errorMsg = "Folder name cannot consist of multiple path components separated by a file separator." + + " Please use newFolder('MyParentFolder','MyFolder') to create hierarchies of folders"; + throw new IOException(errorMsg); + } } - private static File createTemporaryFolderIn(File parentFolder) throws IOException { - try { - return createTemporaryFolderWithNioApi(parentFolder); - } catch (ClassNotFoundException ignore) { - // Fallback for Java 5 and 6 - return createTemporaryFolderWithFileApi(parentFolder); - } catch (InvocationTargetException e) { - Throwable cause = e.getCause(); - if (cause instanceof IOException) { - throw (IOException) cause; - } - if (cause instanceof RuntimeException) { - throw (RuntimeException) cause; - } - IOException exception = new IOException("Failed to create temporary folder in " + parentFolder); - exception.initCause(cause); - throw exception; - } catch (Exception e) { - throw new RuntimeException("Failed to create temporary folder in " + parentFolder, e); - } + private boolean isLastElementInArray(int index, String[] array) { + return index == array.length - 1; } - private static File createTemporaryFolderWithNioApi(File parentFolder) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { - Class filesClass = Class.forName("java.nio.file.Files"); - Object fileAttributeArray = Array.newInstance(Class.forName("java.nio.file.attribute.FileAttribute"), 0); - Class pathClass = Class.forName("java.nio.file.Path"); - Object tempDir; - if (parentFolder != null) { - Method createTempDirectoryMethod = filesClass.getDeclaredMethod("createTempDirectory", pathClass, String.class, fileAttributeArray.getClass()); - Object parentPath = File.class.getDeclaredMethod("toPath").invoke(parentFolder); - tempDir = createTempDirectoryMethod.invoke(null, parentPath, TMP_PREFIX, fileAttributeArray); - } else { - Method createTempDirectoryMethod = filesClass.getDeclaredMethod("createTempDirectory", String.class, fileAttributeArray.getClass()); - tempDir = createTempDirectoryMethod.invoke(null, TMP_PREFIX, fileAttributeArray); - } - return (File) pathClass.getDeclaredMethod("toFile").invoke(tempDir); + /** + * Returns a new fresh folder with a random name under the temporary folder. + */ + public File newFolder() throws IOException { + return createTemporaryFolderIn(getRoot()); } - private static File createTemporaryFolderWithFileApi(File parentFolder) throws IOException { - File createdFolder = null; - for (int i = 0; i < TEMP_DIR_ATTEMPTS; ++i) { - // Use createTempFile to get a suitable folder name. - String suffix = ".tmp"; - File tmpFile = File.createTempFile(TMP_PREFIX, suffix, parentFolder); - String tmpName = tmpFile.toString(); - // Discard .tmp suffix of tmpName. - String folderName = tmpName.substring(0, tmpName.length() - suffix.length()); - createdFolder = new File(folderName); - if (createdFolder.mkdir()) { - tmpFile.delete(); - return createdFolder; - } - tmpFile.delete(); - } - throw new IOException("Unable to create temporary directory in: " - + parentFolder.toString() + ". Tried " + TEMP_DIR_ATTEMPTS + " times. " - + "Last attempted to create: " + createdFolder.toString()); + private File createTemporaryFolderIn(File parentFolder) throws IOException { + File createdFolder = File.createTempFile("junit", "", parentFolder); + createdFolder.delete(); + createdFolder.mkdir(); + return createdFolder; } /** @@ -304,48 +150,21 @@ public class TemporaryFolder extends ExternalResource { /** * Delete all files and folders under the temporary folder. Usually not - * called directly, since it is automatically applied by the {@link Rule}. - * - * @throws AssertionError if unable to clean up resources - * and deletion of resources is assured. + * called directly, since it is automatically applied by the {@link Rule} */ public void delete() { - if (!tryDelete()) { - if (assureDeletion) { - fail("Unable to clean up temporary folder " + folder); - } - } - } - - /** - * Tries to delete all files and folders under the temporary folder and - * returns whether deletion was successful or not. - * - * @return {@code true} if all resources are deleted successfully, - * {@code false} otherwise. - */ - private boolean tryDelete() { - if (folder == null) { - return true; + if (folder != null) { + recursiveDelete(folder); } - - return recursiveDelete(folder); } - private boolean recursiveDelete(File file) { - // Try deleting file before assuming file is a directory - // to prevent following symbolic links. - if (file.delete()) { - return true; - } + private void recursiveDelete(File file) { File[] files = file.listFiles(); if (files != null) { for (File each : files) { - if (!recursiveDelete(each)) { - return false; - } + recursiveDelete(each); } } - return file.delete(); + file.delete(); } } diff --git a/src/main/java/org/junit/rules/TestName.java b/src/main/java/org/junit/rules/TestName.java index e2ebc2e..bf72602 100644 --- a/src/main/java/org/junit/rules/TestName.java +++ b/src/main/java/org/junit/rules/TestName.java @@ -25,7 +25,7 @@ import org.junit.runner.Description; * @since 4.7 */ public class TestName extends TestWatcher { - private volatile String name; + private String name; @Override protected void starting(Description d) { diff --git a/src/main/java/org/junit/rules/TestWatcher.java b/src/main/java/org/junit/rules/TestWatcher.java index a28514d..5492b6b 100644 --- a/src/main/java/org/junit/rules/TestWatcher.java +++ b/src/main/java/org/junit/rules/TestWatcher.java @@ -4,7 +4,6 @@ import java.util.ArrayList; import java.util.List; import org.junit.AssumptionViolatedException; -import org.junit.Rule; import org.junit.runner.Description; import org.junit.runners.model.MultipleFailureException; import org.junit.runners.model.Statement; @@ -18,7 +17,7 @@ import org.junit.runners.model.Statement; * public static class WatchmanTest { * private static String watchedLog; * - * @Rule(order = Integer.MIN_VALUE) + * @Rule * public TestWatcher watchman= new TestWatcher() { * @Override * protected void failed(Throwable e, Description description) { @@ -41,11 +40,6 @@ import org.junit.runners.model.Statement; * } * } * - *

      It is recommended to always set the {@link Rule#order() order} of the - * {@code TestWatcher} to {@code Integer.MIN_VALUE} so that it encloses all - * other rules. Otherwise it may see failed tests as successful and vice versa - * if some rule changes the result of a test (e.g. {@link ErrorCollector} or - * {@link ExpectedException}). * * @since 4.9 */ @@ -60,7 +54,7 @@ public abstract class TestWatcher implements TestRule { try { base.evaluate(); succeededQuietly(description, errors); - } catch (org.junit.internal.AssumptionViolatedException e) { + } catch (@SuppressWarnings("deprecation") org.junit.internal.AssumptionViolatedException e) { errors.add(e); skippedQuietly(e, description, errors); } catch (Throwable e) { @@ -93,6 +87,7 @@ public abstract class TestWatcher implements TestRule { } } + @SuppressWarnings("deprecation") private void skippedQuietly( org.junit.internal.AssumptionViolatedException e, Description description, List errors) { @@ -140,6 +135,7 @@ public abstract class TestWatcher implements TestRule { /** * Invoked when a test is skipped due to a failed assumption. */ + @SuppressWarnings("deprecation") protected void skipped(AssumptionViolatedException e, Description description) { // For backwards compatibility with JUnit 4.11 and earlier, call the legacy version org.junit.internal.AssumptionViolatedException asInternalException = e; diff --git a/src/main/java/org/junit/rules/Timeout.java b/src/main/java/org/junit/rules/Timeout.java index 334a923..8d382df 100644 --- a/src/main/java/org/junit/rules/Timeout.java +++ b/src/main/java/org/junit/rules/Timeout.java @@ -12,7 +12,7 @@ import java.util.concurrent.TimeUnit; * public static class HasGlobalLongTimeout { * * @Rule - * public Timeout globalTimeout = Timeout.millis(20); + * public Timeout globalTimeout= new Timeout(20); * * @Test * public void run1() throws InterruptedException { @@ -40,7 +40,6 @@ import java.util.concurrent.TimeUnit; public class Timeout implements TestRule { private final long timeout; private final TimeUnit timeUnit; - private final boolean lookForStuckThread; /** * Returns a new builder for building an instance. @@ -80,11 +79,10 @@ public class Timeout implements TestRule { public Timeout(long timeout, TimeUnit timeUnit) { this.timeout = timeout; this.timeUnit = timeUnit; - lookForStuckThread = false; } /** - * Create a {@code Timeout} instance initialized with values from + * Create a {@code Timeout} instance initialized with values form * a builder. * * @since 4.12 @@ -92,7 +90,6 @@ public class Timeout implements TestRule { protected Timeout(Builder builder) { timeout = builder.getTimeout(); timeUnit = builder.getTimeUnit(); - lookForStuckThread = builder.getLookingForStuckThread(); } /** @@ -124,16 +121,6 @@ public class Timeout implements TestRule { return unit.convert(timeout, timeUnit); } - /** - * Gets whether this {@code Timeout} will look for a stuck thread - * when the test times out. - * - * @since 4.12 - */ - protected final boolean getLookingForStuckThread() { - return lookForStuckThread; - } - /** * Creates a {@link Statement} that will run the given * {@code statement}, and timeout the operation based @@ -146,7 +133,6 @@ public class Timeout implements TestRule { Statement statement) throws Exception { return FailOnTimeout.builder() .withTimeout(timeout, timeUnit) - .withLookingForStuckThread(lookForStuckThread) .build(statement); } @@ -204,25 +190,6 @@ public class Timeout implements TestRule { return timeUnit; } - /** - * Specifies whether to look for a stuck thread. If a timeout occurs and this - * feature is enabled, the rule will look for a thread that appears to be stuck - * and dump its backtrace. This feature is experimental. Behavior may change - * after the 4.12 release in response to feedback. - * - * @param enable {@code true} to enable the feature - * @return {@code this} for method chaining. - */ - public Builder withLookingForStuckThread(boolean enable) { - this.lookForStuckThread = enable; - return this; - } - - protected boolean getLookingForStuckThread() { - return lookForStuckThread; - } - - /** * Builds a {@link Timeout} instance using the values in this builder., */ diff --git a/src/main/java/org/junit/runner/Computer.java b/src/main/java/org/junit/runner/Computer.java index 18d0d31..8bb4b20 100644 --- a/src/main/java/org/junit/runner/Computer.java +++ b/src/main/java/org/junit/runner/Computer.java @@ -30,17 +30,7 @@ public class Computer { public Runner runnerForClass(Class testClass) throws Throwable { return getRunner(builder, testClass); } - }, classes) { - @Override - protected String getName() { - /* - * #1320 The generated suite is not based on a real class so - * only a 'null' description can be generated from it. This name - * will be overridden here. - */ - return "classes"; - } - }; + }, classes); } /** diff --git a/src/main/java/org/junit/runner/Describable.java b/src/main/java/org/junit/runner/Describable.java index 293fdb3..1514141 100644 --- a/src/main/java/org/junit/runner/Describable.java +++ b/src/main/java/org/junit/runner/Describable.java @@ -10,5 +10,5 @@ public interface Describable { /** * @return a {@link Description} showing the tests to be run by the receiver */ - Description getDescription(); + public abstract Description getDescription(); } \ No newline at end of file diff --git a/src/main/java/org/junit/runner/Description.java b/src/main/java/org/junit/runner/Description.java index 0846a1e..fe47eac 100644 --- a/src/main/java/org/junit/runner/Description.java +++ b/src/main/java/org/junit/runner/Description.java @@ -124,17 +124,6 @@ public class Description implements Serializable { return new Description(testClass, testClass.getName(), testClass.getAnnotations()); } - /** - * Create a Description named after testClass - * - * @param testClass A not null {@link Class} containing tests - * @param annotations meta-data about the test, for downstream interpreters - * @return a Description of testClass - */ - public static Description createSuiteDescription(Class testClass, Annotation... annotations) { - return new Description(testClass, testClass.getName(), annotations); - } - /** * Describes a Runner which runs no tests */ @@ -150,7 +139,7 @@ public class Description implements Serializable { /* * We have to use the f prefix until the next major release to ensure * serialization compatibility. - * See https://github.com/junit-team/junit4/issues/976 + * See https://github.com/junit-team/junit/issues/976 */ private final Collection fChildren = new ConcurrentLinkedQueue(); private final String fDisplayName; diff --git a/src/main/java/org/junit/runner/FilterFactory.java b/src/main/java/org/junit/runner/FilterFactory.java index e2bfb73..57b4eaa 100644 --- a/src/main/java/org/junit/runner/FilterFactory.java +++ b/src/main/java/org/junit/runner/FilterFactory.java @@ -16,8 +16,7 @@ public interface FilterFactory { /** * Exception thrown if the {@link Filter} cannot be created. */ - @SuppressWarnings("serial") - class FilterNotCreatedException extends Exception { + public static class FilterNotCreatedException extends Exception { public FilterNotCreatedException(Exception exception) { super(exception.getMessage(), exception); } diff --git a/src/main/java/org/junit/runner/JUnitCommandLineParseResult.java b/src/main/java/org/junit/runner/JUnitCommandLineParseResult.java index 3383407..434157c 100644 --- a/src/main/java/org/junit/runner/JUnitCommandLineParseResult.java +++ b/src/main/java/org/junit/runner/JUnitCommandLineParseResult.java @@ -85,11 +85,13 @@ class JUnitCommandLineParseResult { } private String[] copyArray(String[] args, int from, int to) { - String[] result = new String[to - from]; + ArrayList result = new ArrayList(); + for (int j = from; j != to; ++j) { - result[j - from] = args[j]; + result.add(args[j]); } - return result; + + return result.toArray(new String[result.size()]); } void parseParameters(String[] args) { diff --git a/src/main/java/org/junit/runner/OrderWith.java b/src/main/java/org/junit/runner/OrderWith.java deleted file mode 100644 index e8470c9..0000000 --- a/src/main/java/org/junit/runner/OrderWith.java +++ /dev/null @@ -1,28 +0,0 @@ -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 deleted file mode 100644 index f8eab25..0000000 --- a/src/main/java/org/junit/runner/OrderWithValidator.java +++ /dev/null @@ -1,38 +0,0 @@ -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 7b9a990..79c0f1e 100644 --- a/src/main/java/org/junit/runner/Request.java +++ b/src/main/java/org/junit/runner/Request.java @@ -5,11 +5,9 @@ import java.util.Comparator; 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; /** @@ -73,11 +71,12 @@ public abstract class Request { */ public static Request classes(Computer computer, Class... classes) { try { - AllDefaultPossibilitiesBuilder builder = new AllDefaultPossibilitiesBuilder(); + AllDefaultPossibilitiesBuilder builder = new AllDefaultPossibilitiesBuilder(true); Runner suite = computer.getSuite(builder, classes); return runner(suite); } catch (InitializationError e) { - return runner(new ErrorReportingRunner(e, classes)); + throw new RuntimeException( + "Bug in saff's brain: Suite constructor, called as above, should always complete"); } } @@ -133,16 +132,13 @@ public abstract class Request { } /** - * Returns a Request that only runs tests whose {@link Description} - * matches the given description. + * Returns a Request that only runs contains tests whose {@link Description} + * equals desiredDescription * - *

      Returns an empty {@code Request} if {@code desiredDescription} is not a single test and filters all but the single - * test if {@code desiredDescription} is a single test.

      - * - * @param desiredDescription {@code Description} of those tests that should be run + * @param desiredDescription {@link Description} of those tests that should be run * @return the filtered Request */ - public Request filterWith(Description desiredDescription) { + public Request filterWith(final Description desiredDescription) { return filterWith(Filter.matchMethodDescription(desiredDescription)); } @@ -153,15 +149,15 @@ public abstract class Request { * 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()));
            * }
            * 
      * @@ -171,32 +167,4 @@ public abstract class Request { 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/Result.java b/src/main/java/org/junit/runner/Result.java index 4b5f4a4..73ad059 100644 --- a/src/main/java/org/junit/runner/Result.java +++ b/src/main/java/org/junit/runner/Result.java @@ -28,7 +28,6 @@ public class Result implements Serializable { ObjectStreamClass.lookup(SerializedForm.class).getFields(); private final AtomicInteger count; private final AtomicInteger ignoreCount; - private final AtomicInteger assumptionFailureCount; private final CopyOnWriteArrayList failures; private final AtomicLong runTime; private final AtomicLong startTime; @@ -39,7 +38,6 @@ public class Result implements Serializable { public Result() { count = new AtomicInteger(); ignoreCount = new AtomicInteger(); - assumptionFailureCount = new AtomicInteger(); failures = new CopyOnWriteArrayList(); runTime = new AtomicLong(); startTime = new AtomicLong(); @@ -48,35 +46,34 @@ public class Result implements Serializable { private Result(SerializedForm serializedForm) { count = serializedForm.fCount; ignoreCount = serializedForm.fIgnoreCount; - assumptionFailureCount = serializedForm.assumptionFailureCount; failures = new CopyOnWriteArrayList(serializedForm.fFailures); runTime = new AtomicLong(serializedForm.fRunTime); startTime = new AtomicLong(serializedForm.fStartTime); } /** - * Returns the number of tests run + * @return the number of tests run */ public int getRunCount() { return count.get(); } /** - * Returns the number of tests that failed during the run + * @return the number of tests that failed during the run */ public int getFailureCount() { return failures.size(); } /** - * Returns the number of milliseconds it took to run the entire suite to run + * @return the number of milliseconds it took to run the entire suite to run */ public long getRunTime() { return runTime.get(); } /** - * Returns the {@link Failure}s describing tests that failed and the problems they encountered + * @return the {@link Failure}s describing tests that failed and the problems they encountered */ public List getFailures() { return failures; @@ -89,20 +86,6 @@ public class Result implements Serializable { return ignoreCount.get(); } - /** - * Returns the number of tests skipped because of an assumption failure - * - * @throws UnsupportedOperationException if the result was serialized in a version before JUnit 4.13 - * @since 4.13 - */ - public int getAssumptionFailureCount() { - if (assumptionFailureCount == null) { - throw new UnsupportedOperationException( - "Result was serialized from a version of JUnit that doesn't support this method"); - } - return assumptionFailureCount.get(); - } - /** * @return true if all tests succeeded */ @@ -154,7 +137,7 @@ public class Result implements Serializable { @Override public void testAssumptionFailure(Failure failure) { - assumptionFailureCount.getAndIncrement(); + // do nothing: same as passing (for 4.5; may change in 4.6) } } @@ -173,7 +156,6 @@ public class Result implements Serializable { private static final long serialVersionUID = 1L; private final AtomicInteger fCount; private final AtomicInteger fIgnoreCount; - private final AtomicInteger assumptionFailureCount; private final List fFailures; private final long fRunTime; private final long fStartTime; @@ -181,7 +163,6 @@ public class Result implements Serializable { public SerializedForm(Result result) { fCount = result.count; fIgnoreCount = result.ignoreCount; - assumptionFailureCount = result.assumptionFailureCount; fFailures = Collections.synchronizedList(new ArrayList(result.failures)); fRunTime = result.runTime.longValue(); fStartTime = result.startTime.longValue(); @@ -191,7 +172,6 @@ public class Result implements Serializable { private SerializedForm(ObjectInputStream.GetField fields) throws IOException { fCount = (AtomicInteger) fields.get("fCount", null); fIgnoreCount = (AtomicInteger) fields.get("fIgnoreCount", null); - assumptionFailureCount = (AtomicInteger) fields.get("assumptionFailureCount", null); fFailures = (List) fields.get("fFailures", null); fRunTime = fields.get("fRunTime", 0L); fStartTime = fields.get("fStartTime", 0L); @@ -204,7 +184,6 @@ public class Result implements Serializable { fields.put("fFailures", fFailures); fields.put("fRunTime", fRunTime); fields.put("fStartTime", fStartTime); - fields.put("assumptionFailureCount", assumptionFailureCount); s.writeFields(); } diff --git a/src/main/java/org/junit/runner/manipulation/Alphanumeric.java b/src/main/java/org/junit/runner/manipulation/Alphanumeric.java deleted file mode 100644 index 8388d21..0000000 --- a/src/main/java/org/junit/runner/manipulation/Alphanumeric.java +++ /dev/null @@ -1,27 +0,0 @@ -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 deleted file mode 100644 index d9d60f7..0000000 --- a/src/main/java/org/junit/runner/manipulation/InvalidOrderingException.java +++ /dev/null @@ -1,21 +0,0 @@ -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 deleted file mode 100644 index 9a12a3b..0000000 --- a/src/main/java/org/junit/runner/manipulation/Orderable.java +++ /dev/null @@ -1,21 +0,0 @@ -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 deleted file mode 100644 index eb13054..0000000 --- a/src/main/java/org/junit/runner/manipulation/Orderer.java +++ /dev/null @@ -1,62 +0,0 @@ -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 deleted file mode 100644 index 0d0ce93..0000000 --- a/src/main/java/org/junit/runner/manipulation/Ordering.java +++ /dev/null @@ -1,172 +0,0 @@ -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/Sortable.java b/src/main/java/org/junit/runner/manipulation/Sortable.java index 0c59f33..9ac864c 100644 --- a/src/main/java/org/junit/runner/manipulation/Sortable.java +++ b/src/main/java/org/junit/runner/manipulation/Sortable.java @@ -15,6 +15,6 @@ public interface Sortable { * * @param sorter the {@link Sorter} to use for sorting the tests */ - void sort(Sorter sorter); + public void sort(Sorter sorter); } diff --git a/src/main/java/org/junit/runner/manipulation/Sorter.java b/src/main/java/org/junit/runner/manipulation/Sorter.java index 4b5274c..20192d0 100644 --- a/src/main/java/org/junit/runner/manipulation/Sorter.java +++ b/src/main/java/org/junit/runner/manipulation/Sorter.java @@ -1,21 +1,16 @@ 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 extends Ordering implements Comparator { +public class Sorter implements Comparator { /** * NULL is a Sorter that leaves elements in an undefined order */ @@ -32,26 +27,17 @@ public class Sorter extends Ordering implements Comparator { * 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 tests in target using comparator. - * - * @since 4.0 + * Sorts the test in runner using comparator */ - @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; + public void apply(Object object) { + if (object instanceof Sortable) { + Sortable sortable = (Sortable) object; sortable.sort(this); } } @@ -59,32 +45,4 @@ public class Sorter extends Ordering implements Comparator { 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/Failure.java b/src/main/java/org/junit/runner/notification/Failure.java index 4551302..c03b4c1 100644 --- a/src/main/java/org/junit/runner/notification/Failure.java +++ b/src/main/java/org/junit/runner/notification/Failure.java @@ -1,8 +1,9 @@ package org.junit.runner.notification; +import java.io.PrintWriter; import java.io.Serializable; +import java.io.StringWriter; -import org.junit.internal.Throwables; import org.junit.runner.Description; /** @@ -20,7 +21,7 @@ public class Failure implements Serializable { /* * We have to use the f prefix until the next major release to ensure * serialization compatibility. - * See https://github.com/junit-team/junit4/issues/976 + * See https://github.com/junit-team/junit/issues/976 */ private final Description fDescription; private final Throwable fThrownException; @@ -64,19 +65,15 @@ public class Failure implements Serializable { } /** - * Gets the printed form of the exception and its stack trace. + * Convenience method + * + * @return the printed form of the exception */ public String getTrace() { - return Throwables.getStacktrace(getException()); - } - - /** - * Gets a the printed form of the exception, with a trimmed version of the stack trace. - * This method will attempt to filter out frames of the stack trace that are below - * the test method call. - */ - public String getTrimmedTrace() { - return Throwables.getTrimmedStackTrace(getException()); + StringWriter stringWriter = new StringWriter(); + PrintWriter writer = new PrintWriter(stringWriter); + getException().printStackTrace(writer); + return stringWriter.toString(); } /** diff --git a/src/main/java/org/junit/runner/notification/RunListener.java b/src/main/java/org/junit/runner/notification/RunListener.java index d7cac00..db9d8c1 100644 --- a/src/main/java/org/junit/runner/notification/RunListener.java +++ b/src/main/java/org/junit/runner/notification/RunListener.java @@ -69,34 +69,6 @@ public class RunListener { public void testRunFinished(Result result) throws Exception { } - /** - * Called when a test suite is about to be started. If this method is - * called for a given {@link Description}, then {@link #testSuiteFinished(Description)} - * will also be called for the same {@code Description}. - * - *

      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 corresponding {@code testSuiteStarted()} call for - * the parent {@code Description}. - * - * @param description the description of the test suite that is about to be run - * (generally a class name) - * @since 4.13 - */ - public void testSuiteStarted(Description description) throws Exception { - } - - /** - * Called when a test suite has finished, whether the test suite succeeds or fails. - * This method will not be called for a given {@link Description} unless - * {@link #testSuiteStarted(Description)} was called for the same @code Description}. - * - * @param description the description of the test suite that just ran - * @since 4.13 - */ - public void testSuiteFinished(Description description) throws Exception { - } - /** * Called when an atomic test is about to be started. * diff --git a/src/main/java/org/junit/runner/notification/RunNotifier.java b/src/main/java/org/junit/runner/notification/RunNotifier.java index 752fa3b..6875f76 100644 --- a/src/main/java/org/junit/runner/notification/RunNotifier.java +++ b/src/main/java/org/junit/runner/notification/RunNotifier.java @@ -65,8 +65,8 @@ public class RunNotifier { void run() { int capacity = currentListeners.size(); - List safeListeners = new ArrayList(capacity); - List failures = new ArrayList(capacity); + ArrayList safeListeners = new ArrayList(capacity); + ArrayList failures = new ArrayList(capacity); for (RunListener listener : currentListeners) { try { notifyListener(listener); @@ -78,7 +78,7 @@ public class RunNotifier { fireTestFailures(safeListeners, failures); } - protected abstract void notifyListener(RunListener each) throws Exception; + abstract protected void notifyListener(RunListener each) throws Exception; } /** @@ -105,41 +105,6 @@ public class RunNotifier { }.run(); } - /** - * Invoke to tell listeners that a test suite is about to start. Runners are strongly - * encouraged--but not required--to call this method. If this method is called for - * a given {@link Description} then {@link #fireTestSuiteFinished(Description)} MUST - * be called for the same {@code Description}. - * - * @param description the description of the suite test (generally a class name) - * @since 4.13 - */ - public void fireTestSuiteStarted(final Description description) { - new SafeNotifier() { - @Override - protected void notifyListener(RunListener each) throws Exception { - each.testSuiteStarted(description); - } - }.run(); - } - - /** - * Invoke to tell listeners that a test suite is about to finish. Always invoke - * this method if you invoke {@link #fireTestSuiteStarted(Description)} - * as listeners are likely to expect them to come in pairs. - * - * @param description the description of the suite test (generally a class name) - * @since 4.13 - */ - public void fireTestSuiteFinished(final Description description) { - new SafeNotifier() { - @Override - protected void notifyListener(RunListener each) throws Exception { - each.testSuiteFinished(description); - } - }.run(); - } - /** * Invoke to tell listeners that an atomic test is about to start. * diff --git a/src/main/java/org/junit/runner/notification/SynchronizedRunListener.java b/src/main/java/org/junit/runner/notification/SynchronizedRunListener.java index 400fed8..c53c1ee 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 @@ import org.junit.runner.Result; *

      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 - * synchronized, clients that added multiple listeners that called common code might see + * sychronized, clients that added multiple listeners that called common code might see * issues due to the reduced synchronization. * * @author Tibor Digana (tibor17) @@ -43,37 +43,6 @@ final class SynchronizedRunListener extends RunListener { } } - /** - * {@inheritDoc} - *

      - * Synchronized decorator for {@link RunListener#testSuiteStarted(Description)}. - * @param description the description of the test suite that is about to be run - * (generally a class name). - * @throws Exception if any occurs. - * @since 4.13 - */ - @Override - public void testSuiteStarted(Description description) throws Exception { - synchronized (monitor) { - listener.testSuiteStarted(description); - } - } - - /** - * {@inheritDoc} - *

      - * Synchronized decorator for {@link RunListener#testSuiteFinished(Description)}. - * @param description the description of the test suite that just ran. - * @throws Exception - * @since 4.13 - */ - @Override - public void testSuiteFinished(Description description) throws Exception { - synchronized (monitor) { - listener.testSuiteFinished(description); - } - } - @Override public void testStarted(Description description) throws Exception { synchronized (monitor) { diff --git a/src/main/java/org/junit/runners/BlockJUnit4ClassRunner.java b/src/main/java/org/junit/runners/BlockJUnit4ClassRunner.java index 455341a..4d06199 100644 --- a/src/main/java/org/junit/runners/BlockJUnit4ClassRunner.java +++ b/src/main/java/org/junit/runners/BlockJUnit4ClassRunner.java @@ -3,10 +3,8 @@ package org.junit.runners; import static org.junit.internal.runners.rules.RuleMemberValidator.RULE_METHOD_VALIDATOR; import static org.junit.internal.runners.rules.RuleMemberValidator.RULE_VALIDATOR; -import java.util.ArrayList; import java.util.List; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; import java.util.concurrent.TimeUnit; import org.junit.After; @@ -23,18 +21,14 @@ import org.junit.internal.runners.statements.InvokeMethod; import org.junit.internal.runners.statements.RunAfters; import org.junit.internal.runners.statements.RunBefores; import org.junit.rules.MethodRule; +import org.junit.rules.RunRules; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runner.notification.RunNotifier; -import org.junit.runners.model.FrameworkMember; import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.InitializationError; -import org.junit.runners.model.MemberValueConsumer; import org.junit.runners.model.MultipleFailureException; import org.junit.runners.model.Statement; -import org.junit.runners.model.TestClass; -import org.junit.validator.PublicClassValidator; -import org.junit.validator.TestClassValidator; /** * Implements the JUnit 4 standard test case class model, as defined by the @@ -61,27 +55,14 @@ import org.junit.validator.TestClassValidator; * @since 4.5 */ public class BlockJUnit4ClassRunner extends ParentRunner { - private static TestClassValidator PUBLIC_CLASS_VALIDATOR = new PublicClassValidator(); - - private final ConcurrentMap methodDescriptions = new ConcurrentHashMap(); - - /** - * Creates a BlockJUnit4ClassRunner to run {@code testClass} - * - * @throws InitializationError if the test class is malformed. - */ - public BlockJUnit4ClassRunner(Class testClass) throws InitializationError { - super(testClass); - } - + private final ConcurrentHashMap methodDescriptions = new ConcurrentHashMap(); /** - * Creates a BlockJUnit4ClassRunner to run {@code testClass}. + * Creates a BlockJUnit4ClassRunner to run {@code klass} * * @throws InitializationError if the test class is malformed. - * @since 4.13 */ - protected BlockJUnit4ClassRunner(TestClass testClass) throws InitializationError { - super(testClass); + public BlockJUnit4ClassRunner(Class klass) throws InitializationError { + super(klass); } // @@ -94,16 +75,10 @@ public class BlockJUnit4ClassRunner extends ParentRunner { if (isIgnored(method)) { notifier.fireTestIgnored(description); } else { - Statement statement = new Statement() { - @Override - public void evaluate() throws Throwable { - methodBlock(method).evaluate(); - } - }; - runLeaf(statement, description, notifier); + runLeaf(methodBlock(method), description, notifier); } } - + /** * Evaluates whether {@link FrameworkMethod}s are ignored based on the * {@link Ignore} annotation. @@ -148,7 +123,6 @@ public class BlockJUnit4ClassRunner extends ParentRunner { protected void collectInitializationErrors(List errors) { super.collectInitializationErrors(errors); - validatePublicConstructor(errors); validateNoNonStaticInnerClass(errors); validateConstructor(errors); validateInstanceMethods(errors); @@ -156,12 +130,6 @@ public class BlockJUnit4ClassRunner extends ParentRunner { validateMethods(errors); } - private void validatePublicConstructor(List errors) { - if (getTestClass().getJavaClass() != null) { - errors.addAll(PUBLIC_CLASS_VALIDATOR.validateTestClass(getTestClass())); - } - } - protected void validateNoNonStaticInnerClass(List errors) { if (getTestClass().isANonStaticInnerClass()) { String gripe = "The inner class " + getTestClass().getName() @@ -212,7 +180,6 @@ public class BlockJUnit4ClassRunner extends ParentRunner { * Adds to {@code errors} for each method annotated with {@code @Test}, * {@code @Before}, or {@code @After} that is not a public, void instance * method with no arguments. - * @deprecated */ @Deprecated protected void validateInstanceMethods(List errors) { @@ -220,7 +187,7 @@ public class BlockJUnit4ClassRunner extends ParentRunner { validatePublicVoidNoArgMethods(Before.class, false, errors); validateTestMethods(errors); - if (computeTestMethods().isEmpty()) { + if (computeTestMethods().size() == 0) { errors.add(new Exception("No runnable methods")); } } @@ -250,16 +217,6 @@ public class BlockJUnit4ClassRunner extends ParentRunner { return getTestClass().getOnlyConstructor().newInstance(); } - /** - * Returns a new fixture to run a particular test {@code method} against. - * Default implementation executes the no-argument {@link #createTest()} method. - * - * @since 4.13 - */ - protected Object createTest(FrameworkMethod method) throws Exception { - return createTest(); - } - /** * Returns the name that describes {@code method} for {@link Description}s. * Default implementation is the method's name @@ -275,10 +232,10 @@ public class BlockJUnit4ClassRunner extends ParentRunner { * Here is an outline of the default implementation: * *

        - *
      • Invoke {@code method} on the result of {@link #createTest(org.junit.runners.model.FrameworkMethod)}, and + *
      • Invoke {@code method} on the result of {@code createTest()}, and * throw any exceptions thrown by either operation. - *
      • HOWEVER, if {@code method}'s {@code @Test} annotation has the {@link Test#expected()} - * attribute, return normally only if the previous step threw an + *
      • HOWEVER, if {@code method}'s {@code @Test} annotation has the {@code + * expecting} attribute, return normally only if the previous step threw an * exception of the correct type, and throw an exception otherwise. *
      • HOWEVER, if {@code method}'s {@code @Test} annotation has the {@code * timeout} attribute, throw an exception if the previous step takes more @@ -300,13 +257,13 @@ public class BlockJUnit4ClassRunner extends ParentRunner { * This can be overridden in subclasses, either by overriding this method, * or the implementations creating each sub-statement. */ - protected Statement methodBlock(final FrameworkMethod method) { + protected Statement methodBlock(FrameworkMethod method) { Object test; try { test = new ReflectiveCallable() { @Override protected Object runReflectiveCall() throws Throwable { - return createTest(method); + return createTest(); } }.run(); } catch (Throwable e) { @@ -319,7 +276,6 @@ public class BlockJUnit4ClassRunner extends ParentRunner { statement = withBefores(method, test, statement); statement = withAfters(method, test, statement); statement = withRules(method, test, statement); - statement = withInterruptIsolation(statement); return statement; } @@ -336,22 +292,21 @@ public class BlockJUnit4ClassRunner extends ParentRunner { /** * Returns a {@link Statement}: if {@code method}'s {@code @Test} annotation - * has the {@link Test#expected()} attribute, return normally only if {@code next} + * has the {@code expecting} attribute, return normally only if {@code next} * throws an exception of the correct type, and throw an exception * otherwise. */ protected Statement possiblyExpectingExceptions(FrameworkMethod method, Object test, Statement next) { Test annotation = method.getAnnotation(Test.class); - Class expectedExceptionClass = getExpectedException(annotation); - return expectedExceptionClass != null ? new ExpectException(next, expectedExceptionClass) : next; + return expectsException(annotation) ? new ExpectException(next, + getExpectedException(annotation)) : next; } /** * Returns a {@link Statement}: if {@code method}'s {@code @Test} annotation * has the {@code timeout} attribute, throw an exception if {@code next} * takes more than the specified number of milliseconds. - * @deprecated */ @Deprecated protected Statement withPotentialTimeout(FrameworkMethod method, @@ -393,23 +348,28 @@ public class BlockJUnit4ClassRunner extends ParentRunner { target); } - private Statement withRules(FrameworkMethod method, Object target, Statement statement) { - RuleContainer ruleContainer = new RuleContainer(); - CURRENT_RULE_CONTAINER.set(ruleContainer); - try { - List testRules = getTestRules(target); - for (MethodRule each : rules(target)) { - if (!(each instanceof TestRule && testRules.contains(each))) { - ruleContainer.add(each); - } - } - for (TestRule rule : testRules) { - ruleContainer.add(rule); + private Statement withRules(FrameworkMethod method, Object target, + Statement statement) { + List testRules = getTestRules(target); + Statement result = statement; + result = withMethodRules(method, testRules, target, result); + result = withTestRules(method, testRules, result); + + return result; + } + + private Statement withMethodRules(FrameworkMethod method, List testRules, + Object target, Statement result) { + for (org.junit.rules.MethodRule each : getMethodRules(target)) { + if (!testRules.contains(each)) { + result = each.apply(result, method, target); } - } finally { - CURRENT_RULE_CONTAINER.remove(); } - return ruleContainer.apply(method, describeChild(method), target, statement); + return result; + } + + private List getMethodRules(Object target) { + return rules(target); } /** @@ -418,12 +378,27 @@ public class BlockJUnit4ClassRunner extends ParentRunner { * test */ protected List rules(Object target) { - RuleCollector collector = new RuleCollector(); - getTestClass().collectAnnotatedMethodValues(target, Rule.class, MethodRule.class, - collector); - getTestClass().collectAnnotatedFieldValues(target, Rule.class, MethodRule.class, - collector); - return collector.result; + List rules = getTestClass().getAnnotatedMethodValues(target, + Rule.class, MethodRule.class); + + rules.addAll(getTestClass().getAnnotatedFieldValues(target, + Rule.class, MethodRule.class)); + + return rules; + } + + /** + * Returns a {@link Statement}: apply all non-static fields + * annotated with {@link Rule}. + * + * @param statement The base statement + * @return a RunRules statement if any class-level {@link Rule}s are + * found, or the base statement + */ + private Statement withTestRules(FrameworkMethod method, List testRules, + Statement statement) { + return testRules.isEmpty() ? statement : + new RunRules(statement, testRules, describeChild(method)); } /** @@ -432,10 +407,13 @@ public class BlockJUnit4ClassRunner extends ParentRunner { * test */ protected List getTestRules(Object target) { - RuleCollector collector = new RuleCollector(); - getTestClass().collectAnnotatedMethodValues(target, Rule.class, TestRule.class, collector); - getTestClass().collectAnnotatedFieldValues(target, Rule.class, TestRule.class, collector); - return collector.result; + List result = getTestClass().getAnnotatedMethodValues(target, + Rule.class, TestRule.class); + + result.addAll(getTestClass().getAnnotatedFieldValues(target, + Rule.class, TestRule.class)); + + return result; } private Class getExpectedException(Test annotation) { @@ -446,28 +424,14 @@ public class BlockJUnit4ClassRunner extends ParentRunner { } } + private boolean expectsException(Test annotation) { + return getExpectedException(annotation) != null; + } + private long getTimeout(Test annotation) { if (annotation == null) { return 0; } return annotation.timeout(); } - - private static final ThreadLocal CURRENT_RULE_CONTAINER = - new ThreadLocal(); - - private static class RuleCollector implements MemberValueConsumer { - final List result = new ArrayList(); - - public void accept(FrameworkMember member, T value) { - Rule rule = member.getAnnotation(Rule.class); - if (rule != null) { - RuleContainer container = CURRENT_RULE_CONTAINER.get(); - if (container != null) { - container.setOrder(value, rule.order()); - } - } - result.add(value); - } - } } diff --git a/src/main/java/org/junit/runners/JUnit4.java b/src/main/java/org/junit/runners/JUnit4.java index 28eafb3..6ba28c2 100644 --- a/src/main/java/org/junit/runners/JUnit4.java +++ b/src/main/java/org/junit/runners/JUnit4.java @@ -1,7 +1,6 @@ package org.junit.runners; import org.junit.runners.model.InitializationError; -import org.junit.runners.model.TestClass; /** * Aliases the current default JUnit 4 class runner, for future-proofing. If @@ -20,6 +19,6 @@ public final class JUnit4 extends BlockJUnit4ClassRunner { * Constructs a new instance of the default runner */ public JUnit4(Class klass) throws InitializationError { - super(new TestClass(klass)); + super(klass); } } diff --git a/src/main/java/org/junit/runners/Parameterized.java b/src/main/java/org/junit/runners/Parameterized.java index d11b66a..829c8f0 100644 --- a/src/main/java/org/junit/runners/Parameterized.java +++ b/src/main/java/org/junit/runners/Parameterized.java @@ -1,6 +1,5 @@ package org.junit.runners; -import java.lang.annotation.Annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; @@ -9,18 +8,12 @@ import java.lang.annotation.Target; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; import java.util.Collections; import java.util.List; -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; import org.junit.runners.model.FrameworkMethod; -import org.junit.runners.model.InvalidTestClassError; +import org.junit.runners.model.InitializationError; import org.junit.runners.model.TestClass; import org.junit.runners.parameterized.BlockJUnit4ClassRunnerWithParametersFactory; import org.junit.runners.parameterized.ParametersRunnerFactory; @@ -31,37 +24,34 @@ import org.junit.runners.parameterized.TestWithParameters; * When running a parameterized test class, instances are created for the * cross-product of the test methods and the test data elements. *

        - * For example, to test the + operator, write: + * For example, to test a Fibonacci function, write: *

          * @RunWith(Parameterized.class)
        - * public class AdditionTest {
        - *     @Parameters(name = "{index}: {0} + {1} = {2}")
        + * public class FibonacciTest {
        + *     @Parameters(name= "{index}: fib[{0}]={1}")
          *     public static Iterable<Object[]> data() {
        - *         return Arrays.asList(new Object[][] { { 0, 0, 0 }, { 1, 1, 2 },
        - *                 { 3, 2, 5 }, { 4, 3, 7 } });
        + *         return Arrays.asList(new Object[][] { { 0, 0 }, { 1, 1 }, { 2, 1 },
        + *                 { 3, 2 }, { 4, 3 }, { 5, 5 }, { 6, 8 } });
          *     }
          *
        - *     private int firstSummand;
        + *     private int fInput;
          *
        - *     private int secondSummand;
        + *     private int fExpected;
          *
        - *     private int sum;
        - *
        - *     public AdditionTest(int firstSummand, int secondSummand, int sum) {
        - *         this.firstSummand = firstSummand;
        - *         this.secondSummand = secondSummand;
        - *         this.sum = sum;
        + *     public FibonacciTest(int input, int expected) {
        + *         fInput= input;
        + *         fExpected= expected;
          *     }
          *
          *     @Test
          *     public void test() {
        - *         assertEquals(sum, firstSummand + secondSummand);
        + *         assertEquals(fExpected, Fibonacci.compute(fInput));
          *     }
          * }
          * 
        *

        - * Each instance of AdditionTest will be constructed using the - * three-argument constructor and the data values in the + * Each instance of FibonacciTest will be constructed using the + * two-argument constructor and the data values in the * @Parameters method. *

        * In order that you can easily identify the individual tests, you may provide a @@ -79,36 +69,33 @@ import org.junit.runners.parameterized.TestWithParameters; * *

        * In the example given above, the Parameterized runner creates - * names like [2: 3 + 2 = 5]. If you don't use the name parameter, + * names like [1: fib(3)=2]. If you don't use the name parameter, * then the current parameter index is used as name. *

        * You can also write: *

          * @RunWith(Parameterized.class)
        - * public class AdditionTest {
        - *     @Parameters(name = "{index}: {0} + {1} = {2}")
        - *     public static Iterable<Object[]> data() {
        - *         return Arrays.asList(new Object[][] { { 0, 0, 0 }, { 1, 1, 2 },
        - *                 { 3, 2, 5 }, { 4, 3, 7 } });
        - *     }
        - *
        - *     @Parameter(0)
        - *     public int firstSummand;
        + * public class FibonacciTest {
        + *  @Parameters
        + *  public static Iterable<Object[]> data() {
        + *      return Arrays.asList(new Object[][] { { 0, 0 }, { 1, 1 }, { 2, 1 },
        + *                 { 3, 2 }, { 4, 3 }, { 5, 5 }, { 6, 8 } });
        + *  }
        + *  
        + *  @Parameter(0)
        + *  public int fInput;
          *
        - *     @Parameter(1)
        - *     public int secondSummand;
        + *  @Parameter(1)
        + *  public int fExpected;
          *
        - *     @Parameter(2)
        - *     public int sum;
        - *
        - *     @Test
        - *     public void test() {
        - *         assertEquals(sum, firstSummand + secondSummand);
        - *     }
        + *  @Test
        + *  public void test() {
        + *      assertEquals(fExpected, Fibonacci.compute(fInput));
        + *  }
          * }
          * 
        *

        - * Each instance of AdditionTest will be constructed with the default constructor + * Each instance of FibonacciTest will be constructed with the default constructor * and fields annotated by @Parameter will be initialized * with the data values in the @Parameters method. * @@ -118,7 +105,8 @@ import org.junit.runners.parameterized.TestWithParameters; *

          * @Parameters
          * public static Object[][] data() {
        - * 	return new Object[][] { { 0, 0, 0 }, { 1, 1, 2 }, { 3, 2, 5 }, { 4, 3, 7 } } };
        + * 	return new Object[][] { { 0, 0 }, { 1, 1 }, { 2, 1 }, { 3, 2 }, { 4, 3 },
        + * 			{ 5, 5 }, { 6, 8 } };
          * }
          * 
        * @@ -142,19 +130,6 @@ import org.junit.runners.parameterized.TestWithParameters; * } * * - *

        Executing code before/after executing tests for specific parameters

        - *

        - * If your test needs to perform some preparation or cleanup based on the - * parameters, this can be done by adding public static methods annotated with - * {@code @BeforeParam}/{@code @AfterParam}. Such methods should either have no - * parameters or the same parameters as the test. - *

        - * @BeforeParam
        - * public static void beforeTestsForParameter(String onlyParameter) {
        - *     System.out.println("Testing " + onlyParameter);
        - * }
        - * 
        - * *

        Create different runners

        *

        * By default the {@code Parameterized} runner creates a slightly modified @@ -166,7 +141,7 @@ import org.junit.runners.parameterized.TestWithParameters; * The factory must have a public zero-arg constructor. * *

        - * public class YourRunnerFactory implements ParametersRunnerFactory {
        + * public class YourRunnerFactory implements ParameterizedRunnerFactory {
          *     public Runner createRunnerForTestWithParameters(TestWithParameters test)
          *             throws InitializationError {
          *         return YourRunner(test);
        @@ -185,21 +160,6 @@ import org.junit.runners.parameterized.TestWithParameters;
          * }
          * 
        * - *

        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 { @@ -210,7 +170,7 @@ public class Parameterized extends Suite { */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) - public @interface Parameters { + public static @interface Parameters { /** * Optional pattern to derive the test's name from the parameters. Use * numbers in braces to refer to the parameters or the additional data @@ -241,7 +201,7 @@ public class Parameterized extends Suite { */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) - public @interface Parameter { + public static @interface Parameter { /** * Method that returns the index of the parameter in the array * returned by the method annotated by Parameters. @@ -270,235 +230,122 @@ public class Parameterized extends Suite { Class value() default BlockJUnit4ClassRunnerWithParametersFactory.class; } - /** - * Annotation for {@code public static void} methods which should be executed before - * evaluating tests with particular parameters. - * - * @see org.junit.BeforeClass - * @see org.junit.Before - * @since 4.13 - */ - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.METHOD) - public @interface BeforeParam { - } + private static final ParametersRunnerFactory DEFAULT_FACTORY = new BlockJUnit4ClassRunnerWithParametersFactory(); - /** - * Annotation for {@code public static void} methods which should be executed after - * evaluating tests with particular parameters. - * - * @see org.junit.AfterClass - * @see org.junit.After - * @since 4.13 - */ - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.METHOD) - public @interface AfterParam { - } + private static final List NO_RUNNERS = Collections.emptyList(); + + private final List runners; /** * Only called reflectively. Do not use programmatically. */ public Parameterized(Class klass) throws Throwable { - this(klass, new RunnersFactory(klass)); - } - - private Parameterized(Class klass, RunnersFactory runnersFactory) throws Exception { - super(klass, runnersFactory.createRunners()); - validateBeforeParamAndAfterParamMethods(runnersFactory.parameterCount); + super(klass, NO_RUNNERS); + ParametersRunnerFactory runnerFactory = getParametersRunnerFactory( + klass); + Parameters parameters = getParametersMethod().getAnnotation( + Parameters.class); + runners = Collections.unmodifiableList(createRunnersForParameters( + allParameters(), parameters.name(), runnerFactory)); } - private void validateBeforeParamAndAfterParamMethods(Integer parameterCount) - throws InvalidTestClassError { - List errors = new ArrayList(); - validatePublicStaticVoidMethods(Parameterized.BeforeParam.class, parameterCount, errors); - validatePublicStaticVoidMethods(Parameterized.AfterParam.class, parameterCount, errors); - if (!errors.isEmpty()) { - throw new InvalidTestClassError(getTestClass().getJavaClass(), errors); + private ParametersRunnerFactory getParametersRunnerFactory(Class klass) + throws InstantiationException, IllegalAccessException { + UseParametersRunnerFactory annotation = klass + .getAnnotation(UseParametersRunnerFactory.class); + if (annotation == null) { + return DEFAULT_FACTORY; + } else { + Class factoryClass = annotation + .value(); + return factoryClass.newInstance(); } } - private void validatePublicStaticVoidMethods( - Class annotation, Integer parameterCount, - List errors) { - List methods = getTestClass().getAnnotatedMethods(annotation); - for (FrameworkMethod fm : methods) { - fm.validatePublicVoid(true, errors); - if (parameterCount != null) { - int methodParameterCount = fm.getMethod().getParameterTypes().length; - if (methodParameterCount != 0 && methodParameterCount != parameterCount) { - errors.add(new Exception("Method " + fm.getName() - + "() should have 0 or " + parameterCount + " parameter(s)")); - } - } - } + @Override + protected List getChildren() { + return runners; } - private static class AssumptionViolationRunner extends Runner { - private final Description description; - private final AssumptionViolatedException exception; - - AssumptionViolationRunner(TestClass testClass, String methodName, - AssumptionViolatedException exception) { - this.description = Description - .createTestDescription(testClass.getJavaClass(), - methodName + "() assumption violation"); - this.exception = exception; - } - - @Override - public Description getDescription() { - return description; - } - - @Override - public void run(RunNotifier notifier) { - notifier.fireTestAssumptionFailed(new Failure(description, exception)); - } + private TestWithParameters createTestWithNotNormalizedParameters( + String pattern, int index, Object parametersOrSingleParameter) { + Object[] parameters= (parametersOrSingleParameter instanceof Object[]) ? (Object[]) parametersOrSingleParameter + : new Object[] { parametersOrSingleParameter }; + return createTestWithParameters(getTestClass(), pattern, index, + parameters); } - private static class RunnersFactory { - private static final ParametersRunnerFactory DEFAULT_FACTORY = new BlockJUnit4ClassRunnerWithParametersFactory(); - - private final TestClass testClass; - private final FrameworkMethod parametersMethod; - private final List allParameters; - private final int parameterCount; - private final Runner runnerOverride; - - private RunnersFactory(Class klass) throws Throwable { - testClass = new TestClass(klass); - parametersMethod = getParametersMethod(testClass); - List allParametersResult; - AssumptionViolationRunner assumptionViolationRunner = null; - try { - allParametersResult = allParameters(testClass, parametersMethod); - } catch (AssumptionViolatedException e) { - allParametersResult = Collections.emptyList(); - assumptionViolationRunner = new AssumptionViolationRunner(testClass, - parametersMethod.getName(), e); - } - allParameters = allParametersResult; - runnerOverride = assumptionViolationRunner; - parameterCount = - allParameters.isEmpty() ? 0 : normalizeParameters(allParameters.get(0)).length; - } - - private List createRunners() throws Exception { - if (runnerOverride != null) { - return Collections.singletonList(runnerOverride); - } - Parameters parameters = parametersMethod.getAnnotation(Parameters.class); - return Collections.unmodifiableList(createRunnersForParameters( - allParameters, parameters.name(), - getParametersRunnerFactory())); - } - - private ParametersRunnerFactory getParametersRunnerFactory() - throws InstantiationException, IllegalAccessException { - UseParametersRunnerFactory annotation = testClass - .getAnnotation(UseParametersRunnerFactory.class); - if (annotation == null) { - return DEFAULT_FACTORY; - } else { - Class factoryClass = annotation - .value(); - return factoryClass.newInstance(); - } - } - - private TestWithParameters createTestWithNotNormalizedParameters( - String pattern, int index, Object parametersOrSingleParameter) { - Object[] parameters = normalizeParameters(parametersOrSingleParameter); - return createTestWithParameters(testClass, pattern, index, parameters); - } - - private static Object[] normalizeParameters(Object parametersOrSingleParameter) { - return (parametersOrSingleParameter instanceof Object[]) ? (Object[]) parametersOrSingleParameter - : new Object[] { parametersOrSingleParameter }; + @SuppressWarnings("unchecked") + private Iterable allParameters() throws Throwable { + Object parameters = getParametersMethod().invokeExplosively(null); + if (parameters instanceof Iterable) { + return (Iterable) parameters; + } else if (parameters instanceof Object[]) { + return Arrays.asList((Object[]) parameters); + } else { + throw parametersMethodReturnedWrongType(); } + } - @SuppressWarnings("unchecked") - private static List allParameters( - TestClass testClass, FrameworkMethod parametersMethod) throws Throwable { - Object parameters = parametersMethod.invokeExplosively(null); - if (parameters instanceof List) { - return (List) parameters; - } else if (parameters instanceof Collection) { - return new ArrayList((Collection) parameters); - } else if (parameters instanceof Iterable) { - List result = new ArrayList(); - for (Object entry : ((Iterable) parameters)) { - result.add(entry); - } - return result; - } else if (parameters instanceof Object[]) { - return Arrays.asList((Object[]) parameters); - } else { - throw parametersMethodReturnedWrongType(testClass, parametersMethod); + private FrameworkMethod getParametersMethod() throws Exception { + List methods = getTestClass().getAnnotatedMethods( + Parameters.class); + for (FrameworkMethod each : methods) { + if (each.isStatic() && each.isPublic()) { + return each; } } - private static FrameworkMethod getParametersMethod(TestClass testClass) throws Exception { - List methods = testClass - .getAnnotatedMethods(Parameters.class); - for (FrameworkMethod each : methods) { - if (each.isStatic() && each.isPublic()) { - return each; - } - } - - throw new Exception("No public static parameters method on class " - + testClass.getName()); - } + throw new Exception("No public static parameters method on class " + + getTestClass().getName()); + } - private List createRunnersForParameters( - Iterable allParameters, String namePattern, - ParametersRunnerFactory runnerFactory) throws Exception { - try { - List tests = createTestsForParameters( - allParameters, namePattern); - List runners = new ArrayList(); - for (TestWithParameters test : tests) { - runners.add(runnerFactory - .createRunnerForTestWithParameters(test)); - } - return runners; - } catch (ClassCastException e) { - throw parametersMethodReturnedWrongType(testClass, parametersMethod); + private List createRunnersForParameters( + Iterable allParameters, String namePattern, + ParametersRunnerFactory runnerFactory) + throws InitializationError, + Exception { + try { + List tests = createTestsForParameters( + allParameters, namePattern); + List runners = new ArrayList(); + for (TestWithParameters test : tests) { + runners.add(runnerFactory + .createRunnerForTestWithParameters(test)); } + return runners; + } catch (ClassCastException e) { + throw parametersMethodReturnedWrongType(); } + } - private List createTestsForParameters( - Iterable allParameters, String namePattern) - throws Exception { - int i = 0; - List children = new ArrayList(); - for (Object parametersOfSingleTest : allParameters) { - children.add(createTestWithNotNormalizedParameters(namePattern, - i++, parametersOfSingleTest)); - } - return children; + private List createTestsForParameters( + Iterable allParameters, String namePattern) + throws Exception { + int i = 0; + List children = new ArrayList(); + for (Object parametersOfSingleTest : allParameters) { + children.add(createTestWithNotNormalizedParameters(namePattern, + i++, parametersOfSingleTest)); } + return children; + } - private static Exception parametersMethodReturnedWrongType( - TestClass testClass, FrameworkMethod parametersMethod) throws Exception { - String className = testClass.getName(); - String methodName = parametersMethod.getName(); - String message = MessageFormat.format( - "{0}.{1}() must return an Iterable of arrays.", className, - methodName); - return new Exception(message); - } + private Exception parametersMethodReturnedWrongType() throws Exception { + String className = getTestClass().getName(); + String methodName = getParametersMethod().getName(); + String message = MessageFormat.format( + "{0}.{1}() must return an Iterable of arrays.", + className, methodName); + return new Exception(message); + } - private TestWithParameters createTestWithParameters( - TestClass testClass, String pattern, int index, - Object[] parameters) { - String finalPattern = pattern.replaceAll("\\{index\\}", - Integer.toString(index)); - String name = MessageFormat.format(finalPattern, parameters); - return new TestWithParameters("[" + name + "]", testClass, - Arrays.asList(parameters)); - } + private static TestWithParameters createTestWithParameters( + TestClass testClass, String pattern, int index, Object[] parameters) { + String finalPattern = pattern.replaceAll("\\{index\\}", + Integer.toString(index)); + String name = MessageFormat.format(finalPattern, parameters); + return new TestWithParameters("[" + name + "]", testClass, + Arrays.asList(parameters)); } } diff --git a/src/main/java/org/junit/runners/ParentRunner.java b/src/main/java/org/junit/runners/ParentRunner.java old mode 100644 new mode 100755 index 0a0e7cb..92641bf --- a/src/main/java/org/junit/runners/ParentRunner.java +++ b/src/main/java/org/junit/runners/ParentRunner.java @@ -1,25 +1,21 @@ package org.junit.runners; -import static org.junit.internal.Checks.notNull; import static org.junit.internal.runners.rules.RuleMemberValidator.CLASS_RULE_METHOD_VALIDATOR; import static org.junit.internal.runners.rules.RuleMemberValidator.CLASS_RULE_VALIDATOR; 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; @@ -32,22 +28,18 @@ import org.junit.runner.Description; 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.RunNotifier; import org.junit.runner.notification.StoppedByUserException; -import org.junit.runners.model.FrameworkMember; import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.InitializationError; -import org.junit.runners.model.InvalidTestClassError; -import org.junit.runners.model.MemberValueConsumer; import org.junit.runners.model.RunnerScheduler; import org.junit.runners.model.Statement; import org.junit.runners.model.TestClass; import org.junit.validator.AnnotationsValidator; +import org.junit.validator.PublicClassValidator; import org.junit.validator.TestClassValidator; /** @@ -64,15 +56,15 @@ import org.junit.validator.TestClassValidator; * @since 4.5 */ public abstract class ParentRunner extends Runner implements Filterable, - Orderable { - private static final List VALIDATORS = Collections.singletonList( - new AnnotationsValidator()); + Sortable { + private static final List VALIDATORS = Arrays.asList( + new AnnotationsValidator(), new PublicClassValidator()); - private final Lock childrenLock = new ReentrantLock(); + private final Object childrenLock = new Object(); private final TestClass testClass; // Guarded by childrenLock - private volatile List filteredChildren = null; + private volatile Collection filteredChildren = null; private volatile RunnerScheduler scheduler = new RunnerScheduler() { public void schedule(Runnable childStatement) { @@ -92,21 +84,6 @@ public abstract class ParentRunner extends Runner implements Filterable, validate(); } - /** - * Constructs a new {@code ParentRunner} that will run the {@code TestClass}. - * - * @since 4.13 - */ - protected ParentRunner(TestClass testClass) throws InitializationError { - this.testClass = notNull(testClass); - validate(); - } - - /** - * @deprecated Please use {@link #ParentRunner(org.junit.runners.model.TestClass)}. - * @since 4.12 - */ - @Deprecated protected TestClass createTestClass(Class testClass) { return new TestClass(testClass); } @@ -215,7 +192,6 @@ public abstract class ParentRunner extends Runner implements Filterable, statement = withBeforeClasses(statement); statement = withAfterClasses(statement); statement = withClassRules(statement); - statement = withInterruptIsolation(statement); } return statement; } @@ -243,7 +219,7 @@ public abstract class ParentRunner extends Runner implements Filterable, /** * Returns a {@link Statement}: run all non-overridden {@code @AfterClass} methods on this class - * and superclasses after executing {@code statement}; all AfterClass methods are + * and superclasses before executing {@code statement}; all AfterClass methods are * always executed: exceptions thrown by previous steps are combined, if * necessary, with exceptions from AfterClass methods into a * {@link org.junit.runners.model.MultipleFailureException}. @@ -275,10 +251,9 @@ public abstract class ParentRunner extends Runner implements Filterable, * each method in the tested class. */ protected List classRules() { - ClassRuleCollector collector = new ClassRuleCollector(); - testClass.collectAnnotatedMethodValues(null, ClassRule.class, TestRule.class, collector); - testClass.collectAnnotatedFieldValues(null, ClassRule.class, TestRule.class, collector); - return collector.getOrderedRules(); + List result = testClass.getAnnotatedMethodValues(null, ClassRule.class, TestRule.class); + result.addAll(testClass.getAnnotatedFieldValues(null, ClassRule.class, TestRule.class)); + return result; } /** @@ -295,22 +270,6 @@ public abstract class ParentRunner extends Runner implements Filterable, }; } - /** - * @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. @@ -387,16 +346,8 @@ public abstract class ParentRunner extends Runner implements Filterable, @Override public Description getDescription() { - Class clazz = getTestClass().getJavaClass(); - Description description; - // if subclass overrides `getName()` then we should use it - // to maintain backwards compatibility with JUnit 4.12 - if (clazz == null || !clazz.getName().equals(getName())) { - description = Description.createSuiteDescription(getName(), getRunnerAnnotations()); - } else { - description = Description.createSuiteDescription(clazz, getRunnerAnnotations()); - } - + Description description = Description.createSuiteDescription(getName(), + getRunnerAnnotations()); for (T child : getFilteredChildren()) { description.addChild(describeChild(child)); } @@ -407,7 +358,6 @@ public abstract class ParentRunner extends Runner implements Filterable, public void run(final RunNotifier notifier) { EachTestNotifier testNotifier = new EachTestNotifier(notifier, getDescription()); - testNotifier.fireTestSuiteStarted(); try { Statement statement = classBlock(notifier); statement.evaluate(); @@ -417,8 +367,6 @@ public abstract class ParentRunner extends Runner implements Filterable, throw e; } catch (Throwable e) { testNotifier.addFailure(e); - } finally { - testNotifier.fireTestSuiteFinished(); } } @@ -427,8 +375,7 @@ public abstract class ParentRunner extends Runner implements Filterable, // public void filter(Filter filter) throws NoTestsRemainException { - childrenLock.lock(); - try { + synchronized (childrenLock) { List children = new ArrayList(getFilteredChildren()); for (Iterator iter = children.iterator(); iter.hasNext(); ) { T each = iter.next(); @@ -442,70 +389,21 @@ public abstract class ParentRunner extends Runner implements Filterable, iter.remove(); } } - filteredChildren = Collections.unmodifiableList(children); + filteredChildren = Collections.unmodifiableCollection(children); if (filteredChildren.isEmpty()) { throw new NoTestsRemainException(); } - } finally { - childrenLock.unlock(); } } public void sort(Sorter sorter) { - if (shouldNotReorder()) { - return; - } - - childrenLock.lock(); - try { + synchronized (childrenLock) { for (T each : getFilteredChildren()) { sorter.apply(each); } List sortedChildren = new ArrayList(getFilteredChildren()); Collections.sort(sortedChildren, comparator(sorter)); - 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(); + filteredChildren = Collections.unmodifiableCollection(sortedChildren); } } @@ -513,29 +411,20 @@ public abstract class ParentRunner extends Runner implements Filterable, // 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); if (!errors.isEmpty()) { - throw new InvalidTestClassError(testClass.getJavaClass(), errors); + throw new InitializationError(errors); } } - private List getFilteredChildren() { + private Collection getFilteredChildren() { if (filteredChildren == null) { - childrenLock.lock(); - try { + synchronized (childrenLock) { if (filteredChildren == null) { - filteredChildren = Collections.unmodifiableList( - new ArrayList(getChildren())); + filteredChildren = Collections.unmodifiableCollection(getChildren()); } - } finally { - childrenLock.unlock(); } } return filteredChildren; @@ -560,23 +449,4 @@ public abstract class ParentRunner extends Runner implements Filterable, public void setScheduler(RunnerScheduler scheduler) { this.scheduler = scheduler; } - - private static class ClassRuleCollector implements MemberValueConsumer { - final List entries = new ArrayList(); - - 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() { - Collections.sort(entries, RuleContainer.ENTRY_COMPARATOR); - List result = new ArrayList(entries.size()); - for (RuleContainer.RuleEntry entry : entries) { - result.add((TestRule) entry.rule); - } - return result; - } - } } diff --git a/src/main/java/org/junit/runners/RuleContainer.java b/src/main/java/org/junit/runners/RuleContainer.java deleted file mode 100644 index 30ddd8d..0000000 --- a/src/main/java/org/junit/runners/RuleContainer.java +++ /dev/null @@ -1,113 +0,0 @@ -package org.junit.runners; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.IdentityHashMap; -import java.util.List; - -import org.junit.Rule; -import org.junit.rules.MethodRule; -import org.junit.rules.TestRule; -import org.junit.runner.Description; -import org.junit.runners.model.FrameworkMethod; -import org.junit.runners.model.Statement; - -/** - * Data structure for ordering of {@link TestRule}/{@link MethodRule} instances. - * - * @since 4.13 - */ -class RuleContainer { - private final IdentityHashMap orderValues = new IdentityHashMap(); - private final List testRules = new ArrayList(); - private final List methodRules = new ArrayList(); - - /** - * Sets order value for the specified rule. - */ - public void setOrder(Object rule, int order) { - orderValues.put(rule, order); - } - - public void add(MethodRule methodRule) { - methodRules.add(methodRule); - } - - public void add(TestRule testRule) { - testRules.add(testRule); - } - - static final Comparator ENTRY_COMPARATOR = new Comparator() { - public int compare(RuleEntry o1, RuleEntry o2) { - int result = compareInt(o1.order, o2.order); - return result != 0 ? result : o1.type - o2.type; - } - - private int compareInt(int a, int b) { - return (a < b) ? 1 : (a == b ? 0 : -1); - } - }; - - /** - * Returns entries in the order how they should be applied, i.e. inner-to-outer. - */ - private List getSortedEntries() { - List ruleEntries = new ArrayList( - methodRules.size() + testRules.size()); - for (MethodRule rule : methodRules) { - ruleEntries.add(new RuleEntry(rule, RuleEntry.TYPE_METHOD_RULE, orderValues.get(rule))); - } - for (TestRule rule : testRules) { - ruleEntries.add(new RuleEntry(rule, RuleEntry.TYPE_TEST_RULE, orderValues.get(rule))); - } - Collections.sort(ruleEntries, ENTRY_COMPARATOR); - return ruleEntries; - } - - /** - * Applies all the rules ordered accordingly to the specified {@code statement}. - */ - public Statement apply(FrameworkMethod method, Description description, Object target, - Statement statement) { - if (methodRules.isEmpty() && testRules.isEmpty()) { - return statement; - } - Statement result = statement; - for (RuleEntry ruleEntry : getSortedEntries()) { - if (ruleEntry.type == RuleEntry.TYPE_TEST_RULE) { - result = ((TestRule) ruleEntry.rule).apply(result, description); - } else { - result = ((MethodRule) ruleEntry.rule).apply(result, method, target); - } - } - return result; - } - - /** - * Returns rule instances in the order how they should be applied, i.e. inner-to-outer. - * VisibleForTesting - */ - List getSortedRules() { - List result = new ArrayList(); - for (RuleEntry entry : getSortedEntries()) { - result.add(entry.rule); - } - return result; - } - - static class RuleEntry { - static final int TYPE_TEST_RULE = 1; - static final int TYPE_METHOD_RULE = 0; - - final Object rule; - final int type; - final int order; - - RuleEntry(Object rule, int type, Integer order) { - this.rule = rule; - this.type = type; - this.order = order != null ? order.intValue() : Rule.DEFAULT_ORDER; - } - } -} diff --git a/src/main/java/org/junit/runners/Suite.java b/src/main/java/org/junit/runners/Suite.java index c2c8e58..b37179f 100644 --- a/src/main/java/org/junit/runners/Suite.java +++ b/src/main/java/org/junit/runners/Suite.java @@ -47,7 +47,7 @@ public class Suite extends ParentRunner { /** * @return the classes to be run */ - Class[] value(); + public Class[] value(); } private static Class[] getAnnotatedClasses(Class klass) throws InitializationError { @@ -88,7 +88,7 @@ public class Suite extends ParentRunner { * @param suiteClasses the classes in the suite */ protected Suite(Class klass, Class[] suiteClasses) throws InitializationError { - this(new AllDefaultPossibilitiesBuilder(), klass, suiteClasses); + this(new AllDefaultPossibilitiesBuilder(true), klass, suiteClasses); } /** diff --git a/src/main/java/org/junit/runners/model/FrameworkField.java b/src/main/java/org/junit/runners/model/FrameworkField.java index ea2b16f..945e389 100644 --- a/src/main/java/org/junit/runners/model/FrameworkField.java +++ b/src/main/java/org/junit/runners/model/FrameworkField.java @@ -14,26 +14,12 @@ import org.junit.runners.BlockJUnit4ClassRunner; public class FrameworkField extends FrameworkMember { private final Field field; - /** - * Returns a new {@code FrameworkField} for {@code field}. - * - *

        Access relaxed to {@code public} since version 4.13.1. - */ - public FrameworkField(Field field) { + FrameworkField(Field field) { if (field == null) { throw new NullPointerException( "FrameworkField cannot be created without an underlying field."); } this.field = field; - - if (isPublic()) { - // This field could be a public field in a package-scope base class - try { - field.setAccessible(true); - } catch (SecurityException e) { - // We may get an IllegalAccessException when we try to access the field - } - } } @Override @@ -54,11 +40,6 @@ public class FrameworkField extends FrameworkMember { return otherMember.getName().equals(getName()); } - @Override - boolean isBridgeMethod() { - return false; - } - @Override protected int getModifiers() { return field.getModifiers(); diff --git a/src/main/java/org/junit/runners/model/FrameworkMember.java b/src/main/java/org/junit/runners/model/FrameworkMember.java index 5634b3f..724f096 100644 --- a/src/main/java/org/junit/runners/model/FrameworkMember.java +++ b/src/main/java/org/junit/runners/model/FrameworkMember.java @@ -12,29 +12,15 @@ public abstract class FrameworkMember> implements Annotatable { abstract boolean isShadowedBy(T otherMember); - T handlePossibleBridgeMethod(List members) { - for (int i = members.size() - 1; i >=0; i--) { - T otherMember = members.get(i); - if (isShadowedBy(otherMember)) { - if (otherMember.isBridgeMethod()) { - /* - * We need to return the previously-encountered bridge method - * because JUnit won't be able to call the parent method, - * because the parent class isn't public. - */ - members.remove(i); - return otherMember; - } - // We found a shadowed member that isn't a bridge method. Ignore it. - return null; + boolean isShadowedBy(List members) { + for (T each : members) { + if (isShadowedBy(each)) { + return true; } } - // No shadow or bridge method found. The caller should add *this* member. - return (T) this; + return false; } - abstract boolean isBridgeMethod(); - protected abstract int getModifiers(); /** diff --git a/src/main/java/org/junit/runners/model/FrameworkMethod.java b/src/main/java/org/junit/runners/model/FrameworkMethod.java index 4471407..3580052 100644 --- a/src/main/java/org/junit/runners/model/FrameworkMethod.java +++ b/src/main/java/org/junit/runners/model/FrameworkMethod.java @@ -28,15 +28,6 @@ public class FrameworkMethod extends FrameworkMember { "FrameworkMethod cannot be created without an underlying method."); } this.method = method; - - if (isPublic()) { - // This method could be a public method in a package-scope base class - try { - method.setAccessible(true); - } catch (SecurityException e) { - // We may get an IllegalAccessException when we try to call the method - } - } } /** @@ -157,11 +148,6 @@ public class FrameworkMethod extends FrameworkMember { return true; } - @Override - boolean isBridgeMethod() { - return method.isBridge(); - } - @Override public boolean equals(Object obj) { if (!FrameworkMethod.class.isInstance(obj)) { diff --git a/src/main/java/org/junit/runners/model/InitializationError.java b/src/main/java/org/junit/runners/model/InitializationError.java index dd9c8b3..841b565 100644 --- a/src/main/java/org/junit/runners/model/InitializationError.java +++ b/src/main/java/org/junit/runners/model/InitializationError.java @@ -14,7 +14,7 @@ public class InitializationError extends Exception { /* * We have to use the f prefix until the next major release to ensure * serialization compatibility. - * See https://github.com/junit-team/junit4/issues/976 + * See https://github.com/junit-team/junit/issues/976 */ private final List fErrors; diff --git a/src/main/java/org/junit/runners/model/InvalidTestClassError.java b/src/main/java/org/junit/runners/model/InvalidTestClassError.java deleted file mode 100644 index 57be610..0000000 --- a/src/main/java/org/junit/runners/model/InvalidTestClassError.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.junit.runners.model; - -import java.util.List; - -/** - * Thrown by {@link org.junit.runner.Runner}s in case the class under test is not valid. - *

        - * Its message conveniently lists all of the validation errors. - * - * @since 4.13 - */ -public class InvalidTestClassError extends InitializationError { - private static final long serialVersionUID = 1L; - - private final String message; - - public InvalidTestClassError(Class offendingTestClass, List validationErrors) { - super(validationErrors); - this.message = createMessage(offendingTestClass, validationErrors); - } - - private static String createMessage(Class testClass, List validationErrors) { - StringBuilder sb = new StringBuilder(); - sb.append(String.format("Invalid test class '%s':", testClass.getName())); - int i = 1; - for (Throwable error : validationErrors) { - sb.append("\n " + (i++) + ". " + error.getMessage()); - } - return sb.toString(); - } - - /** - * @return a message with a list of all of the validation errors - */ - @Override - public String getMessage() { - return message; - } -} diff --git a/src/main/java/org/junit/runners/model/MemberValueConsumer.java b/src/main/java/org/junit/runners/model/MemberValueConsumer.java deleted file mode 100644 index a6157bf..0000000 --- a/src/main/java/org/junit/runners/model/MemberValueConsumer.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.junit.runners.model; - -/** - * Represents a receiver for values of annotated fields/methods together with the declaring member. - * - * @see TestClass#collectAnnotatedFieldValues(Object, Class, Class, MemberValueConsumer) - * @see TestClass#collectAnnotatedMethodValues(Object, Class, Class, MemberValueConsumer) - * @since 4.13 - */ -public interface MemberValueConsumer { - /** - * Receives the next value and its declaring member. - * - * @param member declaring member ({@link FrameworkMethod} or {@link FrameworkField}) - * @param value the value of the next member - */ - void accept(FrameworkMember member, T value); -} diff --git a/src/main/java/org/junit/runners/model/MultipleFailureException.java b/src/main/java/org/junit/runners/model/MultipleFailureException.java index 8e355a7..325c645 100644 --- a/src/main/java/org/junit/runners/model/MultipleFailureException.java +++ b/src/main/java/org/junit/runners/model/MultipleFailureException.java @@ -1,13 +1,9 @@ package org.junit.runners.model; -import java.io.PrintStream; -import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import org.junit.TestCouldNotBeSkippedException; -import org.junit.internal.AssumptionViolatedException; import org.junit.internal.Throwables; /** @@ -21,22 +17,12 @@ public class MultipleFailureException extends Exception { /* * We have to use the f prefix until the next major release to ensure * serialization compatibility. - * See https://github.com/junit-team/junit4/issues/976 + * See https://github.com/junit-team/junit/issues/976 */ private final List fErrors; public MultipleFailureException(List errors) { - if (errors.isEmpty()) { - throw new IllegalArgumentException( - "List of Throwables must not be empty"); - } - this.fErrors = new ArrayList(errors.size()); - for (Throwable error : errors) { - if (error instanceof AssumptionViolatedException) { - error = new TestCouldNotBeSkippedException((AssumptionViolatedException) error); - } - fErrors.add(error); - } + this.fErrors = new ArrayList(errors); } public List getFailures() { @@ -48,32 +34,11 @@ public class MultipleFailureException extends Exception { StringBuilder sb = new StringBuilder( String.format("There were %d errors:", fErrors.size())); for (Throwable e : fErrors) { - sb.append(String.format("%n %s(%s)", e.getClass().getName(), e.getMessage())); + sb.append(String.format("\n %s(%s)", e.getClass().getName(), e.getMessage())); } return sb.toString(); } - @Override - public void printStackTrace() { - for (Throwable e: fErrors) { - e.printStackTrace(); - } - } - - @Override - public void printStackTrace(PrintStream s) { - for (Throwable e: fErrors) { - e.printStackTrace(s); - } - } - - @Override - public void printStackTrace(PrintWriter s) { - for (Throwable e: fErrors) { - e.printStackTrace(s); - } - } - /** * Asserts that a list of throwables is empty. If it isn't empty, * will throw {@link MultipleFailureException} (if there are diff --git a/src/main/java/org/junit/runners/model/RunnerBuilder.java b/src/main/java/org/junit/runners/model/RunnerBuilder.java index ba7c9e2..7d3eee3 100644 --- a/src/main/java/org/junit/runners/model/RunnerBuilder.java +++ b/src/main/java/org/junit/runners/model/RunnerBuilder.java @@ -6,11 +6,7 @@ import java.util.List; 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. @@ -53,39 +49,19 @@ public abstract class RunnerBuilder { public abstract Runner runnerForClass(Class testClass) throws Throwable; /** - * Always returns a runner for the given test class. - * - *

        In case of an exception a runner will be returned that prints an error instead of running - * tests. - * - *

        Note that some of the internal JUnit implementations of RunnerBuilder will return - * {@code null} from this method, but no RunnerBuilder passed to a Runner constructor will - * return {@code null} from this method. + * Always returns a runner, even if it is just one that prints an error instead of running tests. * * @param testClass class to be run * @return a Runner */ public Runner safeRunnerForClass(Class testClass) { try { - Runner runner = runnerForClass(testClass); - if (runner != null) { - configureRunner(runner); - } - return runner; + return runnerForClass(testClass); } 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())); @@ -120,7 +96,7 @@ public abstract class RunnerBuilder { } private List runners(Class[] children) { - List runners = new ArrayList(); + ArrayList runners = new ArrayList(); for (Class each : children) { Runner childRunner = safeRunnerForClass(each); if (childRunner != null) { diff --git a/src/main/java/org/junit/runners/model/TestClass.java b/src/main/java/org/junit/runners/model/TestClass.java old mode 100644 new mode 100755 index 5962c2b..c8a544d --- a/src/main/java/org/junit/runners/model/TestClass.java +++ b/src/main/java/org/junit/runners/model/TestClass.java @@ -84,21 +84,20 @@ public class TestClass implements Annotatable { for (Annotation each : member.getAnnotations()) { Class type = each.annotationType(); List members = getAnnotatedMembers(map, type, true); - T memberToAdd = member.handlePossibleBridgeMethod(members); - if (memberToAdd == null) { + if (member.isShadowedBy(members)) { return; } if (runsTopToBottom(type)) { - members.add(0, memberToAdd); + members.add(0, member); } else { - members.add(memberToAdd); + members.add(member); } } } private static > Map, List> makeDeeplyUnmodifiable(Map, List> source) { - Map, List> copy = + LinkedHashMap, List> copy = new LinkedHashMap, List>(); for (Map.Entry, List> entry : source.entrySet()) { copy.put(entry.getKey(), Collections.unmodifiableList(entry.getValue())); @@ -169,7 +168,7 @@ public class TestClass implements Annotatable { } private static List> getSuperClasses(Class testClass) { - List> results = new ArrayList>(); + ArrayList> results = new ArrayList>(); Class current = testClass; while (current != null) { results.add(current); @@ -225,59 +224,24 @@ public class TestClass implements Annotatable { public List getAnnotatedFieldValues(Object test, Class annotationClass, Class valueClass) { - final List results = new ArrayList(); - collectAnnotatedFieldValues(test, annotationClass, valueClass, - new MemberValueConsumer() { - public void accept(FrameworkMember member, T value) { - results.add(value); - } - }); - return results; - } - - /** - * Finds the fields annotated with the specified annotation and having the specified type, - * retrieves the values and passes those to the specified consumer. - * - * @since 4.13 - */ - public void collectAnnotatedFieldValues(Object test, - Class annotationClass, Class valueClass, - MemberValueConsumer consumer) { + List results = new ArrayList(); for (FrameworkField each : getAnnotatedFields(annotationClass)) { try { Object fieldValue = each.get(test); if (valueClass.isInstance(fieldValue)) { - consumer.accept(each, valueClass.cast(fieldValue)); + results.add(valueClass.cast(fieldValue)); } } catch (IllegalAccessException e) { throw new RuntimeException( "How did getFields return a field we couldn't access?", e); } } + return results; } public List getAnnotatedMethodValues(Object test, Class annotationClass, Class valueClass) { - final List results = new ArrayList(); - collectAnnotatedMethodValues(test, annotationClass, valueClass, - new MemberValueConsumer() { - public void accept(FrameworkMember member, T value) { - results.add(value); - } - }); - return results; - } - - /** - * Finds the methods annotated with the specified annotation and returning the specified type, - * invokes it and pass the return value to the specified consumer. - * - * @since 4.13 - */ - public void collectAnnotatedMethodValues(Object test, - Class annotationClass, Class valueClass, - MemberValueConsumer consumer) { + List results = new ArrayList(); for (FrameworkMethod each : getAnnotatedMethods(annotationClass)) { try { /* @@ -290,13 +254,14 @@ public class TestClass implements Annotatable { */ if (valueClass.isAssignableFrom(each.getReturnType())) { Object fieldValue = each.invokeExplosively(test); - consumer.accept(each, valueClass.cast(fieldValue)); + results.add(valueClass.cast(fieldValue)); } } catch (Throwable e) { throw new RuntimeException( "Exception in " + each.getName(), e); } } + return results; } public boolean isPublic() { diff --git a/src/main/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParameters.java b/src/main/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParameters.java index 5c70a75..1c49f84 100644 --- a/src/main/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParameters.java +++ b/src/main/java/org/junit/runners/parameterized/BlockJUnit4ClassRunnerWithParameters.java @@ -4,12 +4,8 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.util.List; -import org.junit.internal.runners.statements.RunAfters; -import org.junit.internal.runners.statements.RunBefores; -import org.junit.runner.RunWith; import org.junit.runner.notification.RunNotifier; import org.junit.runners.BlockJUnit4ClassRunner; -import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameter; import org.junit.runners.model.FrameworkField; import org.junit.runners.model.FrameworkMethod; @@ -22,17 +18,13 @@ import org.junit.runners.model.Statement; */ public class BlockJUnit4ClassRunnerWithParameters extends BlockJUnit4ClassRunner { - private enum InjectionType { - CONSTRUCTOR, FIELD - } - private final Object[] parameters; private final String name; public BlockJUnit4ClassRunnerWithParameters(TestWithParameters test) throws InitializationError { - super(test.getTestClass()); + super(test.getTestClass().getJavaClass()); parameters = test.getParameters().toArray( new Object[test.getParameters().size()]); name = test.getName(); @@ -40,15 +32,10 @@ public class BlockJUnit4ClassRunnerWithParameters extends @Override public Object createTest() throws Exception { - InjectionType injectionType = getInjectionType(); - switch (injectionType) { - case CONSTRUCTOR: - return createTestUsingConstructorInjection(); - case FIELD: - return createTestUsingFieldInjection(); - default: - throw new IllegalStateException("The injection type " - + injectionType + " is not supported."); + if (fieldsAreAnnotated()) { + return createTestUsingFieldInjection(); + } else { + return createTestUsingConstructorInjection(); } } @@ -73,13 +60,6 @@ public class BlockJUnit4ClassRunnerWithParameters extends int index = annotation.value(); try { field.set(testClassInstance, parameters[index]); - } catch (IllegalAccessException e) { - IllegalAccessException wrappedException = new IllegalAccessException( - "Cannot set parameter '" + field.getName() - + "'. Ensure that the field '" + field.getName() - + "' is public."); - wrappedException.initCause(e); - throw wrappedException; } catch (IllegalArgumentException iare) { throw new Exception(getTestClass().getName() + ": Trying to set " + field.getName() @@ -106,7 +86,7 @@ public class BlockJUnit4ClassRunnerWithParameters extends @Override protected void validateConstructor(List errors) { validateOnlyOneConstructor(errors); - if (getInjectionType() != InjectionType.CONSTRUCTOR) { + if (fieldsAreAnnotated()) { validateZeroArgConstructor(errors); } } @@ -114,7 +94,7 @@ public class BlockJUnit4ClassRunnerWithParameters extends @Override protected void validateFields(List errors) { super.validateFields(errors); - if (getInjectionType() == InjectionType.FIELD) { + if (fieldsAreAnnotated()) { List annotatedFieldsByParameter = getAnnotatedFieldsByParameter(); int[] usedIndices = new int[annotatedFieldsByParameter.size()]; for (FrameworkField each : annotatedFieldsByParameter) { @@ -145,74 +125,18 @@ public class BlockJUnit4ClassRunnerWithParameters extends @Override protected Statement classBlock(RunNotifier notifier) { - Statement statement = childrenInvoker(notifier); - statement = withBeforeParams(statement); - statement = withAfterParams(statement); - return statement; - } - - private Statement withBeforeParams(Statement statement) { - List befores = getTestClass() - .getAnnotatedMethods(Parameterized.BeforeParam.class); - return befores.isEmpty() ? statement : new RunBeforeParams(statement, befores); - } - - private class RunBeforeParams extends RunBefores { - RunBeforeParams(Statement next, List befores) { - super(next, befores, null); - } - - @Override - protected void invokeMethod(FrameworkMethod method) throws Throwable { - int paramCount = method.getMethod().getParameterTypes().length; - method.invokeExplosively(null, paramCount == 0 ? (Object[]) null : parameters); - } - } - - private Statement withAfterParams(Statement statement) { - List afters = getTestClass() - .getAnnotatedMethods(Parameterized.AfterParam.class); - return afters.isEmpty() ? statement : new RunAfterParams(statement, afters); - } - - private class RunAfterParams extends RunAfters { - RunAfterParams(Statement next, List afters) { - super(next, afters, null); - } - - @Override - protected void invokeMethod(FrameworkMethod method) throws Throwable { - int paramCount = method.getMethod().getParameterTypes().length; - method.invokeExplosively(null, paramCount == 0 ? (Object[]) null : parameters); - } + return childrenInvoker(notifier); } @Override protected Annotation[] getRunnerAnnotations() { - Annotation[] allAnnotations = super.getRunnerAnnotations(); - Annotation[] annotationsWithoutRunWith = new Annotation[allAnnotations.length - 1]; - int i = 0; - for (Annotation annotation: allAnnotations) { - if (!annotation.annotationType().equals(RunWith.class)) { - annotationsWithoutRunWith[i] = annotation; - ++i; - } - } - return annotationsWithoutRunWith; + return new Annotation[0]; } private List getAnnotatedFieldsByParameter() { return getTestClass().getAnnotatedFields(Parameter.class); } - private InjectionType getInjectionType() { - if (fieldsAreAnnotated()) { - return InjectionType.FIELD; - } else { - return InjectionType.CONSTRUCTOR; - } - } - private boolean fieldsAreAnnotated() { return !getAnnotatedFieldsByParameter().isEmpty(); } diff --git a/src/main/java/org/junit/runners/parameterized/ParametersRunnerFactory.java b/src/main/java/org/junit/runners/parameterized/ParametersRunnerFactory.java index 8123e83..16ea1f3 100644 --- a/src/main/java/org/junit/runners/parameterized/ParametersRunnerFactory.java +++ b/src/main/java/org/junit/runners/parameterized/ParametersRunnerFactory.java @@ -4,7 +4,7 @@ import org.junit.runner.Runner; import org.junit.runners.model.InitializationError; /** - * A {@code ParametersRunnerFactory} creates a runner for a single + * A {@code ParameterizedRunnerFactory} creates a runner for a single * {@link TestWithParameters}. * * @since 4.12 diff --git a/src/main/java/org/junit/runners/parameterized/TestWithParameters.java b/src/main/java/org/junit/runners/parameterized/TestWithParameters.java index 1c5abd9..1b86644 100644 --- a/src/main/java/org/junit/runners/parameterized/TestWithParameters.java +++ b/src/main/java/org/junit/runners/parameterized/TestWithParameters.java @@ -1,7 +1,6 @@ package org.junit.runners.parameterized; import static java.util.Collections.unmodifiableList; -import static org.junit.internal.Checks.notNull; import java.util.ArrayList; import java.util.List; @@ -74,4 +73,10 @@ public class TestWithParameters { return testClass.getName() + " '" + name + "' with parameters " + parameters; } + + private static void notNull(Object value, String message) { + if (value == null) { + throw new NullPointerException(message); + } + } } diff --git a/src/main/java/org/junit/validator/AnnotationValidatorFactory.java b/src/main/java/org/junit/validator/AnnotationValidatorFactory.java index fb2460d..7309fdd 100644 --- a/src/main/java/org/junit/validator/AnnotationValidatorFactory.java +++ b/src/main/java/org/junit/validator/AnnotationValidatorFactory.java @@ -27,6 +27,9 @@ public class AnnotationValidatorFactory { } Class clazz = validateWithAnnotation.value(); + if (clazz == null) { + throw new IllegalArgumentException("Can't create validator, value is null in annotation " + validateWithAnnotation.getClass().getName()); + } try { AnnotationValidator annotationValidator = clazz.newInstance(); VALIDATORS_FOR_ANNOTATION_TYPES.putIfAbsent(validateWithAnnotation, annotationValidator); diff --git a/src/main/java/org/junit/validator/AnnotationsValidator.java b/src/main/java/org/junit/validator/AnnotationsValidator.java index d8b5840..30f54a6 100644 --- a/src/main/java/org/junit/validator/AnnotationsValidator.java +++ b/src/main/java/org/junit/validator/AnnotationsValidator.java @@ -40,7 +40,7 @@ public final class AnnotationsValidator implements TestClassValidator { return validationErrors; } - private abstract static class AnnotatableValidator { + private static abstract class AnnotatableValidator { private static final AnnotationValidatorFactory ANNOTATION_VALIDATOR_FACTORY = new AnnotationValidatorFactory(); abstract Iterable getAnnotatablesForTestClass(TestClass testClass); @@ -116,5 +116,5 @@ public final class AnnotationsValidator implements TestClassValidator { AnnotationValidator validator, FrameworkField field) { return validator.validateAnnotatedField(field); } - } + }; } diff --git a/src/main/java/org/junit/validator/TestClassValidator.java b/src/main/java/org/junit/validator/TestClassValidator.java index ba5e892..43cb787 100644 --- a/src/main/java/org/junit/validator/TestClassValidator.java +++ b/src/main/java/org/junit/validator/TestClassValidator.java @@ -17,5 +17,5 @@ public interface TestClassValidator { * the {@link TestClass} that is validated. * @return the validation errors found by the validator. */ - List validateTestClass(TestClass testClass); + public List validateTestClass(TestClass testClass); } diff --git a/src/main/java/org/junit/validator/ValidateWith.java b/src/main/java/org/junit/validator/ValidateWith.java index 3725db8..03d7906 100644 --- a/src/main/java/org/junit/validator/ValidateWith.java +++ b/src/main/java/org/junit/validator/ValidateWith.java @@ -1,10 +1,8 @@ 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. @@ -15,7 +13,6 @@ import java.lang.annotation.Target; * @since 4.12 */ @Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.ANNOTATION_TYPE) @Inherited public @interface ValidateWith { Class value(); -- cgit v1.2.3