Fix case-insensitive character-wise comparison KT-45496
- Step 1: add failing tests - Step 2: fix common case insensitive Char.equals - Step 3: fix case insensitive String.equals in K/JS - Step 4: enable unicode case folding in K/JS Regexes and string replacement (KT-45928) - Step 5: fix case insensitive char comparison in K/N in String functions String.replace, equals, compareTo with ignoreCase
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@@ -9,6 +9,16 @@ import kotlin.test.*
|
||||
|
||||
class CharTest {
|
||||
|
||||
companion object {
|
||||
val equalIgnoreCaseGroups = listOf(
|
||||
"Aa", "Zz", "üÜ", "öÖ", "äÄ",
|
||||
"KkK", "Ssſ", "µΜμ", "ÅåÅ",
|
||||
"DŽDždž", "LJLjlj", "NJNjnj", "DZDzdz", "ͅΙιι", "Ββϐ", "Εεϵ",
|
||||
"Κκϰ", "Ππϖ", "Ρρϱ", "Σςσ", "Φφϕ", "ΩωΩ", "Ṡṡẛ",
|
||||
"Θθϑϴ", "Iiİı",
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun charFromIntCode() {
|
||||
val codes = listOf(48, 65, 122, 946, '+'.code, 'Ö'.code, 0xFFFC)
|
||||
@@ -145,6 +155,20 @@ class CharTest {
|
||||
testFails(100, radix = 110)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun equalsIgnoreCase() {
|
||||
val nonEqual = equalIgnoreCaseGroups.flatMap { allEqualChars ->
|
||||
allEqualChars.flatMap { c1 -> allEqualChars.mapNotNull { c2 ->
|
||||
if (!c1.equals(c2, ignoreCase = true)) "$c1 != $c2" else null
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nonEqual.isNotEmpty()) {
|
||||
fail("Expected chars to be equal ignoring case:\n${nonEqual.joinToString("\n")}")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun charToCategory() = mapOf(
|
||||
'\u0378' to "Cn",
|
||||
'A' to "Lu", // \u0041
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@@ -847,7 +847,7 @@ class StringTest {
|
||||
val result = v1.compareTo(v2, ignoreCase = ignoreCase).sign
|
||||
assertEquals(expectedResult, result, "Comparing '$v1' with '$v2', ignoreCase = $ignoreCase")
|
||||
if (expectedResult == 0)
|
||||
assertTrue(v1.equals(v2, ignoreCase = ignoreCase))
|
||||
assertTrue(v1.equals(v2, ignoreCase = ignoreCase), "'$v1'=='$v2' should be consistent with ordering, ignoreCase = $ignoreCase")
|
||||
if (!ignoreCase)
|
||||
assertEquals(v1.compareTo(v2).sign, result)
|
||||
}
|
||||
@@ -886,6 +886,16 @@ class StringTest {
|
||||
assertCompareResult(EQ, item1, item2, ignoreCase = true)
|
||||
}
|
||||
}
|
||||
|
||||
CharTest.equalIgnoreCaseGroups
|
||||
.filterNot { "i" in it }
|
||||
.forEach { equalGroup ->
|
||||
for (char1 in equalGroup) {
|
||||
for (char2 in equalGroup) {
|
||||
assertCompareResult(EQ, char1.toString(), char2.toString(), ignoreCase = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -915,12 +925,14 @@ class StringTest {
|
||||
assertEquals(expectAllReplaced, chars.replace(c, '_', ignoreCase = true), "$message, ignoreCase")
|
||||
assertEquals(expectOneReplaced, chars.replace(c.toString(), "_"), "$message, as string")
|
||||
assertEquals(expectAllReplaced, chars.replace(c.toString(), "_", ignoreCase = true), "$message, as string, ignoreCase")
|
||||
assertEquals(expectOneReplaced, chars.replace(Regex(Regex.escape(c.toString())), "_"), "$message, as regex")
|
||||
assertEquals(expectAllReplaced, chars.replace(Regex(Regex.escape(c.toString()), RegexOption.IGNORE_CASE), "_"), "$message, as regex, ignoreCase")
|
||||
}
|
||||
}
|
||||
|
||||
testIgnoreCase("üÜ")
|
||||
testIgnoreCase("öÖ")
|
||||
testIgnoreCase("äÄ")
|
||||
CharTest.equalIgnoreCaseGroups
|
||||
.filterNot { "i" in it } // not supported by JS
|
||||
.forEach { testIgnoreCase(it) }
|
||||
}
|
||||
|
||||
@Test fun replaceFirst() {
|
||||
|
||||
Reference in New Issue
Block a user