diff --git a/src/main/java/org/assertj/core/api/AbstractAssert.java b/src/main/java/org/assertj/core/api/AbstractAssert.java index 894528b7a4..31066dfd19 100644 --- a/src/main/java/org/assertj/core/api/AbstractAssert.java +++ b/src/main/java/org/assertj/core/api/AbstractAssert.java @@ -119,6 +119,59 @@ public S as(Description description) { return describedAs(description); } + /** + * Use hexadecimal object representation instead of standard representation in error messages. + *
+ * It can be useful when comparing UNICODE characters - many unicode chars have duplicate characters assigned, + * it is thus impossible to find differences from the standard error message: + * + * With standard message: + *+ * assertThat("µµµ").contains("μμμ"); + * + * java.lang.AssertionError: + * Expecting: + * <"µµµ"> + * to contain: + * <"μμμ"> + *+ * + * With Hexadecimal message: + *
+ * assertThat("µµµ").asHexadecimal().contains("μμμ"); + * + * java.lang.AssertionError: + * Expecting: + * <"['00B5', '00B5', '00B5']"> + * to contain: + * <"['03BC', '03BC', '03BC']"> + *+ * + * @return {@code this} assertion object. + */ + protected S asHexadecimal() { + info.representationAsHexadecimal(); + return myself; + } + + /** + * Use binary object representation instead of standard representation in error messages. + * + * Example: + *
+ * assertThat(1).asBinary().isEqualTo(2); + * + * org.junit.ComparisonFailure: + * Expected :0b00000000_00000000_00000000_00000010 + * Actual :0b00000000_00000000_00000000_00000001 + * + * @return {@code this} assertion object. + */ + protected S asBinary() { + info.representationAsBinary(); + return myself; + } + /** {@inheritDoc} */ @Override public S describedAs(String description, Object... args) { diff --git a/src/main/java/org/assertj/core/api/AbstractCharSequenceAssert.java b/src/main/java/org/assertj/core/api/AbstractCharSequenceAssert.java index ed8da5ea30..5e605b0ced 100644 --- a/src/main/java/org/assertj/core/api/AbstractCharSequenceAssert.java +++ b/src/main/java/org/assertj/core/api/AbstractCharSequenceAssert.java @@ -594,4 +594,45 @@ public S usingDefaultComparator() { this.strings = Strings.instance(); return myself; } + + @Override + public S asHexadecimal() { + return super.asHexadecimal(); + } + + /** + * Use unicode character representation instead of standard representation in error messages. + * + * It can be useful when comparing UNICODE characters - many unicode chars have duplicate characters assigned, + * it is thus impossible to find differences from the standard error message: + * + * With standard message: + ** - * Method is public because we need to call it from {@link ShouldBeEqual#newAssertionError(org.assertj.core.description.Description)} that is building a junit ComparisonFailure by reflection. + * Method is public because we need to call it from {@link ShouldBeEqual#newAssertionError(Description, org.assertj.core.presentation.Representation)} that is building a junit ComparisonFailure by reflection. * * @param assertionError the {@code AssertionError} to filter stack trace if option is set. */ diff --git a/src/main/java/org/assertj/core/internal/Objects.java b/src/main/java/org/assertj/core/internal/Objects.java index fccc14ca61..84b95b366f 100644 --- a/src/main/java/org/assertj/core/internal/Objects.java +++ b/src/main/java/org/assertj/core/internal/Objects.java @@ -38,7 +38,6 @@ import static org.assertj.core.internal.CommonValidations.checkTypeIsNotNull; import static org.assertj.core.util.Lists.*; import static org.assertj.core.util.Sets.*; -import static org.assertj.core.util.ToString.toStringOf; import java.lang.reflect.Field; import java.util.Comparator; @@ -93,7 +92,7 @@ public Comparator> getComparator() { /** * Verifies that the given object is an instance of the given type. - * + * * @param info contains information about the assertion. * @param actual the given object. * @param type the type to check the given object against. @@ -107,7 +106,7 @@ public void assertIsInstanceOf(AssertionInfo info, Object actual, Class> type) /** * Verifies that the given object is an instance of any of the given types. - * + * * @param info contains information about the assertion. * @param actual the given object. * @param types the types to check the given object against. @@ -128,7 +127,7 @@ private boolean objectIsInstanceOfOneOfGivenClasses(Object actual, Class>[] ty for (Class> type : types) { if (type == null) { String format = "The given array of types:<%s> should not have null elements"; - throw new NullPointerException(format(format, toStringOf(types))); + throw new NullPointerException(format(format, info.representation().toStringOf(types))); } if (type.isInstance(actual)) { return true; @@ -139,7 +138,7 @@ private boolean objectIsInstanceOfOneOfGivenClasses(Object actual, Class>[] ty /** * Verifies that the given object is not an instance of the given type. - * + * * @param info contains information about the assertion. * @param actual the given object. * @param type the type to check the given object against. @@ -159,7 +158,7 @@ private boolean isInstanceOfClass(Object actual, Class> clazz, AssertionInfo i /** * Verifies that the given object is not an instance of any of the given types. - * + * * @param info contains information about the assertion. * @param actual the given object. * @param types the types to check the given object against. @@ -176,7 +175,7 @@ public void assertIsNotInstanceOfAny(AssertionInfo info, Object actual, Class> /** * Verifies that the actual value has the same class as the given object. - * + * * @param info contains information about the assertion. * @param actual the given object. * @throws AssertionError if the actual has not the same type has the given object. @@ -199,7 +198,7 @@ private boolean haveSameClass(Object actual, Object other, AssertionInfo info) { /** * Verifies that the actual value does not have the same class as the given object. - * + * * @param info contains information about the assertion. * @param actual the given object. * @param other the object to check type against. @@ -213,7 +212,7 @@ public void assertDoesNotHaveSameClassAs(AssertionInfo info, Object actual, Obje /** * Verifies that the actual value is exactly a instance of given type. - * + * * @param info contains information about the assertion. * @param actual the given object. * @param type the type to check the actual value against. @@ -234,7 +233,7 @@ private boolean actualIsExactlyInstanceOfType(Object actual, Class> expectedTy /** * Verifies that the actual value is not exactly a instance of given type. - * + * * @param info contains information about the assertion. * @param actual the given object. * @param type the type to check the actual value against. @@ -249,7 +248,7 @@ public void assertIsNotExactlyInstanceOf(AssertionInfo info, Object actual, Clas /** * Verifies that the actual value type is in given types. - * + * * @param info contains information about the assertion. * @param actual the given object. * @param types the types to check the actual value against. @@ -270,7 +269,7 @@ private boolean isOfOneOfGivenTypes(Object actual, Class>[] types, AssertionIn /** * Verifies that the actual value type is not in given types. - * + * * @param info contains information about the assertion. * @param actual the given object. * @param types the types to check the actual value against. @@ -294,7 +293,7 @@ private void checkIsNotNullAndIsNotEmpty(Class>[] types) { /** * Asserts that two objects are equal. - * + * * @param info contains information about the assertion. * @param actual the "actual" object. * @param expected the "expected" object. @@ -306,12 +305,12 @@ public void assertEqual(AssertionInfo info, Object actual, Object expected) { if (areEqual(actual, expected)) { return; } - throw failures.failure(info, shouldBeEqual(actual, expected, comparisonStrategy)); + throw failures.failure(info, shouldBeEqual(actual, expected, comparisonStrategy, info.representation())); } /** * Asserts that two objects are not equal. - * + * * @param info contains information about the assertion. * @param actual the given object. * @param other the object to compare {@code actual} to. @@ -326,7 +325,7 @@ public void assertNotEqual(AssertionInfo info, Object actual, Object other) { /** * Compares actual and other with standard strategy (null safe equals check). - * + * * @param actual the object to compare to other * @param other the object to compare to actual * @return true if actual and other are equal (null safe equals check), false otherwise. @@ -337,7 +336,7 @@ private boolean areEqual(Object actual, Object other) { /** * Asserts that the given object is {@code null}. - * + * * @param info contains information about the assertion. * @param actual the given object. * @throws AssertionError if the given object is not {@code null}. @@ -346,12 +345,12 @@ public void assertNull(AssertionInfo info, Object actual) { if (actual == null) { return; } - throw failures.failure(info, shouldBeEqual(actual, null, comparisonStrategy)); + throw failures.failure(info, shouldBeEqual(actual, null, comparisonStrategy, info.representation())); } /** * Asserts that the given object is not {@code null}. - * + * * @param info contains information about the assertion. * @param actual the given object. * @throws AssertionError if the given object is {@code null}. @@ -365,7 +364,7 @@ public void assertNotNull(AssertionInfo info, Object actual) { /** * Asserts that two objects refer to the same object. - * + * * @param info contains information about the assertion. * @param actual the given object. * @param expected the expected object. @@ -380,7 +379,7 @@ public void assertSame(AssertionInfo info, Object actual, Object expected) { /** * Asserts that two objects do not refer to the same object. - * + * * @param info contains information about the assertion. * @param actual the given object. * @param other the object to compare {@code actual} to. @@ -395,7 +394,7 @@ public void assertNotSame(AssertionInfo info, Object actual, Object other) { /** * Asserts that the given object is present in the given array. - * + * * @param info contains information about the assertion. * @param actual the given object. * @param values the given array. @@ -414,7 +413,7 @@ public void assertIsIn(AssertionInfo info, Object actual, Object[] values) { /** * Asserts that the given object is not present in the given array. - * + * * @param info contains information about the assertion. * @param actual the given object. * @param values the given array. @@ -442,7 +441,7 @@ private void checkIsNotNullAndNotEmpty(Object[] values) { /** * Returns+ * assertThat("µµµ").contains("μμμ"); + * + * java.lang.AssertionError: + * Expecting: + * <"µµµ"> + * to contain: + * <"μμμ"> + *+ * + * With Hexadecimal message: + *+ * assertThat("µµµ").asUnicode().contains("μμμ"); + * + * java.lang.AssertionError: + * Expecting: + * <\u00b5\u00b5\u00b5> + * to contain: + * <\u03bc\u03bc\u03bc> + *+ * + * @return {@code this} assertion object. + */ + public S asUnicode() { + info.representationAsUnicode(); + return myself; + } + } diff --git a/src/main/java/org/assertj/core/api/AbstractCharacterAssert.java b/src/main/java/org/assertj/core/api/AbstractCharacterAssert.java index 069f6026c9..c8ab721893 100644 --- a/src/main/java/org/assertj/core/api/AbstractCharacterAssert.java +++ b/src/main/java/org/assertj/core/api/AbstractCharacterAssert.java @@ -150,6 +150,38 @@ public S isGreaterThan(char other) { return myself; } + /** + /** + * Use unicode character representation instead of standard representation in error messages. + * + * It can be useful when comparing UNICODE characters - many unicode chars have duplicate characters assigned, + * it is thus impossible to find differences from the standard error message: + * + * With standard error message: + *+ * assertThat('µ').isEqualTo('μ'); + * + * org.junit.ComparisonFailure: + * Expected :'μ' + * Actual :'µ' + *+ * + * With unicode based error message: + *+ * assertThat('µ').asUnicode().isEqualTo('μ'); + * + * org.junit.ComparisonFailure: + * Expected :\u03bc + * Actual :\u00b5 + *+ * + * @return {@code this} assertion object. + */ + public S asUnicode() { + info.representationAsUnicode(); + return myself; + } + /** * Verifies that the actual value is greater than or equal to the given one. *@@ -195,6 +227,7 @@ public S isGreaterThanOrEqualTo(char other) { * @throws AssertionError if the actual value is {@code null}. * @throws AssertionError if the actual value is not a lowercase character. */ + public S isLowerCase() { characters.assertLowerCase(info, actual); return myself; diff --git a/src/main/java/org/assertj/core/api/AbstractComparableAssert.java b/src/main/java/org/assertj/core/api/AbstractComparableAssert.java index 31ad297599..3644b475c8 100644 --- a/src/main/java/org/assertj/core/api/AbstractComparableAssert.java +++ b/src/main/java/org/assertj/core/api/AbstractComparableAssert.java @@ -80,4 +80,14 @@ public S usingDefaultComparator() { this.comparables = Comparables.instance(); return myself; } + + @Override + public S asHexadecimal() { + return super.asHexadecimal(); + } + + @Override + public S asBinary() { + return super.asBinary(); + } } diff --git a/src/main/java/org/assertj/core/api/AbstractDateAssert.java b/src/main/java/org/assertj/core/api/AbstractDateAssert.java index 2ef205c0a7..efbe9698b2 100644 --- a/src/main/java/org/assertj/core/api/AbstractDateAssert.java +++ b/src/main/java/org/assertj/core/api/AbstractDateAssert.java @@ -3,7 +3,6 @@ import static org.assertj.core.util.Dates.newIsoDateFormat; import static org.assertj.core.util.Dates.newIsoDateTimeFormat; import static org.assertj.core.util.Dates.newIsoDateTimeWithMsFormat; -import static org.assertj.core.util.ToString.toStringOf; import java.text.DateFormat; import java.text.ParseException; @@ -2157,7 +2156,7 @@ public static void useDefaultDateFormats() { * @throws AssertionError if the string can't be parsed as a Date */ @VisibleForTesting - static Date parse(String dateAsString) { + Date parse(String dateAsString) { if (dateAsString == null) return null; // use synchronized block because SimpleDateFormat which is not thread safe (sigh). // parse with date format specified by user @@ -2167,7 +2166,7 @@ static Date parse(String dateAsString) { return customDateFormat.parse(dateAsString); } catch (ParseException e) { throw new AssertionError("Failed to parse " + dateAsString + " with date format: " - + toStringOf(customDateFormat)); + + info.representation().toStringOf(customDateFormat)); } } } @@ -2182,7 +2181,7 @@ static Date parse(String dateAsString) { } // no suitable date format throw new AssertionError("Failed to parse " + dateAsString + " with any of these date formats: " - + toStringOf(defaultDateFormats)); + + info.representation().toStringOf(defaultDateFormats)); } } diff --git a/src/main/java/org/assertj/core/api/AbstractEnumerableAssert.java b/src/main/java/org/assertj/core/api/AbstractEnumerableAssert.java index a76e8c3836..fd47403c4e 100644 --- a/src/main/java/org/assertj/core/api/AbstractEnumerableAssert.java +++ b/src/main/java/org/assertj/core/api/AbstractEnumerableAssert.java @@ -40,4 +40,47 @@ public S hasSameSizeAs(Object other) { protected AbstractEnumerableAssert(final A actual, final Class> selfType) { super(actual, selfType); } + + /** + * Enable hexadecimal object representation of Itearble elements instead of standard java representation in error messages. + *
+ * It can be useful to better understand what the error was with a more meaningful error message. + * + * Example + *+ * assertThat(new byte[]{0x10,0x20}).asHex().contains(new byte[]{0x30}); + *+ * + * With standard error message: + *+ * Expecting: + * <[16, 32]> + * to contain: + * <[48]> + * but could not find: + * <[48]> + *+ * + * With Hexadecimal error message: + *+ * Expecting: + * <[0x10, 0x20]> + * to contain: + * <[0x30]> + * but could not find: + * <[0x30]> + *+ * + * @return {@code this} assertion object. + */ + @Override + public S asHexadecimal() { + return super.asHexadecimal(); + } + + @Override + public S asBinary() { + return super.asBinary(); + } + } diff --git a/src/main/java/org/assertj/core/api/AbstractIterableAssert.java b/src/main/java/org/assertj/core/api/AbstractIterableAssert.java index 7a99931787..a0e2b649da 100644 --- a/src/main/java/org/assertj/core/api/AbstractIterableAssert.java +++ b/src/main/java/org/assertj/core/api/AbstractIterableAssert.java @@ -763,4 +763,84 @@ protected S usingComparisonStrategy(ComparisonStrategy comparisonStrategy) { public S usingElementComparatorIgnoringFields(String... fields) { return usingComparisonStrategy(new IgnoringFieldsComparisonStrategy(fields)); } + + /** + * Enable hexadecimal representation of Iterable elements instead of standard representation in error messages. + * + * It can be useful to better understand what the error was with a more meaningful error message. + * + * Example + *+ * final List+ * + * With standard error message: + *bytes = newArrayList((byte)0x10, (byte) 0x20); + * + * assertThat(bytes).contains((byte)0x30); + * + * Expecting: + * <[16, 32]> + * to contain: + * <[48]> + * but could not find: + * <[48]> + *+ * + * With Hexadecimal error message: + *+ * assertThat(bytes).asHexadecimal().contains((byte)0x30); + * + * Expecting: + * <[0x10, 0x20]> + * to contain: + * <[0x30]> + * but could not find: + * <[0x30]> + *+ * + * @return {@code this} assertion object. + */ + @Override + public S asHexadecimal() { // TODO rename to asHexadecimalElements() ? + return super.asHexadecimal(); + } + + /** + * Enable binary representation of Iterable elements instead of standard representation in error messages. + * + * Example: + *+ * final List+ * + * With standard error message: + *bytes = newArrayList((byte)0x10, (byte) 0x20); + * + * assertThat(bytes).contains((byte)0x30); + * + * Expecting: + * <[16, 32]> + * to contain: + * <[48]> + * but could not find: + * <[48]> + *+ * + * With binary error message: + *+ * assertThat(bytes).asBinary().contains((byte)0x30); + * + * Expecting: + * <[0b00010000, 0b00100000]> + * to contain: + * <[0b00110000]> + * but could not find: + * <[0b00110000]> + *+ * + * @return {@code this} assertion object. + */ + @Override + public S asBinary() { + return super.asBinary(); + } } diff --git a/src/main/java/org/assertj/core/api/AbstractObjectArrayAssert.java b/src/main/java/org/assertj/core/api/AbstractObjectArrayAssert.java index 5bcdb3d408..522f14ae90 100644 --- a/src/main/java/org/assertj/core/api/AbstractObjectArrayAssert.java +++ b/src/main/java/org/assertj/core/api/AbstractObjectArrayAssert.java @@ -528,5 +528,46 @@ publicObjectArrayAssert
extractingResultOf(String method, Class
extra return new ObjectArrayAssert
(values); } - + + /** + * Enable hexadecimal object representation of Itearble elements instead of standard java representation in error messages. + *
+ * It can be useful to better understand what the error was with a more meaningful error message. + * + * Example + *+ * assertThat(new Byte[]{0x10,0x20}).asHexadecimal().contains(new Byte[]{0x30}); + *+ * + * With standard error message: + *+ * Expecting: + * <[16, 32]> + * to contain: + * <[48]> + * but could not find: + * <[48]> + *+ * + * With Hexadecimal error message: + *+ * Expecting: + * <[0x10, 0x20]> + * to contain: + * <[0x30]> + * but could not find: + * <[0x30]> + *+ * + * @return {@code this} assertion object. + */ + @Override + public S asHexadecimal() { + return super.asHexadecimal(); + } + + @Override + public S asBinary() { + return super.asBinary(); + } } diff --git a/src/main/java/org/assertj/core/api/AssertionInfo.java b/src/main/java/org/assertj/core/api/AssertionInfo.java index c7a843983e..f5f2a0c22a 100644 --- a/src/main/java/org/assertj/core/api/AssertionInfo.java +++ b/src/main/java/org/assertj/core/api/AssertionInfo.java @@ -15,6 +15,7 @@ package org.assertj.core.api; import org.assertj.core.description.Description; +import org.assertj.core.presentation.Representation; /** * Information about an assertion. @@ -36,4 +37,5 @@ public interface AssertionInfo { */ Description description(); + Representation representation(); } \ No newline at end of file diff --git a/src/main/java/org/assertj/core/api/WritableAssertionInfo.java b/src/main/java/org/assertj/core/api/WritableAssertionInfo.java index 475d5fe91c..bb901b02da 100644 --- a/src/main/java/org/assertj/core/api/WritableAssertionInfo.java +++ b/src/main/java/org/assertj/core/api/WritableAssertionInfo.java @@ -21,11 +21,14 @@ import org.assertj.core.description.Description; import org.assertj.core.description.EmptyTextDescription; +import org.assertj.core.presentation.*; +import org.assertj.core.presentation.BinaryRepresentation; +import org.assertj.core.presentation.HexadecimalRepresentation; /** * Writable information about an assertion. - * + * * @author Alex Ruiz * @author Yvonne Wang */ @@ -33,8 +36,11 @@ public class WritableAssertionInfo implements AssertionInfo { private String overridingErrorMessage; private Description description; + private Representation representation; - /** {@inheritDoc} */ + /** + * {@inheritDoc} + */ @Override public String overridingErrorMessage() { return overridingErrorMessage; @@ -42,20 +48,25 @@ public String overridingErrorMessage() { /** * Sets the message that will replace the default message of an assertion failure. + * * @param newErrorMessage the new message. It can be {@code null}. */ public void overridingErrorMessage(String newErrorMessage) { overridingErrorMessage = newErrorMessage; } - /** {@inheritDoc} */ + /** + * {@inheritDoc} + */ @Override public Description description() { return description; } + /** * Returns the text of this object's description, or {@code null} if such description is {@code null}. + * * @return the text of this object's description, or {@code null} if such description is {@code null}. */ public String descriptionText() { @@ -64,8 +75,9 @@ public String descriptionText() { /** * Sets the description of an assertion. + * * @param newDescription the new description. - * @param args if {@code newDescription} is a format String, {@code args} is argument of {@link String#format(String, Object...)} + * @param args if {@code newDescription} is a format String, {@code args} is argument of {@link String#format(String, Object...)} * @throws NullPointerException if the given description is {@code null}. * @see #description(Description) */ @@ -76,6 +88,7 @@ public void description(String newDescription, Object... args) { /** * Sets the description of an assertion. To remove or clear the description, pass a{@link EmptyTextDescription}
as * argument. + * * @param newDescription the new description. * @throws NullPointerException if the given description is {@code null}. */ @@ -83,7 +96,36 @@ public void description(Description newDescription) { description = checkIsNotNull(newDescription); } - /** {@inheritDoc} */ + /** + * {@inheritDoc} + */ + @Override + public Representation representation() { + if (representation == null) { + representation = new StandardRepresentation(); + } + return representation; + } + + public void representationAsHexadecimal() { + representation = new HexadecimalRepresentation(); + } + + public void representationAsUnicode() { + representation = new UnicodeRepresentation(); + } + + public void representationAsBinary() { + representation = new BinaryRepresentation(); + } + + public void representation(Representation newRepresentation) { + representation = newRepresentation; + } + + /** + * {@inheritDoc} + */ @Override public String toString() { String format = "%s[overridingErrorMessage=%s, description=%s]"; diff --git a/src/main/java/org/assertj/core/error/AbstractShouldHaveTextContent.java b/src/main/java/org/assertj/core/error/AbstractShouldHaveTextContent.java index 293423b8f6..5927bb5e20 100644 --- a/src/main/java/org/assertj/core/error/AbstractShouldHaveTextContent.java +++ b/src/main/java/org/assertj/core/error/AbstractShouldHaveTextContent.java @@ -5,6 +5,7 @@ import java.util.List; import org.assertj.core.description.Description; +import org.assertj.core.presentation.Representation; /** @@ -23,7 +24,7 @@ public AbstractShouldHaveTextContent(String format, Object... arguments) { } @Override - public String create(Description d) { + public String create(Description d, Representation representation) { // we append diffs here as we can't add in super constructor call, see why below. // // case 1 - append diffs to String passed in super : @@ -37,7 +38,7 @@ public String create(Description d) { // error message. This is not what we want // // The solution is to keep diffs as an attribute and append it after String.format has been applied on the error message. - return super.create(d) + diffs; + return super.create(d, representation) + diffs; } protected static String diffsAsString(ListdiffsList) { diff --git a/src/main/java/org/assertj/core/error/AssertionErrorFactory.java b/src/main/java/org/assertj/core/error/AssertionErrorFactory.java index c70ddbe1af..d36b6a24b0 100644 --- a/src/main/java/org/assertj/core/error/AssertionErrorFactory.java +++ b/src/main/java/org/assertj/core/error/AssertionErrorFactory.java @@ -15,6 +15,7 @@ package org.assertj.core.error; import org.assertj.core.description.Description; +import org.assertj.core.presentation.Representation; /** * Factory of {@link AssertionError}
s. @@ -27,7 +28,8 @@ public interface AssertionErrorFactory { /** * Creates an{@link AssertionError}
. * @param d the description of the failed assertion. + * @param representation * @return the created {@code AssertionError}. */ - AssertionError newAssertionError(Description d); + AssertionError newAssertionError(Description d, Representation representation); } diff --git a/src/main/java/org/assertj/core/error/BasicErrorMessageFactory.java b/src/main/java/org/assertj/core/error/BasicErrorMessageFactory.java index 86f2823beb..8063622a7a 100644 --- a/src/main/java/org/assertj/core/error/BasicErrorMessageFactory.java +++ b/src/main/java/org/assertj/core/error/BasicErrorMessageFactory.java @@ -26,6 +26,8 @@ import org.assertj.core.description.Description; import org.assertj.core.description.EmptyTextDescription; +import org.assertj.core.presentation.Representation; +import org.assertj.core.presentation.StandardRepresentation; import org.assertj.core.util.VisibleForTesting; /** @@ -114,14 +116,14 @@ public BasicErrorMessageFactory(String format, Object... arguments) { /** {@inheritDoc} */ @Override - public String create(Description d) { - return formatter.format(d, format, arguments); + public String create(Description d, Representation representation) { + return formatter.format(d, representation, format, arguments); } /** {@inheritDoc} */ @Override public String create() { - return formatter.format(EmptyTextDescription.emptyText(), format, arguments); + return formatter.format(EmptyTextDescription.emptyText(), new StandardRepresentation(), format, arguments); } /** @@ -161,7 +163,8 @@ public int hashCode() { @Override public String toString() { - return format("%s[format=%s, arguments=%s]", getClass().getSimpleName(), quote(format), format(arguments)); + return format("%s[format=%s, arguments=%s]", getClass().getSimpleName(), quote(format), + format(new StandardRepresentation(), arguments)); } } diff --git a/src/main/java/org/assertj/core/error/ErrorMessageFactory.java b/src/main/java/org/assertj/core/error/ErrorMessageFactory.java index 410a8bccbf..f74f249bc3 100644 --- a/src/main/java/org/assertj/core/error/ErrorMessageFactory.java +++ b/src/main/java/org/assertj/core/error/ErrorMessageFactory.java @@ -15,6 +15,7 @@ package org.assertj.core.error; import org.assertj.core.description.Description; +import org.assertj.core.presentation.Representation; /** * Factory of error messages. @@ -26,9 +27,10 @@ public interface ErrorMessageFactory { /** * Creates a new error message as a result of a failed assertion. * @param d the description of the failed assertion. + * @param p * @return the created error message. */ - String create(Description d); + String create(Description d, Representation p); /** * Creates a new error message as a result of a failed assertion without description. diff --git a/src/main/java/org/assertj/core/error/MessageFormatter.java b/src/main/java/org/assertj/core/error/MessageFormatter.java index 327e206b58..c9b9f2e912 100644 --- a/src/main/java/org/assertj/core/error/MessageFormatter.java +++ b/src/main/java/org/assertj/core/error/MessageFormatter.java @@ -16,15 +16,13 @@ import static org.assertj.core.util.Preconditions.checkNotNull; import static org.assertj.core.util.Strings.formatIfArgs; -import static org.assertj.core.util.ToString.toStringOf; import org.assertj.core.description.Description; import org.assertj.core.internal.ComparatorBasedComparisonStrategy; import org.assertj.core.internal.StandardComparisonStrategy; -import org.assertj.core.util.ToString; +import org.assertj.core.presentation.Representation; import org.assertj.core.util.VisibleForTesting; - /** * Formats the messages to be included in assertion errors. * @@ -41,7 +39,8 @@ public static MessageFormatter instance() { DescriptionFormatter descriptionFormatter = DescriptionFormatter.instance(); @VisibleForTesting - MessageFormatter() {} + MessageFormatter() { + } /** * Interprets a printf-style format {@code String} for failed assertion messages. It is similar to @@ -50,7 +49,7 @@ public static MessageFormatter instance() { *the value of the given *{@link Description}
is used as the first argument referenced in the format * stringeach of the arguments in the given array is converted to a {@code String} by invoking - * {@link ToString#toStringOf(Object)}
. + *{@link org.assertj.core.presentation.Representation#toStringOf(Object)}
. * * * @param d the description of the failed assertion, may be {@code null}. @@ -59,28 +58,28 @@ public static MessageFormatter instance() { * @throws NullPointerException if the format string is {@code null}. * @return A formatted {@code String}. */ - public String format(Description d, String format, Object... args) { + public String format(Description d, Representation p, String format, Object... args) { checkNotNull(format); checkNotNull(args); - return descriptionFormatter.format(d) + formatIfArgs(format, format(args)); + return descriptionFormatter.format(d) + formatIfArgs(format, format(p, args)); } - private Object[] format(Object[] args) { + private Object[] format(Representation p, Object[] args) { int argCount = args.length; String[] formatted = new String[argCount]; for (int i = 0; i < argCount; i++) { - formatted[i] = asText(args[i]); + formatted[i] = asText(p, args[i]); } return formatted; } - private String asText(Object o) { + private String asText(Representation p, Object o) { if (o instanceof ComparatorBasedComparisonStrategy) { return "according to " + o + " comparator"; } if (o instanceof StandardComparisonStrategy) { return ""; } - return toStringOf(o); + return p.toStringOf(o); } } diff --git a/src/main/java/org/assertj/core/error/ShouldBeBetween.java b/src/main/java/org/assertj/core/error/ShouldBeBetween.java index 7c08e94149..d7177588f8 100644 --- a/src/main/java/org/assertj/core/error/ShouldBeBetween.java +++ b/src/main/java/org/assertj/core/error/ShouldBeBetween.java @@ -92,7 +92,7 @@ private ShouldBeBetween(Date actual, Date start, Date end, boolean inclusiveStar } private> ShouldBeBetween(T actual, T start, T end, boolean inclusiveStart, boolean inclusiveEnd, - ComparisonStrategy comparisonStrategy) { + ComparisonStrategy comparisonStrategy) { super("\nExpecting:\n <%s>\nto be between:\n " + (inclusiveStart ? '[' : ']') +"%s, %s%s" + (inclusiveEnd ? ']' : '['), actual, start, end, comparisonStrategy); } diff --git a/src/main/java/org/assertj/core/error/ShouldBeEqual.java b/src/main/java/org/assertj/core/error/ShouldBeEqual.java index 66431b0d6f..6863f63f2b 100644 --- a/src/main/java/org/assertj/core/error/ShouldBeEqual.java +++ b/src/main/java/org/assertj/core/error/ShouldBeEqual.java @@ -21,10 +21,10 @@ import static org.assertj.core.util.Arrays.array; import static org.assertj.core.util.Objects.*; -import static org.assertj.core.util.ToString.toStringOf; import org.assertj.core.description.Description; import org.assertj.core.internal.*; +import org.assertj.core.presentation.Representation; import org.assertj.core.util.VisibleForTesting; @@ -51,6 +51,7 @@ public class ShouldBeEqual implements AssertionErrorFactory { @VisibleForTesting final MessageFormatter messageFormatter = MessageFormatter.instance(); private final ComparisonStrategy comparisonStrategy; + private Representation representation; @VisibleForTesting ConstructorInvoker constructorInvoker = new ConstructorInvoker(); @VisibleForTesting @@ -63,8 +64,8 @@ public class ShouldBeEqual implements AssertionErrorFactory { * @param expected the expected value in the failed assertion. * @return the created {@code AssertionErrorFactory}. */ - public static AssertionErrorFactory shouldBeEqual(Object actual, Object expected) { - return new ShouldBeEqual(actual, expected, StandardComparisonStrategy.instance()); + public static AssertionErrorFactory shouldBeEqual(Object actual, Object expected, Representation representation) { + return new ShouldBeEqual(actual, expected, StandardComparisonStrategy.instance(), representation); } /** @@ -76,15 +77,16 @@ public static AssertionErrorFactory shouldBeEqual(Object actual, Object expected * @return the created {@code AssertionErrorFactory}. */ public static AssertionErrorFactory shouldBeEqual(Object actual, Object expected, - ComparisonStrategy comparisonStrategy) { - return new ShouldBeEqual(actual, expected, comparisonStrategy); + ComparisonStrategy comparisonStrategy, Representation representation) { + return new ShouldBeEqual(actual, expected, comparisonStrategy, representation); } @VisibleForTesting - ShouldBeEqual(Object actual, Object expected, ComparisonStrategy comparisonStrategy) { + ShouldBeEqual(Object actual, Object expected, ComparisonStrategy comparisonStrategy, Representation representation) { this.actual = actual; this.expected = expected; this.comparisonStrategy = comparisonStrategy; + this.representation = representation; } /** @@ -98,10 +100,11 @@ public static AssertionErrorFactory shouldBeEqual(Object actual, Object expected * (see {@link Failures#setRemoveAssertJRelatedElementsFromStackTrace(boolean)}). * * @param description the description of the failed assertion. + * @param representation * @return the created {@code AssertionError}. */ @Override - public AssertionError newAssertionError(Description description) { + public AssertionError newAssertionError(Description description, Representation representation) { if (actualAndExpectedHaveSameStringRepresentation()) { // Example : actual = 42f and expected = 42d gives actual : "42" and expected : "42" and // JUnit 4 manages this case even worst, it will output something like : @@ -109,7 +112,7 @@ public AssertionError newAssertionError(Description description) { // which does not solve the problem and makes things even more confusing since we lost the fact that 42 was a // float or a double, it is then better to built our own description, with the drawback of not using a // ComparisonFailure (which looks nice in eclipse) - return Failures.instance().failure(defaultDetailedErrorMessage(description)); + return Failures.instance().failure(defaultDetailedErrorMessage(description, representation)); } // if comparison strategy was based on a custom comparator, we build the assertion error message, the result is // better than the JUnit ComparisonFailure we could build (that would not mention the comparator). @@ -119,11 +122,11 @@ public AssertionError newAssertionError(Description description) { if (error != null) { return error; } } // No JUnit in the classpath => fall back to default error message. - return Failures.instance().failure(defaultErrorMessage(description)); + return Failures.instance().failure(defaultErrorMessage(description, representation)); } /** - * Tells {@link #newAssertionError(Description)} if it should try a build a {@link org.junit.ComparisonFailure}.
+ * Tells {@link AssertionErrorFactory#newAssertionError(org.assertj.core.description.Description, org.assertj.core.presentation.Representation)} if it should try a build a {@link org.junit.ComparisonFailure}.
* Returnstrue
as we try in this class (may not be the case in subclasses). * * @returntrue
@@ -136,7 +139,7 @@ private boolean isJUnitComparisonFailureRelevant() { } private boolean actualAndExpectedHaveSameStringRepresentation() { - return areEqual(toStringOf(actual), toStringOf(expected)); + return areEqual(representation.toStringOf(actual), representation.toStringOf(expected)); } /** @@ -144,13 +147,14 @@ private boolean actualAndExpectedHaveSameStringRepresentation() { * representation. * * @param description the {@link Description} used to build the returned error message + * @param representation the {@link org.assertj.core.presentation.Representation} used to build String representation of object * @return the error message from description using {@link #expected} and {@link #actual} basic representation. */ - private String defaultErrorMessage(Description description) { + private String defaultErrorMessage(Description description, Representation representation) { if (comparisonStrategy instanceof ComparatorBasedComparisonStrategy) return messageFormatter - .format(description, EXPECTED_BUT_WAS_MESSAGE_USING_COMPARATOR, actual, expected, comparisonStrategy); - return messageFormatter.format(description, EXPECTED_BUT_WAS_MESSAGE, expected, actual); + .format(description, representation, EXPECTED_BUT_WAS_MESSAGE_USING_COMPARATOR, actual, expected, comparisonStrategy); + return messageFormatter.format(description, representation, EXPECTED_BUT_WAS_MESSAGE, expected, actual); } /** @@ -158,14 +162,15 @@ private String defaultErrorMessage(Description description) { * #detailedActual()} detailed representation. * * @param description the {@link Description} used to build the returned error message + * @param representation the {@link org.assertj.core.presentation.Representation} used to build String representation of object * @return the error message from description using {@link #detailedExpected()} and {@link #detailedActual()} * detailed representation. */ - private String defaultDetailedErrorMessage(Description description) { + private String defaultDetailedErrorMessage(Description description, Representation representation) { if (comparisonStrategy instanceof ComparatorBasedComparisonStrategy) - return messageFormatter.format(description, EXPECTED_BUT_WAS_MESSAGE_USING_COMPARATOR, detailedActual(), + return messageFormatter.format(description, representation, EXPECTED_BUT_WAS_MESSAGE_USING_COMPARATOR, detailedActual(), detailedExpected(), comparisonStrategy); - return messageFormatter.format(description, EXPECTED_BUT_WAS_MESSAGE, detailedExpected(), detailedActual()); + return messageFormatter.format(description, representation, EXPECTED_BUT_WAS_MESSAGE, detailedExpected(), detailedActual()); } private AssertionError comparisonFailure(Description description) { @@ -185,11 +190,11 @@ private AssertionError newComparisonFailure(String description) throws Exception } private Object[] msgArgs(String description) { - return array(description, toStringOf(expected), toStringOf(actual)); + return array(description, representation.toStringOf(expected), representation.toStringOf(actual)); } - private static String detailedToStringOf(Object obj) { - return toStringOf(obj) + " (" + obj.getClass().getSimpleName() + "@" + toHexString(obj.hashCode()) + ")"; + private String detailedToStringOf(Object obj) { + return representation.toStringOf(obj) + " (" + obj.getClass().getSimpleName() + "@" + toHexString(obj.hashCode()) + ")"; } private String detailedActual() { diff --git a/src/main/java/org/assertj/core/groups/Tuple.java b/src/main/java/org/assertj/core/groups/Tuple.java index 1dd4ca3427..8eb860979d 100644 --- a/src/main/java/org/assertj/core/groups/Tuple.java +++ b/src/main/java/org/assertj/core/groups/Tuple.java @@ -19,12 +19,8 @@ import java.util.ArrayList; import java.util.List; -import org.assertj.core.util.Collections; - public class Tuple { - private static final String END = ")"; - private static final String START = "("; private final List
true
if given item is in given array, false
otherwise.
- *
+ *
* @param item the object to look for in arrayOfValues
* @param arrayOfValues the array of values
* @return true
if given item is in given array, false
otherwise.
@@ -456,7 +455,7 @@ private boolean isItemInArray(Object item, Object[] arrayOfValues) {
/**
* Asserts that the given object is present in the given collection.
- *
+ *
* @param info contains information about the assertion.
* @param actual the given object.
* @param values the given iterable.
@@ -475,7 +474,7 @@ public void assertIsIn(AssertionInfo info, Object actual, Iterable> values) {
/**
* Asserts that the given object is not present in the given collection.
- *
+ *
* @param info contains information about the assertion.
* @param actual the given object.
* @param values the given collection.
@@ -513,7 +512,7 @@ private boolean isActualIn(Object actual, Iterable> values) {
/**
* Assert that the given object is lenient equals by ignoring null fields value on other object (including inherited
* fields).
- *
+ *
* @param info contains information about the assertion.
* @param actual the given object.
* @param other the object to compare {@code actual} to.
@@ -552,7 +551,7 @@ public void assertIsLenientEqualsToIgnoringNullFields(AssertionInfo info, A
/**
* Assert that the given object is lenient equals to other object by comparing given fields value only.
- *
+ *
* @param info contains information about the assertion.
* @param actual the given object.
* @param other the object to compare {@code actual} to.
@@ -613,7 +612,7 @@ private Field findField(String fieldName, Setjava.lang
* package whose fields are not included.
- *
+ *
* @param clazz the class we want the declared fields.
* @return the declared fields of given class and its superclasses.
*/
@@ -697,7 +696,7 @@ private static Set