Skip to content
Snippets Groups Projects
Commit facdecc8 authored by Paul Duffin's avatar Paul Duffin
Browse files

Revert "Revert matchers back to 4.10 to compile against Hamcrest 1.1"

This reverts commit 86f323b2.

Bug: 30946317
Test: make checkbuild
Change-Id: Ie72fec656d01f24a1724d33a35ceecdb57aaba57
parent 7323bf63
No related branches found
No related tags found
No related merge requests found
Showing
with 564 additions and 394 deletions
......@@ -5,5 +5,4 @@ BugComponent: 40416
Local Changes:
Remove DisableOnDebug (new in 4.12) as it is not supported on Android
Remove support for stuck threads
Revert matchers back to 4.10 to compile against Hamcrest 1.1
Extra generic type information to aid certain javacs.
package org.junit;
import static java.util.Arrays.asList;
import static org.hamcrest.CoreMatchers.everyItem;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.CoreMatchers.nullValue;
import org.hamcrest.Matcher;
import org.junit.internal.matchers.Each;
/**
* A set of methods useful for stating assumptions about the conditions in which a test is meaningful.
......@@ -66,13 +66,12 @@ public class Assume {
assumeTrue(message, !b);
}
/**
* If called with one or more null elements in <code>objects</code>, the test will halt and be ignored.
* @param objects
*/
public static void assumeNotNull(Object... objects) {
assumeThat(asList(objects), Each.each(notNullValue()));
}
/**
* If called with one or more null elements in <code>objects</code>, the test will halt and be ignored.
*/
public static void assumeNotNull(Object... objects) {
assumeThat(asList(objects), everyItem(notNullValue()));
}
/**
* Call to assume that <code>actual</code> satisfies the condition specified by <code>matcher</code>.
......
package org.junit.internal.matchers;
import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.CoreMatchers.anyOf;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
public class CombinableMatcher<T> extends BaseMatcher<T> {
private final Matcher<? extends T> fMatcher;
public CombinableMatcher(Matcher<? extends T> matcher) {
fMatcher= matcher;
}
public boolean matches(Object item) {
return fMatcher.matches(item);
}
public void describeTo(Description description) {
description.appendDescriptionOf(fMatcher);
}
@SuppressWarnings("unchecked")
public CombinableMatcher<T> and(Matcher<? extends T> matcher) {
return new CombinableMatcher<T>(allOf(matcher, fMatcher));
}
@SuppressWarnings("unchecked")
public CombinableMatcher<T> or(Matcher<? extends T> matcher) {
return new CombinableMatcher<T>(anyOf(matcher, fMatcher));
}
}
\ No newline at end of file
package org.junit.internal.matchers;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.internal.matchers.IsCollectionContaining.hasItem;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
public class Each {
public static <T> Matcher<Iterable<T>> each(final Matcher<T> individual) {
final Matcher<Iterable<T>> allItemsAre = not(hasItem(not(individual)));
return new BaseMatcher<Iterable<T>>() {
public boolean matches(Object item) {
return allItemsAre.matches(item);
}
public void describeTo(Description description) {
description.appendText("each ");
individual.describeTo(description);
}
};
}
}
package org.junit.internal.matchers;
import static org.hamcrest.core.AllOf.allOf;
import static org.hamcrest.core.IsEqual.equalTo;
import java.util.ArrayList;
import java.util.Collection;
import org.hamcrest.Description;
import org.hamcrest.Factory;
import org.hamcrest.Matcher;
// Copied (hopefully temporarily) from hamcrest-library
public class IsCollectionContaining<T> extends TypeSafeMatcher<Iterable<T>> {
private final Matcher<? extends T> elementMatcher;
public IsCollectionContaining(Matcher<? extends T> elementMatcher) {
this.elementMatcher = elementMatcher;
}
@Override
public boolean matchesSafely(Iterable<T> collection) {
for (T item : collection) {
if (elementMatcher.matches(item)){
return true;
}
}
return false;
}
public void describeTo(Description description) {
description
.appendText("a collection containing ")
.appendDescriptionOf(elementMatcher);
}
@Factory
public static <T> Matcher<Iterable<T>> hasItem(Matcher<? extends T> elementMatcher) {
return new IsCollectionContaining<T>(elementMatcher);
}
@Factory
public static <T> Matcher<Iterable<T>> hasItem(T element) {
return hasItem(equalTo(element));
}
@Factory
public static <T> Matcher<Iterable<T>> hasItems(Matcher<? extends T>... elementMatchers) {
Collection<Matcher<? extends Iterable<T>>> all
= new ArrayList<Matcher<? extends Iterable<T>>>(elementMatchers.length);
for (Matcher<? extends T> elementMatcher : elementMatchers) {
all.add(hasItem(elementMatcher));
}
return allOf(all);
}
@Factory
public static <T> Matcher<Iterable<T>> hasItems(T... elements) {
Collection<Matcher<? extends Iterable<T>>> all
= new ArrayList<Matcher<? extends Iterable<T>>>(elements.length);
for (T element : elements) {
all.add(hasItem(element));
}
return allOf(all);
}
}
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;
/**
* A matcher that delegates to throwableMatcher and in addition appends the
* stacktrace of the actual Throwable in case of a mismatch.
*/
public class StacktracePrintingMatcher<T extends Throwable> extends
org.hamcrest.TypeSafeMatcher<T> {
private final Matcher<T> throwableMatcher;
public StacktracePrintingMatcher(Matcher<T> throwableMatcher) {
this.throwableMatcher = throwableMatcher;
}
public void describeTo(Description description) {
throwableMatcher.describeTo(description);
}
@Override
protected boolean matchesSafely(T item) {
return throwableMatcher.matches(item);
}
@Override
protected void describeMismatchSafely(T item, Description description) {
throwableMatcher.describeMismatch(item, description);
description.appendText("\nStacktrace was: ");
description.appendText(readStacktrace(item));
}
private String readStacktrace(Throwable throwable) {
StringWriter stringWriter = new StringWriter();
throwable.printStackTrace(new PrintWriter(stringWriter));
return stringWriter.toString();
}
@Factory
public static <T extends Throwable> Matcher<T> isThrowable(
Matcher<T> throwableMatcher) {
return new StacktracePrintingMatcher<T>(throwableMatcher);
}
@Factory
public static <T extends Exception> Matcher<T> isException(
Matcher<T> exceptionMatcher) {
return new StacktracePrintingMatcher<T>(exceptionMatcher);
}
}
/* Copyright (c) 2000-2006 hamcrest.org
*/
package org.junit.internal.matchers;
import org.hamcrest.Factory;
import org.hamcrest.Matcher;
/**
* Tests if the argument is a string that contains a substring.
*/
public class StringContains extends SubstringMatcher {
public StringContains(String substring) {
super(substring);
}
@Override
protected boolean evalSubstringOf(String s) {
return s.indexOf(substring) >= 0;
}
@Override
protected String relationship() {
return "containing";
}
@Factory
public static Matcher<String> containsString(String substring) {
return new StringContains(substring);
}
}
\ No newline at end of file
package org.junit.internal.matchers;
import org.hamcrest.Description;
public abstract class SubstringMatcher extends TypeSafeMatcher<String> {
protected final String substring;
protected SubstringMatcher(final String substring) {
this.substring = substring;
}
@Override
public boolean matchesSafely(String item) {
return evalSubstringOf(item);
}
public void describeTo(Description description) {
description.appendText("a string ")
.appendText(relationship())
.appendText(" ")
.appendValue(substring);
}
protected abstract boolean evalSubstringOf(String string);
protected abstract String relationship();
}
\ No newline at end of file
package org.junit.internal.matchers;
import org.hamcrest.Description;
import org.hamcrest.Factory;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
/**
* A matcher that applies a delegate matcher to the cause of the current Throwable, returning the result of that
* match.
*
* @param <T> the type of the throwable being matched
*/
public class ThrowableCauseMatcher<T extends Throwable> extends
TypeSafeMatcher<T> {
private final Matcher<? extends Throwable> causeMatcher;
public ThrowableCauseMatcher(Matcher<? extends Throwable> causeMatcher) {
this.causeMatcher = causeMatcher;
}
public void describeTo(Description description) {
description.appendText("exception with cause ");
description.appendDescriptionOf(causeMatcher);
}
@Override
protected boolean matchesSafely(T item) {
return causeMatcher.matches(item.getCause());
}
@Override
protected void describeMismatchSafely(T item, Description description) {
description.appendText("cause ");
causeMatcher.describeMismatch(item.getCause(), description);
}
/**
* Returns a matcher that verifies that the outer exception has a cause for which the supplied matcher
* evaluates to true.
*
* @param matcher to apply to the cause of the outer exception
* @param <T> type of the outer exception
*/
@Factory
public static <T extends Throwable> Matcher<T> hasCause(final Matcher<? extends Throwable> matcher) {
return new ThrowableCauseMatcher<T>(matcher);
}
}
\ No newline at end of file
package org.junit.internal.matchers;
import org.hamcrest.Description;
import org.hamcrest.Factory;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
public class ThrowableMessageMatcher<T extends Throwable> extends
TypeSafeMatcher<T> {
private final Matcher<String> matcher;
public ThrowableMessageMatcher(Matcher<String> matcher) {
this.matcher = matcher;
}
public void describeTo(Description description) {
description.appendText("exception with message ");
description.appendDescriptionOf(matcher);
}
@Override
protected boolean matchesSafely(T item) {
return matcher.matches(item.getMessage());
}
@Override
protected void describeMismatchSafely(T item, Description description) {
description.appendText("message ");
matcher.describeMismatch(item.getMessage(), description);
}
@Factory
public static <T extends Throwable> Matcher<T> hasMessage(final Matcher<String> matcher) {
return new ThrowableMessageMatcher<T>(matcher);
}
}
\ No newline at end of file
......@@ -3,13 +3,16 @@ package org.junit.internal.matchers;
import java.lang.reflect.Method;
import org.hamcrest.BaseMatcher;
import org.junit.internal.MethodSorter;
/**
* Convenient base class for Matchers that require a non-null value of a specific type.
* This simply implements the null check, checks the type and then casts.
*
* @author Joe Walnes
* @deprecated Please use {@link org.hamcrest.TypeSafeMatcher}.
*/
@Deprecated
public abstract class TypeSafeMatcher<T> extends BaseMatcher<T> {
private Class<?> expectedType;
......@@ -23,27 +26,27 @@ public abstract class TypeSafeMatcher<T> extends BaseMatcher<T> {
protected TypeSafeMatcher() {
expectedType = findExpectedType(getClass());
}
private static Class<?> findExpectedType(Class<?> fromClass) {
for (Class<?> c = fromClass; c != Object.class; c = c.getSuperclass()) {
for (Method method : c.getDeclaredMethods()) {
for (Method method : MethodSorter.getDeclaredMethods(c)) {
if (isMatchesSafelyMethod(method)) {
return method.getParameterTypes()[0];
}
}
}
throw new Error("Cannot determine correct type for matchesSafely() method.");
}
private static boolean isMatchesSafelyMethod(Method method) {
return method.getName().equals("matchesSafely")
&& method.getParameterTypes().length == 1
&& !method.isSynthetic();
return method.getName().equals("matchesSafely")
&& method.getParameterTypes().length == 1
&& !method.isSynthetic();
}
protected TypeSafeMatcher(Class<T> expectedType) {
this.expectedType = expectedType;
this.expectedType = expectedType;
}
/**
......
package org.junit.matchers;
import org.hamcrest.CoreMatchers;
import org.hamcrest.Matcher;
import org.junit.internal.matchers.CombinableMatcher;
import org.junit.internal.matchers.Each;
import org.junit.internal.matchers.IsCollectionContaining;
import org.junit.internal.matchers.StringContains;
import org.hamcrest.core.CombinableMatcher.CombinableBothMatcher;
import org.hamcrest.core.CombinableMatcher.CombinableEitherMatcher;
import org.junit.internal.matchers.StacktracePrintingMatcher;
/**
* Convenience import class: these are useful matchers for use with the assertThat method, but they are
* not currently included in the basic CoreMatchers class from hamcrest.
*
* @since 4.4
*/
public class JUnitMatchers {
/**
* @param element
* @return A matcher matching any collection containing element
*/
public static <T> org.hamcrest.Matcher<java.lang.Iterable<T>> hasItem(T element) {
return IsCollectionContaining.hasItem(element);
}
/**
* @return A matcher matching any collection containing element
* @deprecated Please use {@link CoreMatchers#hasItem(Object)} instead.
*/
@Deprecated
public static <T> Matcher<Iterable<? super T>> hasItem(T element) {
return CoreMatchers.hasItem(element);
}
/**
* @param elementMatcher
* @return A matcher matching any collection containing an element matching elementMatcher
*/
public static <T> org.hamcrest.Matcher<java.lang.Iterable<T>> hasItem(org.hamcrest.Matcher<? extends T> elementMatcher) {
return IsCollectionContaining.<T>hasItem(elementMatcher);
}
/**
* @return A matcher matching any collection containing an element matching elementMatcher
* @deprecated Please use {@link CoreMatchers#hasItem(Matcher)} instead.
*/
@Deprecated
public static <T> Matcher<Iterable<? super T>> hasItem(Matcher<? super T> elementMatcher) {
return CoreMatchers.<T>hasItem(elementMatcher);
}
/**
* @param elements
* @return A matcher matching any collection containing every element in elements
*/
public static <T> org.hamcrest.Matcher<java.lang.Iterable<T>> hasItems(T... elements) {
return IsCollectionContaining.hasItems(elements);
}
/**
* @return A matcher matching any collection containing every element in elements
* @deprecated Please use {@link CoreMatchers#hasItems(Object...)} instead.
*/
@Deprecated
public static <T> Matcher<Iterable<T>> hasItems(T... elements) {
return CoreMatchers.hasItems(elements);
}
/**
* @param elementMatchers
* @return A matcher matching any collection containing at least one element that matches
* each matcher in elementMatcher (this may be one element matching all matchers,
* or different elements matching each matcher)
*/
public static <T> org.hamcrest.Matcher<java.lang.Iterable<T>> hasItems(org.hamcrest.Matcher<? extends T>... elementMatchers) {
return IsCollectionContaining.<T>hasItems(elementMatchers);
}
/**
* @return A matcher matching any collection containing at least one element that matches
* each matcher in elementMatcher (this may be one element matching all matchers,
* or different elements matching each matcher)
* @deprecated Please use {@link CoreMatchers#hasItems(Matcher...)} instead.
*/
@Deprecated
public static <T> Matcher<Iterable<T>> hasItems(Matcher<? super T>... elementMatchers) {
return CoreMatchers.hasItems(elementMatchers);
}
/**
* @param elementMatcher
* @return A matcher matching any collection in which every element matches elementMatcher
*/
public static <T> Matcher<Iterable<T>> everyItem(final Matcher<T> elementMatcher) {
return Each.each(elementMatcher);
}
/**
* @return A matcher matching any collection in which every element matches elementMatcher
* @deprecated Please use {@link CoreMatchers#everyItem(Matcher)} instead.
*/
@Deprecated
public static <T> Matcher<Iterable<T>> everyItem(final Matcher<T> elementMatcher) {
return CoreMatchers.everyItem(elementMatcher);
}
/**
* @param substring
* @return a matcher matching any string that contains substring
*/
public static org.hamcrest.Matcher<java.lang.String> containsString(java.lang.String substring) {
return StringContains.containsString(substring);
}
/**
* This is useful for fluently combining matchers that must both pass. For example:
* <pre>
* assertThat(string, both(containsString("a")).and(containsString("b")));
* </pre>
*/
public static <T> CombinableMatcher<T> both(Matcher<T> matcher) {
return new CombinableMatcher<T>(matcher);
}
/**
* This is useful for fluently combining matchers where either may pass, for example:
* <pre>
* assertThat(string, either(containsString("a")).or(containsString("b")));
* </pre>
*/
public static <T> CombinableMatcher<T> either(Matcher<T> matcher) {
return new CombinableMatcher<T>(matcher);
}
/**
* @return a matcher matching any string that contains substring
* @deprecated Please use {@link CoreMatchers#containsString(String)} instead.
*/
@Deprecated
public static Matcher<java.lang.String> containsString(java.lang.String substring) {
return CoreMatchers.containsString(substring);
}
/**
* This is useful for fluently combining matchers that must both pass. For example:
* <pre>
* assertThat(string, both(containsString("a")).and(containsString("b")));
* </pre>
*
* @deprecated Please use {@link CoreMatchers#both(Matcher)} instead.
*/
@Deprecated
public static <T> CombinableBothMatcher<T> both(Matcher<? super T> matcher) {
return CoreMatchers.both(matcher);
}
/**
* This is useful for fluently combining matchers where either may pass, for example:
* <pre>
* assertThat(string, either(containsString("a")).or(containsString("b")));
* </pre>
*
* @deprecated Please use {@link CoreMatchers#either(Matcher)} instead.
*/
@Deprecated
public static <T> CombinableEitherMatcher<T> either(Matcher<? super T> matcher) {
return CoreMatchers.either(matcher);
}
/**
* @return A matcher that delegates to throwableMatcher and in addition
* appends the stacktrace of the actual Throwable in case of a mismatch.
*/
public static <T extends Throwable> Matcher<T> isThrowable(Matcher<T> throwableMatcher) {
return StacktracePrintingMatcher.isThrowable(throwableMatcher);
}
/**
* @return A matcher that delegates to exceptionMatcher and in addition
* appends the stacktrace of the actual Exception in case of a mismatch.
*/
public static <T extends Exception> Matcher<T> isException(Matcher<T> exceptionMatcher) {
return StacktracePrintingMatcher.isException(exceptionMatcher);
}
}
package org.junit.rules;
import static java.lang.String.format;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.junit.matchers.JUnitMatchers.both;
import static org.junit.matchers.JUnitMatchers.containsString;
import org.hamcrest.Description;
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.Assert;
import org.junit.internal.matchers.TypeSafeMatcher;
import org.junit.AssumptionViolatedException;
import org.junit.runners.model.Statement;
/**
* The ExpectedException Rule allows in-test specification of expected exception
* types and messages:
*
* <pre>
* // These tests all pass.
* public static class HasExpectedException {
* &#064;Rule
* public ExpectedException thrown= ExpectedException.none();
*
* &#064;Test
* public void throwsNothing() {
* // no exception expected, none thrown: passes.
* }
* The {@code ExpectedException} rule allows you to verify that your code
* throws a specific exception.
*
* <h3>Usage</h3>
*
* <pre> public class SimpleExpectedExceptionTest {
* &#064;Rule
* public ExpectedException thrown= ExpectedException.none();
*
* &#064;Test
* public void throwsNothing() {
* // no exception expected, none thrown: passes.
* }
*
* &#064;Test
* public void throwsExceptionWithSpecificType() {
* thrown.expect(NullPointerException.class);
* throw new NullPointerException();
* }
* }</pre>
*
* &#064;Test
* public void throwsNullPointerException() {
* thrown.expect(NullPointerException.class);
* throw new NullPointerException();
* }
*
* &#064;Test
* public void throwsNullPointerExceptionWithMessage() {
* thrown.expect(NullPointerException.class);
* thrown.expectMessage(&quot;happened?&quot;);
* thrown.expectMessage(startsWith(&quot;What&quot;));
* throw new NullPointerException(&quot;What happened?&quot;);
* }
* }
* </pre>
* <p>
* You have to add the {@code ExpectedException} rule to your test.
* This doesn't affect your existing tests (see {@code throwsNothing()}).
* 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.
*
* <p>
* Instead of specifying the exception's type you can characterize the
* expected exception based on other criterias, too:
*
* <ul>
* <li>The exception's message contains a specific text: {@link #expectMessage(String)}</li>
* <li>The exception's message complies with a Hamcrest matcher: {@link #expectMessage(Matcher)}</li>
* <li>The exception's cause complies with a Hamcrest matcher: {@link #expectCause(Matcher)}</li>
* <li>The exception itself complies with a Hamcrest matcher: {@link #expect(Matcher)}</li>
* </ul>
*
* <p>
* You can combine any of the presented expect-methods. The test is
* successful if all specifications are met.
* <pre> &#064;Test
* public void throwsException() {
* thrown.expect(NullPointerException.class);
* thrown.expectMessage(&quot;happened&quot;);
* throw new NullPointerException(&quot;What happened?&quot;);
* }</pre>
*
* <h3>AssumptionViolatedExceptions</h3>
* <p>
* 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
* will not handle consume the exceptions and it can be handled by the
* framework. E.g. the following test is ignored by JUnit's default runner.
*
* <pre> &#064;Test
* public void ignoredBecauseOfFailedAssumption() {
* assumeTrue(false); // throws AssumptionViolatedException
* thrown.expect(NullPointerException.class);
* }</pre>
*
* <h3>AssertionErrors</h3>
*
* <p>
* 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.
*
* <pre> &#064;Test
* public void throwsUnhandled() {
* assertTrue(false); // throws AssertionError
* thrown.expect(NullPointerException.class);
* }</pre>
*
* <h3>Missing Exceptions</h3>
* <p>
* 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
* exception. E.g. "Test doesn't throw %s." will fail with the error message
* "Test doesn't throw an instance of foo.".
*
* @since 4.7
*/
public class ExpectedException implements TestRule {
/**
* @return a Rule that expects no exception to be thrown
* (identical to behavior without this Rule)
*/
public static ExpectedException none() {
return new ExpectedException();
}
private Matcher<Object> fMatcher= null;
private ExpectedException() {
}
public Statement apply(Statement base,
org.junit.runner.Description description) {
return new ExpectedExceptionStatement(base);
}
/**
* Adds {@code matcher} to the list of requirements for any thrown exception.
*/
// Should be able to remove this suppression in some brave new hamcrest world.
@SuppressWarnings("unchecked")
public void expect(Matcher<?> matcher) {
if (fMatcher == null)
fMatcher= (Matcher<Object>) matcher;
else
fMatcher= both(fMatcher).and(matcher);
}
/**
* Adds to the list of requirements for any thrown exception that it
* should be an instance of {@code type}
*/
public void expect(Class<? extends Throwable> type) {
expect(instanceOf(type));
}
/**
* Adds to the list of requirements for any thrown exception that it
* should <em>contain</em> string {@code substring}
*/
public void expectMessage(String substring) {
expectMessage(containsString(substring));
}
/**
* Adds {@code matcher} to the list of requirements for the message
* returned from any thrown exception.
*/
public void expectMessage(Matcher<String> matcher) {
expect(hasMessage(matcher));
}
private class ExpectedExceptionStatement extends Statement {
private final Statement fNext;
public ExpectedExceptionStatement(Statement base) {
fNext= base;
}
@Override
public void evaluate() throws Throwable {
try {
fNext.evaluate();
} catch (Throwable e) {
if (fMatcher == null)
throw e;
Assert.assertThat(e, fMatcher);
return;
}
if (fMatcher != null)
throw new AssertionError("Expected test to throw "
+ StringDescription.toString(fMatcher));
}
}
private Matcher<Throwable> hasMessage(final Matcher<String> matcher) {
return new TypeSafeMatcher<Throwable>() {
public void describeTo(Description description) {
description.appendText("exception with message ");
description.appendDescriptionOf(matcher);
}
@Override
public boolean matchesSafely(Throwable item) {
return matcher.matches(item.getMessage());
}
};
}
/**
* Returns a {@linkplain TestRule rule} that expects no exception to
* be thrown (identical to behavior without this rule).
*/
public static ExpectedException none() {
return new ExpectedException();
}
private final ExpectedExceptionMatcherBuilder matcherBuilder = new ExpectedExceptionMatcherBuilder();
private String missingExceptionMessage= "Expected test to throw %s";
private ExpectedException() {
}
/**
* This method does nothing. Don't use it.
* @deprecated AssertionErrors are handled by default since JUnit 4.12. Just
* like in JUnit &lt;= 4.10.
*/
@Deprecated
public ExpectedException handleAssertionErrors() {
return this;
}
/**
* This method does nothing. Don't use it.
* @deprecated AssumptionViolatedExceptions are handled by default since
* JUnit 4.12. Just like in JUnit &lt;= 4.10.
*/
@Deprecated
public ExpectedException handleAssumptionViolatedExceptions() {
return this;
}
/**
* Specifies the failure message for tests that are expected to throw
* an exception but do not throw any. You can use a {@code %s} placeholder for
* the description of the expected exception. E.g. "Test doesn't throw %s."
* will fail with the error message
* "Test doesn't throw an instance of foo.".
*
* @param message exception detail message
* @return the rule itself
*/
public ExpectedException reportMissingExceptionWithMessage(String message) {
missingExceptionMessage = message;
return this;
}
public Statement apply(Statement base,
org.junit.runner.Description description) {
return new ExpectedExceptionStatement(base);
}
/**
* Verify that your code throws an exception that is matched by
* a Hamcrest matcher.
* <pre> &#064;Test
* public void throwsExceptionThatCompliesWithMatcher() {
* NullPointerException e = new NullPointerException();
* thrown.expect(is(e));
* throw e;
* }</pre>
*/
public void expect(Matcher<?> matcher) {
matcherBuilder.add(matcher);
}
/**
* Verify that your code throws an exception that is an
* instance of specific {@code type}.
* <pre> &#064;Test
* public void throwsExceptionWithSpecificType() {
* thrown.expect(NullPointerException.class);
* throw new NullPointerException();
* }</pre>
*/
public void expect(Class<? extends Throwable> type) {
expect(instanceOf(type));
}
/**
* Verify that your code throws an exception whose message contains
* a specific text.
* <pre> &#064;Test
* public void throwsExceptionWhoseMessageContainsSpecificText() {
* thrown.expectMessage(&quot;happened&quot;);
* throw new NullPointerException(&quot;What happened?&quot;);
* }</pre>
*/
public void expectMessage(String substring) {
expectMessage(containsString(substring));
}
/**
* Verify that your code throws an exception whose message is matched
* by a Hamcrest matcher.
* <pre> &#064;Test
* public void throwsExceptionWhoseMessageCompliesWithMatcher() {
* thrown.expectMessage(startsWith(&quot;What&quot;));
* throw new NullPointerException(&quot;What happened?&quot;);
* }</pre>
*/
public void expectMessage(Matcher<String> matcher) {
expect(hasMessage(matcher));
}
/**
* Verify that your code throws an exception whose cause is matched by
* a Hamcrest matcher.
* <pre> &#064;Test
* public void throwsExceptionWhoseCauseCompliesWithMatcher() {
* NullPointerException expectedCause = new NullPointerException();
* thrown.expectCause(is(expectedCause));
* throw new IllegalArgumentException(&quot;What happened?&quot;, cause);
* }</pre>
*/
public void expectCause(Matcher<? extends Throwable> expectedCause) {
expect(hasCause(expectedCause));
}
private class ExpectedExceptionStatement extends Statement {
private final Statement next;
public ExpectedExceptionStatement(Statement base) {
next = base;
}
@Override
public void evaluate() throws Throwable {
try {
next.evaluate();
} catch (Throwable e) {
handleException(e);
return;
}
if (isAnyExceptionExpected()) {
failDueToMissingException();
}
}
}
private void handleException(Throwable e) throws Throwable {
if (isAnyExceptionExpected()) {
assertThat(e, matcherBuilder.build());
} else {
throw e;
}
}
private boolean isAnyExceptionExpected() {
return matcherBuilder.expectsThrowable();
}
private void failDueToMissingException() throws AssertionError {
fail(missingExceptionMessage());
}
private String missingExceptionMessage() {
String expectation= StringDescription.toString(matcherBuilder.build());
return format(missingExceptionMessage, expectation);
}
}
package org.junit.rules;
import static org.hamcrest.CoreMatchers.allOf;
import static org.junit.matchers.JUnitMatchers.isThrowable;
import java.util.ArrayList;
import java.util.List;
import org.hamcrest.Matcher;
/**
* Builds special matcher used by {@link ExpectedException}.
*/
class ExpectedExceptionMatcherBuilder {
private final List<Matcher<?>> matchers = new ArrayList<Matcher<?>>();
void add(Matcher<?> matcher) {
matchers.add(matcher);
}
boolean expectsThrowable() {
return !matchers.isEmpty();
}
Matcher<Throwable> build() {
return isThrowable(allOfTheMatchers());
}
private Matcher<Throwable> allOfTheMatchers() {
if (matchers.size() == 1) {
return cast(matchers.get(0));
}
return allOf(castedMatchers());
}
@SuppressWarnings({"unchecked", "rawtypes"})
private List<Matcher<? super Throwable>> castedMatchers() {
return new ArrayList<Matcher<? super Throwable>>((List) matchers);
}
@SuppressWarnings("unchecked")
private Matcher<Throwable> cast(Matcher<?> singleMatcher) {
return (Matcher<Throwable>) singleMatcher;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment