Skip to content

Conversation

Marcono1234
Copy link
Contributor

@Marcono1234 Marcono1234 commented Sep 23, 2024

Currently CharSequence has no special handling in StandardRepresentation, so when you accidentally compare a String with for example a StringBuilder you get something like:

expected: test
but was: "test"

This assumes that for custom CharSequence types users have overridden toString, as required by the CharSequence Javadoc. Otherwise it might be a bit confusing that the result is now enclosed in ".

Check List:

  • Fixes #??? (ignore if not applicable)
  • Unit tests : YES
  • Javadoc with a code example (on API only) : NA
  • PR meets the contributing guidelines

Following the contributing guidelines will make it easier for us to review and accept your PR.

This also makes the assertion message more helpful when comparing a String
and a different CharSequence object.
Comment on lines 404 to 410
protected String toStringOf(String s) {
return toStringOf((CharSequence) s);
}

protected String toStringOf(CharSequence s) {
return concat("\"", s, "\"");
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't sure whether the existing toStringOf(String) should be replaced (since String implements CharSequence), or whether that would be a breaking API change.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not a binary breaking change but if some users rely on that representation then it would be, so I'm inclined we don't change it. Reusing the String representation for char sequence is ok as if the contents are the same we would add the type to differentiate the values.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah sorry my comment was a bit misleading. What I meant is:

  • Should there be toStringOf(String) and toStringOf(CharSequence) (as done here currently)
  • Or, should there only be toStringOf(CharSequence), and toStringOf(String) is removed
    The code would then simply use the CharSequence variant for String as well. But removing the toStringOf(String) overload would technically be an incompatible API change since it is protected and users might have overridden it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better to extract concat("\"", s, "\""); to a private method and call it from both toStringOf, users can then override toStringOf(CharSequence s) without impacting toStringOf(String s).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hope the latest changes in 6952df8 are what you had in mind.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, I'll review that next week, I'm off for a few days

@@ -66,6 +66,18 @@ void should_use_actual_and_expected_representation_in_AssertionFailedError_actua
" but was: [1, 2, 3]"));
}

@Test
void should_display_class_for_ambiguous_CharSequence() {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not completely sure where the 'right' place for this test is. All these test classes seem to perform variants of ambiguous toString checks:

  • ShouldBeEqual_Test (this class here)
  • ShouldBeEqual_newAssertionError_differentiating_expected_and_actual_Test
  • StandardRepresentation_unambiguousToStringOf_Test

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would be in StandardRepresentation_unambiguousToStringOf_Test where we should have exhaustive tests for representation, the other tests are just to check that ShouldBeEqual honors that too but we only one test proving that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I will completely remove this test method again. StandardRepresentation_unambiguousToStringOf_Test already has one generic test, isEqualTo_should_show_disambiguated_.... Would probably not fit to add this specific String/CharSequence test there.

@Marcono1234 Marcono1234 marked this pull request as draft September 23, 2024 16:06
@Marcono1234 Marcono1234 marked this pull request as ready for review September 23, 2024 16:22
Comment on lines 35 to 37
if (object instanceof String) return toStringOf((String) object);
if (object instanceof CharSequence) return toStringOf((CharSequence) object);
if (object instanceof Character) return toStringOf((Character) object);
Copy link
Contributor Author

@Marcono1234 Marcono1234 Sep 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think technically all these instanceof checks are redundant because they are equivalent to what the parent class StandardRepresentation would do in its toStringOf method (and then call the methods overridden within this class here), but for consistency I added the check for CharSequence here as well.

@joel-costigliola joel-costigliola added this to the 3.27.0 milestone Oct 2, 2024
@joel-costigliola
Copy link
Member

Integrated thanks @Marcono1234 !

@Marcono1234 Marcono1234 deleted the CharSequence-standard-representation branch October 6, 2024 12:54
nosan pushed a commit to nosan/assertj that referenced this pull request Mar 4, 2025
This also makes the assertion message more helpful when comparing a String
and a different CharSequence object.

Fix assertj#3617
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants