Repository: assertj/assertj (Java)

Issue:
assertContainsIgnoringCase fails to compare i and I in tr_TR locale
See `org.assertj.core.internal.Strings#assertContainsIgnoringCase`

https://github.com/assertj/assertj-core/blob/9051a958e6ab0a750bb243060aef57001ab97e6e/src/main/java/org/assertj/core/internal/Strings.java#L528-L531

I would suggest adding https://github.com/policeman-tools/forbidden-apis verification to just ban `toLowerCase()`, `toUpperCase()` and other unsafe methods: https://github.com/assertj/assertj-core/issues/2664



Hints:

Patch:
diff --git a/src/main/java/org/assertj/core/internal/Strings.java b/src/main/java/org/assertj/core/internal/Strings.java
--- a/src/main/java/org/assertj/core/internal/Strings.java
+++ b/src/main/java/org/assertj/core/internal/Strings.java
@@ -528,8 +528,7 @@ private boolean stringContains(CharSequence actual, CharSequence sequence) {
   public void assertContainsIgnoringCase(AssertionInfo info, CharSequence actual, CharSequence sequence) {
     checkCharSequenceIsNotNull(sequence);
     assertNotNull(info, actual);
-    if (!actual.toString().toLowerCase().contains(sequence.toString().toLowerCase()))
-      throw failures.failure(info, shouldContainIgnoringCase(actual, sequence));
+    if (!containsIgnoreCase(actual, sequence)) throw failures.failure(info, shouldContainIgnoringCase(actual, sequence));
   }
 
   // CS427 Issue link: https://github.com/assertj/assertj-core/issues/2060
@@ -593,8 +592,7 @@ public void assertContainsIgnoringWhitespaces(AssertionInfo info, CharSequence a
   public void assertDoesNotContainIgnoringCase(AssertionInfo info, CharSequence actual, CharSequence... values) {
     doCommonCheckForCharSequence(info, actual, values);
 
-    String actualLowerCase = actual.toString().toLowerCase();
-    Set<CharSequence> foundValues = stream(values).filter(value -> actualLowerCase.contains(value.toString().toLowerCase()))
+    Set<CharSequence> foundValues = stream(values).filter(value -> containsIgnoreCase(actual, value))
                                                   .collect(toCollection(LinkedHashSet::new));
     if (foundValues.isEmpty()) return;
     if (foundValues.size() == 1 && values.length == 1) {
@@ -900,7 +898,7 @@ public void assertStartsWith(AssertionInfo info, CharSequence actual, CharSequen
   public void assertStartsWithIgnoringCase(AssertionInfo info, CharSequence actual, CharSequence prefix) {
     failIfPrefixIsNull(prefix);
     assertNotNull(info, actual);
-    if (!comparisonStrategy.stringStartsWith(actual.toString().toLowerCase(), prefix.toString().toLowerCase()))
+    if (!startsWith(actual, prefix, true))
       throw failures.failure(info, shouldStartWithIgnoringCase(actual, prefix, comparisonStrategy));
   }
 
@@ -935,7 +933,7 @@ public void assertDoesNotStartWith(AssertionInfo info, CharSequence actual, Char
   public void assertDoesNotStartWithIgnoringCase(AssertionInfo info, CharSequence actual, CharSequence prefix) {
     failIfPrefixIsNull(prefix);
     assertNotNull(info, actual);
-    if (comparisonStrategy.stringStartsWith(actual.toString().toLowerCase(), prefix.toString().toLowerCase()))
+    if (startsWith(actual, prefix, true))
       throw failures.failure(info, shouldNotStartWithIgnoringCase(actual, prefix, comparisonStrategy));
   }
 
@@ -974,7 +972,7 @@ public void assertEndsWith(AssertionInfo info, CharSequence actual, CharSequence
   public void assertEndsWithIgnoringCase(AssertionInfo info, CharSequence actual, CharSequence suffix) {
     failIfSuffixIsNull(suffix);
     assertNotNull(info, actual);
-    if (!comparisonStrategy.stringEndsWith(actual.toString().toLowerCase(), suffix.toString().toLowerCase()))
+    if (!endsWith(actual, suffix, true))
       throw failures.failure(info, shouldEndWithIgnoringCase(actual, suffix, comparisonStrategy));
   }
 
@@ -1009,7 +1007,7 @@ public void assertDoesNotEndWith(AssertionInfo info, CharSequence actual, CharSe
   public void assertDoesNotEndWithIgnoringCase(AssertionInfo info, CharSequence actual, CharSequence suffix) {
     failIfSuffixIsNull(suffix);
     assertNotNull(info, actual);
-    if (comparisonStrategy.stringEndsWith(actual.toString().toLowerCase(), suffix.toString().toLowerCase()))
+    if (endsWith(actual, suffix, true))
       throw failures.failure(info, shouldNotEndWithIgnoringCase(actual, suffix, comparisonStrategy));
   }
 
@@ -1358,4 +1356,92 @@ private void doCommonCheckForCharSequence(AssertionInfo info, CharSequence actua
     checkIsNotEmpty(sequence);
     checkCharSequenceArrayDoesNotHaveNullElements(sequence);
   }
+
+  // Source: org.apache.commons.lang3.StringUtils
+  private static boolean containsIgnoreCase(CharSequence str, CharSequence searchStr) {
+    if (str == null || searchStr == null) {
+      return false;
+    }
+    final int len = searchStr.length();
+    final int max = str.length() - len;
+    for (int i = 0; i <= max; i++) {
+      if (regionMatches(str, true, i, searchStr, 0, len)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  // Source: org.apache.commons.lang3.StringUtils
+  private static boolean endsWith(CharSequence str, CharSequence suffix, boolean ignoreCase) {
+    if (str == null || suffix == null) {
+      return str == suffix;
+    }
+    if (suffix.length() > str.length()) {
+      return false;
+    }
+    final int strOffset = str.length() - suffix.length();
+    return regionMatches(str, ignoreCase, strOffset, suffix, 0, suffix.length());
+  }
+
+  // Source: org.apache.commons.lang3.StringUtils
+  private static boolean startsWith(CharSequence str, CharSequence prefix, boolean ignoreCase) {
+    if (str == null || prefix == null) {
+      return str == prefix;
+    }
+    // Get length once instead of twice in the unlikely case that it changes.
+    final int preLen = prefix.length();
+    if (prefix.length() > str.length()) {
+      return false;
+    }
+    return regionMatches(str, ignoreCase, 0, prefix, 0, preLen);
+  }
+
+  // Source: org.apache.commons.lang3.CharSequenceUtils
+  private static boolean regionMatches(CharSequence cs, boolean ignoreCase, int thisStart,
+                                       CharSequence substring, int start, int length) {
+    if (cs instanceof String && substring instanceof String) {
+      return ((String) cs).regionMatches(ignoreCase, thisStart, (String) substring, start, length);
+    }
+    int index1 = thisStart;
+    int index2 = start;
+    int tmpLen = length;
+
+    // Extract these first so we detect NPEs the same as the java.lang.String version
+    final int srcLen = cs.length() - thisStart;
+    final int otherLen = substring.length() - start;
+
+    // Check for invalid parameters
+    if (thisStart < 0 || start < 0 || length < 0) {
+      return false;
+    }
+
+    // Check that the regions are long enough
+    if (srcLen < length || otherLen < length) {
+      return false;
+    }
+
+    while (tmpLen-- > 0) {
+      final char c1 = cs.charAt(index1++);
+      final char c2 = substring.charAt(index2++);
+
+      if (c1 == c2) {
+        continue;
+      }
+
+      if (!ignoreCase) {
+        return false;
+      }
+
+      // The real same check as in String.regionMatches():
+      final char u1 = Character.toUpperCase(c1);
+      final char u2 = Character.toUpperCase(c2);
+      if (u1 != u2 && Character.toLowerCase(u1) != Character.toLowerCase(u2)) {
+        return false;
+      }
+    }
+
+    return true;
+  }
+
 }


Test patch:
diff --git a/src/test/java/org/assertj/core/internal/strings/Strings_assertContainsIgnoringCase_Test.java b/src/test/java/org/assertj/core/internal/strings/Strings_assertContainsIgnoringCase_Test.java
--- a/src/test/java/org/assertj/core/internal/strings/Strings_assertContainsIgnoringCase_Test.java
+++ b/src/test/java/org/assertj/core/internal/strings/Strings_assertContainsIgnoringCase_Test.java
@@ -12,22 +12,19 @@
  */
 package org.assertj.core.internal.strings;
 
-import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
-import static org.assertj.core.api.Assertions.assertThatNullPointerException;
+import static org.assertj.core.api.Assertions.catchNullPointerException;
+import static org.assertj.core.api.BDDAssertions.then;
 import static org.assertj.core.error.ShouldContainCharSequence.shouldContainIgnoringCase;
 import static org.assertj.core.internal.ErrorMessages.charSequenceToLookForIsNull;
 import static org.assertj.core.test.TestData.someInfo;
+import static org.assertj.core.util.AssertionsUtil.expectAssertionError;
 import static org.assertj.core.util.FailureMessages.actualIsNull;
 
-import org.assertj.core.api.AssertionInfo;
-import org.assertj.core.internal.Strings;
 import org.assertj.core.internal.StringsBaseTest;
 import org.junit.jupiter.api.Test;
-
+import org.junitpioneer.jupiter.DefaultLocale;
 
 /**
- * Tests for <code>{@link Strings#assertContainsIgnoringCase(AssertionInfo, CharSequence, CharSequence)}</code>.
- * 
  * @author Alex Ruiz
  * @author Joel Costigliola
  */
@@ -35,59 +32,88 @@ class Strings_assertContainsIgnoringCase_Test extends StringsBaseTest {
 
   @Test
   void should_fail_if_actual_does_not_contain_sequence() {
-    assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> strings.assertContainsIgnoringCase(someInfo(), "Yoda", "Luke"))
-                                                   .withMessage(shouldContainIgnoringCase("Yoda", "Luke").create());
+    // WHEN
+    AssertionError assertionError = expectAssertionError(() -> strings.assertContainsIgnoringCase(someInfo(), "Yoda", "Luke"));
+    // THEN
+    then(assertionError).hasMessage(shouldContainIgnoringCase("Yoda", "Luke").create());
   }
 
   @Test
   void should_throw_error_if_sequence_is_null() {
-    assertThatNullPointerException().isThrownBy(() -> strings.assertContainsIgnoringCase(someInfo(), "Yoda", null))
-                                    .withMessage(charSequenceToLookForIsNull());
+    // WHEN
+    NullPointerException exception = catchNullPointerException(() -> strings.assertContainsIgnoringCase(someInfo(), "Yoda",
+                                                                                                        null));
+    // THEN
+    then(exception).hasMessage(charSequenceToLookForIsNull());
   }
 
   @Test
   void should_fail_if_actual_is_null() {
-    assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> strings.assertContainsIgnoringCase(someInfo(), null, "Yoda"))
-                                                   .withMessage(actualIsNull());
+    // WHEN
+    AssertionError assertionError = expectAssertionError(() -> strings.assertContainsIgnoringCase(someInfo(), null, "Yoda"));
+    // THEN
+    then(assertionError).hasMessage(actualIsNull());
   }
 
   @Test
   void should_pass_if_actual_contains_sequence() {
+    // WHEN/THEN
     strings.assertContainsIgnoringCase(someInfo(), "Yoda", "Yo");
   }
 
   @Test
   void should_pass_if_actual_contains_sequence_in_different_case() {
+    // WHEN/THEN
     strings.assertContainsIgnoringCase(someInfo(), "Yoda", "yo");
   }
 
   @Test
   void should_fail_if_actual_does_not_contain_sequence_whatever_custom_comparison_strategy_is() {
-    assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> stringsWithCaseInsensitiveComparisonStrategy.assertContainsIgnoringCase(someInfo(), "Yoda", "Luke"))
-                                                   .withMessage(shouldContainIgnoringCase("Yoda", "Luke").create());
+    // WHEN
+    AssertionError assertionError = expectAssertionError(() -> stringsWithCaseInsensitiveComparisonStrategy.assertContainsIgnoringCase(someInfo(),
+                                                                                                                                       "Yoda",
+                                                                                                                                       "Luke"));
+    // THEN
+    then(assertionError).hasMessage(shouldContainIgnoringCase("Yoda", "Luke").create());
   }
 
   @Test
   void should_throw_error_if_sequence_is_null_whatever_custom_comparison_strategy_is() {
-    assertThatNullPointerException().isThrownBy(() -> stringsWithCaseInsensitiveComparisonStrategy.assertContainsIgnoringCase(someInfo(),
-                                                                                                                              "Yoda",
-                                                                                                                              null))
-                                    .withMessage(charSequenceToLookForIsNull());
+    // WHEN
+    NullPointerException exception = catchNullPointerException(() -> stringsWithCaseInsensitiveComparisonStrategy.assertContainsIgnoringCase(someInfo(),
+                                                                                                                                             "Yoda",
+                                                                                                                                             null));
+    // THEN
+    then(exception).hasMessage(charSequenceToLookForIsNull());
   }
 
   @Test
   void should_fail_if_actual_is_null_whatever_custom_comparison_strategy_is() {
-    assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> stringsWithCaseInsensitiveComparisonStrategy.assertContainsIgnoringCase(someInfo(), null, "Yoda"))
-                                                   .withMessage(actualIsNull());
+    // WHEN
+    AssertionError assertionError = expectAssertionError(() -> stringsWithCaseInsensitiveComparisonStrategy.assertContainsIgnoringCase(someInfo(),
+                                                                                                                                       null,
+                                                                                                                                       "Yoda"));
+    // THEN
+    then(assertionError).hasMessage(actualIsNull());
   }
 
   @Test
   void should_pass_if_actual_contains_sequence_whatever_custom_comparison_strategy_is() {
+    // WHEN/THEN
     stringsWithCaseInsensitiveComparisonStrategy.assertContainsIgnoringCase(someInfo(), "Yoda", "Yo");
   }
 
   @Test
   void should_pass_if_actual_contains_sequence_in_different_case_whatever_custom_comparison_strategy_is() {
+    // WHEN/THEN
     stringsWithCaseInsensitiveComparisonStrategy.assertContainsIgnoringCase(someInfo(), "Yoda", "yo");
   }
+
+  @Test
+  @DefaultLocale("tr-TR")
+  void should_pass_with_Turkish_default_locale() {
+    // WHEN/THEN
+    strings.assertContainsIgnoringCase(someInfo(), "Leia", "IA");
+  }
+
 }
diff --git a/src/test/java/org/assertj/core/internal/strings/Strings_assertDoesNotContainIgnoringCase_Test.java b/src/test/java/org/assertj/core/internal/strings/Strings_assertDoesNotContainIgnoringCase_Test.java
--- a/src/test/java/org/assertj/core/internal/strings/Strings_assertDoesNotContainIgnoringCase_Test.java
+++ b/src/test/java/org/assertj/core/internal/strings/Strings_assertDoesNotContainIgnoringCase_Test.java
@@ -12,39 +12,37 @@
  */
 package org.assertj.core.internal.strings;
 
-import static org.assertj.core.api.Assertions.catchThrowable;
+import static org.assertj.core.api.Assertions.catchNullPointerException;
 import static org.assertj.core.api.BDDAssertions.then;
 import static org.assertj.core.api.BDDAssertions.thenIllegalArgumentException;
 import static org.assertj.core.error.ShouldNotContainCharSequence.shouldNotContainIgnoringCase;
 import static org.assertj.core.internal.ErrorMessages.arrayOfValuesToLookForIsEmpty;
 import static org.assertj.core.internal.ErrorMessages.valuesToLookForIsNull;
 import static org.assertj.core.test.TestData.someInfo;
+import static org.assertj.core.util.Arrays.array;
 import static org.assertj.core.util.AssertionsUtil.expectAssertionError;
 import static org.assertj.core.util.FailureMessages.actualIsNull;
-import static org.mockito.internal.util.collections.Sets.newSet;
+import static org.assertj.core.util.Sets.set;
 
-import org.assertj.core.api.AssertionInfo;
-import org.assertj.core.internal.Strings;
 import org.assertj.core.internal.StringsBaseTest;
-import org.junit.jupiter.api.DisplayName;
 import org.junit.jupiter.api.Test;
+import org.junitpioneer.jupiter.DefaultLocale;
 
 /**
- * Tests for <code>{@link Strings#assertDoesNotContainIgnoringCase(AssertionInfo, CharSequence, CharSequence...)}</code>.
- *
  * @author Brummolix
  */
-@DisplayName("Strings assertDoesNotContainIgnoringCase")
 class Strings_assertDoesNotContainIgnoringCase_Test extends StringsBaseTest {
 
   @Test
   void should_pass_if_actual_does_not_contain_value_ignoring_case() {
-    assertDoesNotContainIgnoringCase("Yoda", "no");
+    // WHEN/THEN
+    strings.assertDoesNotContainIgnoringCase(someInfo(), "Yoda", "no");
   }
 
   @Test
   void should_pass_if_actual_does_not_contain_values_ignoring_case() {
-    assertDoesNotContainIgnoringCase("Yoda", "no", "also no");
+    // WHEN/THEN
+    strings.assertDoesNotContainIgnoringCase(someInfo(), "Yoda", "no", "also no");
   }
 
   @Test
@@ -52,7 +50,8 @@ void should_fail_if_actual_contains_value() {
     // GIVEN
     String actual = "Yoda";
     // WHEN
-    AssertionError assertionError = expectAssertionError(() -> assertDoesNotContainIgnoringCase(actual, "od"));
+    AssertionError assertionError = expectAssertionError(() -> strings.assertDoesNotContainIgnoringCase(someInfo(), actual,
+                                                                                                        "od"));
     // THEN
     then(assertionError).hasMessage(shouldNotContainIgnoringCase(actual, "od").create());
   }
@@ -62,7 +61,8 @@ void should_fail_if_actual_contains_value_with_different_case() {
     // GIVEN
     String actual = "Yoda";
     // WHEN
-    AssertionError assertionError = expectAssertionError(() -> assertDoesNotContainIgnoringCase(actual, "OD"));
+    AssertionError assertionError = expectAssertionError(() -> strings.assertDoesNotContainIgnoringCase(someInfo(), actual,
+                                                                                                        "OD"));
     // THEN
     then(assertionError).hasMessage(shouldNotContainIgnoringCase(actual, "OD").create());
   }
@@ -72,10 +72,10 @@ void should_fail_if_actual_contains_one_of_several_values() {
     // GIVEN
     String actual = "Yoda";
     // WHEN
-    AssertionError assertionError = expectAssertionError(() -> assertDoesNotContainIgnoringCase(actual, "od", "Yo", "Luke"));
+    AssertionError assertionError = expectAssertionError(() -> strings.assertDoesNotContainIgnoringCase(someInfo(), actual, "od",
+                                                                                                        "Yo", "Luke"));
     // THEN
-    String message = shouldNotContainIgnoringCase(actual, new CharSequence[] { "od", "Yo", "Luke" }, newSet("od", "Yo")).create();
-    then(assertionError).hasMessage(message);
+    then(assertionError).hasMessage(shouldNotContainIgnoringCase(actual, array("od", "Yo", "Luke"), set("od", "Yo")).create());
   }
 
   @Test
@@ -83,10 +83,10 @@ void should_fail_if_actual_contains_one_of_several_values_with_different_case()
     // GIVEN
     String actual = "Yoda";
     // WHEN
-    AssertionError assertionError = expectAssertionError(() -> assertDoesNotContainIgnoringCase(actual, "OD", "yo", "Luke"));
+    AssertionError assertionError = expectAssertionError(() -> strings.assertDoesNotContainIgnoringCase(someInfo(), actual, "OD",
+                                                                                                        "yo", "Luke"));
     // THEN
-    String message = shouldNotContainIgnoringCase(actual, new CharSequence[] { "OD", "yo", "Luke" }, newSet("OD", "yo")).create();
-    then(assertionError).hasMessage(message);
+    then(assertionError).hasMessage(shouldNotContainIgnoringCase(actual, array("OD", "yo", "Luke"), set("OD", "yo")).create());
   }
 
   @Test
@@ -94,10 +94,10 @@ void should_fail_if_values_are_null() {
     // GIVEN
     CharSequence[] values = null;
     // WHEN
-    Throwable npe = catchThrowable(() -> assertDoesNotContainIgnoringCase("Yoda", values));
+    NullPointerException exception = catchNullPointerException(() -> strings.assertDoesNotContainIgnoringCase(someInfo(), "Yoda",
+                                                                                                              values));
     // THEN
-    then(npe).isInstanceOf(NullPointerException.class)
-             .hasMessage(valuesToLookForIsNull());
+    then(exception).hasMessage(valuesToLookForIsNull());
   }
 
   @Test
@@ -105,14 +105,15 @@ void should_fail_if_actual_is_null() {
     // GIVEN
     String actual = null;
     // WHEN
-    AssertionError assertionError = expectAssertionError(() -> assertDoesNotContainIgnoringCase(actual, "Yoda"));
+    AssertionError assertionError = expectAssertionError(() -> strings.assertDoesNotContainIgnoringCase(someInfo(), actual,
+                                                                                                        "Yoda"));
     // THEN
     then(assertionError).hasMessage(actualIsNull());
   }
 
   @Test
   void should_throw_error_if_values_are_empty() {
-    thenIllegalArgumentException().isThrownBy(() -> assertDoesNotContainIgnoringCase("Yoda"))
+    thenIllegalArgumentException().isThrownBy(() -> strings.assertDoesNotContainIgnoringCase(someInfo(), "Yoda"))
                                   .withMessage(arrayOfValuesToLookForIsEmpty());
   }
 
@@ -121,13 +122,19 @@ void should_throw_error_if_values_contains_null() {
     // GIVEN
     CharSequence[] values = new CharSequence[] { "1", null };
     // WHEN
-    Throwable npe = catchThrowable(() -> assertDoesNotContainIgnoringCase("Yoda", values));
+    NullPointerException exception = catchNullPointerException(() -> strings.assertDoesNotContainIgnoringCase(someInfo(), "Yoda",
+                                                                                                              values));
     // THEN
-    then(npe).isInstanceOf(NullPointerException.class)
-             .hasMessage("Expecting CharSequence elements not to be null but found one at index 1");
+    then(exception).hasMessage("Expecting CharSequence elements not to be null but found one at index 1");
   }
 
-  private void assertDoesNotContainIgnoringCase(CharSequence actual, CharSequence... values) {
-    strings.assertDoesNotContainIgnoringCase(someInfo(), actual, values);
+  @Test
+  @DefaultLocale("tr-TR")
+  void should_fail_with_Turkish_default_locale() {
+    // WHEN
+    AssertionError assertionError = expectAssertionError(() -> strings.assertDoesNotContainIgnoringCase(INFO, "Leia", "EI"));
+    // THEN
+    then(assertionError).hasMessage(shouldNotContainIgnoringCase("Leia", "EI").create());
   }
+
 }
diff --git a/src/test/java/org/assertj/core/internal/strings/Strings_assertDoesNotEndWithIgnoringCase_Test.java b/src/test/java/org/assertj/core/internal/strings/Strings_assertDoesNotEndWithIgnoringCase_Test.java
--- a/src/test/java/org/assertj/core/internal/strings/Strings_assertDoesNotEndWithIgnoringCase_Test.java
+++ b/src/test/java/org/assertj/core/internal/strings/Strings_assertDoesNotEndWithIgnoringCase_Test.java
@@ -18,7 +18,6 @@
 import static org.assertj.core.util.AssertionsUtil.expectAssertionError;
 import static org.assertj.core.util.FailureMessages.actualIsNull;
 
-import org.assertj.core.api.AssertionInfo;
 import org.assertj.core.internal.ComparatorBasedComparisonStrategy;
 import org.assertj.core.internal.ComparisonStrategy;
 import org.assertj.core.internal.StandardComparisonStrategy;
@@ -26,11 +25,9 @@
 import org.assertj.core.internal.StringsBaseTest;
 import org.assertj.core.util.StringHashCodeTestComparator;
 import org.junit.jupiter.api.Test;
+import org.junitpioneer.jupiter.DefaultLocale;
 
-/**
- * Tests for <code>{@link Strings#assertDoesNotEndWithIgnoringCase(AssertionInfo, CharSequence, CharSequence)}</code>.
- */
-class Strings_assertDoesNotEndWithIgnoringCaseIgnoringCase_Test extends StringsBaseTest {
+class Strings_assertDoesNotEndWithIgnoringCase_Test extends StringsBaseTest {
 
   @Test
   void should_pass_if_actual_does_not_end_with_suffix() {
@@ -78,4 +75,14 @@ void should_fail_if_actual_ends_with_suffix_according_to_custom_comparison_strat
     // THEN
     then(assertionError).hasMessage(shouldNotEndWithIgnoringCase("Yoda", "A", hashCodeComparisonStrategy).create());
   }
+
+  @Test
+  @DefaultLocale("tr-TR")
+  void should_fail_with_Turkish_default_locale() {
+    // WHEN
+    AssertionError assertionError = expectAssertionError(() -> strings.assertDoesNotEndWithIgnoringCase(INFO, "Leia", "IA"));
+    // THEN
+    then(assertionError).hasMessage(shouldNotEndWithIgnoringCase("Leia", "IA", StandardComparisonStrategy.instance()).create());
+  }
+
 }
diff --git a/src/test/java/org/assertj/core/internal/strings/Strings_assertDoesNotStartWithIgnoringCase_Test.java b/src/test/java/org/assertj/core/internal/strings/Strings_assertDoesNotStartWithIgnoringCase_Test.java
--- a/src/test/java/org/assertj/core/internal/strings/Strings_assertDoesNotStartWithIgnoringCase_Test.java
+++ b/src/test/java/org/assertj/core/internal/strings/Strings_assertDoesNotStartWithIgnoringCase_Test.java
@@ -18,7 +18,6 @@
 import static org.assertj.core.util.AssertionsUtil.expectAssertionError;
 import static org.assertj.core.util.FailureMessages.actualIsNull;
 
-import org.assertj.core.api.AssertionInfo;
 import org.assertj.core.internal.ComparatorBasedComparisonStrategy;
 import org.assertj.core.internal.ComparisonStrategy;
 import org.assertj.core.internal.StandardComparisonStrategy;
@@ -26,10 +25,8 @@
 import org.assertj.core.internal.StringsBaseTest;
 import org.assertj.core.util.StringHashCodeTestComparator;
 import org.junit.jupiter.api.Test;
+import org.junitpioneer.jupiter.DefaultLocale;
 
-/**
- * Tests for <code>{@link Strings#assertDoesNotStartWithIgnoringCase(AssertionInfo, CharSequence, CharSequence)}</code>.
- */
 class Strings_assertDoesNotStartWithIgnoringCase_Test extends StringsBaseTest {
 
   @Test
@@ -42,7 +39,7 @@ void should_pass_if_actual_does_not_start_with_prefix() {
   void should_fail_if_actual_starts_with_prefix() {
     // WHEN
     AssertionError assertionError = expectAssertionError(() -> strings.assertDoesNotStartWithIgnoringCase(INFO, "Yoda", "yo"));
-    //THEN
+    // THEN
     then(assertionError).hasMessage(shouldNotStartWithIgnoringCase("Yoda", "yo", StandardComparisonStrategy.instance()).create());
   }
 
@@ -76,6 +73,17 @@ void should_fail_if_actual_starts_with_prefix_according_to_custom_comparison_str
     // WHEN
     AssertionError assertionError = expectAssertionError(() -> strings.assertDoesNotStartWithIgnoringCase(INFO, "Yoda", "yODA"));
     // THEN
-    then(assertionError).hasMessageContainingAll(shouldNotStartWithIgnoringCase("Yoda", "yODA", hashCodeComparisonStrategy).create());
+    then(assertionError).hasMessageContainingAll(shouldNotStartWithIgnoringCase("Yoda", "yODA",
+                                                                                hashCodeComparisonStrategy).create());
+  }
+
+  @Test
+  @DefaultLocale("tr-TR")
+  void should_fail_with_Turkish_default_locale() {
+    // WHEN
+    AssertionError assertionError = expectAssertionError(() -> strings.assertDoesNotStartWithIgnoringCase(INFO, "Leia", "LEI"));
+    // THEN
+    then(assertionError).hasMessage(shouldNotStartWithIgnoringCase("Leia", "LEI", StandardComparisonStrategy.instance()).create());
   }
+
 }
diff --git a/src/test/java/org/assertj/core/internal/strings/Strings_assertEndsWithIgnoringCase_Test.java b/src/test/java/org/assertj/core/internal/strings/Strings_assertEndsWithIgnoringCase_Test.java
--- a/src/test/java/org/assertj/core/internal/strings/Strings_assertEndsWithIgnoringCase_Test.java
+++ b/src/test/java/org/assertj/core/internal/strings/Strings_assertEndsWithIgnoringCase_Test.java
@@ -15,10 +15,10 @@
 import static org.assertj.core.api.Assertions.assertThatNullPointerException;
 import static org.assertj.core.api.BDDAssertions.then;
 import static org.assertj.core.error.ShouldEndWithIgnoringCase.shouldEndWithIgnoringCase;
+import static org.assertj.core.test.TestData.someInfo;
 import static org.assertj.core.util.AssertionsUtil.expectAssertionError;
 import static org.assertj.core.util.FailureMessages.actualIsNull;
 
-import org.assertj.core.api.AssertionInfo;
 import org.assertj.core.internal.ComparatorBasedComparisonStrategy;
 import org.assertj.core.internal.ComparisonStrategy;
 import org.assertj.core.internal.StandardComparisonStrategy;
@@ -26,10 +26,8 @@
 import org.assertj.core.internal.StringsBaseTest;
 import org.assertj.core.util.StringHashCodeTestComparator;
 import org.junit.jupiter.api.Test;
+import org.junitpioneer.jupiter.DefaultLocale;
 
-/**
- * Tests for <code>{@link Strings#assertEndsWithIgnoringCase(AssertionInfo, CharSequence, CharSequence)}</code>.
- */
 class Strings_assertEndsWithIgnoringCase_Test extends StringsBaseTest {
 
   @Test
@@ -84,4 +82,12 @@ void should_fail_if_actual_does_not_end_with_suffix_according_to_custom_comparis
     // THEN
     then(assertionError).hasMessage(shouldEndWithIgnoringCase("Yoda", "Luke", hashCodeComparisonStrategy).create());
   }
+
+  @Test
+  @DefaultLocale("tr-TR")
+  void should_pass_with_Turkish_default_locale() {
+    // WHEN/THEN
+    strings.assertEndsWithIgnoringCase(someInfo(), "Leia", "IA");
+  }
+
 }
diff --git a/src/test/java/org/assertj/core/internal/strings/Strings_assertEqualsIgnoringCase_Test.java b/src/test/java/org/assertj/core/internal/strings/Strings_assertEqualsIgnoringCase_Test.java
--- a/src/test/java/org/assertj/core/internal/strings/Strings_assertEqualsIgnoringCase_Test.java
+++ b/src/test/java/org/assertj/core/internal/strings/Strings_assertEqualsIgnoringCase_Test.java
@@ -17,15 +17,11 @@
 import static org.assertj.core.test.CharArrays.arrayOf;
 import static org.assertj.core.test.TestData.someInfo;
 
-import org.assertj.core.api.AssertionInfo;
-import org.assertj.core.internal.Strings;
 import org.assertj.core.internal.StringsBaseTest;
 import org.junit.jupiter.api.Test;
-
+import org.junitpioneer.jupiter.DefaultLocale;
 
 /**
- * Tests for <code>{@link Strings#assertEqualsIgnoringCase(AssertionInfo, CharSequence, CharSequence)}</code>.
- * 
  * @author Alex Ruiz
  * @author Joel Costigliola
  */
@@ -103,4 +99,12 @@ void should_pass_if_both_Strings_are_equal_but_not_same_whatever_custom_comparis
   void should_pass_if_both_Strings_are_equal_ignoring_case_whatever_custom_comparison_strategy_is() {
     stringsWithCaseInsensitiveComparisonStrategy.assertEqualsIgnoringCase(someInfo(), "Yoda", "YODA");
   }
+
+  @Test
+  @DefaultLocale("tr-TR")
+  void should_pass_with_Turkish_default_locale() {
+    // WHEN/THEN
+    strings.assertEqualsIgnoringCase(someInfo(), "Leia", "LEIA");
+  }
+
 }
diff --git a/src/test/java/org/assertj/core/internal/strings/Strings_assertNotEqualsIgnoringCase_Test.java b/src/test/java/org/assertj/core/internal/strings/Strings_assertNotEqualsIgnoringCase_Test.java
--- a/src/test/java/org/assertj/core/internal/strings/Strings_assertNotEqualsIgnoringCase_Test.java
+++ b/src/test/java/org/assertj/core/internal/strings/Strings_assertNotEqualsIgnoringCase_Test.java
@@ -15,20 +15,19 @@
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
 import static org.assertj.core.api.Assertions.catchThrowable;
+import static org.assertj.core.api.BDDAssertions.then;
 import static org.assertj.core.error.ShouldNotBeEqualIgnoringCase.shouldNotBeEqualIgnoringCase;
 import static org.assertj.core.test.CharArrays.arrayOf;
 import static org.assertj.core.test.TestData.someInfo;
+import static org.assertj.core.util.AssertionsUtil.expectAssertionError;
 import static org.mockito.Mockito.verify;
 
 import org.assertj.core.api.AssertionInfo;
 import org.assertj.core.internal.StringsBaseTest;
 import org.junit.jupiter.api.Test;
+import org.junitpioneer.jupiter.DefaultLocale;
 
 /**
- * Tests for
- * <code>{@link org.assertj.core.internal.Strings#assertNotEqualsIgnoringCase(org.assertj.core.api.AssertionInfo, CharSequence, CharSequence)}</code>
- * .
- *
  * @author Alexander Bischof
  */
 class Strings_assertNotEqualsIgnoringCase_Test extends StringsBaseTest {
@@ -127,4 +126,14 @@ void should_fail_if_both_Strings_are_equal_ignoring_case_whatever_custom_compari
     assertThat(error).isInstanceOf(AssertionError.class);
     verifyFailureThrownWhenStringsAreNotEqual(info, "Yoda", "YODA");
   }
+
+  @Test
+  @DefaultLocale("tr-TR")
+  void should_fail_with_Turkish_default_locale() {
+    // WHEN
+    AssertionError assertionError = expectAssertionError(() -> strings.assertNotEqualsIgnoringCase(INFO, "Leia", "LEIA"));
+    // THEN
+    then(assertionError).hasMessage(shouldNotBeEqualIgnoringCase("Leia", "LEIA").create());
+  }
+
 }
diff --git a/src/test/java/org/assertj/core/internal/strings/Strings_assertStartsWithIgnoringCase_Test.java b/src/test/java/org/assertj/core/internal/strings/Strings_assertStartsWithIgnoringCase_Test.java
--- a/src/test/java/org/assertj/core/internal/strings/Strings_assertStartsWithIgnoringCase_Test.java
+++ b/src/test/java/org/assertj/core/internal/strings/Strings_assertStartsWithIgnoringCase_Test.java
@@ -18,7 +18,6 @@
 import static org.assertj.core.util.AssertionsUtil.expectAssertionError;
 import static org.assertj.core.util.FailureMessages.actualIsNull;
 
-import org.assertj.core.api.AssertionInfo;
 import org.assertj.core.internal.ComparatorBasedComparisonStrategy;
 import org.assertj.core.internal.ComparisonStrategy;
 import org.assertj.core.internal.StandardComparisonStrategy;
@@ -26,10 +25,8 @@
 import org.assertj.core.internal.StringsBaseTest;
 import org.assertj.core.util.StringHashCodeTestComparator;
 import org.junit.jupiter.api.Test;
+import org.junitpioneer.jupiter.DefaultLocale;
 
-/**
- * Tests for <code>{@link Strings#assertStartsWithIgnoringCase(AssertionInfo, CharSequence, CharSequence)}</code>.
- */
 class Strings_assertStartsWithIgnoringCase_Test extends StringsBaseTest {
 
   @Test
@@ -82,4 +79,12 @@ void should_fail_if_actual_does_not_start_with_prefix_according_to_custom_compar
     // THEN
     then(assertionError).hasMessage(shouldStartWithIgnoringCase("Yoda", "Luke", hashCodeComparisonStrategy).create());
   }
+
+  @Test
+  @DefaultLocale("tr-TR")
+  void should_pass_with_Turkish_default_locale() {
+    // WHEN/THEN
+    strings.assertStartsWithIgnoringCase(INFO, "Leia", "LEI");
+  }
+
 }
diff --git a/src/test/java/org/assertj/core/test/CaseInsensitiveStringComparatorTest.java b/src/test/java/org/assertj/core/test/CaseInsensitiveStringComparatorTest.java
--- a/src/test/java/org/assertj/core/test/CaseInsensitiveStringComparatorTest.java
+++ b/src/test/java/org/assertj/core/test/CaseInsensitiveStringComparatorTest.java
@@ -23,7 +23,7 @@ class CaseInsensitiveStringComparatorTest {
 
   @Test
   @DefaultLocale("tr-TR")
-  void should_work_with_turkish_locale() {
+  void should_work_with_Turkish_default_locale() {
     // WHEN
     int result = underTest.compare("i", "I");
     // THEN