Repository: assertj/assertj

Problem statement:
Remove space in default error message for ShouldBeEqual to help IntelliJ diff detection
Referencing this StackOverflow ticket: https://stackoverflow.com/questions/10934743/formatting-output-so-that-intellij-idea-shows-diffs-for-two-texts

It seems that IntelliJ expects assertion errors to be in this format in order to have nicely rendered diffs:

`expected: xxx but was: yyy`

But AssertJ would format this with an extra space after the `was`:

`expected: xxx but was : yyy`

Which would cause it to fail the regex, and IntelliJ defaults to just printing the error string. I tried patching my AssertJ `ShouldBeEqual` locally without that extra space, and IntelliJ was then able to detect it properly.

Would it be possible to remove the extraneous space after the `was` so that the test output can automatically be detected as a diff?

Thanks!

Link to message: https://github.com/assertj/assertj-core/blob/main/src/main/java/org/assertj/core/error/ShouldBeEqual.java#L44


Hints:
We did that to get values aligned but I guess we can remove that space for intellij idea
```
expected:
but was :
```
@rpeng could we do that instead?:
```
expected:
 but was:
```
@scordio did you have that issue? can you try that second proposal to see if it renders properly?

Just tried it out with the second proposal (leading space) and it works in IntelliJ! For reference, the detectable patterns are here https://github.com/17712484466/intellij-community/blob/master/plugins/testng/src/com/theoryinpractice/testng/model/TestProxy.java#L48
thanks @rpeng! let's do that then.
Do you want to contribute it?

Patch:
diff --git a/src/main/java/org/assertj/core/api/Descriptable.java b/src/main/java/org/assertj/core/api/Descriptable.java
--- a/src/main/java/org/assertj/core/api/Descriptable.java
+++ b/src/main/java/org/assertj/core/api/Descriptable.java
@@ -46,7 +46,7 @@ public interface Descriptable<SELF> {
    * } catch (AssertionError e) {
    *   assertThat(e).hasMessage(&quot;[check Frodo's age]\n
    *                             expected: 33\n
-   *                             but was : 50&quot;);
+   *                              but was: 50&quot;);
    * }</code></pre>
    *
    * @param description the new description to set.
@@ -82,7 +82,7 @@ default SELF as(String description, Object... args) {
    * {
    *   assertThat(e).hasMessage(&quot;[check Frodo's age]\n
    *                             expected: 33\n
-   *                             but was : 50&quot;);
+   *                              but was: 50&quot;);
    * }</code></pre>
    *
    * @param descriptionSupplier the description {@link Supplier}.
diff --git a/src/main/java/org/assertj/core/error/ShouldBeEqual.java b/src/main/java/org/assertj/core/error/ShouldBeEqual.java
--- a/src/main/java/org/assertj/core/error/ShouldBeEqual.java
+++ b/src/main/java/org/assertj/core/error/ShouldBeEqual.java
@@ -41,7 +41,7 @@
  */
 public class ShouldBeEqual implements AssertionErrorFactory {
 
-  private static final String EXPECTED_BUT_WAS_MESSAGE = "%nexpected: %s%nbut was : %s";
+  private static final String EXPECTED_BUT_WAS_MESSAGE = "%nexpected: %s%n but was: %s";
   private static final String EXPECTED_BUT_WAS_MESSAGE_USING_COMPARATOR = EXPECTED_BUT_WAS_MESSAGE + "%n%s";
   private static final Class<?>[] MSG_ARG_TYPES = array(String.class, String.class, String.class);
   private static final Class<?>[] MSG_ARG_TYPES_FOR_ASSERTION_FAILED_ERROR = array(String.class, Object.class,
diff --git a/src/main/java/org/assertj/core/error/ShouldBeEqualIgnoringCase.java b/src/main/java/org/assertj/core/error/ShouldBeEqualIgnoringCase.java
--- a/src/main/java/org/assertj/core/error/ShouldBeEqualIgnoringCase.java
+++ b/src/main/java/org/assertj/core/error/ShouldBeEqualIgnoringCase.java
@@ -31,6 +31,6 @@ public static ErrorMessageFactory shouldBeEqual(CharSequence actual, CharSequenc
   }
 
   private ShouldBeEqualIgnoringCase(CharSequence actual, CharSequence expected) {
-    super("%nexpected: %s%nbut was : %s%nignoring case considerations", expected, actual);
+    super("%nexpected: %s%n but was: %s%nignoring case considerations", expected, actual);
   }
 }


Test patch:
diff --git a/src/test/java/org/assertj/core/api/abstract_/AbstractAssert_isInstanceOfSatisfying_Test.java b/src/test/java/org/assertj/core/api/abstract_/AbstractAssert_isInstanceOfSatisfying_Test.java
--- a/src/test/java/org/assertj/core/api/abstract_/AbstractAssert_isInstanceOfSatisfying_Test.java
+++ b/src/test/java/org/assertj/core/api/abstract_/AbstractAssert_isInstanceOfSatisfying_Test.java
@@ -78,7 +78,7 @@ void should_fail_according_to_requirements() {
     // THEN
     then(assertionError).hasMessage(format("[check light saber] %n" +
                                            "expected: \"Green\"%n" +
-                                           "but was : \"Red\""));
+                                           " but was: \"Red\""));
   }
 
   @Test
diff --git a/src/test/java/org/assertj/core/api/atomic/reference/AtomicReferenceAssert_hasValueSatisfying_Test.java b/src/test/java/org/assertj/core/api/atomic/reference/AtomicReferenceAssert_hasValueSatisfying_Test.java
--- a/src/test/java/org/assertj/core/api/atomic/reference/AtomicReferenceAssert_hasValueSatisfying_Test.java
+++ b/src/test/java/org/assertj/core/api/atomic/reference/AtomicReferenceAssert_hasValueSatisfying_Test.java
@@ -44,7 +44,7 @@ void should_fail_when_actual_has_value_which_does_not_satisfy_given_requirements
     AssertionError error = expectAssertionError(() -> assertThat(actual).hasValueSatisfying(value -> assertThat(value).isEqualToIgnoringCase(expectedValue)));
     // THEN
     then(error).hasMessageContainingAll("expected: \"bar\"",
-                                        "but was : \"foo\"");
+                                        " but was: \"foo\"");
   }
 
   @Test
diff --git a/src/test/java/org/assertj/core/error/ShouldBeEqual_Test.java b/src/test/java/org/assertj/core/error/ShouldBeEqual_Test.java
--- a/src/test/java/org/assertj/core/error/ShouldBeEqual_Test.java
+++ b/src/test/java/org/assertj/core/error/ShouldBeEqual_Test.java
@@ -39,7 +39,7 @@ void should_display_comparison_strategy_in_error_message() {
     then(error.getExpected().getValue()).isEqualTo(STANDARD_REPRESENTATION.toStringOf(expected));
     then(error).hasMessage(format("[Jedi] %n" +
                                   "expected: \"Yoda\"%n" +
-                                  "but was : \"Luke\"%n" +
+                                  " but was: \"Luke\"%n" +
                                   "when comparing values using CaseInsensitiveStringComparator"));
   }
 
@@ -56,7 +56,7 @@ void should_use_actual_and_expected_representation_in_AssertionFailedError_actua
     then(error.getExpected().getValue()).isEqualTo("[1, 2, 4]");
     then(error).hasMessage(format("[numbers] %n" +
                                   "expected: [1, 2, 4]%n" +
-                                  "but was : [1, 2, 3]"));
+                                  " but was: [1, 2, 3]"));
   }
 
 }
