Assertj-core: Add `isMixedCase`to `CharSequence` assertions

Created on 1 Jun 2021  路  13Comments  路  Source: assertj/assertj-core

Summary

The assertion should verify that the input is neither uppercase nor lowercase.

Example

assertThat("Hello World").isMixedCase();
good first issue

All 13 comments

Hi, i would like to work on this issue

Sure @himanshu007-creator, let us know if you need anything.

yes @scordio , i wanted to ask , that i just need to append this method to all instances where assertions are made to non numerical values right?
example:-
assertThat(${Class_being_asserted} actual)
changed to
assertThat(${Class_being_asserted} actual).isMixedCase()

isMixedCase() should be added to AbstractCharSequenceAssert and the internal implementation can be part of org.assertj.core.internal.Strings

Please have a look at my PR, i tried to implement the changes. If there are any changes, do let me know, Thanks馃檪

@scordio can I grab it then?

Sure, thanks @nach-o-man!

I wish to thank @scordio for opening this issue, as well as all other contributors.

I also wish to clarify what I had in mind when I tweeted @scordio RE a mixed-case assertion.

Some characters have a case property: they are mutated upon application of String.toLowerCase() or String.toUpperCase().

Any isMixedCase() assertion must be consistent with existing isLowerCase() and isUpperCase() assertions. I.e., we cannot apply restrictions to isMixedCase() that do not also apply to these other char sequence assertions.

Char sequences that are not mutated by String.toLowerCase() and String.toUpperCase() are not in the domain of char sequence case assertions, and thus they do not fail such assertions.

assertThat("").isLowerCase();
assertThat("").isUpperCase();
assertThat(" ").isLowerCase();
assertThat(" ").isUpperCase();
assertThat("!@#").isLowerCase();
assertThat("!@#").isUpperCase();
assertThat("765").isLowerCase();
assertThat("765").isUpperCase();
assertThat("b765").isLowerCase();
assertThat("B765").isUpperCase();

Similarly, sequences that do not fail both isLowerCase() and isUpperCase() assertions must not fail a isMixedCase() assertion. This includes: empty char sequence, char sequences composed of whitespace, numerals, punctuation, etc.

isMixedCase() is true if:

  1. The sequence contains >1 chars with lower/upper case.
  2. The case of said characters is non-uniform.

This may all sound complicated, but the implementation is wonderfully simple.

  1. if char sequence has no chars with case, the results of both toLowerCase() and toUpperCase() will be equal to the input sequence.
    str.equals(str.toLowerCase()) == str.equals(str.toUpperCase())
    evaluates to TRUE

  2. if char sequence has >1 chars with case property, and the case of these chars is mixed, the result of both toLowerCase() and toUpperCase() will not equal the input sequence.
    str.equals(str.toLowerCase()) == str.equals(str.toUpperCase())
    FALSE == FALSE evaluates to TRUE

implementation

static boolean isMixedCase(final String it) {
  assertThat(it).isNotNull();
  return it.equals(it.toLowerCase()) == it.equals(it.toUpperCase());
}

test

assertThat(isMixedCase("")).isTrue();
assertThat(isMixedCase(" ")).isTrue();
assertThat(isMixedCase("!@#")).isTrue();
assertThat(isMixedCase("765")).isTrue();
assertThat(isMixedCase("b765")).isFalse();
assertThat(isMixedCase("Ab765")).isTrue();
assertThat(isMixedCase("a")).isFalse();
assertThat(isMixedCase("A")).isFalse();
assertThat(isMixedCase("Aa")).isTrue();

The function isMixedCase is consistent with existing isLowerCase() and isUpperCase() assertions.

Again, thanks to all participants in this discussion.

Thank you very much for all the details @chagmed, we will make sure that the final implementation behaves accordingly.

@chagmed thank you for details. Keeping it consistent is really convincing argument 馃槂

Thank you, @nach-o-man.

For completeness, may I suggest a few additional tests for Strings_assertIsMixedCase_Test.java.

  • a String consisting solely of whitepace " "
  • Strings composed solely of single chars of each case "A","a"

Fair enough. Added cases

Thank you @nach-o-man. Excellent work. Much appreciated!

There is one small typo ("pas") in Strings_assertIsMixedCase_Test.java:
should_pas_if_actual_is_has_no_letters().

AbstractCharSequenceAssert.java method isMixedCase() Javadocs currently read:

Verifies that the actual {@code CharSequence} is a mixed case {@code CharSequence} by checking that if fails both {@code isLowerCase()} assertion and {@code isUpperCase()} assertion.`

Let's rephrase that slightly, as we are actually testing whether Strings.isLowerCase() equals Strings.isUpperCase().

My suggestion:

Verifies that the actual {@code CharSequence} is a mixed case {@code CharSequence} by comparing it to
actuals built with String.toLowerCase() and String.toUpperCase().

The code examples should make it clear that this assertion is consistent with the assertions isLowerCase() and isUpperCase().

What do the rest of you think?

Again, thank you very much.

Was this page helpful?
0 / 5 - 0 ratings