[K/N] Migrate runtime/text tests to new testing infra ^KT-61259
This commit is contained in:
committed by
Space Team
parent
e9983a947f
commit
17dc60aac9
@@ -63,10 +63,59 @@ class CharNativeTest {
|
||||
assertEquals("\u0069\u0307", '\u0130'.lowercase())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun titlecase() {
|
||||
// titlecase = titlecaseChar = char != uppercaseChar
|
||||
assertEquals('\u10F0'.titlecaseChar().toString(), '\u10F0'.titlecase())
|
||||
assertEquals('\u10F0', '\u10F0'.titlecaseChar())
|
||||
assertNotEquals('\u10F0', '\u10F0'.uppercaseChar())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testIsSupplementaryCodePoint() {
|
||||
assertFalse(Char.isSupplementaryCodePoint(-1))
|
||||
for (c in 0..0xFFFF) {
|
||||
assertFalse(Char.isSupplementaryCodePoint(c.toInt()))
|
||||
}
|
||||
for (c in 0xFFFF + 1..0x10FFFF) {
|
||||
assertTrue(Char.isSupplementaryCodePoint(c))
|
||||
}
|
||||
assertFalse(Char.isSupplementaryCodePoint(0x10FFFF + 1))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isSurrogatePair() {
|
||||
assertFalse(Char.isSurrogatePair('\u0000', '\u0000'))
|
||||
assertFalse(Char.isSurrogatePair('\u0000', '\uDC00'))
|
||||
assertTrue( Char.isSurrogatePair('\uD800', '\uDC00'))
|
||||
assertTrue( Char.isSurrogatePair('\uD800', '\uDFFF'))
|
||||
assertTrue( Char.isSurrogatePair('\uDBFF', '\uDFFF'))
|
||||
assertFalse(Char.isSurrogatePair('\uDBFF', '\uF000'))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun toChars() {
|
||||
assertContentEquals(Char.toChars(0x010000), charArrayOf('\uD800', '\uDC00'))
|
||||
assertContentEquals(Char.toChars(0x010001), charArrayOf('\uD800', '\uDC01'))
|
||||
assertContentEquals(Char.toChars(0x010401), charArrayOf('\uD801', '\uDC01'))
|
||||
assertContentEquals(Char.toChars(0x10FFFF), charArrayOf('\uDBFF', '\uDFFF'))
|
||||
|
||||
assertFailsWith<IllegalArgumentException> { Char.toChars(Int.MAX_VALUE) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun toCodePoint() {
|
||||
assertEquals(0x010000, Char.toCodePoint('\uD800', '\uDC00'))
|
||||
assertEquals(0x010001, Char.toCodePoint('\uD800', '\uDC01'))
|
||||
assertEquals(0x010401, Char.toCodePoint('\uD801', '\uDC01'))
|
||||
assertEquals(0x10FFFF, Char.toCodePoint('\uDBFF', '\uDFFF'))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun category() {
|
||||
assertTrue('<' in CharCategory.MATH_SYMBOL)
|
||||
assertTrue(';' in CharCategory.OTHER_PUNCTUATION)
|
||||
assertTrue('_' in CharCategory.CONNECTOR_PUNCTUATION)
|
||||
assertTrue('$' in CharCategory.CURRENCY_SYMBOL)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Copyright 2010-2023 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.*
|
||||
|
||||
// Native-specific part of stdlib/test/text/StringBuilderTest.kt
|
||||
class StringBuilderNativeTest {
|
||||
@Test
|
||||
fun insertCharSequence() {
|
||||
StringBuilder("my insert CharSequence test").let { sb ->
|
||||
sb.insert(0, null as CharSequence?)
|
||||
assertEquals("nullmy insert CharSequence test", sb.toString())
|
||||
sb.insert(2, null as CharSequence?)
|
||||
assertEquals("nunullllmy insert CharSequence test", sb.toString())
|
||||
sb.insert(sb.length, null as CharSequence?)
|
||||
assertEquals("nunullllmy insert CharSequence testnull", sb.toString())
|
||||
sb.insert(2, "12" as CharSequence)
|
||||
assertEquals("nu12nullllmy insert CharSequence testnull", sb.toString())
|
||||
sb.insert(sb.length, "12" as CharSequence)
|
||||
assertEquals("nu12nullllmy insert CharSequence testnull12", sb.toString())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun insertString() {
|
||||
StringBuilder("my insert String test").let { sb ->
|
||||
sb.insertRange(0, "1234", 0, 0)
|
||||
assertEquals("my insert String test", sb.toString())
|
||||
sb.insertRange(0, "1234", 0, 1)
|
||||
assertEquals("1my insert String test", sb.toString())
|
||||
sb.insertRange(0, "1234", 1, 3)
|
||||
assertEquals("231my insert String test", sb.toString())
|
||||
sb.insertRange(2, "1234", 0, 0)
|
||||
assertEquals("231my insert String test", sb.toString())
|
||||
sb.insertRange(2, "1234", 0, 1)
|
||||
assertEquals("2311my insert String test", sb.toString())
|
||||
sb.insertRange(2, "1234", 1, 3)
|
||||
assertEquals("232311my insert String test", sb.toString())
|
||||
sb.insertRange(sb.length, "1234", 0, 0)
|
||||
assertEquals("232311my insert String test", sb.toString())
|
||||
sb.insertRange(sb.length, "1234", 0, 1)
|
||||
assertEquals("232311my insert String test1", sb.toString())
|
||||
sb.insertRange(sb.length, "1234", 1, 3)
|
||||
assertEquals("232311my insert String test123", sb.toString())
|
||||
|
||||
assertFailsWith<IndexOutOfBoundsException> { sb.insert(-1, "_") }
|
||||
assertFailsWith<IndexOutOfBoundsException> { sb.insert(sb.length + 1, "_") }
|
||||
assertFails { sb.insertRange(0, "null", -1, 0) }
|
||||
assertFails { sb.insertRange(0, "null", 0, 5) }
|
||||
assertFails { sb.insertRange(0, "null", 2, 1) }
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun insertByte() {
|
||||
StringBuilder().let { sb ->
|
||||
sb.insert(0, 42.toByte())
|
||||
assertEquals("42", sb.toString())
|
||||
sb.insert(0, 13.toByte())
|
||||
assertEquals("1342", sb.toString())
|
||||
sb.insert(3, -1.toByte())
|
||||
assertEquals("134-12", sb.toString())
|
||||
|
||||
assertFailsWith<IndexOutOfBoundsException> { sb.insert(-1, 42.toByte()) }
|
||||
assertFailsWith<IndexOutOfBoundsException> { sb.insert(sb.length + 1, 42.toByte()) }
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun insertShort() {
|
||||
StringBuilder().let { sb ->
|
||||
sb.insert(0, 42.toShort())
|
||||
assertEquals("42", sb.toString())
|
||||
sb.insert(0, 13.toShort())
|
||||
assertEquals("1342", sb.toString())
|
||||
sb.insert(3, -1.toShort())
|
||||
assertEquals("134-12", sb.toString())
|
||||
|
||||
assertFailsWith<IndexOutOfBoundsException> { sb.insert(-1, 42.toShort()) }
|
||||
assertFailsWith<IndexOutOfBoundsException> { sb.insert(sb.length + 1, 42.toShort()) }
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun insertInt() {
|
||||
StringBuilder().let { sb ->
|
||||
sb.insert(0, 42.toInt())
|
||||
assertEquals("42", sb.toString())
|
||||
sb.insert(0, 13.toInt())
|
||||
assertEquals("1342", sb.toString())
|
||||
sb.insert(3, -1.toInt())
|
||||
assertEquals("134-12", sb.toString())
|
||||
|
||||
assertFailsWith<IndexOutOfBoundsException> { sb.insert(-1, 42.toInt()) }
|
||||
assertFailsWith<IndexOutOfBoundsException> { sb.insert(sb.length + 1, 42.toInt()) }
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun insertLong() {
|
||||
StringBuilder().let { sb ->
|
||||
sb.insert(0, 42.toLong())
|
||||
assertEquals("42", sb.toString())
|
||||
sb.insert(0, 13.toLong())
|
||||
assertEquals("1342", sb.toString())
|
||||
sb.insert(3, -1.toLong())
|
||||
assertEquals("134-12", sb.toString())
|
||||
|
||||
assertFailsWith<IndexOutOfBoundsException> { sb.insert(-1, 42.toLong()) }
|
||||
assertFailsWith<IndexOutOfBoundsException> { sb.insert(sb.length + 1, 42.toLong()) }
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun insertFloat() {
|
||||
StringBuilder().let { sb ->
|
||||
sb.insert(0, 42.2.toFloat())
|
||||
assertEquals("42.2", sb.toString())
|
||||
sb.insert(0, 13.1.toFloat())
|
||||
assertEquals("13.142.2", sb.toString())
|
||||
sb.insert(3, -1.toFloat())
|
||||
assertEquals("13.-1.0142.2", sb.toString())
|
||||
|
||||
assertFailsWith<IndexOutOfBoundsException> { sb.insert(-1, 42.2.toFloat()) }
|
||||
assertFailsWith<IndexOutOfBoundsException> { sb.insert(sb.length + 1, 42.2.toFloat()) }
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun insertDouble() {
|
||||
StringBuilder().let { sb ->
|
||||
sb.insert(0, 42.2.toDouble())
|
||||
assertEquals("42.2", sb.toString())
|
||||
sb.insert(0, 13.1.toDouble())
|
||||
assertEquals("13.142.2", sb.toString())
|
||||
sb.insert(3, -1.toDouble())
|
||||
assertEquals("13.-1.0142.2", sb.toString())
|
||||
|
||||
assertFailsWith<IndexOutOfBoundsException> { sb.insert(-1, 42.2.toDouble()) }
|
||||
assertFailsWith<IndexOutOfBoundsException> { sb.insert(sb.length + 1, 42.2.toDouble()) }
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testReverse() {
|
||||
val sb = StringBuilder("123456")
|
||||
assertTrue(sb === sb.reverse())
|
||||
assertEquals("654321", sb.toString())
|
||||
|
||||
sb.setLength(1)
|
||||
assertEquals("6", sb.toString())
|
||||
|
||||
sb.setLength(0)
|
||||
assertEquals("", sb.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDoubleReverse() {
|
||||
fun assertReversed(original: String, reversed: String, reversedBack: String = original) {
|
||||
assertEquals(reversed, StringBuilder(original).reverse().toString())
|
||||
assertEquals(reversedBack, StringBuilder(reversed).reverse().toString())
|
||||
}
|
||||
|
||||
assertReversed("a", "a")
|
||||
assertReversed("ab", "ba")
|
||||
assertReversed("abcdef", "fedcba")
|
||||
assertReversed("abcdefg", "gfedcba")
|
||||
assertReversed("\ud800\udc00", "\ud800\udc00")
|
||||
assertReversed("\udc00\ud800", "\ud800\udc00", "\ud800\udc00")
|
||||
assertReversed("a\ud800\udc00", "\ud800\udc00a")
|
||||
assertReversed("ab\ud800\udc00", "\ud800\udc00ba")
|
||||
assertReversed("abc\ud800\udc00", "\ud800\udc00cba")
|
||||
assertReversed("\ud800\udc00\udc01\ud801\ud802\udc02", "\ud802\udc02\ud801\udc01\ud800\udc00", "\ud800\udc00\ud801\udc01\ud802\udc02")
|
||||
assertReversed("\ud800\udc00\ud801\udc01\ud802\udc02", "\ud802\udc02\ud801\udc01\ud800\udc00")
|
||||
assertReversed("\ud800\udc00\udc01\ud801a", "a\ud801\udc01\ud800\udc00", "\ud800\udc00\ud801\udc01a")
|
||||
assertReversed("a\ud800\udc00\ud801\udc01", "\ud801\udc01\ud800\udc00a")
|
||||
assertReversed("\ud800\udc00\udc01\ud801ab", "ba\ud801\udc01\ud800\udc00", "\ud800\udc00\ud801\udc01ab")
|
||||
assertReversed("ab\ud800\udc00\ud801\udc01", "\ud801\udc01\ud800\udc00ba")
|
||||
assertReversed("\ud800\udc00\ud801\udc01", "\ud801\udc01\ud800\udc00")
|
||||
assertReversed("a\ud800\udc00z\ud801\udc01", "\ud801\udc01z\ud800\udc00a")
|
||||
assertReversed("a\ud800\udc00bz\ud801\udc01", "\ud801\udc01zb\ud800\udc00a")
|
||||
assertReversed("abc\ud802\udc02\ud801\udc01\ud800\udc00", "\ud800\udc00\ud801\udc01\ud802\udc02cba")
|
||||
assertReversed("abcd\ud802\udc02\ud801\udc01\ud800\udc00", "\ud800\udc00\ud801\udc01\ud802\udc02dcba")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun appendLong() {
|
||||
val times = 100
|
||||
val expected = (12345678L until (12345678L + times)).fold("") { res, idx -> res + idx }
|
||||
|
||||
val sb = StringBuilder()
|
||||
repeat(times) { sb.append(12345678L + it) }
|
||||
assertEquals(expected, sb.toString())
|
||||
|
||||
val cornerCase = listOf(0L, -1L, Long.MIN_VALUE, Long.MAX_VALUE)
|
||||
val expectedCornerCase = cornerCase.fold("") { res, e -> res + e }
|
||||
for (v in cornerCase) sb.append(v)
|
||||
assertEquals(expected + expectedCornerCase, sb.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun appendNullCharSequence() {
|
||||
val sb = StringBuilder()
|
||||
sb.append(null as CharSequence?)
|
||||
assertEquals("null", sb.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun appendLine() {
|
||||
val sb = StringBuilder()
|
||||
sb.appendLine("abc").appendLine(42).appendLine(0.1)
|
||||
assertEquals("abc\n42\n0.1\n", sb.toString())
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,216 @@
|
||||
|
||||
package test.text
|
||||
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.test.*
|
||||
import kotlinx.cinterop.toKString
|
||||
import test.assertArrayContentEquals
|
||||
|
||||
internal actual val surrogateCodePointDecoding: String = "\uFFFD".repeat(3)
|
||||
|
||||
internal actual val surrogateCharEncoding: ByteArray = byteArrayOf(0xEF.toByte(), 0xBF.toByte(), 0xBD.toByte())
|
||||
|
||||
// Native-specific part of stdlib/test/text/StringEncodingTest.kt
|
||||
class StringEncodingTestNative {
|
||||
private fun bytes(vararg elements: Int) = ByteArray(elements.size) {
|
||||
val v = elements[it]
|
||||
require(v in Byte.MIN_VALUE..Byte.MAX_VALUE)
|
||||
v.toByte()
|
||||
}
|
||||
|
||||
private fun testEncoding(isWellFormed: Boolean, expected: ByteArray, string: String) {
|
||||
assertArrayContentEquals(expected, string.encodeToByteArray())
|
||||
if (!isWellFormed) {
|
||||
assertFailsWith<CharacterCodingException> { string.encodeToByteArray(throwOnInvalidSequence = true) }
|
||||
} else {
|
||||
assertArrayContentEquals(expected, string.encodeToByteArray(throwOnInvalidSequence = true))
|
||||
assertEquals(string, string.encodeToByteArray(throwOnInvalidSequence = true).decodeToString())
|
||||
}
|
||||
}
|
||||
|
||||
private fun testEncoding(isWellFormed: Boolean, expected: ByteArray, string: String, startIndex: Int, endIndex: Int) {
|
||||
assertArrayContentEquals(expected, string.encodeToByteArray(startIndex, endIndex))
|
||||
if (!isWellFormed) {
|
||||
assertFailsWith<CharacterCodingException> { string.encodeToByteArray(startIndex, endIndex, true) }
|
||||
} else {
|
||||
assertArrayContentEquals(expected, string.encodeToByteArray(startIndex, endIndex, true))
|
||||
string.encodeToByteArray(startIndex, endIndex, true).decodeToString()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun encodeToByteArray() {
|
||||
// Valid strings.
|
||||
testEncoding(true, bytes('H'.toInt(), 'e'.toInt(), 'l'.toInt(), 'l'.toInt(), 'o'.toInt()), "Hello")
|
||||
testEncoding(true, bytes(-48, -97, -47, -128, -48, -72, -48, -78, -48, -75, -47, -126), "Привет")
|
||||
|
||||
// Different kinds of input
|
||||
testEncoding(false, bytes(-16, -112, -128, -128, '1'.toInt(), -17, -65, -67, -17, -65, -67), "\uD800\uDC001\uDC00\uD800")
|
||||
// Lone surrogate
|
||||
testEncoding(false, bytes(-17, -65, -67, '1'.toInt(), '2'.toInt()), "\uD80012", )
|
||||
testEncoding(false, bytes(-17, -65, -67, '1'.toInt(), '2'.toInt()), "\uDC0012")
|
||||
testEncoding(false, bytes('1'.toInt(), '2'.toInt(), -17, -65, -67), "12\uD800")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun encodeToByteArraySlice() {
|
||||
// Valid strings.
|
||||
testEncoding(true, bytes(-16, -112, -128, -128, -16, -112, -128, -128), "\uD800\uDC00\uD800\uDC00\uD800\uDC00\uD800\uDC00", 0, 4)
|
||||
testEncoding(true, bytes(-16, -112, -128, -128, -16, -112, -128, -128), "\uD800\uDC00\uD800\uDC00\uD800\uDC00\uD800\uDC00", 2, 6)
|
||||
testEncoding(true, bytes(-16, -112, -128, -128, -16, -112, -128, -128), "\uD800\uDC00\uD800\uDC00\uD800\uDC00\uD800\uDC00", 4, 8)
|
||||
|
||||
// Illegal surrogate pair
|
||||
testEncoding(false, bytes(-17, -65, -67, -17, -65, -67, '1'.toInt()), "\uDC00\uD80012", 0, 3)
|
||||
testEncoding(false, bytes(-17, -65, -67, -17, -65, -67, '2'.toInt()), "1\uDC00\uD8002", 1, 4)
|
||||
testEncoding(false, bytes('2'.toInt(), -17, -65, -67, -17, -65, -67), "12\uDC00\uD800", 1, 4)
|
||||
// Lone surrogate
|
||||
testEncoding(false, bytes('1'.toInt(), -17, -65, -67), "1\uD800\uDC002", 0, 2)
|
||||
testEncoding(false, bytes(-17, -65, -67, '2'.toInt()), "1\uD800\uDC002", 2, 4)
|
||||
}
|
||||
|
||||
private fun testDecoding(isWellFormed: Boolean, expected: String, bytes: ByteArray) {
|
||||
assertEquals(expected, bytes.decodeToString())
|
||||
if (!isWellFormed) {
|
||||
assertFailsWith<CharacterCodingException> { bytes.decodeToString(throwOnInvalidSequence = true) }
|
||||
} else {
|
||||
assertEquals(expected, bytes.decodeToString(throwOnInvalidSequence = true))
|
||||
assertArrayContentEquals(bytes, bytes.decodeToString(throwOnInvalidSequence = true).encodeToByteArray())
|
||||
}
|
||||
}
|
||||
|
||||
private fun testDecoding(isWellFormed: Boolean, expected: String, bytes: ByteArray, startIndex: Int, endIndex: Int) {
|
||||
assertEquals(expected, bytes.decodeToString(startIndex, endIndex))
|
||||
if (!isWellFormed) {
|
||||
assertFailsWith<CharacterCodingException> { bytes.decodeToString(startIndex, endIndex, true) }
|
||||
} else {
|
||||
assertEquals(expected, bytes.decodeToString(startIndex, endIndex, true))
|
||||
assertArrayContentEquals(
|
||||
bytes.sliceArray(startIndex until endIndex),
|
||||
bytes.decodeToString(startIndex, endIndex, true).encodeToByteArray()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun decodeToString() {
|
||||
// Valid strings.
|
||||
testDecoding(true, "Hello", bytes('H'.toInt(), 'e'.toInt(), 'l'.toInt(), 'l'.toInt(), 'o'.toInt()))
|
||||
testDecoding(true, "Привет", bytes(-48, -97, -47, -128, -48, -72, -48, -78, -48, -75, -47, -126))
|
||||
testDecoding(true, "\uD800\uDC00", bytes(-16, -112, -128, -128))
|
||||
|
||||
// Incorrect UTF-8 lead character.
|
||||
testDecoding(false, "\uFFFD1", bytes(-1, '1'.toInt()))
|
||||
|
||||
// Incomplete codepoint.
|
||||
testDecoding(false, "\uFFFD1", bytes(-16, -97, -104, '1'.toInt()))
|
||||
testDecoding(false, "\uFFFD1\uFFFD", bytes(-16, -97, -104, '1'.toInt(), -16, -97, -104))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun decodeToStringSlice() {
|
||||
// Valid strings.
|
||||
testDecoding(true, "\uD800\uDC00\uD800\uDC00", bytes(-16, -112, -128, -128, -16, -112, -128, -128, -16, -112, -128, -128, -16, -112, -128, -128), 0, 8)
|
||||
testDecoding(true, "\uD800\uDC00\uD800\uDC00", bytes(-16, -112, -128, -128, -16, -112, -128, -128, -16, -112, -128, -128, -16, -112, -128, -128), 4, 12)
|
||||
testDecoding(true, "\uD800\uDC00\uD800\uDC00", bytes(-16, -112, -128, -128, -16, -112, -128, -128, -16, -112, -128, -128, -16, -112, -128, -128), 8, 16)
|
||||
|
||||
// Incorrect UTF-8 lead character.
|
||||
testDecoding(false, "\uFFFD1", bytes(-1, '1'.toInt(), '2'.toInt()), 0, 2)
|
||||
testDecoding(false, "\uFFFD2", bytes('1'.toInt(), -1, '2'.toInt(), '3'.toInt()), 1, 3)
|
||||
testDecoding(false, "2\uFFFD", bytes('1'.toInt(), '2'.toInt(), -1), 1, 3)
|
||||
|
||||
// Incomplete codepoint.
|
||||
testDecoding(false, "\uFFFD1", bytes(-16, -97, -104, '1'.toInt(), '2'.toInt()), 0, 4)
|
||||
testDecoding(false, "\uFFFD2", bytes('1'.toInt(), -16, -97, -104, '2'.toInt(), '3'.toInt()), 1, 5)
|
||||
testDecoding(false, "2\uFFFD", bytes('1'.toInt(), '2'.toInt(), -16, -97, -104), 1, 5)
|
||||
}
|
||||
|
||||
private fun testToKString(isWellFormed: Boolean, expected: String, bytes: ByteArray) {
|
||||
assertEquals(expected, bytes.toKString())
|
||||
assertEquals(expected, bytes.copyOf(bytes.size + 1).toKString())
|
||||
if (!isWellFormed) {
|
||||
assertFailsWith<CharacterCodingException> { bytes.toKString(throwOnInvalidSequence = true) }
|
||||
assertFailsWith<CharacterCodingException> { bytes.copyOf(bytes.size + 1).toKString(throwOnInvalidSequence = true) }
|
||||
} else {
|
||||
assertEquals(expected, bytes.toKString(throwOnInvalidSequence = true))
|
||||
assertEquals(expected, bytes.copyOf(bytes.size + 1).toKString(throwOnInvalidSequence = true))
|
||||
}
|
||||
}
|
||||
|
||||
private fun testToKString(isWellFormed: Boolean, expected: String, bytes: ByteArray, startIndex: Int, endIndex: Int) {
|
||||
assertEquals(expected, bytes.toKString(startIndex, endIndex))
|
||||
assertEquals(expected, bytes.copyOf(bytes.size + 1).toKString(startIndex, endIndex))
|
||||
if (!isWellFormed) {
|
||||
assertFailsWith<CharacterCodingException> { bytes.toKString(startIndex, endIndex, true) }
|
||||
assertFailsWith<CharacterCodingException> { bytes.copyOf(bytes.size + 1).toKString(startIndex, endIndex, true) }
|
||||
} else {
|
||||
assertEquals(expected, bytes.toKString(startIndex, endIndex, true))
|
||||
assertEquals(expected, bytes.copyOf(bytes.size + 1).toKString(startIndex, endIndex, true))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun toKString() {
|
||||
// Valid strings.
|
||||
testToKString(true, "Hello", bytes('H'.toInt(), 'e'.toInt(), 'l'.toInt(), 'l'.toInt(), 'o'.toInt()))
|
||||
testToKString(true, "Hell", bytes('H'.toInt(), 'e'.toInt(), 'l'.toInt(), 'l'.toInt(), 0, 'o'.toInt()))
|
||||
testToKString(true, "Привет", bytes(-48, -97, -47, -128, -48, -72, -48, -78, -48, -75, -47, -126))
|
||||
testToKString(true, "При", bytes(-48, -97, -47, -128, -48, -72, 0, -48, -78, 0, -48, -75, -47, -126))
|
||||
testToKString(true, "\uD800\uDC00", bytes(-16, -112, -128, -128))
|
||||
testToKString(true, "\uD800\uDC00", bytes(-16, -112, -128, -128, 0, -16, -112, -128, -128))
|
||||
testToKString(true, "", bytes())
|
||||
testToKString(true, "", bytes(0, 'H'.toInt()))
|
||||
|
||||
// Incorrect UTF-8 lead character.
|
||||
testToKString(false, "\uFFFD1", bytes(-1, '1'.toInt()))
|
||||
testToKString(false, "\uFFFD", bytes(-1, 0, '1'.toInt()))
|
||||
|
||||
// Incomplete codepoint.
|
||||
testToKString(false, "\uFFFD1", bytes(-16, -97, -104, '1'.toInt()))
|
||||
testToKString(false, "\uFFFD", bytes(-16, -97, -104, 0, '1'.toInt()))
|
||||
testToKString(false, "\uFFFD1\uFFFD", bytes(-16, -97, -104, '1'.toInt(), -16, -97, -104))
|
||||
testToKString(false, "\uFFFD1", bytes(-16, -97, -104, '1'.toInt(), 0, -16, -97, -104))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun toKStringSlice() {
|
||||
assertFailsWith<IndexOutOfBoundsException> { bytes('H'.toInt(), 'e'.toInt(), 'l'.toInt(), 'l'.toInt(), 'o'.toInt()).toKString(-1, 3) }
|
||||
assertFailsWith<IndexOutOfBoundsException> { bytes('H'.toInt(), 'e'.toInt(), 'l'.toInt(), 'l'.toInt(), 'o'.toInt()).toKString(5, 15) }
|
||||
assertFailsWith<IndexOutOfBoundsException> { bytes('H'.toInt(), 'e'.toInt(), 'l'.toInt(), 'l'.toInt(), 'o'.toInt()).toKString(2, 12) }
|
||||
assertFailsWith<IndexOutOfBoundsException> { bytes('H'.toInt(), 'e'.toInt(), 'l'.toInt(), 'l'.toInt(), 'o'.toInt()).toKString(10, 10) }
|
||||
assertFailsWith<IllegalArgumentException> { bytes('H'.toInt(), 'e'.toInt(), 'l'.toInt(), 'l'.toInt(), 'o'.toInt()).toKString(3, 1) }
|
||||
assertFailsWith<IndexOutOfBoundsException> { bytes('a'.toInt(), 'a'.toInt(), 'a'.toInt(), 0, 'b'.toInt(), 'b'.toInt(), 'b'.toInt(), 0).toKString(-1, 3) }
|
||||
assertFailsWith<IndexOutOfBoundsException> { bytes('a'.toInt(), 'a'.toInt(), 'a'.toInt(), 0, 'b'.toInt(), 'b'.toInt(), 'b'.toInt(), 0).toKString(8, 18) }
|
||||
assertFailsWith<IndexOutOfBoundsException> { bytes('a'.toInt(), 'a'.toInt(), 'a'.toInt(), 0, 'b'.toInt(), 'b'.toInt(), 'b'.toInt(), 0).toKString(2, 12) }
|
||||
assertFailsWith<IndexOutOfBoundsException> { bytes('a'.toInt(), 'a'.toInt(), 'a'.toInt(), 0, 'b'.toInt(), 'b'.toInt(), 'b'.toInt(), 0).toKString(10, 10) }
|
||||
assertFailsWith<IllegalArgumentException> { bytes('a'.toInt(), 'a'.toInt(), 'a'.toInt(), 0, 'b'.toInt(), 'b'.toInt(), 'b'.toInt(), 0).toKString(3, 1) }
|
||||
|
||||
// Valid strings.
|
||||
testToKString(true, "He", bytes('H'.toInt(), 'e'.toInt(), 'l'.toInt(), 'l'.toInt(), 'o'.toInt()), 0, 2)
|
||||
testToKString(true, "ll", bytes('H'.toInt(), 'e'.toInt(), 'l'.toInt(), 'l'.toInt(), 'o'.toInt()), 2, 4)
|
||||
testToKString(true, "lo", bytes('H'.toInt(), 'e'.toInt(), 'l'.toInt(), 'l'.toInt(), 'o'.toInt()), 3, 5)
|
||||
testToKString(true, "", bytes('H'.toInt(), 'e'.toInt(), 'l'.toInt(), 'l'.toInt(), 'o'.toInt()), 0, 0)
|
||||
testToKString(true, "\uD800\uDC00\uD800\uDC00", bytes(-16, -112, -128, -128, -16, -112, -128, -128, -16, -112, -128, -128, -16, -112, -128, -128), 0, 8)
|
||||
testToKString(true, "\uD800\uDC00\uD800\uDC00", bytes(-16, -112, -128, -128, -16, -112, -128, -128, -16, -112, -128, -128, -16, -112, -128, -128), 4, 12)
|
||||
testToKString(true, "\uD800\uDC00\uD800\uDC00", bytes(-16, -112, -128, -128, -16, -112, -128, -128, -16, -112, -128, -128, -16, -112, -128, -128), 8, 16)
|
||||
testToKString(true, "aaa", bytes('a'.toInt(), 'a'.toInt(), 'a'.toInt(), 0, 'b'.toInt(), 'b'.toInt(), 'b'.toInt(), 0), 0, 5)
|
||||
testToKString(true, "a", bytes('a'.toInt(), 'a'.toInt(), 'a'.toInt(), 0, 'b'.toInt(), 'b'.toInt(), 'b'.toInt(), 0), 2, 4)
|
||||
testToKString(true, "", bytes('a'.toInt(), 'a'.toInt(), 'a'.toInt(), 0, 'b'.toInt(), 'b'.toInt(), 'b'.toInt(), 0), 3, 5)
|
||||
testToKString(true, "bb", bytes('a'.toInt(), 'a'.toInt(), 'a'.toInt(), 0, 'b'.toInt(), 'b'.toInt(), 'b'.toInt(), 0), 4, 6)
|
||||
testToKString(true, "bbb", bytes('a'.toInt(), 'a'.toInt(), 'a'.toInt(), 0, 'b'.toInt(), 'b'.toInt(), 'b'.toInt(), 0), 4, 7)
|
||||
testToKString(true, "bbb", bytes('a'.toInt(), 'a'.toInt(), 'a'.toInt(), 0, 'b'.toInt(), 'b'.toInt(), 'b'.toInt(), 0), 4, 8)
|
||||
testToKString(true, "bb", bytes('a'.toInt(), 'a'.toInt(), 'a'.toInt(), 0, 'b'.toInt(), 'b'.toInt(), 'b'.toInt(), 0), 5, 8)
|
||||
testToKString(true, "b", bytes('a'.toInt(), 'a'.toInt(), 'a'.toInt(), 0, 'b'.toInt(), 'b'.toInt(), 'b'.toInt(), 0), 6, 8)
|
||||
testToKString(true, "", bytes('a'.toInt(), 'a'.toInt(), 'a'.toInt(), 0, 'b'.toInt(), 'b'.toInt(), 'b'.toInt(), 0), 7, 8)
|
||||
testToKString(true, "", bytes('a'.toInt(), 'a'.toInt(), 'a'.toInt(), 0, 'b'.toInt(), 'b'.toInt(), 'b'.toInt(), 0), 8, 8)
|
||||
|
||||
// Incorrect UTF-8 lead character.
|
||||
testToKString(false, "\uFFFD1", bytes(-1, '1'.toInt(), '2'.toInt()), 0, 2)
|
||||
testToKString(false, "\uFFFD2", bytes('1'.toInt(), -1, '2'.toInt(), '3'.toInt()), 1, 3)
|
||||
testToKString(false, "2\uFFFD", bytes('1'.toInt(), '2'.toInt(), -1), 1, 3)
|
||||
|
||||
// Incomplete codepoint.
|
||||
testToKString(false, "\uFFFD1", bytes(-16, -97, -104, '1'.toInt(), '2'.toInt()), 0, 4)
|
||||
testToKString(false, "\uFFFD2", bytes('1'.toInt(), -16, -97, -104, '2'.toInt(), '3'.toInt()), 1, 5)
|
||||
testToKString(false, "2\uFFFD", bytes('1'.toInt(), '2'.toInt(), -16, -97, -104), 1, 5)
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,8 @@ class StringNativeTest {
|
||||
|
||||
// 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
|
||||
@@ -102,5 +104,51 @@ class StringNativeTest {
|
||||
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")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright 2010-2023 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.*
|
||||
|
||||
// Native-specific part of stdlib/test/text/StringNumberConversionTest.kt
|
||||
class StringNumberConversionNativeTest {
|
||||
@Test
|
||||
fun toDouble() {
|
||||
assertEquals(0.5, "0.5".toDouble())
|
||||
assertEquals(-5000000000.0, "-00000000000000000000.5e10".toDouble())
|
||||
assertEquals(-0.005, "-00000000000000000000.5e-2".toDouble())
|
||||
assertEquals(50000000000.0, "+5e10".toDouble())
|
||||
assertEquals(50000000000.0, " +5e10 ".toDouble())
|
||||
assertEquals(520.0, "+5.2e2d".toDouble())
|
||||
assertEquals(0.052, "+5.2e-2d".toDouble())
|
||||
assertEquals(52340000000.0, "+5.234e+10d".toDouble())
|
||||
assertEquals(5.234E123, "+5.234e+123d".toDouble())
|
||||
assertEquals(5.234E123, "+5.234e+123f".toDouble())
|
||||
assertEquals(5.234E123, "+5.234e+123".toDouble())
|
||||
assertEquals(5.5, "5.5f".toDouble())
|
||||
assertEquals(2.71, "\u0009 \u000A 2.71 \u000D".toDouble())
|
||||
assertEquals(42.3, "\n 42.3 ".toDouble())
|
||||
|
||||
assertFailsWith<NumberFormatException> {
|
||||
"+-5.0".toDouble()
|
||||
}
|
||||
assertFailsWith<NumberFormatException> {
|
||||
"d".toDouble()
|
||||
}
|
||||
assertFailsWith<NumberFormatException> {
|
||||
"5.5.3e123d".toDouble()
|
||||
}
|
||||
|
||||
// regression of incorrect processing of long lines - such values returned Infinity
|
||||
assertFailsWith<NumberFormatException> {
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa".toDouble()
|
||||
}
|
||||
assertFailsWith<NumberFormatException> {
|
||||
"+-my free text with different letters $3213#. e ".toDouble()
|
||||
}
|
||||
assertFailsWith<NumberFormatException> {
|
||||
"eeeeeEEEEEeeeeeee".toDouble()
|
||||
}
|
||||
assertFailsWith<NumberFormatException> {
|
||||
"InfinityN".toDouble()
|
||||
}
|
||||
assertFailsWith<NumberFormatException> {
|
||||
"NaNPICEZy".toDouble()
|
||||
}
|
||||
|
||||
assertFailsWith<NumberFormatException> { "\u20293.14".toDouble() }
|
||||
assertFailsWith<NumberFormatException> { "3.14\u200B".toDouble() }
|
||||
assertFailsWith<NumberFormatException> { "3.14\u200B ABC".toDouble() }
|
||||
|
||||
// Illegal surrogate pair
|
||||
assertFailsWith<NumberFormatException> { "\uDC00\uD800".toDouble() }
|
||||
// Different kinds of input (including illegal one)
|
||||
assertFailsWith<NumberFormatException> { "\uD800\uDC001\uDC00\uD800".toDouble() }
|
||||
// Lone surrogate
|
||||
assertFailsWith<NumberFormatException> { "\uD80012".toDouble() }
|
||||
assertFailsWith<NumberFormatException> { "\uDC0012".toDouble() }
|
||||
assertFailsWith<NumberFormatException> { "12\uD800".toDouble() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun toFloat() {
|
||||
assertEquals(0.5f, "0.5".toFloat())
|
||||
assertEquals(-5000000000f, "-00000000000000000000.5e10f".toFloat())
|
||||
assertEquals(-0.005f, "-00000000000000000000.5e-2f".toFloat())
|
||||
assertEquals(50000000000f, "+5e10".toFloat())
|
||||
assertEquals(50000000000f, " +5e10 ".toFloat())
|
||||
assertEquals(0.052f, "+5.2e-2f".toFloat())
|
||||
assertEquals(520f, "+5.2e2f".toFloat())
|
||||
assertEquals(0.052f, "+5.2e-2f".toFloat())
|
||||
assertEquals(52340000000f, "+5.234e+10f".toFloat())
|
||||
assertEquals(Float.POSITIVE_INFINITY, "+5.234e+123f".toFloat())
|
||||
assertEquals(7.15f, "\u0019 7.15 ".toFloat())
|
||||
assertEquals(2.71f, "\u0009 \u000A 2.71 \u000D".toFloat())
|
||||
|
||||
assertFailsWith<NumberFormatException> {
|
||||
"+-5.0f".toFloat()
|
||||
}
|
||||
assertFailsWith<NumberFormatException> {
|
||||
"f".toFloat()
|
||||
}
|
||||
assertFailsWith<NumberFormatException> {
|
||||
"5.5.3e123f".toFloat()
|
||||
}
|
||||
|
||||
// regression of incorrect processing of long lines - such values returned Infinity
|
||||
assertFailsWith<NumberFormatException> {
|
||||
// should be more than 38 symbols
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa".toFloat()
|
||||
}
|
||||
assertFailsWith<NumberFormatException> {
|
||||
// should be more than 38 symbols
|
||||
"this string is not a numb3r, am I right?????????????".toFloat()
|
||||
}
|
||||
assertFailsWith<NumberFormatException> {
|
||||
// should be more than 38 symbols
|
||||
"+-my free text with different letters $3213#. e ".toFloat()
|
||||
}
|
||||
assertFailsWith<NumberFormatException> {
|
||||
// should be more than 38 symbols
|
||||
"eeeeeEEEEEeeeeeee".toFloat()
|
||||
}
|
||||
assertFailsWith<NumberFormatException> {
|
||||
"InfinityN".toFloat()
|
||||
}
|
||||
assertFailsWith<NumberFormatException> {
|
||||
"NaNPICEZy".toFloat()
|
||||
}
|
||||
|
||||
assertFailsWith<NumberFormatException> { "\u202F3.14".toFloat() }
|
||||
|
||||
// Illegal surrogate pair
|
||||
assertFailsWith<NumberFormatException> { "\uDC00\uD800".toFloat() }
|
||||
// Different kinds of input (including illegal one)
|
||||
assertFailsWith<NumberFormatException> { "\uD800\uDC001\uDC00\uD800".toFloat() }
|
||||
// Lone surrogate
|
||||
assertFailsWith<NumberFormatException> { "\uD80012".toFloat() }
|
||||
assertFailsWith<NumberFormatException> { "\uDC0012".toFloat() }
|
||||
assertFailsWith<NumberFormatException> { "12\uD800".toFloat() }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user