diff --git a/src/test/java/org/assertj/core/error/ShouldBeEqual_newAssertionError_Test.java b/src/test/java/org/assertj/core/error/ShouldBeEqual_newAssertionError_Test.java
--- a/src/test/java/org/assertj/core/error/ShouldBeEqual_newAssertionError_Test.java
+++ b/src/test/java/org/assertj/core/error/ShouldBeEqual_newAssertionError_Test.java
@@ -59,7 +59,7 @@ void should_create_AssertionFailedError_if_JUnit5_is_present_and_trim_spaces_in_
     then(error).isInstanceOf(AssertionFailedError.class)
                .hasMessage(format("[Jedi] %n" +
                                   "expected: \"Yoda\"%n" +
-                                  "but was : \"Luke\""));
+                                  " but was: \"Luke\""));
   }
 
   public static Stream<String> parameters() {
diff --git a/src/test/java/org/assertj/core/error/ShouldBeEqual_newAssertionError_differentiating_expected_and_actual_Test.java b/src/test/java/org/assertj/core/error/ShouldBeEqual_newAssertionError_differentiating_expected_and_actual_Test.java
--- a/src/test/java/org/assertj/core/error/ShouldBeEqual_newAssertionError_differentiating_expected_and_actual_Test.java
+++ b/src/test/java/org/assertj/core/error/ShouldBeEqual_newAssertionError_differentiating_expected_and_actual_Test.java
@@ -61,7 +61,7 @@ void should_create_AssertionError_with_message_differentiating_expected_double_a
     then(error).isInstanceOf(AssertionFailedError.class)
                .hasMessage(format("[my test] %n" +
                                   "expected: 42.0%n" +
-                                  "but was : 42.0f"));
+                                  " but was: 42.0f"));
   }
 
   @Test
@@ -78,7 +78,7 @@ void should_create_AssertionError_with_message_differentiating_expected_and_actu
     then(error).isInstanceOf(AssertionFailedError.class)
                .hasMessage("[my test] %n" +
                            "expected: \"Person[name=Jake] (Person@%s)\"%n" +
-                           "but was : \"Person[name=Jake] (Person@%s)\"",
+                           " but was: \"Person[name=Jake] (Person@%s)\"",
                            toHexString(expected.hashCode()), toHexString(actual.hashCode()));
   }
 
@@ -97,7 +97,7 @@ void should_create_AssertionError_with_message_differentiating_expected_and_actu
     then(error).isInstanceOf(AssertionFailedError.class)
                .hasMessage("[my test] %n" +
                            "expected: \"Person[name=Jake] (Person@%s)\"%n" +
-                           "but was : \"Person[name=Jake] (Person@%s)\"%n" +
+                           " but was: \"Person[name=Jake] (Person@%s)\"%n" +
                            "when comparing values using PersonComparator",
                            toHexString(expected.hashCode()), toHexString(actual.hashCode()));
   }
@@ -116,7 +116,7 @@ void should_create_AssertionError_with_message_differentiating_null_and_object_w
     then(error).isInstanceOf(AssertionFailedError.class)
                .hasMessage("[my test] %n" +
                            "expected: \"null (ToStringIsNull@%s)\"%n" +
-                           "but was : null",
+                           " but was: null",
                            toHexString(expected.hashCode()));
   }
 
@@ -134,7 +134,7 @@ void should_create_AssertionError_with_message_differentiating_object_with_null_
     then(error).isInstanceOf(AssertionFailedError.class)
                .hasMessage("[my test] %n" +
                            "expected: null%n" +
-                           "but was : \"null (ToStringIsNull@%s)\"",
+                           " but was: \"null (ToStringIsNull@%s)\"",
                            toHexString(actual.hashCode()));
   }
 
diff --git a/src/test/java/org/assertj/core/error/ShouldBeEqual_newAssertionError_without_JUnit_Test.java b/src/test/java/org/assertj/core/error/ShouldBeEqual_newAssertionError_without_JUnit_Test.java
--- a/src/test/java/org/assertj/core/error/ShouldBeEqual_newAssertionError_without_JUnit_Test.java
+++ b/src/test/java/org/assertj/core/error/ShouldBeEqual_newAssertionError_without_JUnit_Test.java
@@ -75,7 +75,7 @@ private void check(AssertionError error) throws Exception {
                                            new Class<?>[] { String.class, Object.class, Object.class },
                                            format("[Jedi] %n" +
                                                   "expected: \"Yoda\"%n" +
-                                                  "but was : \"Luke\""),
+                                                  " but was: \"Luke\""),
                                            STANDARD_REPRESENTATION.toStringOf("Yoda"),
                                            STANDARD_REPRESENTATION.toStringOf("Luke"));
     assertThat(error).isNotInstanceOf(ComparisonFailure.class)
