161 lines
6.4 KiB
Kotlin
161 lines
6.4 KiB
Kotlin
/*
|
|
* Copyright 2010-2020 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.
|
|
*/
|
|
|
|
package test.text
|
|
|
|
import kotlin.test.*
|
|
|
|
class StringNativeTest {
|
|
|
|
@Test
|
|
fun lowercase() {
|
|
// Non-ASCII
|
|
assertEquals("\u214E\uA7B5\u2CEF", "\u2132\uA7B4\u2CEF".lowercase())
|
|
|
|
// Surrogate pairs
|
|
assertEquals("\uD801\uDC4F\uD806\uDCD0\uD81B\uDE7F", "\uD801\uDC27\uD806\uDCB0\uD81B\uDE5F".lowercase())
|
|
assertEquals("\ud801\udc28", "\ud801\udc28".lowercase())
|
|
assertEquals("\ud801\udc28", "\ud801\udc00".lowercase())
|
|
|
|
// Special Casing
|
|
// LATIN CAPITAL LETTER I WITH DOT ABOVE
|
|
assertEquals("\u0069\u0307", "\u0130".lowercase())
|
|
assertEquals("a\u0069\u0307z", "a\u0130Z".lowercase())
|
|
|
|
// Final_Sigma
|
|
run {
|
|
fun caseIgnorable(length: Int): String {
|
|
return listOf(
|
|
"\u0483", // COMBINING CYRILLIC TITLO; Mn
|
|
"\u20DF", // COMBINING ENCLOSING DIAMOND; Me
|
|
"\uD804\uDCBD", // 110BD; KAITHI NUMBER SIGN; Cf
|
|
"\u2C7D", // MODIFIER LETTER CAPITAL V; Lm
|
|
"\uD83C\uDFFD", // 1F3FD; EMOJI MODIFIER FITZPATRICK TYPE-4; Sk
|
|
"\u003A", // COLON; Po; Word_Break=MidLetter
|
|
"\uFF0E", // FULLWIDTH FULL STOP; Po; Word_Break=MidNumLet
|
|
"\u0027" // APOSTROPHE; Po; Word_Break=Single_Quote
|
|
).shuffled().take(length).joinToString(separator = "")
|
|
}
|
|
|
|
fun cased(): String {
|
|
return listOf(
|
|
"\u0041", // LATIN CAPITAL LETTER A; Lu
|
|
"\uD81B\uDE63", // 16E63; MEDEFAIDRIN SMALL LETTER W; Ll
|
|
"\u01CB", // LATIN CAPITAL LETTER N WITH SMALL LETTER J; Lt
|
|
"\u217A", // SMALL ROMAN NUMERAL ELEVEN; Nl; Other_Lowercase
|
|
"\uD83C\uDD50" // 1F150; NEGATIVE CIRCLED LATIN CAPITAL LETTER A; So; Other_Uppercase
|
|
).random()
|
|
}
|
|
|
|
fun other(): String {
|
|
return listOf(
|
|
"\u0000", // <control>; Cc
|
|
"\u0030", // DIGIT ZERO; Nd
|
|
"\uD838\uDEC6" // 1E2C6; WANCHO LETTER YA; Lo
|
|
).random()
|
|
}
|
|
|
|
fun Char.hex(): String {
|
|
return code.toString(16).padStart(4, '0')
|
|
}
|
|
|
|
val sigma = '\u03A3'
|
|
val lowerSigma = '\u03C3'
|
|
val specialLowerSigma = '\u03C2'
|
|
|
|
// Build a string of the form: [cased][other](caseIgnorable*)(sigma)(caseIgnorable*)[other][cased]
|
|
for (precedingCaseIgnorable in 0..5) {
|
|
for (succeedingCaseIgnorable in 0..5) {
|
|
val caseIgnorableBefore = caseIgnorable(precedingCaseIgnorable)
|
|
val caseIgnorableAfter = caseIgnorable(succeedingCaseIgnorable)
|
|
val sigmaNearby = caseIgnorableBefore + sigma + caseIgnorableAfter
|
|
val lowerSigmaNearby = caseIgnorableBefore + lowerSigma + caseIgnorableAfter
|
|
val specialSigmaNearby = caseIgnorableBefore + specialLowerSigma + caseIgnorableAfter
|
|
|
|
for (mask in 0 until (1 shl 4)) {
|
|
val casedBefore = cased().repeat((mask shr 0) and 1)
|
|
val casedAfter = cased().repeat((mask shr 1) and 1)
|
|
val otherBefore = other().repeat((mask shr 2) and 1)
|
|
val otherAfter = other().repeat((mask shr 3) and 1)
|
|
|
|
val resultSigmaNearby =
|
|
if (otherBefore.isEmpty() && casedBefore.isNotEmpty() && (otherAfter.isNotEmpty() || casedAfter.isEmpty()))
|
|
specialSigmaNearby
|
|
else
|
|
lowerSigmaNearby
|
|
|
|
val actual = (casedBefore + otherBefore + sigmaNearby + otherAfter + casedAfter).lowercase()
|
|
val expected = casedBefore.lowercase() + otherBefore + resultSigmaNearby + otherAfter + casedAfter.lowercase()
|
|
|
|
assertEquals(
|
|
expected,
|
|
actual,
|
|
"Expected <$expected>${expected.map { it.hex() }}, Actual <$actual>${actual.map { it.hex() }}"
|
|
)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@Test
|
|
fun uppercase() {
|
|
// Non-ASCII
|
|
assertEquals("\u00DE\u03A9\u0403\uA779", "\u00FE\u03A9\u0453\uA77A".uppercase())
|
|
|
|
// Surrogate pairs
|
|
assertEquals("\ud801\udc00", "\ud801\udc28".uppercase())
|
|
assertEquals("\ud801\udc00", "\ud801\udc00".uppercase())
|
|
}
|
|
|
|
@Test
|
|
fun capitalize() {
|
|
// Non-ASCII
|
|
assertEquals("\u00DE\u03A9\u0453\uA77A", "\u00FE\u03A9\u0453\uA77A".capitalize())
|
|
}
|
|
|
|
@Test fun indexOfString() {
|
|
assertEquals(1, "bceded".indexOf("ced", -1))
|
|
|
|
assertEquals(-1, "bceded".indexOf("e", 7))
|
|
assertEquals(-1, "bceded".indexOf("e", Int.MAX_VALUE))
|
|
assertEquals(6, "bceded".indexOf("", Int.MAX_VALUE))
|
|
|
|
assertEquals(-1, "".indexOf("a", -3))
|
|
assertEquals(0, "".indexOf("", 0))
|
|
}
|
|
|
|
@Test
|
|
fun indexOfChar() {
|
|
assertEquals(-1, "bcedef".indexOf('e', 5))
|
|
|
|
assertEquals(-1, "".indexOf('a', -3))
|
|
assertEquals(-1, "".indexOf('a', 10))
|
|
|
|
assertEquals(-1, "".indexOf(0.toChar(), -3))
|
|
assertEquals(-1, "".indexOf(0.toChar(), 10))
|
|
}
|
|
|
|
@Test
|
|
fun equalsIgnoreCase() {
|
|
assertTrue("hello".equals("HElLo", true))
|
|
assertTrue("Привет".equals("прИВет", true))
|
|
}
|
|
|
|
@Test
|
|
fun trim() {
|
|
assertEquals(expected = "String", actual = "\u0020 \u202FString\u2028\u2029".trim(),
|
|
message = "Trim special whitespaces")
|
|
assertEquals(expected = "\u1FFFString", actual = "\u00A0 \u1FFFString".trim(),
|
|
message = "Trim special whitespace but should left a unicode symbol")
|
|
}
|
|
|
|
@Test
|
|
fun subSequence() {
|
|
assertEquals("ello", "Hello world".subSequence(1, 5).toString())
|
|
assertEquals("", "Hello world".subSequence(1, 1).toString())
|
|
}
|
|
}
|