diff options
Diffstat (limited to 'src')
-rwxr-xr-x[-rw-r--r--] | src/main/java/org/junit/Assert.java | 1701 | ||||
-rw-r--r-- | src/main/java/org/junit/internal/runners/rules/RuleMemberValidator.java | 91 | ||||
-rw-r--r-- | src/main/java/org/junit/runner/Description.java | 522 | ||||
-rw-r--r-- | src/main/java/org/junit/runners/BlockJUnit4ClassRunner.java | 2 |
4 files changed, 1328 insertions, 988 deletions
diff --git a/src/main/java/org/junit/Assert.java b/src/main/java/org/junit/Assert.java index b585b87..d7deb06 100644..100755 --- a/src/main/java/org/junit/Assert.java +++ b/src/main/java/org/junit/Assert.java @@ -1,8 +1,7 @@ package org.junit; -import org.hamcrest.Description; import org.hamcrest.Matcher; -import org.hamcrest.StringDescription; +import org.hamcrest.MatcherAssert; import org.junit.internal.ArrayComparisonFailure; import org.junit.internal.ExactComparisonCriteria; import org.junit.internal.InexactComparisonCriteria; @@ -11,773 +10,949 @@ import org.junit.internal.InexactComparisonCriteria; * A set of assertion methods useful for writing tests. Only failed assertions * are recorded. These methods can be used directly: * <code>Assert.assertEquals(...)</code>, however, they read better if they - * are referenced through static import:<br/> - * + * are referenced through static import: + * * <pre> * import static org.junit.Assert.*; * ... * assertEquals(...); * </pre> - * + * * @see AssertionError + * @since 4.0 */ public class Assert { - /** - * Protect constructor since it is a static only class - */ - protected Assert() { - } - - /** - * Asserts that a condition is true. If it isn't it throws an - * {@link AssertionError} with the given message. - * - * @param message - * the identifying message for the {@link AssertionError} (<code>null</code> - * okay) - * @param condition - * condition to be checked - */ - static public void assertTrue(String message, boolean condition) { - if (!condition) - fail(message); - } - - /** - * Asserts that a condition is true. If it isn't it throws an - * {@link AssertionError} without a message. - * - * @param condition - * condition to be checked - */ - static public void assertTrue(boolean condition) { - assertTrue(null, condition); - } - - /** - * Asserts that a condition is false. If it isn't it throws an - * {@link AssertionError} with the given message. - * - * @param message - * the identifying message for the {@link AssertionError} (<code>null</code> - * okay) - * @param condition - * condition to be checked - */ - static public void assertFalse(String message, boolean condition) { - assertTrue(message, !condition); - } - - /** - * Asserts that a condition is false. If it isn't it throws an - * {@link AssertionError} without a message. - * - * @param condition - * condition to be checked - */ - static public void assertFalse(boolean condition) { - assertFalse(null, condition); - } - - /** - * Fails a test with the given message. - * - * @param message - * the identifying message for the {@link AssertionError} (<code>null</code> - * okay) - * @see AssertionError - */ - static public void fail(String message) { - if (message == null) - throw new AssertionError(); - throw new AssertionError(message); - } - - /** - * Fails a test with no message. - */ - static public void fail() { - fail(null); - } - - /** - * Asserts that two objects are equal. If they are not, an - * {@link AssertionError} is thrown with the given message. If - * <code>expected</code> and <code>actual</code> are <code>null</code>, - * they are considered equal. - * - * @param message - * the identifying message for the {@link AssertionError} (<code>null</code> - * okay) - * @param expected - * expected value - * @param actual - * actual value - */ - static public void assertEquals(String message, Object expected, - Object actual) { - if (expected == null && actual == null) - return; - if (expected != null && isEquals(expected, actual)) - return; - else if (expected instanceof String && actual instanceof String) { - String cleanMessage= message == null ? "" : message; - throw new ComparisonFailure(cleanMessage, (String) expected, - (String) actual); - } else - failNotEquals(message, expected, actual); - } - - private static boolean isEquals(Object expected, Object actual) { - return expected.equals(actual); - } - - /** - * Asserts that two objects are equal. If they are not, an - * {@link AssertionError} without a message is thrown. If - * <code>expected</code> and <code>actual</code> are <code>null</code>, - * they are considered equal. - * - * @param expected - * expected value - * @param actual - * the value to check against <code>expected</code> - */ - static public void assertEquals(Object expected, Object actual) { - assertEquals(null, expected, actual); - } - - /** - * Asserts that two object arrays are equal. If they are not, an - * {@link AssertionError} is thrown with the given message. If - * <code>expecteds</code> and <code>actuals</code> are <code>null</code>, - * they are considered equal. - * - * @param message - * the identifying message for the {@link AssertionError} (<code>null</code> - * okay) - * @param expecteds - * Object array or array of arrays (multi-dimensional array) with - * expected values. - * @param actuals - * Object array or array of arrays (multi-dimensional array) with - * actual values - */ - public static void assertArrayEquals(String message, Object[] expecteds, - Object[] actuals) throws ArrayComparisonFailure { - internalArrayEquals(message, expecteds, actuals); - } - - /** - * Asserts that two object arrays are equal. If they are not, an - * {@link AssertionError} is thrown. If <code>expected</code> and - * <code>actual</code> are <code>null</code>, they are considered - * equal. - * - * @param expecteds - * Object array or array of arrays (multi-dimensional array) with - * expected values - * @param actuals - * Object array or array of arrays (multi-dimensional array) with - * actual values - */ - public static void assertArrayEquals(Object[] expecteds, Object[] actuals) { - assertArrayEquals(null, expecteds, actuals); - } - - /** - * Asserts that two byte arrays are equal. If they are not, an - * {@link AssertionError} is thrown with the given message. - * - * @param message - * the identifying message for the {@link AssertionError} (<code>null</code> - * okay) - * @param expecteds - * byte array with expected values. - * @param actuals - * byte array with actual values - */ - public static void assertArrayEquals(String message, byte[] expecteds, - byte[] actuals) throws ArrayComparisonFailure { - internalArrayEquals(message, expecteds, actuals); - } - - /** - * Asserts that two byte arrays are equal. If they are not, an - * {@link AssertionError} is thrown. - * - * @param expecteds - * byte array with expected values. - * @param actuals - * byte array with actual values - */ - public static void assertArrayEquals(byte[] expecteds, byte[] actuals) { - assertArrayEquals(null, expecteds, actuals); - } - - /** - * Asserts that two char arrays are equal. If they are not, an - * {@link AssertionError} is thrown with the given message. - * - * @param message - * the identifying message for the {@link AssertionError} (<code>null</code> - * okay) - * @param expecteds - * char array with expected values. - * @param actuals - * char array with actual values - */ - public static void assertArrayEquals(String message, char[] expecteds, - char[] actuals) throws ArrayComparisonFailure { - internalArrayEquals(message, expecteds, actuals); - } - - /** - * Asserts that two char arrays are equal. If they are not, an - * {@link AssertionError} is thrown. - * - * @param expecteds - * char array with expected values. - * @param actuals - * char array with actual values - */ - public static void assertArrayEquals(char[] expecteds, char[] actuals) { - assertArrayEquals(null, expecteds, actuals); - } - - /** - * Asserts that two short arrays are equal. If they are not, an - * {@link AssertionError} is thrown with the given message. - * - * @param message - * the identifying message for the {@link AssertionError} (<code>null</code> - * okay) - * @param expecteds - * short array with expected values. - * @param actuals - * short array with actual values - */ - public static void assertArrayEquals(String message, short[] expecteds, - short[] actuals) throws ArrayComparisonFailure { - internalArrayEquals(message, expecteds, actuals); - } - - /** - * Asserts that two short arrays are equal. If they are not, an - * {@link AssertionError} is thrown. - * - * @param expecteds - * short array with expected values. - * @param actuals - * short array with actual values - */ - public static void assertArrayEquals(short[] expecteds, short[] actuals) { - assertArrayEquals(null, expecteds, actuals); - } - - /** - * Asserts that two int arrays are equal. If they are not, an - * {@link AssertionError} is thrown with the given message. - * - * @param message - * the identifying message for the {@link AssertionError} (<code>null</code> - * okay) - * @param expecteds - * int array with expected values. - * @param actuals - * int array with actual values - */ - public static void assertArrayEquals(String message, int[] expecteds, - int[] actuals) throws ArrayComparisonFailure { - internalArrayEquals(message, expecteds, actuals); - } - - /** - * Asserts that two int arrays are equal. If they are not, an - * {@link AssertionError} is thrown. - * - * @param expecteds - * int array with expected values. - * @param actuals - * int array with actual values - */ - public static void assertArrayEquals(int[] expecteds, int[] actuals) { - assertArrayEquals(null, expecteds, actuals); - } - - /** - * Asserts that two long arrays are equal. If they are not, an - * {@link AssertionError} is thrown with the given message. - * - * @param message - * the identifying message for the {@link AssertionError} (<code>null</code> - * okay) - * @param expecteds - * long array with expected values. - * @param actuals - * long array with actual values - */ - public static void assertArrayEquals(String message, long[] expecteds, - long[] actuals) throws ArrayComparisonFailure { - internalArrayEquals(message, expecteds, actuals); - } - - /** - * Asserts that two long arrays are equal. If they are not, an - * {@link AssertionError} is thrown. - * - * @param expecteds - * long array with expected values. - * @param actuals - * long array with actual values - */ - public static void assertArrayEquals(long[] expecteds, long[] actuals) { - assertArrayEquals(null, expecteds, actuals); - } - - /** - * Asserts that two double arrays are equal. If they are not, an - * {@link AssertionError} is thrown with the given message. - * - * @param message - * the identifying message for the {@link AssertionError} (<code>null</code> - * okay) - * @param expecteds - * double array with expected values. - * @param actuals - * double array with actual values - */ - public static void assertArrayEquals(String message, double[] expecteds, - double[] actuals, double delta) throws ArrayComparisonFailure { - new InexactComparisonCriteria(delta).arrayEquals(message, expecteds, actuals); - } - - /** - * Asserts that two double arrays are equal. If they are not, an - * {@link AssertionError} is thrown. - * - * @param expecteds - * double array with expected values. - * @param actuals - * double array with actual values - */ - public static void assertArrayEquals(double[] expecteds, double[] actuals, double delta) { - assertArrayEquals(null, expecteds, actuals, delta); - } - - /** - * Asserts that two float arrays are equal. If they are not, an - * {@link AssertionError} is thrown with the given message. - * - * @param message - * the identifying message for the {@link AssertionError} (<code>null</code> - * okay) - * @param expecteds - * float array with expected values. - * @param actuals - * float array with actual values - */ - public static void assertArrayEquals(String message, float[] expecteds, - float[] actuals, float delta) throws ArrayComparisonFailure { - new InexactComparisonCriteria(delta).arrayEquals(message, expecteds, actuals); - } - - /** - * Asserts that two float arrays are equal. If they are not, an - * {@link AssertionError} is thrown. - * - * @param expecteds - * float array with expected values. - * @param actuals - * float array with actual values - */ - public static void assertArrayEquals(float[] expecteds, float[] actuals, float delta) { - assertArrayEquals(null, expecteds, actuals, delta); - } - - /** - * Asserts that two object arrays are equal. If they are not, an - * {@link AssertionError} is thrown with the given message. If - * <code>expecteds</code> and <code>actuals</code> are <code>null</code>, - * they are considered equal. - * - * @param message - * the identifying message for the {@link AssertionError} (<code>null</code> - * okay) - * @param expecteds - * Object array or array of arrays (multi-dimensional array) with - * expected values. - * @param actuals - * Object array or array of arrays (multi-dimensional array) with - * actual values - */ - private static void internalArrayEquals(String message, Object expecteds, - Object actuals) throws ArrayComparisonFailure { - new ExactComparisonCriteria().arrayEquals(message, expecteds, actuals); - } - - /** - * Asserts that two doubles or floats are equal to within a positive delta. - * If they are not, an {@link AssertionError} is thrown with the given - * message. If the expected value is infinity then the delta value is - * ignored. NaNs are considered equal: - * <code>assertEquals(Double.NaN, Double.NaN, *)</code> passes - * - * @param message - * the identifying message for the {@link AssertionError} (<code>null</code> - * okay) - * @param expected - * expected value - * @param actual - * the value to check against <code>expected</code> - * @param delta - * the maximum delta between <code>expected</code> and - * <code>actual</code> for which both numbers are still - * considered equal. - */ - 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, new Double(expected), new Double(actual)); - } - - /** - * Asserts that two longs are equal. If they are not, an - * {@link AssertionError} is thrown. - * - * @param expected - * expected long value. - * @param actual - * actual long value - */ - static public void assertEquals(long expected, long actual) { - assertEquals(null, expected, actual); - } - - /** - * Asserts that two longs are equal. If they are not, an - * {@link AssertionError} is thrown with the given message. - * - * @param message - * the identifying message for the {@link AssertionError} (<code>null</code> - * okay) - * @param expected - * long expected value. - * @param actual - * long actual value - */ - static public void assertEquals(String message, long expected, long actual) { - assertEquals(message, (Long) expected, (Long) actual); - } - - /** - * @deprecated Use - * <code>assertEquals(double expected, double actual, double delta)</code> - * instead - */ - @Deprecated - static public void assertEquals(double expected, double actual) { - assertEquals(null, expected, actual); - } - - /** - * @deprecated Use - * <code>assertEquals(String message, double expected, double actual, double delta)</code> - * instead - */ - @Deprecated - static public void assertEquals(String message, double expected, - double actual) { - fail("Use assertEquals(expected, actual, delta) to compare floating-point numbers"); - } - - /** - * Asserts that two doubles or floats are equal to within a positive delta. - * If they are not, an {@link AssertionError} is thrown. If the expected - * value is infinity then the delta value is ignored.NaNs are considered - * equal: <code>assertEquals(Double.NaN, Double.NaN, *)</code> passes - * - * @param expected - * expected value - * @param actual - * the value to check against <code>expected</code> - * @param delta - * the maximum delta between <code>expected</code> and - * <code>actual</code> for which both numbers are still - * considered equal. - */ - static public void assertEquals(double expected, double actual, double delta) { - assertEquals(null, expected, actual, delta); - } - - /** - * Asserts that an object isn't null. If it is an {@link AssertionError} is - * thrown with the given message. - * - * @param message - * the identifying message for the {@link AssertionError} (<code>null</code> - * okay) - * @param object - * Object to check or <code>null</code> - */ - static public void assertNotNull(String message, Object object) { - assertTrue(message, object != null); - } - - /** - * Asserts that an object isn't null. If it is an {@link AssertionError} is - * thrown. - * - * @param object - * Object to check or <code>null</code> - */ - static public void assertNotNull(Object object) { - assertNotNull(null, object); - } - - /** - * Asserts that an object is null. If it is not, an {@link AssertionError} - * is thrown with the given message. - * - * @param message - * the identifying message for the {@link AssertionError} (<code>null</code> - * okay) - * @param object - * Object to check or <code>null</code> - */ - static public void assertNull(String message, Object object) { - assertTrue(message, object == null); - } - - /** - * Asserts that an object is null. If it isn't an {@link AssertionError} is - * thrown. - * - * @param object - * Object to check or <code>null</code> - */ - static public void assertNull(Object object) { - assertNull(null, object); - } - - /** - * Asserts that two objects refer to the same object. If they are not, an - * {@link AssertionError} is thrown with the given message. - * - * @param message - * the identifying message for the {@link AssertionError} (<code>null</code> - * okay) - * @param expected - * the expected object - * @param actual - * the object to compare to <code>expected</code> - */ - static public void assertSame(String message, Object expected, Object actual) { - if (expected == actual) - return; - failNotSame(message, expected, actual); - } - - /** - * Asserts that two objects refer to the same object. If they are not the - * same, an {@link AssertionError} without a message is thrown. - * - * @param expected - * the expected object - * @param actual - * the object to compare to <code>expected</code> - */ - static public void assertSame(Object expected, Object actual) { - assertSame(null, expected, actual); - } - - /** - * Asserts that two objects do not refer to the same object. If they do - * refer to the same object, an {@link AssertionError} is thrown with the - * given message. - * - * @param message - * the identifying message for the {@link AssertionError} (<code>null</code> - * okay) - * @param unexpected - * the object you don't expect - * @param actual - * the object to compare to <code>unexpected</code> - */ - static public void assertNotSame(String message, Object unexpected, - Object actual) { - if (unexpected == actual) - failSame(message); - } - - /** - * Asserts that two objects do not refer to the same object. If they do - * refer to the same object, an {@link AssertionError} without a message is - * thrown. - * - * @param unexpected - * the object you don't expect - * @param actual - * the object to compare to <code>unexpected</code> - */ - static public void assertNotSame(Object unexpected, Object actual) { - assertNotSame(null, unexpected, actual); - } - - static private void failSame(String message) { - String formatted= ""; - if (message != null) - formatted= message + " "; - fail(formatted + "expected not same"); - } - - static private void failNotSame(String message, Object expected, - Object actual) { - String formatted= ""; - if (message != null) - formatted= message + " "; - fail(formatted + "expected same:<" + expected + "> was not:<" + actual - + ">"); - } - - 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 && !message.equals("")) - formatted= message + " "; - String expectedString= String.valueOf(expected); - String actualString= String.valueOf(actual); - if (expectedString.equals(actualString)) - return formatted + "expected: " - + formatClassAndValue(expected, expectedString) - + " but was: " + formatClassAndValue(actual, actualString); - else - return formatted + "expected:<" + expectedString + "> but was:<" - + actualString + ">"; - } - - private static String formatClassAndValue(Object value, String valueString) { - String className= value == null ? "null" : value.getClass().getName(); - return className + "<" + valueString + ">"; - } - - /** - * Asserts that two object arrays are equal. If they are not, an - * {@link AssertionError} is thrown with the given message. If - * <code>expecteds</code> and <code>actuals</code> are <code>null</code>, - * they are considered equal. - * - * @param message - * the identifying message for the {@link AssertionError} (<code>null</code> - * okay) - * @param expecteds - * Object array or array of arrays (multi-dimensional array) with - * expected values. - * @param actuals - * Object array or array of arrays (multi-dimensional array) with - * actual values - * @deprecated use assertArrayEquals - */ - @Deprecated - public static void assertEquals(String message, Object[] expecteds, - Object[] actuals) { - assertArrayEquals(message, expecteds, actuals); - } - - /** - * Asserts that two object arrays are equal. If they are not, an - * {@link AssertionError} is thrown. If <code>expected</code> and - * <code>actual</code> are <code>null</code>, they are considered - * equal. - * - * @param expecteds - * Object array or array of arrays (multi-dimensional array) with - * expected values - * @param actuals - * Object array or array of arrays (multi-dimensional array) with - * actual values - * @deprecated use assertArrayEquals - */ - @Deprecated - public static void assertEquals(Object[] expecteds, Object[] actuals) { - assertArrayEquals(expecteds, actuals); - } - - /** - * Asserts that <code>actual</code> satisfies the condition specified by - * <code>matcher</code>. If not, an {@link AssertionError} is thrown with - * information about the matcher and failing value. Example: - * - * <pre> - * assertThat(0, is(1)); // fails: - * // failure message: - * // expected: is <1> - * // got value: <0> - * assertThat(0, is(not(1))) // passes - * </pre> - * - * @param <T> - * the static type accepted by the matcher (this can flag obvious - * compile-time problems such as {@code assertThat(1, is("a"))} - * @param actual - * the computed value being compared - * @param matcher - * an expression, built of {@link Matcher}s, specifying allowed - * values - * - * @see org.hamcrest.CoreMatchers - * @see org.junit.matchers.JUnitMatchers - */ - public static <T> void assertThat(T actual, Matcher<T> matcher) { - assertThat("", actual, matcher); - } - - /** - * Asserts that <code>actual</code> satisfies the condition specified by - * <code>matcher</code>. If not, an {@link AssertionError} is thrown with - * the reason and information about the matcher and failing value. Example: - * - * <pre> - * : - * assertThat("Help! Integers don't work", 0, is(1)); // fails: - * // failure message: - * // Help! Integers don't work - * // expected: is <1> - * // got value: <0> - * assertThat("Zero is one", 0, is(not(1))) // passes - * </pre> - * - * @param reason - * additional information about the error - * @param <T> - * the static type accepted by the matcher (this can flag obvious - * compile-time problems such as {@code assertThat(1, is("a"))} - * @param actual - * the computed value being compared - * @param matcher - * an expression, built of {@link Matcher}s, specifying allowed - * values - * - * @see org.hamcrest.CoreMatchers - * @see org.junit.matchers.JUnitMatchers - */ - public static <T> void assertThat(String reason, T actual, - Matcher<T> matcher) { - if (!matcher.matches(actual)) { - Description description= new StringDescription(); - description.appendText(reason); - description.appendText("\nExpected: "); - description.appendDescriptionOf(matcher); - description.appendText("\n got: "); - description.appendValue(actual); - description.appendText("\n"); - throw new java.lang.AssertionError(description.toString()); - } - } + /** + * Protect constructor since it is a static only class + */ + protected Assert() { + } + + /** + * Asserts that a condition is true. If it isn't it throws an + * {@link AssertionError} with the given message. + * + * @param message the identifying message for the {@link AssertionError} (<code>null</code> + * okay) + * @param condition condition to be checked + */ + static public void assertTrue(String message, boolean condition) { + if (!condition) { + fail(message); + } + } + + /** + * Asserts that a condition is true. If it isn't it throws an + * {@link AssertionError} without a message. + * + * @param condition condition to be checked + */ + static public void assertTrue(boolean condition) { + assertTrue(null, condition); + } + + /** + * Asserts that a condition is false. If it isn't it throws an + * {@link AssertionError} with the given message. + * + * @param message the identifying message for the {@link AssertionError} (<code>null</code> + * okay) + * @param condition condition to be checked + */ + static public void assertFalse(String message, boolean condition) { + assertTrue(message, !condition); + } + + /** + * Asserts that a condition is false. If it isn't it throws an + * {@link AssertionError} without a message. + * + * @param condition condition to be checked + */ + static public void assertFalse(boolean condition) { + assertFalse(null, condition); + } + + /** + * Fails a test with the given message. + * + * @param message the identifying message for the {@link AssertionError} (<code>null</code> + * okay) + * @see AssertionError + */ + static public void fail(String message) { + if (message == null) { + throw new AssertionError(); + } + throw new AssertionError(message); + } + + /** + * Fails a test with no message. + */ + static public void fail() { + fail(null); + } + + /** + * Asserts that two objects are equal. If they are not, an + * {@link AssertionError} is thrown with the given message. If + * <code>expected</code> and <code>actual</code> are <code>null</code>, + * they are considered equal. + * + * @param message the identifying message for the {@link AssertionError} (<code>null</code> + * okay) + * @param expected expected value + * @param actual actual value + */ + static public void assertEquals(String message, Object expected, + Object actual) { + if (equalsRegardingNull(expected, actual)) { + return; + } else if (expected instanceof String && actual instanceof String) { + String cleanMessage = message == null ? "" : message; + throw new ComparisonFailure(cleanMessage, (String) expected, + (String) actual); + } else { + failNotEquals(message, expected, actual); + } + } + + private static boolean equalsRegardingNull(Object expected, Object actual) { + if (expected == null) { + return actual == null; + } + + return isEquals(expected, actual); + } + + private static boolean isEquals(Object expected, Object actual) { + return expected.equals(actual); + } + + /** + * Asserts that two objects are equal. If they are not, an + * {@link AssertionError} without a message is thrown. If + * <code>expected</code> and <code>actual</code> are <code>null</code>, + * they are considered equal. + * + * @param expected expected value + * @param actual the value to check against <code>expected</code> + */ + static public void assertEquals(Object expected, Object actual) { + assertEquals(null, expected, actual); + } + + /** + * Asserts that two objects are <b>not</b> equals. If they are, an + * {@link AssertionError} is thrown with the given message. If + * <code>unexpected</code> and <code>actual</code> are <code>null</code>, + * they are considered equal. + * + * @param message the identifying message for the {@link AssertionError} (<code>null</code> + * okay) + * @param unexpected unexpected value to check + * @param actual the value to check against <code>unexpected</code> + */ + static public void assertNotEquals(String message, Object unexpected, + Object actual) { + if (equalsRegardingNull(unexpected, actual)) { + failEquals(message, actual); + } + } + + /** + * Asserts that two objects are <b>not</b> equals. If they are, an + * {@link AssertionError} without a message is thrown. If + * <code>unexpected</code> and <code>actual</code> are <code>null</code>, + * they are considered equal. + * + * @param unexpected unexpected value to check + * @param actual the value to check against <code>unexpected</code> + */ + static public void assertNotEquals(Object unexpected, Object actual) { + assertNotEquals(null, unexpected, actual); + } + + private static void failEquals(String message, Object actual) { + String formatted = "Values should be different. "; + if (message != null) { + formatted = message + ". "; + } + + formatted += "Actual: " + actual; + fail(formatted); + } + + /** + * Asserts that two longs are <b>not</b> equals. If they are, an + * {@link AssertionError} is thrown with the given message. + * + * @param message the identifying message for the {@link AssertionError} (<code>null</code> + * okay) + * @param unexpected unexpected value to check + * @param actual the value to check against <code>unexpected</code> + */ + static public void assertNotEquals(String message, long unexpected, long actual) { + if (unexpected == actual) { + failEquals(message, Long.valueOf(actual)); + } + } + + /** + * Asserts that two longs are <b>not</b> equals. If they are, an + * {@link AssertionError} without a message is thrown. + * + * @param unexpected unexpected value to check + * @param actual the value to check against <code>unexpected</code> + */ + static public void assertNotEquals(long unexpected, long actual) { + assertNotEquals(null, unexpected, actual); + } + + /** + * Asserts that two doubles are <b>not</b> equal to within a positive delta. + * If they are, an {@link AssertionError} is thrown with the given + * message. If the unexpected value is infinity then the delta value is + * ignored. NaNs are considered equal: + * <code>assertNotEquals(Double.NaN, Double.NaN, *)</code> fails + * + * @param message the identifying message for the {@link AssertionError} (<code>null</code> + * okay) + * @param unexpected unexpected value + * @param actual the value to check against <code>unexpected</code> + * @param delta the maximum delta between <code>unexpected</code> and + * <code>actual</code> for which both numbers are still + * considered equal. + */ + static public void assertNotEquals(String message, double unexpected, + double actual, double delta) { + if (!doubleIsDifferent(unexpected, actual, delta)) { + failEquals(message, Double.valueOf(actual)); + } + } + + /** + * Asserts that two doubles are <b>not</b> equal to within a positive delta. + * If they are, an {@link AssertionError} is thrown. If the unexpected + * value is infinity then the delta value is ignored.NaNs are considered + * equal: <code>assertNotEquals(Double.NaN, Double.NaN, *)</code> fails + * + * @param unexpected unexpected value + * @param actual the value to check against <code>unexpected</code> + * @param delta the maximum delta between <code>unexpected</code> and + * <code>actual</code> for which both numbers are still + * considered equal. + */ + static public void assertNotEquals(double unexpected, double actual, double delta) { + assertNotEquals(null, unexpected, actual, delta); + } + + /** + * Asserts that two floats are <b>not</b> equal to within a positive delta. + * If they are, an {@link AssertionError} is thrown. If the unexpected + * value is infinity then the delta value is ignored.NaNs are considered + * equal: <code>assertNotEquals(Float.NaN, Float.NaN, *)</code> fails + * + * @param unexpected unexpected value + * @param actual the value to check against <code>unexpected</code> + * @param delta the maximum delta between <code>unexpected</code> and + * <code>actual</code> for which both numbers are still + * considered equal. + */ + static public void assertNotEquals(float unexpected, float actual, float delta) { + assertNotEquals(null, unexpected, actual, delta); + } + + /** + * Asserts that two object arrays are equal. If they are not, an + * {@link AssertionError} is thrown with the given message. If + * <code>expecteds</code> and <code>actuals</code> are <code>null</code>, + * they are considered equal. + * + * @param message the identifying message for the {@link AssertionError} (<code>null</code> + * okay) + * @param expecteds Object array or array of arrays (multi-dimensional array) with + * expected values. + * @param actuals Object array or array of arrays (multi-dimensional array) with + * actual values + */ + public static void assertArrayEquals(String message, Object[] expecteds, + Object[] actuals) throws ArrayComparisonFailure { + internalArrayEquals(message, expecteds, actuals); + } + + /** + * Asserts that two object arrays are equal. If they are not, an + * {@link AssertionError} is thrown. If <code>expected</code> and + * <code>actual</code> are <code>null</code>, they are considered + * equal. + * + * @param expecteds Object array or array of arrays (multi-dimensional array) with + * expected values + * @param actuals Object array or array of arrays (multi-dimensional array) with + * actual values + */ + 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 + * <code>expecteds</code> and <code>actuals</code> are <code>null</code>, + * they are considered equal. + * + * @param message the identifying message for the {@link AssertionError} (<code>null</code> + * okay) + * @param expecteds boolean array with expected values. + * @param actuals boolean array with expected values. + */ + 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 <code>expected</code> and + * <code>actual</code> are <code>null</code>, they are considered + * equal. + * + * @param expecteds boolean array with expected values. + * @param actuals boolean array with expected values. + */ + public static void assertArrayEquals(boolean[] expecteds, boolean[] actuals) { + assertArrayEquals(null, expecteds, actuals); + } + + /** + * Asserts that two byte arrays are equal. If they are not, an + * {@link AssertionError} is thrown with the given message. + * + * @param message the identifying message for the {@link AssertionError} (<code>null</code> + * okay) + * @param expecteds byte array with expected values. + * @param actuals byte array with actual values + */ + public static void assertArrayEquals(String message, byte[] expecteds, + byte[] actuals) throws ArrayComparisonFailure { + internalArrayEquals(message, expecteds, actuals); + } + + /** + * Asserts that two byte arrays are equal. If they are not, an + * {@link AssertionError} is thrown. + * + * @param expecteds byte array with expected values. + * @param actuals byte array with actual values + */ + public static void assertArrayEquals(byte[] expecteds, byte[] actuals) { + assertArrayEquals(null, expecteds, actuals); + } + + /** + * Asserts that two char arrays are equal. If they are not, an + * {@link AssertionError} is thrown with the given message. + * + * @param message the identifying message for the {@link AssertionError} (<code>null</code> + * okay) + * @param expecteds char array with expected values. + * @param actuals char array with actual values + */ + public static void assertArrayEquals(String message, char[] expecteds, + char[] actuals) throws ArrayComparisonFailure { + internalArrayEquals(message, expecteds, actuals); + } + + /** + * Asserts that two char arrays are equal. If they are not, an + * {@link AssertionError} is thrown. + * + * @param expecteds char array with expected values. + * @param actuals char array with actual values + */ + public static void assertArrayEquals(char[] expecteds, char[] actuals) { + assertArrayEquals(null, expecteds, actuals); + } + + /** + * Asserts that two short arrays are equal. If they are not, an + * {@link AssertionError} is thrown with the given message. + * + * @param message the identifying message for the {@link AssertionError} (<code>null</code> + * okay) + * @param expecteds short array with expected values. + * @param actuals short array with actual values + */ + public static void assertArrayEquals(String message, short[] expecteds, + short[] actuals) throws ArrayComparisonFailure { + internalArrayEquals(message, expecteds, actuals); + } + + /** + * Asserts that two short arrays are equal. If they are not, an + * {@link AssertionError} is thrown. + * + * @param expecteds short array with expected values. + * @param actuals short array with actual values + */ + public static void assertArrayEquals(short[] expecteds, short[] actuals) { + assertArrayEquals(null, expecteds, actuals); + } + + /** + * Asserts that two int arrays are equal. If they are not, an + * {@link AssertionError} is thrown with the given message. + * + * @param message the identifying message for the {@link AssertionError} (<code>null</code> + * okay) + * @param expecteds int array with expected values. + * @param actuals int array with actual values + */ + public static void assertArrayEquals(String message, int[] expecteds, + int[] actuals) throws ArrayComparisonFailure { + internalArrayEquals(message, expecteds, actuals); + } + + /** + * Asserts that two int arrays are equal. If they are not, an + * {@link AssertionError} is thrown. + * + * @param expecteds int array with expected values. + * @param actuals int array with actual values + */ + public static void assertArrayEquals(int[] expecteds, int[] actuals) { + assertArrayEquals(null, expecteds, actuals); + } + + /** + * Asserts that two long arrays are equal. If they are not, an + * {@link AssertionError} is thrown with the given message. + * + * @param message the identifying message for the {@link AssertionError} (<code>null</code> + * okay) + * @param expecteds long array with expected values. + * @param actuals long array with actual values + */ + public static void assertArrayEquals(String message, long[] expecteds, + long[] actuals) throws ArrayComparisonFailure { + internalArrayEquals(message, expecteds, actuals); + } + + /** + * Asserts that two long arrays are equal. If they are not, an + * {@link AssertionError} is thrown. + * + * @param expecteds long array with expected values. + * @param actuals long array with actual values + */ + public static void assertArrayEquals(long[] expecteds, long[] actuals) { + assertArrayEquals(null, expecteds, actuals); + } + + /** + * Asserts that two double arrays are equal. If they are not, an + * {@link AssertionError} is thrown with the given message. + * + * @param message the identifying message for the {@link AssertionError} (<code>null</code> + * okay) + * @param expecteds double array with expected values. + * @param actuals double array with actual values + * @param delta the maximum delta between <code>expecteds[i]</code> and + * <code>actuals[i]</code> for which both numbers are still + * considered equal. + */ + public static void assertArrayEquals(String message, double[] expecteds, + double[] actuals, double delta) throws ArrayComparisonFailure { + new InexactComparisonCriteria(delta).arrayEquals(message, expecteds, actuals); + } + + /** + * Asserts that two double arrays are equal. If they are not, an + * {@link AssertionError} is thrown. + * + * @param expecteds double array with expected values. + * @param actuals double array with actual values + * @param delta the maximum delta between <code>expecteds[i]</code> and + * <code>actuals[i]</code> for which both numbers are still + * considered equal. + */ + public static void assertArrayEquals(double[] expecteds, double[] actuals, double delta) { + assertArrayEquals(null, expecteds, actuals, delta); + } + + /** + * Asserts that two float arrays are equal. If they are not, an + * {@link AssertionError} is thrown with the given message. + * + * @param message the identifying message for the {@link AssertionError} (<code>null</code> + * okay) + * @param expecteds float array with expected values. + * @param actuals float array with actual values + * @param delta the maximum delta between <code>expecteds[i]</code> and + * <code>actuals[i]</code> for which both numbers are still + * considered equal. + */ + public static void assertArrayEquals(String message, float[] expecteds, + float[] actuals, float delta) throws ArrayComparisonFailure { + new InexactComparisonCriteria(delta).arrayEquals(message, expecteds, actuals); + } + + /** + * Asserts that two float arrays are equal. If they are not, an + * {@link AssertionError} is thrown. + * + * @param expecteds float array with expected values. + * @param actuals float array with actual values + * @param delta the maximum delta between <code>expecteds[i]</code> and + * <code>actuals[i]</code> for which both numbers are still + * considered equal. + */ + public static void assertArrayEquals(float[] expecteds, float[] actuals, float delta) { + assertArrayEquals(null, expecteds, actuals, delta); + } + + /** + * Asserts that two object arrays are equal. If they are not, an + * {@link AssertionError} is thrown with the given message. If + * <code>expecteds</code> and <code>actuals</code> are <code>null</code>, + * they are considered equal. + * + * @param message the identifying message for the {@link AssertionError} (<code>null</code> + * okay) + * @param expecteds Object array or array of arrays (multi-dimensional array) with + * expected values. + * @param actuals Object array or array of arrays (multi-dimensional array) with + * actual values + */ + private static void internalArrayEquals(String message, Object expecteds, + Object actuals) throws ArrayComparisonFailure { + new ExactComparisonCriteria().arrayEquals(message, expecteds, actuals); + } + + /** + * Asserts that two doubles are equal to within a positive delta. + * If they are not, an {@link AssertionError} is thrown with the given + * message. If the expected value is infinity then the delta value is + * ignored. NaNs are considered equal: + * <code>assertEquals(Double.NaN, Double.NaN, *)</code> passes + * + * @param message the identifying message for the {@link AssertionError} (<code>null</code> + * okay) + * @param expected expected value + * @param actual the value to check against <code>expected</code> + * @param delta the maximum delta between <code>expected</code> and + * <code>actual</code> for which both numbers are still + * considered equal. + */ + 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)); + } + } + + /** + * Asserts that two floats are equal to within a positive delta. + * If they are not, an {@link AssertionError} is thrown with the given + * message. If the expected value is infinity then the delta value is + * ignored. NaNs are considered equal: + * <code>assertEquals(Float.NaN, Float.NaN, *)</code> passes + * + * @param message the identifying message for the {@link AssertionError} (<code>null</code> + * okay) + * @param expected expected value + * @param actual the value to check against <code>expected</code> + * @param delta the maximum delta between <code>expected</code> and + * <code>actual</code> for which both numbers are still + * considered equal. + */ + 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)); + } + } + + /** + * Asserts that two floats are <b>not</b> equal to within a positive delta. + * If they are, an {@link AssertionError} is thrown with the given + * message. If the unexpected value is infinity then the delta value is + * ignored. NaNs are considered equal: + * <code>assertNotEquals(Float.NaN, Float.NaN, *)</code> fails + * + * @param message the identifying message for the {@link AssertionError} (<code>null</code> + * okay) + * @param unexpected unexpected value + * @param actual the value to check against <code>unexpected</code> + * @param delta the maximum delta between <code>unexpected</code> and + * <code>actual</code> for which both numbers are still + * considered equal. + */ + static public void assertNotEquals(String message, float unexpected, + float actual, float delta) { + if (!floatIsDifferent(unexpected, actual, delta)) { + failEquals(message, Float.valueOf(actual)); + } + } + + static private boolean doubleIsDifferent(double d1, double d2, double delta) { + if (Double.compare(d1, d2) == 0) { + return false; + } + if ((Math.abs(d1 - d2) <= delta)) { + return false; + } + + return true; + } + + static private boolean floatIsDifferent(float f1, float f2, float delta) { + if (Float.compare(f1, f2) == 0) { + return false; + } + if ((Math.abs(f1 - f2) <= delta)) { + return false; + } + + return true; + } + + /** + * Asserts that two longs are equal. If they are not, an + * {@link AssertionError} is thrown. + * + * @param expected expected long value. + * @param actual actual long value + */ + static public void assertEquals(long expected, long actual) { + assertEquals(null, expected, actual); + } + + /** + * Asserts that two longs are equal. If they are not, an + * {@link AssertionError} is thrown with the given message. + * + * @param message the identifying message for the {@link AssertionError} (<code>null</code> + * okay) + * @param expected long expected value. + * @param actual long actual value + */ + static public void assertEquals(String message, long expected, long actual) { + if (expected != actual) { + failNotEquals(message, Long.valueOf(expected), Long.valueOf(actual)); + } + } + + /** + * @deprecated Use + * <code>assertEquals(double expected, double actual, double delta)</code> + * instead + */ + @Deprecated + static public void assertEquals(double expected, double actual) { + assertEquals(null, expected, actual); + } + + /** + * @deprecated Use + * <code>assertEquals(String message, double expected, double actual, double delta)</code> + * instead + */ + @Deprecated + static public void assertEquals(String message, double expected, + double actual) { + fail("Use assertEquals(expected, actual, delta) to compare floating-point numbers"); + } + + /** + * Asserts that two doubles are equal to within a positive delta. + * If they are not, an {@link AssertionError} is thrown. If the expected + * value is infinity then the delta value is ignored.NaNs are considered + * equal: <code>assertEquals(Double.NaN, Double.NaN, *)</code> passes + * + * @param expected expected value + * @param actual the value to check against <code>expected</code> + * @param delta the maximum delta between <code>expected</code> and + * <code>actual</code> for which both numbers are still + * considered equal. + */ + static public void assertEquals(double expected, double actual, double delta) { + assertEquals(null, expected, actual, delta); + } + + /** + * Asserts that two floats are equal to within a positive delta. + * If they are not, an {@link AssertionError} is thrown. If the expected + * value is infinity then the delta value is ignored. NaNs are considered + * equal: <code>assertEquals(Float.NaN, Float.NaN, *)</code> passes + * + * @param expected expected value + * @param actual the value to check against <code>expected</code> + * @param delta the maximum delta between <code>expected</code> and + * <code>actual</code> for which both numbers are still + * considered equal. + */ + + static public void assertEquals(float expected, float actual, float delta) { + assertEquals(null, expected, actual, delta); + } + + /** + * Asserts that an object isn't null. If it is an {@link AssertionError} is + * thrown with the given message. + * + * @param message the identifying message for the {@link AssertionError} (<code>null</code> + * okay) + * @param object Object to check or <code>null</code> + */ + static public void assertNotNull(String message, Object object) { + assertTrue(message, object != null); + } + + /** + * Asserts that an object isn't null. If it is an {@link AssertionError} is + * thrown. + * + * @param object Object to check or <code>null</code> + */ + static public void assertNotNull(Object object) { + assertNotNull(null, object); + } + + /** + * Asserts that an object is null. If it is not, an {@link AssertionError} + * is thrown with the given message. + * + * @param message the identifying message for the {@link AssertionError} (<code>null</code> + * okay) + * @param object Object to check or <code>null</code> + */ + static public void assertNull(String message, Object object) { + if (object == null) { + return; + } + failNotNull(message, object); + } + + /** + * Asserts that an object is null. If it isn't an {@link AssertionError} is + * thrown. + * + * @param object Object to check or <code>null</code> + */ + static public void assertNull(Object object) { + assertNull(null, object); + } + + static private void failNotNull(String message, Object actual) { + String formatted = ""; + if (message != null) { + formatted = message + " "; + } + fail(formatted + "expected null, but was:<" + actual + ">"); + } + + /** + * Asserts that two objects refer to the same object. If they are not, an + * {@link AssertionError} is thrown with the given message. + * + * @param message the identifying message for the {@link AssertionError} (<code>null</code> + * okay) + * @param expected the expected object + * @param actual the object to compare to <code>expected</code> + */ + static public void assertSame(String message, Object expected, Object actual) { + if (expected == actual) { + return; + } + failNotSame(message, expected, actual); + } + + /** + * Asserts that two objects refer to the same object. If they are not the + * same, an {@link AssertionError} without a message is thrown. + * + * @param expected the expected object + * @param actual the object to compare to <code>expected</code> + */ + static public void assertSame(Object expected, Object actual) { + assertSame(null, expected, actual); + } + + /** + * Asserts that two objects do not refer to the same object. If they do + * refer to the same object, an {@link AssertionError} is thrown with the + * given message. + * + * @param message the identifying message for the {@link AssertionError} (<code>null</code> + * okay) + * @param unexpected the object you don't expect + * @param actual the object to compare to <code>unexpected</code> + */ + static public void assertNotSame(String message, Object unexpected, + Object actual) { + if (unexpected == actual) { + failSame(message); + } + } + + /** + * Asserts that two objects do not refer to the same object. If they do + * refer to the same object, an {@link AssertionError} without a message is + * thrown. + * + * @param unexpected the object you don't expect + * @param actual the object to compare to <code>unexpected</code> + */ + static public void assertNotSame(Object unexpected, Object actual) { + assertNotSame(null, unexpected, actual); + } + + static private void failSame(String message) { + String formatted = ""; + if (message != null) { + formatted = message + " "; + } + fail(formatted + "expected not same"); + } + + static private void failNotSame(String message, Object expected, + Object actual) { + String formatted = ""; + if (message != null) { + formatted = message + " "; + } + fail(formatted + "expected same:<" + expected + "> was not:<" + actual + + ">"); + } + + 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 && !message.equals("")) { + formatted = message + " "; + } + String expectedString = String.valueOf(expected); + String actualString = String.valueOf(actual); + if (expectedString.equals(actualString)) { + return formatted + "expected: " + + formatClassAndValue(expected, expectedString) + + " but was: " + formatClassAndValue(actual, actualString); + } else { + return formatted + "expected:<" + expectedString + "> but was:<" + + actualString + ">"; + } + } + + private static String formatClassAndValue(Object value, String valueString) { + String className = value == null ? "null" : value.getClass().getName(); + return className + "<" + valueString + ">"; + } + + /** + * Asserts that two object arrays are equal. If they are not, an + * {@link AssertionError} is thrown with the given message. If + * <code>expecteds</code> and <code>actuals</code> are <code>null</code>, + * they are considered equal. + * + * @param message the identifying message for the {@link AssertionError} (<code>null</code> + * okay) + * @param expecteds Object array or array of arrays (multi-dimensional array) with + * expected values. + * @param actuals Object array or array of arrays (multi-dimensional array) with + * actual values + * @deprecated use assertArrayEquals + */ + @Deprecated + public static void assertEquals(String message, Object[] expecteds, + Object[] actuals) { + assertArrayEquals(message, expecteds, actuals); + } + + /** + * Asserts that two object arrays are equal. If they are not, an + * {@link AssertionError} is thrown. If <code>expected</code> and + * <code>actual</code> are <code>null</code>, they are considered + * equal. + * + * @param expecteds Object array or array of arrays (multi-dimensional array) with + * expected values + * @param actuals Object array or array of arrays (multi-dimensional array) with + * actual values + * @deprecated use assertArrayEquals + */ + @Deprecated + public static void assertEquals(Object[] expecteds, Object[] actuals) { + assertArrayEquals(expecteds, actuals); + } + + /** + * Asserts that <code>actual</code> satisfies the condition specified by + * <code>matcher</code>. If not, an {@link AssertionError} is thrown with + * information about the matcher and failing value. Example: + * + * <pre> + * assertThat(0, is(1)); // fails: + * // failure message: + * // expected: is <1> + * // got value: <0> + * assertThat(0, is(not(1))) // passes + * </pre> + * + * <code>org.hamcrest.Matcher</code> does not currently document the meaning + * of its type parameter <code>T</code>. This method assumes that a matcher + * typed as <code>Matcher<T></code> can be meaningfully applied only + * to values that could be assigned to a variable of type <code>T</code>. + * + * @param <T> the static type accepted by the matcher (this can flag obvious + * compile-time problems such as {@code assertThat(1, is("a"))} + * @param actual the computed value being compared + * @param matcher an expression, built of {@link Matcher}s, specifying allowed + * values + * @see org.hamcrest.CoreMatchers + * @see org.hamcrest.MatcherAssert + */ + public static <T> void assertThat(T actual, Matcher<? super T> matcher) { + assertThat("", actual, matcher); + } + + /** + * Asserts that <code>actual</code> satisfies the condition specified by + * <code>matcher</code>. If not, an {@link AssertionError} is thrown with + * the reason and information about the matcher and failing value. Example: + * + * <pre> + * assertThat("Help! Integers don't work", 0, is(1)); // fails: + * // failure message: + * // Help! Integers don't work + * // expected: is <1> + * // got value: <0> + * assertThat("Zero is one", 0, is(not(1))) // passes + * </pre> + * + * <code>org.hamcrest.Matcher</code> does not currently document the meaning + * of its type parameter <code>T</code>. This method assumes that a matcher + * typed as <code>Matcher<T></code> can be meaningfully applied only + * to values that could be assigned to a variable of type <code>T</code>. + * + * @param reason additional information about the error + * @param <T> the static type accepted by the matcher (this can flag obvious + * compile-time problems such as {@code assertThat(1, is("a"))} + * @param actual the computed value being compared + * @param matcher an expression, built of {@link Matcher}s, specifying allowed + * values + * @see org.hamcrest.CoreMatchers + * @see org.hamcrest.MatcherAssert + */ + public static <T> void assertThat(String reason, T actual, + Matcher<? super T> matcher) { + MatcherAssert.assertThat(reason, actual, matcher); + } } diff --git a/src/main/java/org/junit/internal/runners/rules/RuleMemberValidator.java b/src/main/java/org/junit/internal/runners/rules/RuleMemberValidator.java new file mode 100644 index 0000000..23f921b --- /dev/null +++ b/src/main/java/org/junit/internal/runners/rules/RuleMemberValidator.java @@ -0,0 +1,91 @@ +package org.junit.internal.runners.rules; + +import java.lang.annotation.Annotation; +import java.util.List; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.rules.TestRule; +import org.junit.runners.model.FrameworkField; +import org.junit.runners.model.TestClass; + +/** + * A RuleFieldValidator validates the rule fields of a + * {@link TestClass}. All reasons for rejecting the + * {@code TestClass} are written to a list of errors. + * + * There are two slightly different validators. The {@link #CLASS_RULE_VALIDATOR} + * validates fields with a {@link ClassRule} annotation and the + * {@link #RULE_VALIDATOR} validates fields with a {@link Rule} annotation. + */ +public enum RuleMemberValidator { + /** + * Validates fields with a {@link ClassRule} annotation. + */ + CLASS_RULE_VALIDATOR(ClassRule.class, true), + /** + * Validates fields with a {@link Rule} annotation. + */ + RULE_VALIDATOR(Rule.class, false); + + private final Class<? extends Annotation> fAnnotation; + + private final boolean fOnlyStaticFields; + + private RuleMemberValidator(Class<? extends Annotation> annotation, + boolean onlyStaticFields) { + this.fAnnotation= annotation; + this.fOnlyStaticFields= onlyStaticFields; + } + + /** + * Validate the {@link TestClass} and adds reasons + * for rejecting the class to a list of errors. + * @param target the {@code TestClass} to validate. + * @param errors the list of errors. + */ + public void validate(TestClass target, List<Throwable> errors) { + List<FrameworkField> fields= target.getAnnotatedFields(fAnnotation); + for (FrameworkField each : fields) + validateField(each, errors); + } + + private void validateField(FrameworkField field, List<Throwable> errors) { + optionallyValidateStatic(field, errors); + validatePublic(field, errors); + validateTestRuleOrMethodRule(field, errors); + } + + private void optionallyValidateStatic(FrameworkField field, + List<Throwable> errors) { + if (fOnlyStaticFields && !field.isStatic()) + addError(errors, field, "must be static."); + } + + private void validatePublic(FrameworkField field, List<Throwable> errors) { + if (!field.isPublic()) + addError(errors, field, "must be public."); + } + + private void validateTestRuleOrMethodRule(FrameworkField field, + List<Throwable> errors) { + if (!isMethodRule(field) && !isTestRule(field)) + addError(errors, field, "must implement MethodRule or TestRule."); + } + + private boolean isTestRule(FrameworkField target) { + return TestRule.class.isAssignableFrom(target.getType()); + } + + @SuppressWarnings("deprecation") + private boolean isMethodRule(FrameworkField target) { + return org.junit.rules.MethodRule.class.isAssignableFrom(target + .getType()); + } + + private void addError(List<Throwable> errors, FrameworkField field, + String suffix) { + String message= "The @" + fAnnotation.getSimpleName() + " '" + + field.getName() + "' " + suffix; + errors.add(new Exception(message)); + } +} diff --git a/src/main/java/org/junit/runner/Description.java b/src/main/java/org/junit/runner/Description.java index b3083d5..fe47eac 100644 --- a/src/main/java/org/junit/runner/Description.java +++ b/src/main/java/org/junit/runner/Description.java @@ -5,238 +5,312 @@ import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.concurrent.ConcurrentLinkedQueue; import java.util.regex.Matcher; import java.util.regex.Pattern; /** - * <p>A <code>Description</code> describes a test which is to be run or has been run. <code>Descriptions</code> + * A <code>Description</code> describes a test which is to be run or has been run. <code>Descriptions</code> * can be atomic (a single test) or compound (containing children tests). <code>Descriptions</code> are used * to provide feedback about the tests that are about to run (for example, the tree view - * visible in many IDEs) or tests that have been run (for example, the failures view).</p> - * - * <p><code>Descriptions</code> are implemented as a single class rather than a Composite because - * they are entirely informational. They contain no logic aside from counting their tests.</p> - * - * <p>In the past, we used the raw {@link junit.framework.TestCase}s and {@link junit.framework.TestSuite}s - * to display the tree of tests. This was no longer viable in JUnit 4 because atomic tests no longer have - * a superclass below {@link Object}. We needed a way to pass a class and name together. Description - * emerged from this.</p> - * + * visible in many IDEs) or tests that have been run (for example, the failures view). + * <p> + * <code>Descriptions</code> are implemented as a single class rather than a Composite because + * they are entirely informational. They contain no logic aside from counting their tests. + * <p> + * In the past, we used the raw {@link junit.framework.TestCase}s and {@link junit.framework.TestSuite}s + * to display the tree of tests. This was no longer viable in JUnit 4 because atomic tests no longer have + * a superclass below {@link Object}. We needed a way to pass a class and name together. Description + * emerged from this. + * * @see org.junit.runner.Request * @see org.junit.runner.Runner + * @since 4.0 */ public class Description implements Serializable { - private static final long serialVersionUID = 1L; - - /** - * Create a <code>Description</code> named <code>name</code>. - * Generally, you will add children to this <code>Description</code>. - * @param name the name of the <code>Description</code> - * @param annotations - * @return a <code>Description</code> named <code>name</code> - */ - public static Description createSuiteDescription(String name, Annotation... annotations) { - if (name.length() == 0) - throw new IllegalArgumentException("name must have non-zero length"); - return new Description(name, annotations); - } - - /** - * Create a <code>Description</code> of a single test named <code>name</code> in the class <code>clazz</code>. - * Generally, this will be a leaf <code>Description</code>. - * @param clazz the class of the test - * @param name the name of the test (a method name for test annotated with {@link org.junit.Test}) - * @param annotations meta-data about the test, for downstream interpreters - * @return a <code>Description</code> named <code>name</code> - */ - public static Description createTestDescription(Class<?> clazz, String name, Annotation... annotations) { - return new Description(String.format("%s(%s)", name, clazz.getName()), annotations); - } - - /** - * Create a <code>Description</code> of a single test named <code>name</code> in the class <code>clazz</code>. - * Generally, this will be a leaf <code>Description</code>. - * (This remains for binary compatibility with clients of JUnit 4.3) - * @param clazz the class of the test - * @param name the name of the test (a method name for test annotated with {@link org.junit.Test}) - * @return a <code>Description</code> named <code>name</code> - */ - public static Description createTestDescription(Class<?> clazz, String name) { - return createTestDescription(clazz, name, new Annotation[0]); - } - - /** - * Create a <code>Description</code> named after <code>testClass</code> - * @param testClass A {@link Class} containing tests - * @return a <code>Description</code> of <code>testClass</code> - */ - public static Description createSuiteDescription(Class<?> testClass) { - return new Description(testClass.getName(), testClass.getAnnotations()); - } - - /** - * Describes a Runner which runs no tests - */ - public static final Description EMPTY= new Description("No Tests"); - - /** - * Describes a step in the test-running mechanism that goes so wrong no - * other description can be used (for example, an exception thrown from a Runner's - * constructor - */ - public static final Description TEST_MECHANISM= new Description("Test mechanism"); - - private final ArrayList<Description> fChildren= new ArrayList<Description>(); - private final String fDisplayName; - - private final Annotation[] fAnnotations; - - private Description(final String displayName, Annotation... annotations) { - fDisplayName= displayName; - fAnnotations= annotations; - } - - /** - * @return a user-understandable label - */ - public String getDisplayName() { - return fDisplayName; - } - - /** - * Add <code>Description</code> as a child of the receiver. - * @param description the soon-to-be child. - */ - public void addChild(Description description) { - getChildren().add(description); - } - - /** - * @return the receiver's children, if any - */ - public ArrayList<Description> getChildren() { - return fChildren; - } - - /** - * @return <code>true</code> if the receiver is a suite - */ - public boolean isSuite() { - return !isTest(); - } - - /** - * @return <code>true</code> if the receiver is an atomic test - */ - public boolean isTest() { - return getChildren().isEmpty(); - } - - /** - * @return the total number of atomic tests in the receiver - */ - public int testCount() { - if (isTest()) - return 1; - int result= 0; - for (Description child : getChildren()) - result+= child.testCount(); - return result; - } - - @Override - public int hashCode() { - return getDisplayName().hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof Description)) - return false; - Description d = (Description) obj; - return getDisplayName().equals(d.getDisplayName()); - } - - @Override - public String toString() { - return getDisplayName(); - } - - /** - * @return true if this is a description of a Runner that runs no tests - */ - public boolean isEmpty() { - return equals(EMPTY); - } - - /** - * @return a copy of this description, with no children (on the assumption that some of the - * children will be added back) - */ - public Description childlessCopy() { - return new Description(fDisplayName, fAnnotations); - } - - /** - * @return the annotation of type annotationType that is attached to this description node, - * or null if none exists - */ - public <T extends Annotation> T getAnnotation(Class<T> annotationType) { - for (Annotation each : fAnnotations) - if (each.annotationType().equals(annotationType)) - return annotationType.cast(each); - return null; - } - - /** - * @return all of the annotations attached to this description node - */ - public Collection<Annotation> getAnnotations() { - return Arrays.asList(fAnnotations); - } - - /** - * @return If this describes a method invocation, - * the class of the test instance. - */ - public Class<?> getTestClass() { - String name= getClassName(); - if (name == null) - return null; - try { - return Class.forName(name); - } catch (ClassNotFoundException e) { - return null; - } - } - - /** - * @return If this describes a method invocation, - * the name of the class of the test instance - */ - public String getClassName() { - Matcher matcher= methodStringMatcher(); - return matcher.matches() - ? matcher.group(2) - : toString(); - } - - /** - * @return If this describes a method invocation, - * the name of the method (or null if not) - */ - public String getMethodName() { - return parseMethod(); - } - - private String parseMethod() { - Matcher matcher= methodStringMatcher(); - if (matcher.matches()) - return matcher.group(1); - return null; - } - - private Matcher methodStringMatcher() { - return Pattern.compile("(.*)\\((.*)\\)").matcher(toString()); - } + private static final long serialVersionUID = 1L; + + private static final Pattern METHOD_AND_CLASS_NAME_PATTERN = Pattern + .compile("([\\s\\S]*)\\((.*)\\)"); + + /** + * Create a <code>Description</code> named <code>name</code>. + * Generally, you will add children to this <code>Description</code>. + * + * @param name the name of the <code>Description</code> + * @param annotations meta-data about the test, for downstream interpreters + * @return a <code>Description</code> named <code>name</code> + */ + public static Description createSuiteDescription(String name, Annotation... annotations) { + return new Description(null, name, annotations); + } + + /** + * Create a <code>Description</code> named <code>name</code>. + * Generally, you will add children to this <code>Description</code>. + * + * @param name the name of the <code>Description</code> + * @param uniqueId an arbitrary object used to define uniqueness (in {@link #equals(Object)} + * @param annotations meta-data about the test, for downstream interpreters + * @return a <code>Description</code> named <code>name</code> + */ + public static Description createSuiteDescription(String name, Serializable uniqueId, Annotation... annotations) { + return new Description(null, name, uniqueId, annotations); + } + + /** + * Create a <code>Description</code> of a single test named <code>name</code> in the 'class' named + * <code>className</code>. Generally, this will be a leaf <code>Description</code>. This method is a better choice + * than {@link #createTestDescription(Class, String, Annotation...)} for test runners whose test cases are not + * defined in an actual Java <code>Class</code>. + * + * @param className the class name of the test + * @param name the name of the test (a method name for test annotated with {@link org.junit.Test}) + * @param annotations meta-data about the test, for downstream interpreters + * @return a <code>Description</code> named <code>name</code> + */ + public static Description createTestDescription(String className, String name, Annotation... annotations) { + return new Description(null, formatDisplayName(name, className), annotations); + } + + /** + * Create a <code>Description</code> of a single test named <code>name</code> in the class <code>clazz</code>. + * Generally, this will be a leaf <code>Description</code>. + * + * @param clazz the class of the test + * @param name the name of the test (a method name for test annotated with {@link org.junit.Test}) + * @param annotations meta-data about the test, for downstream interpreters + * @return a <code>Description</code> named <code>name</code> + */ + public static Description createTestDescription(Class<?> clazz, String name, Annotation... annotations) { + return new Description(clazz, formatDisplayName(name, clazz.getName()), annotations); + } + + /** + * Create a <code>Description</code> of a single test named <code>name</code> in the class <code>clazz</code>. + * Generally, this will be a leaf <code>Description</code>. + * (This remains for binary compatibility with clients of JUnit 4.3) + * + * @param clazz the class of the test + * @param name the name of the test (a method name for test annotated with {@link org.junit.Test}) + * @return a <code>Description</code> named <code>name</code> + */ + public static Description createTestDescription(Class<?> clazz, String name) { + return new Description(clazz, formatDisplayName(name, clazz.getName())); + } + + /** + * Create a <code>Description</code> of a single test named <code>name</code> in the class <code>clazz</code>. + * Generally, this will be a leaf <code>Description</code>. + * + * @param name the name of the test (a method name for test annotated with {@link org.junit.Test}) + * @return a <code>Description</code> named <code>name</code> + */ + public static Description createTestDescription(String className, String name, Serializable uniqueId) { + return new Description(null, formatDisplayName(name, className), uniqueId); + } + + private static String formatDisplayName(String name, String className) { + return String.format("%s(%s)", name, className); + } + + /** + * Create a <code>Description</code> named after <code>testClass</code> + * + * @param testClass A {@link Class} containing tests + * @return a <code>Description</code> of <code>testClass</code> + */ + public static Description createSuiteDescription(Class<?> testClass) { + return new Description(testClass, testClass.getName(), testClass.getAnnotations()); + } + + /** + * Describes a Runner which runs no tests + */ + public static final Description EMPTY = new Description(null, "No Tests"); + + /** + * Describes a step in the test-running mechanism that goes so wrong no + * other description can be used (for example, an exception thrown from a Runner's + * constructor + */ + public static final Description TEST_MECHANISM = new Description(null, "Test mechanism"); + + /* + * We have to use the f prefix until the next major release to ensure + * serialization compatibility. + * See https://github.com/junit-team/junit/issues/976 + */ + private final Collection<Description> fChildren = new ConcurrentLinkedQueue<Description>(); + private final String fDisplayName; + private final Serializable fUniqueId; + private final Annotation[] fAnnotations; + private volatile /* write-once */ Class<?> fTestClass; + + private Description(Class<?> clazz, String displayName, Annotation... annotations) { + this(clazz, displayName, displayName, annotations); + } + + private Description(Class<?> testClass, String displayName, Serializable uniqueId, Annotation... annotations) { + if ((displayName == null) || (displayName.length() == 0)) { + throw new IllegalArgumentException( + "The display name must not be empty."); + } + if ((uniqueId == null)) { + throw new IllegalArgumentException( + "The unique id must not be null."); + } + this.fTestClass = testClass; + this.fDisplayName = displayName; + this.fUniqueId = uniqueId; + this.fAnnotations = annotations; + } + + /** + * @return a user-understandable label + */ + public String getDisplayName() { + return fDisplayName; + } + + /** + * Add <code>Description</code> as a child of the receiver. + * + * @param description the soon-to-be child. + */ + public void addChild(Description description) { + fChildren.add(description); + } + + /** + * Gets the copy of the children of this {@code Description}. + * Returns an empty list if there are no children. + */ + public ArrayList<Description> getChildren() { + return new ArrayList<Description>(fChildren); + } + + /** + * @return <code>true</code> if the receiver is a suite + */ + public boolean isSuite() { + return !isTest(); + } + + /** + * @return <code>true</code> if the receiver is an atomic test + */ + public boolean isTest() { + return fChildren.isEmpty(); + } + + /** + * @return the total number of atomic tests in the receiver + */ + public int testCount() { + if (isTest()) { + return 1; + } + int result = 0; + for (Description child : fChildren) { + result += child.testCount(); + } + return result; + } + + @Override + public int hashCode() { + return fUniqueId.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof Description)) { + return false; + } + Description d = (Description) obj; + return fUniqueId.equals(d.fUniqueId); + } + + @Override + public String toString() { + return getDisplayName(); + } + + /** + * @return true if this is a description of a Runner that runs no tests + */ + public boolean isEmpty() { + return equals(EMPTY); + } + + /** + * @return a copy of this description, with no children (on the assumption that some of the + * children will be added back) + */ + public Description childlessCopy() { + return new Description(fTestClass, fDisplayName, fAnnotations); + } + + /** + * @return the annotation of type annotationType that is attached to this description node, + * or null if none exists + */ + public <T extends Annotation> T getAnnotation(Class<T> annotationType) { + for (Annotation each : fAnnotations) { + if (each.annotationType().equals(annotationType)) { + return annotationType.cast(each); + } + } + return null; + } + + /** + * @return all of the annotations attached to this description node + */ + public Collection<Annotation> getAnnotations() { + return Arrays.asList(fAnnotations); + } + + /** + * @return If this describes a method invocation, + * the class of the test instance. + */ + public Class<?> getTestClass() { + if (fTestClass != null) { + return fTestClass; + } + String name = getClassName(); + if (name == null) { + return null; + } + try { + fTestClass = Class.forName(name, false, getClass().getClassLoader()); + return fTestClass; + } catch (ClassNotFoundException e) { + return null; + } + } + + /** + * @return If this describes a method invocation, + * the name of the class of the test instance + */ + public String getClassName() { + return fTestClass != null ? fTestClass.getName() : methodAndClassNamePatternGroupOrDefault(2, toString()); + } + + /** + * @return If this describes a method invocation, + * the name of the method (or null if not) + */ + public String getMethodName() { + return methodAndClassNamePatternGroupOrDefault(1, null); + } + + private String methodAndClassNamePatternGroupOrDefault(int group, + String defaultString) { + Matcher matcher = METHOD_AND_CLASS_NAME_PATTERN.matcher(toString()); + return matcher.matches() ? matcher.group(group) : defaultString; + } }
\ No newline at end of file diff --git a/src/main/java/org/junit/runners/BlockJUnit4ClassRunner.java b/src/main/java/org/junit/runners/BlockJUnit4ClassRunner.java index 92e0d07..397da19 100644 --- a/src/main/java/org/junit/runners/BlockJUnit4ClassRunner.java +++ b/src/main/java/org/junit/runners/BlockJUnit4ClassRunner.java @@ -166,7 +166,7 @@ public class BlockJUnit4ClassRunner extends ParentRunner<FrameworkMethod> { errors.add(new Exception("No runnable methods")); } - private void validateFields(List<Throwable> errors) { + protected void validateFields(List<Throwable> errors) { RULE_VALIDATOR.validate(getTestClass(), errors); } |