@@ -85,7 +85,7 @@ private void check(AssertionError error) throws Exception {
     assertThat(assertionFailedError.getExpected().getValue()).isEqualTo(STANDARD_REPRESENTATION.toStringOf("Yoda"));
     assertThat(error).hasMessage(format("[Jedi] %n" +
                                         "expected: \"Yoda\"%n" +
-                                        "but was : \"Luke\""));
+                                        " but was: \"Luke\""));
   }
 
   private static Object createComparisonFailure(ConstructorInvoker invoker) throws Exception {
diff --git a/src/test/java/org/assertj/core/error/ShouldBeEqual_newAssertionError_without_JUnit_and_OTA4J_Test.java b/src/test/java/org/assertj/core/error/ShouldBeEqual_newAssertionError_without_JUnit_and_OTA4J_Test.java
--- a/src/test/java/org/assertj/core/error/ShouldBeEqual_newAssertionError_without_JUnit_and_OTA4J_Test.java
+++ b/src/test/java/org/assertj/core/error/ShouldBeEqual_newAssertionError_without_JUnit_and_OTA4J_Test.java
@@ -79,7 +79,7 @@ private void check(AssertionError error) throws Exception {
                                                      array(String.class, Object.class, Object.class),
                                                      format("[Jedi] %n" +
                                                             "expected: \"Yoda\"%n" +
-                                                            "but was : \"Luke\""),
+                                                            " but was: \"Luke\""),
                                                      STANDARD_REPRESENTATION.toStringOf("Yoda"),
                                                      STANDARD_REPRESENTATION.toStringOf("Luke"));
     verify(constructorInvoker).newInstance(ComparisonFailure.class.getName(),
@@ -90,6 +90,6 @@ private void check(AssertionError error) throws Exception {
     assertThat(error).isNotInstanceOfAny(ComparisonFailure.class, AssertionFailedError.class)
                      .hasMessage(format("[Jedi] %n" +
                                         "expected: \"Yoda\"%n" +
-                                        "but was : \"Luke\""));
+                                        " but was: \"Luke\""));
   }
 }
diff --git a/src/test/java/org/assertj/core/matcher/AssertionMatcher_matches_Test.java b/src/test/java/org/assertj/core/matcher/AssertionMatcher_matches_Test.java
--- a/src/test/java/org/assertj/core/matcher/AssertionMatcher_matches_Test.java
+++ b/src/test/java/org/assertj/core/matcher/AssertionMatcher_matches_Test.java
@@ -94,7 +94,7 @@ void matcher_should_fill_description_when_assertion_fails() {
     verify(description).appendText(argThat(new ArgumentMatcher<String>() {
       @Override
       public boolean matches(String s) {
-        return s.contains(format("%nexpected: 0%nbut was : 1"))
+        return s.contains(format("%nexpected: 0%n but was: 1"))
             && s.contains("at org.assertj.core.matcher.AssertionMatcher_matches_Test$1.assertion(AssertionMatcher_matches_Test.java:")
             && s.contains("at org.assertj.core.matcher.AssertionMatcher.matches(AssertionMatcher.java:")
             && s.contains("at org.assertj.core.matcher.AssertionMatcher_matches_Test.matcher_should_fill_description_when_assertion_fails(AssertionMatcher_matches_Test.java:");
diff --git a/src/test/java/org/assertj/core/test/ErrorMessagesForTest.java b/src/test/java/org/assertj/core/test/ErrorMessagesForTest.java
--- a/src/test/java/org/assertj/core/test/ErrorMessagesForTest.java
+++ b/src/test/java/org/assertj/core/test/ErrorMessagesForTest.java
@@ -17,11 +17,11 @@
 public class ErrorMessagesForTest {
 
   public static String shouldBeEqualMessage(String actual, String expected) {
-    return format("%nexpected: " + expected + "%nbut was : " + actual);
+    return format("%nexpected: " + expected + "%n but was: " + actual);
   }
 
   public static String shouldBeEqualMessage(String description, String actual, String expected) {
-    return format("[" + description + "] %nexpected: " + expected + "%nbut was : " + actual);
+    return format("[" + description + "] %nexpected: " + expected + "%n but was: " + actual);
   }
 
 }