Move everything under kotlin-native folder
I was forced to manually do update the following files, because otherwise they would be ignored according .gitignore settings. Probably they should be deleted from repo. Interop/.idea/compiler.xml Interop/.idea/gradle.xml Interop/.idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_runtime_1_0_3.xml Interop/.idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_stdlib_1_0_3.xml Interop/.idea/modules.xml Interop/.idea/modules/Indexer/Indexer.iml Interop/.idea/modules/Runtime/Runtime.iml Interop/.idea/modules/StubGenerator/StubGenerator.iml backend.native/backend.native.iml backend.native/bc.frontend/bc.frontend.iml backend.native/cli.bc/cli.bc.iml backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.kt backend.native/tests/link/lib/foo.kt backend.native/tests/link/lib/foo2.kt backend.native/tests/teamcity-test.property
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
package runtime.text.chars0
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
fun assertTrue(v: Boolean) = if (!v) throw AssertionError() else Unit
|
||||
fun assertFalse(v: Boolean) = if (v) throw AssertionError() else Unit
|
||||
fun assertEquals(a: Int, b: Int) { if (a != b) throw AssertionError() }
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
fun testIsSurrogatePair() {
|
||||
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'))
|
||||
}
|
||||
|
||||
fun testToChars() {
|
||||
assertTrue(charArrayOf('\uD800', '\uDC00').contentEquals(Char.toChars(0x010000)))
|
||||
assertTrue(charArrayOf('\uD800', '\uDC01').contentEquals(Char.toChars(0x010001)))
|
||||
assertTrue(charArrayOf('\uD801', '\uDC01').contentEquals(Char.toChars(0x010401)))
|
||||
assertTrue(charArrayOf('\uDBFF', '\uDFFF').contentEquals(Char.toChars(0x10FFFF)))
|
||||
|
||||
try {
|
||||
Char.toChars(Int.MAX_VALUE)
|
||||
throw AssertionError()
|
||||
} catch (e: IllegalArgumentException) {}
|
||||
}
|
||||
|
||||
fun testToCodePoint() {
|
||||
assertEquals(0x010000, Char.toCodePoint('\uD800', '\uDC00'))
|
||||
assertEquals(0x010001, Char.toCodePoint('\uD800', '\uDC01'))
|
||||
assertEquals(0x010401, Char.toCodePoint('\uD801', '\uDC01'))
|
||||
assertEquals(0x10FFFF, Char.toCodePoint('\uDBFF', '\uDFFF'))
|
||||
}
|
||||
|
||||
// TODO: Uncomment when such operations are supported for supplementary codepoints and the API is public.
|
||||
fun testCase() {
|
||||
/*
|
||||
assertEquals('A'.toInt(), Char.toUpperCase('a'.toInt()))
|
||||
assertEquals('A'.toInt(), Char.toUpperCase('A'.toInt()))
|
||||
assertEquals('1'.toInt(), Char.toUpperCase('1'.toInt()))
|
||||
|
||||
assertEquals('a'.toInt(), Char.toLowerCase('A'.toInt()))
|
||||
assertEquals('a'.toInt(), Char.toLowerCase('a'.toInt()))
|
||||
assertEquals('1'.toInt(), Char.toLowerCase('1'.toInt()))
|
||||
|
||||
assertEquals(0x010400, Char.toUpperCase(0x010428))
|
||||
assertEquals(0x010400, Char.toUpperCase(0x010400))
|
||||
assertEquals(0x10FFFF, Char.toUpperCase(0x10FFFF))
|
||||
assertEquals(0x110000, Char.toUpperCase(0x110000))
|
||||
|
||||
assertEquals(0x010428, Char.toLowerCase(0x010400))
|
||||
assertEquals(0x010428, Char.toLowerCase(0x010428))
|
||||
assertEquals(0x10FFFF, Char.toLowerCase(0x10FFFF))
|
||||
assertEquals(0x110000, Char.toLowerCase(0x110000))
|
||||
*/
|
||||
}
|
||||
|
||||
fun testCategory() {
|
||||
assertEquals('\n'.category.value, CharCategory.CONTROL.value)
|
||||
assertEquals('1'.category.value, CharCategory.DECIMAL_DIGIT_NUMBER.value)
|
||||
assertEquals(' '.category.value, CharCategory.SPACE_SEPARATOR.value)
|
||||
assertEquals('a'.category.value, CharCategory.LOWERCASE_LETTER.value)
|
||||
assertEquals('A'.category.value, CharCategory.UPPERCASE_LETTER.value)
|
||||
assertEquals('<'.category.value, CharCategory.MATH_SYMBOL.value)
|
||||
assertEquals(';'.category.value, CharCategory.OTHER_PUNCTUATION.value)
|
||||
assertEquals('_'.category.value, CharCategory.CONNECTOR_PUNCTUATION.value)
|
||||
assertEquals('$'.category.value, CharCategory.CURRENCY_SYMBOL.value)
|
||||
assertEquals('\u2029'.category.value, CharCategory.PARAGRAPH_SEPARATOR.value)
|
||||
|
||||
assertTrue('\n' in CharCategory.CONTROL)
|
||||
assertTrue('1' in CharCategory.DECIMAL_DIGIT_NUMBER)
|
||||
assertTrue(' ' in CharCategory.SPACE_SEPARATOR)
|
||||
assertTrue('a' in CharCategory.LOWERCASE_LETTER)
|
||||
assertTrue('A' in CharCategory.UPPERCASE_LETTER)
|
||||
assertTrue('<' in CharCategory.MATH_SYMBOL)
|
||||
assertTrue(';' in CharCategory.OTHER_PUNCTUATION)
|
||||
assertTrue('_' in CharCategory.CONNECTOR_PUNCTUATION)
|
||||
assertTrue('$' in CharCategory.CURRENCY_SYMBOL)
|
||||
assertTrue('\u2029' in CharCategory.PARAGRAPH_SEPARATOR)
|
||||
|
||||
try {
|
||||
CharCategory.valueOf(-1)
|
||||
throw AssertionError()
|
||||
} catch (e: IllegalArgumentException) {}
|
||||
|
||||
try {
|
||||
CharCategory.valueOf(31)
|
||||
throw AssertionError()
|
||||
} catch (e: IllegalArgumentException) {}
|
||||
|
||||
try {
|
||||
CharCategory.valueOf(17)
|
||||
throw AssertionError()
|
||||
} catch (e: IllegalArgumentException) {}
|
||||
}
|
||||
|
||||
@Test fun runTest() {
|
||||
testIsSurrogatePair()
|
||||
testToChars()
|
||||
testToCodePoint()
|
||||
testIsSupplementaryCodePoint()
|
||||
testCase()
|
||||
testCategory()
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
package runtime.text.indexof
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
@Test fun runTest() {
|
||||
var str = "Hello World!!" // for indexOf String
|
||||
var ch = 'a' // for indexOf Char
|
||||
|
||||
assertEquals(6, str.indexOf("World", 0))
|
||||
assertEquals(6, str.indexOf("World", -1))
|
||||
|
||||
assertEquals(-1, str.indexOf(ch, 0))
|
||||
|
||||
str = "Kotlin/Native"
|
||||
assertEquals(-1, str.indexOf("/", str.length + 1))
|
||||
assertEquals(-1, str.indexOf("/", Int.MAX_VALUE))
|
||||
assertEquals(str.length, str.indexOf("", Int.MAX_VALUE))
|
||||
assertEquals(1, str.indexOf("", 1))
|
||||
|
||||
assertEquals(8, str.indexOf(ch, 1))
|
||||
assertEquals(-1, str.indexOf(ch, str.length - 1))
|
||||
|
||||
str = ""
|
||||
assertEquals(-1, str.indexOf("a", -3))
|
||||
assertEquals(0, str.indexOf("", 0))
|
||||
|
||||
assertEquals(-1, str.indexOf(ch, -3))
|
||||
assertEquals(-1, str.indexOf(ch, 10))
|
||||
|
||||
ch = 0.toChar()
|
||||
assertEquals(-1, str.indexOf(ch, -3))
|
||||
assertEquals(-1, str.indexOf(ch, 10))
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
package runtime.text.parse0
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
@Test fun runTest() {
|
||||
println("false".toBoolean())
|
||||
println("true".toBoolean())
|
||||
println("-1".toByte())
|
||||
println("a".toByte(16))
|
||||
println("aa".toShort(16))
|
||||
println("11110".toInt(2))
|
||||
println("ffffffff".toLong(16))
|
||||
try {
|
||||
val x = "ffffffff".toLong(10)
|
||||
} catch (ne: NumberFormatException) {
|
||||
println("bad format")
|
||||
}
|
||||
println("0.5".toFloat())
|
||||
println("2.39".toDouble())
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
package runtime.text.string0
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
@Test fun runTest() {
|
||||
val str = "hello"
|
||||
println(str.equals("HElLo", true))
|
||||
val strI18n = "Привет"
|
||||
println(strI18n.equals("прИВет", true))
|
||||
println(strI18n.toUpperCase())
|
||||
println(strI18n.toLowerCase())
|
||||
println("пока".capitalize())
|
||||
println("http://jetbrains.com".startsWith("http://"))
|
||||
}
|
||||
@@ -0,0 +1,280 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
package runtime.text.string_builder0
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
// Utils ====================================================================================================
|
||||
fun assertTrue(cond: Boolean) {
|
||||
if (!cond)
|
||||
throw AssertionError("Condition expected to be true")
|
||||
}
|
||||
|
||||
fun assertFalse(cond: Boolean) {
|
||||
if (cond)
|
||||
throw AssertionError("Condition expected to be false")
|
||||
}
|
||||
|
||||
fun assertEquals(value1: String, value2: String) {
|
||||
if (value1 != value2)
|
||||
throw AssertionError("FAIL: '" + value1 + "' != '" + value2 + "'")
|
||||
}
|
||||
|
||||
fun assertEquals(value1: Int, value2: Int) {
|
||||
if (value1 != value2)
|
||||
throw AssertionError("FAIL" + value1.toString() + " != " + value2.toString())
|
||||
}
|
||||
|
||||
fun assertEquals(builder: StringBuilder, content: String) = assertEquals(builder.toString(), content)
|
||||
|
||||
// IndexOutOfBoundsException.
|
||||
fun assertException(body: () -> Unit) {
|
||||
try {
|
||||
body()
|
||||
throw AssertionError ("Test failed: no IndexOutOfBoundsException on wrong indices")
|
||||
} catch (e: IndexOutOfBoundsException) {
|
||||
} catch (e: IllegalArgumentException) {}
|
||||
}
|
||||
|
||||
// Insert ===================================================================================================
|
||||
fun testInsertString(initial: String, index: Int, toInsert: String, expected: String) {
|
||||
assertEquals(StringBuilder(initial).insert(index, toInsert), expected)
|
||||
assertEquals(StringBuilder(initial).insert(index, toInsert.toCharArray()), expected)
|
||||
assertEquals(StringBuilder(initial).insert(index, toInsert as CharSequence), expected)
|
||||
}
|
||||
|
||||
fun testInsertStringException(initial: String, index: Int, toInsert: String) {
|
||||
assertException { StringBuilder(initial).insert(index, toInsert) }
|
||||
assertException { StringBuilder(initial).insert(index, toInsert.toCharArray()) }
|
||||
assertException { StringBuilder(initial).insert(index, toInsert as CharSequence) }
|
||||
}
|
||||
|
||||
fun testInsertSingle(value: Byte) {
|
||||
assertEquals(StringBuilder("abcd").insert(0, value), value.toString() + "abcd")
|
||||
assertEquals(StringBuilder("abcd").insert(4, value), "abcd" + value.toString())
|
||||
assertEquals(StringBuilder("abcd").insert(2, value), "ab" + value.toString() + "cd")
|
||||
assertEquals(StringBuilder("").insert(0, value), value.toString())
|
||||
}
|
||||
|
||||
fun testInsertSingle(value: Short) {
|
||||
assertEquals(StringBuilder("abcd").insert(0, value), value.toString() + "abcd")
|
||||
assertEquals(StringBuilder("abcd").insert(4, value), "abcd" + value.toString())
|
||||
assertEquals(StringBuilder("abcd").insert(2, value), "ab" + value.toString() + "cd")
|
||||
assertEquals(StringBuilder("").insert(0, value), value.toString())
|
||||
}
|
||||
|
||||
fun testInsertSingle(value: Int) {
|
||||
assertEquals(StringBuilder("abcd").insert(0, value), value.toString() + "abcd")
|
||||
assertEquals(StringBuilder("abcd").insert(4, value), "abcd" + value.toString())
|
||||
assertEquals(StringBuilder("abcd").insert(2, value), "ab" + value.toString() + "cd")
|
||||
assertEquals(StringBuilder("").insert(0, value), value.toString())
|
||||
}
|
||||
|
||||
fun testInsertSingle(value: Long) {
|
||||
assertEquals(StringBuilder("abcd").insert(0, value), value.toString() + "abcd")
|
||||
assertEquals(StringBuilder("abcd").insert(4, value), "abcd" + value.toString())
|
||||
assertEquals(StringBuilder("abcd").insert(2, value), "ab" + value.toString() + "cd")
|
||||
assertEquals(StringBuilder("").insert(0, value), value.toString())
|
||||
}
|
||||
|
||||
fun testInsertSingle(value: Float) {
|
||||
assertEquals(StringBuilder("abcd").insert(0, value), value.toString() + "abcd")
|
||||
assertEquals(StringBuilder("abcd").insert(4, value), "abcd" + value.toString())
|
||||
assertEquals(StringBuilder("abcd").insert(2, value), "ab" + value.toString() + "cd")
|
||||
assertEquals(StringBuilder("").insert(0, value), value.toString())
|
||||
}
|
||||
|
||||
fun testInsertSingle(value: Double) {
|
||||
assertEquals(StringBuilder("abcd").insert(0, value), value.toString() + "abcd")
|
||||
assertEquals(StringBuilder("abcd").insert(4, value), "abcd" + value.toString())
|
||||
assertEquals(StringBuilder("abcd").insert(2, value), "ab" + value.toString() + "cd")
|
||||
assertEquals(StringBuilder("").insert(0, value), value.toString())
|
||||
}
|
||||
|
||||
fun testInsertSingle(value: Any?) {
|
||||
assertEquals(StringBuilder("abcd").insert(0, value), value.toString() + "abcd")
|
||||
assertEquals(StringBuilder("abcd").insert(4, value), "abcd" + value.toString())
|
||||
assertEquals(StringBuilder("abcd").insert(2, value), "ab" + value.toString() + "cd")
|
||||
assertEquals(StringBuilder("").insert(0, value), value.toString())
|
||||
}
|
||||
|
||||
fun testInsertSingle(value: Char) {
|
||||
assertEquals(StringBuilder("abcd").insert(0, value), value.toString() + "abcd")
|
||||
assertEquals(StringBuilder("abcd").insert(4, value), "abcd" + value.toString())
|
||||
assertEquals(StringBuilder("abcd").insert(2, value), "ab" + value.toString() + "cd")
|
||||
assertEquals(StringBuilder("").insert(0, value), value.toString())
|
||||
}
|
||||
|
||||
fun testInsert() {
|
||||
// String/CharSequence/CharArray.
|
||||
testInsertString("abcd", 0, "12", "12abcd")
|
||||
testInsertString("abcd", 4, "12", "abcd12")
|
||||
testInsertString("abcd", 2, "12", "ab12cd")
|
||||
testInsertString("", 0, "12", "12")
|
||||
testInsertStringException("a", -1, "1")
|
||||
testInsertStringException("a", 2, "1")
|
||||
|
||||
// Null inserting.
|
||||
assertEquals(StringBuilder("abcd").insert(0, null as CharSequence?), "nullabcd")
|
||||
assertEquals(StringBuilder("abcd").insert(4, null as CharSequence?), "abcdnull")
|
||||
assertEquals(StringBuilder("abcd").insert(2, null as CharSequence?), "abnullcd")
|
||||
assertEquals(StringBuilder("").insert(0, null as CharSequence?), "null")
|
||||
|
||||
// Subsequence of CharSequence.
|
||||
// Insert in the beginning.
|
||||
assertEquals(StringBuilder("abcd").insert(0, "1234", 0, 0), "abcd") // 0 symbols
|
||||
assertEquals(StringBuilder("abcd").insert(0, "1234", 0, 1), "1abcd") // 1 symbol
|
||||
assertEquals(StringBuilder("abcd").insert(0, "1234", 1, 3), "23abcd") // 2 symbols
|
||||
assertEquals(StringBuilder("abcd").insert(0, null as CharSequence?, 1, 3), "ulabcd") // 2 symbols of null
|
||||
|
||||
// Insert in the end.
|
||||
assertEquals(StringBuilder("abcd").insert(4, "1234", 0, 0), "abcd")
|
||||
assertEquals(StringBuilder("abcd").insert(4, "1234", 0, 1), "abcd1")
|
||||
assertEquals(StringBuilder("abcd").insert(4, "1234", 1, 3), "abcd23")
|
||||
assertEquals(StringBuilder("abcd").insert(4, null as CharSequence?, 1, 3), "abcdul")
|
||||
|
||||
// Insert in the middle.
|
||||
assertEquals(StringBuilder("abcd").insert(2, "1234", 0, 0), "abcd")
|
||||
assertEquals(StringBuilder("abcd").insert(2, "1234", 0, 1), "ab1cd")
|
||||
assertEquals(StringBuilder("abcd").insert(2, "1234", 1, 3), "ab23cd")
|
||||
assertEquals(StringBuilder("abcd").insert(2, null as CharSequence?, 1, 3), "abulcd")
|
||||
|
||||
// Incorrect indices.
|
||||
assertException { StringBuilder("a").insert(-1, "1", 0, 0) }
|
||||
assertException { StringBuilder("a").insert(2, "1", 0, 0) }
|
||||
assertException { StringBuilder("a").insert(1, "1", -1, 0) }
|
||||
assertException { StringBuilder("a").insert(1, "1", 0, 2) }
|
||||
assertException { StringBuilder("a").insert(1, "123", 2, 0) }
|
||||
|
||||
// Other types.
|
||||
testInsertSingle(true)
|
||||
testInsertSingle(42.toByte())
|
||||
testInsertSingle(42.toShort())
|
||||
testInsertSingle(42.toInt())
|
||||
testInsertSingle(42.toLong())
|
||||
testInsertSingle(42.2.toFloat())
|
||||
testInsertSingle(42.2.toDouble())
|
||||
testInsertSingle(object {
|
||||
override fun toString(): String {
|
||||
return "Object"
|
||||
}
|
||||
})
|
||||
testInsertSingle('a')
|
||||
}
|
||||
|
||||
// Reverse ==================================================================================================
|
||||
fun testReverse(original: String, reversed: String, reversedBack: String) {
|
||||
assertEquals(StringBuilder(original).reverse(), reversed)
|
||||
assertEquals(StringBuilder(reversed).reverse(), reversedBack)
|
||||
}
|
||||
|
||||
fun testReverse() {
|
||||
var builder = StringBuilder("123456")
|
||||
assertTrue(builder === builder.reverse())
|
||||
assertEquals(builder, "654321")
|
||||
|
||||
builder.setLength(1)
|
||||
assertEquals(builder, "6")
|
||||
|
||||
builder.setLength(0)
|
||||
assertEquals(builder, "")
|
||||
|
||||
var str: String = "a"
|
||||
testReverse(str, str, str)
|
||||
|
||||
str = "ab"
|
||||
testReverse(str, "ba", str)
|
||||
|
||||
str = "abcdef"
|
||||
testReverse(str, "fedcba", str)
|
||||
|
||||
str = "abcdefg"
|
||||
testReverse(str, "gfedcba", str)
|
||||
|
||||
str = "\ud800\udc00"
|
||||
testReverse(str, str, str)
|
||||
|
||||
str = "\udc00\ud800"
|
||||
testReverse(str, "\ud800\udc00", "\ud800\udc00")
|
||||
|
||||
str = "a\ud800\udc00"
|
||||
testReverse(str, "\ud800\udc00a", str)
|
||||
|
||||
str = "ab\ud800\udc00"
|
||||
testReverse(str, "\ud800\udc00ba", str)
|
||||
|
||||
str = "abc\ud800\udc00"
|
||||
testReverse(str, "\ud800\udc00cba", str)
|
||||
|
||||
str = "\ud800\udc00\udc01\ud801\ud802\udc02"
|
||||
testReverse(str, "\ud802\udc02\ud801\udc01\ud800\udc00",
|
||||
"\ud800\udc00\ud801\udc01\ud802\udc02")
|
||||
|
||||
str = "\ud800\udc00\ud801\udc01\ud802\udc02"
|
||||
testReverse(str, "\ud802\udc02\ud801\udc01\ud800\udc00", str)
|
||||
|
||||
str = "\ud800\udc00\udc01\ud801a"
|
||||
testReverse(str, "a\ud801\udc01\ud800\udc00",
|
||||
"\ud800\udc00\ud801\udc01a")
|
||||
|
||||
str = "a\ud800\udc00\ud801\udc01"
|
||||
testReverse(str, "\ud801\udc01\ud800\udc00a", str)
|
||||
|
||||
str = "\ud800\udc00\udc01\ud801ab"
|
||||
testReverse(str, "ba\ud801\udc01\ud800\udc00",
|
||||
"\ud800\udc00\ud801\udc01ab")
|
||||
|
||||
str = "ab\ud800\udc00\ud801\udc01"
|
||||
testReverse(str, "\ud801\udc01\ud800\udc00ba", str)
|
||||
|
||||
str = "\ud800\udc00\ud801\udc01"
|
||||
testReverse(str, "\ud801\udc01\ud800\udc00", str)
|
||||
|
||||
str = "a\ud800\udc00z\ud801\udc01"
|
||||
testReverse(str, "\ud801\udc01z\ud800\udc00a", str)
|
||||
|
||||
str = "a\ud800\udc00bz\ud801\udc01"
|
||||
testReverse(str, "\ud801\udc01zb\ud800\udc00a", str)
|
||||
|
||||
str = "abc\ud802\udc02\ud801\udc01\ud800\udc00"
|
||||
testReverse(str, "\ud800\udc00\ud801\udc01\ud802\udc02cba", str)
|
||||
|
||||
str = "abcd\ud802\udc02\ud801\udc01\ud800\udc00"
|
||||
testReverse(str, "\ud800\udc00\ud801\udc01\ud802\udc02dcba", str)
|
||||
}
|
||||
|
||||
// Basic ====================================================================================================
|
||||
fun testBasic() {
|
||||
val sb = StringBuilder()
|
||||
assertEquals(0, sb.length)
|
||||
assertEquals("", sb.toString())
|
||||
sb.append(1)
|
||||
assertEquals(1, sb.length)
|
||||
assertEquals("1", sb.toString())
|
||||
sb.append(", ")
|
||||
assertEquals(3, sb.length)
|
||||
assertEquals("1, ", sb.toString())
|
||||
sb.append(true)
|
||||
assertEquals(7, sb.length)
|
||||
assertEquals("1, true", sb.toString())
|
||||
sb.append(12345678L)
|
||||
assertEquals(15, sb.length)
|
||||
assertEquals("1, true12345678", sb.toString())
|
||||
sb.append(null as CharSequence?)
|
||||
assertEquals(19, sb.length)
|
||||
assertEquals("1, true12345678null", sb.toString())
|
||||
|
||||
sb.setLength(0)
|
||||
assertEquals(0, sb.length)
|
||||
assertEquals("", sb.toString())
|
||||
}
|
||||
|
||||
@Test fun runTest() {
|
||||
testBasic()
|
||||
testInsert()
|
||||
testReverse()
|
||||
println("OK")
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
package runtime.text.string_builder1
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
@Test fun runTest() {
|
||||
val a = StringBuilder()
|
||||
a.append("Hello").appendln("Kotlin").appendln(42).appendln(0.1).appendln(true)
|
||||
println(a.toString())
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
package runtime.text.to_string0
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
// Based on Apache Harmony tests.
|
||||
|
||||
fun assertEquals(actual: String, expected: String, msg: String) {
|
||||
if (actual != expected) throw AssertionError("$msg. Actual: $actual. Expected: $expected")
|
||||
}
|
||||
|
||||
fun testIntToStringWithRadix() {
|
||||
assertEquals(2147483647.toString(8), "17777777777", "Octal string")
|
||||
assertEquals(2147483647.toString(16), "7fffffff", "Hex string")
|
||||
assertEquals(2147483647.toString(2), "1111111111111111111111111111111", "Binary string")
|
||||
assertEquals(2147483647.toString(10), "2147483647", "Decimal string")
|
||||
|
||||
assertEquals((-2147483647).toString(8), "-17777777777", "Octal string")
|
||||
assertEquals((-2147483647).toString(16), "-7fffffff", "Hex string")
|
||||
assertEquals((-2147483647).toString(2), "-1111111111111111111111111111111", "Binary string")
|
||||
assertEquals((-2147483647).toString(10), "-2147483647", "Decimal string")
|
||||
|
||||
assertEquals((-2147483648).toString(8), "-20000000000", "Octal string")
|
||||
assertEquals((-2147483648).toString(16), "-80000000", "Hex string")
|
||||
assertEquals((-2147483648).toString(2), "-10000000000000000000000000000000", "Binary string")
|
||||
assertEquals((-2147483648).toString(10), "-2147483648", "Decimal string")
|
||||
}
|
||||
|
||||
fun testLongToStringWithRadix() {
|
||||
assertEquals(100000000L.toString(10), "100000000", "Decimal string")
|
||||
assertEquals(68719476735L.toString(16), "fffffffff", "Hex string")
|
||||
assertEquals(8589934591L.toString(8), "77777777777", "Octal string")
|
||||
assertEquals(8796093022207L.toString(2), "1111111111111111111111111111111111111111111", "Binary string")
|
||||
|
||||
assertEquals((-0x7fffffffffffffffL - 1).toString(10), "-9223372036854775808", "Min decimal string")
|
||||
assertEquals(0x7fffffffffffffffL.toString(10), "9223372036854775807", "Max decimal string")
|
||||
assertEquals((-0x7fffffffffffffffL - 1).toString(16), "-8000000000000000", "Min hex string")
|
||||
assertEquals(0x7fffffffffffffffL.toString(16), "7fffffffffffffff", "Max hex string")
|
||||
|
||||
}
|
||||
|
||||
@Test fun runTest() {
|
||||
testIntToStringWithRadix()
|
||||
testLongToStringWithRadix()
|
||||
println("OK")
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
package runtime.text.trim
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
/**
|
||||
* Tests correct conversions of floats/doubles along with trimming of leading/trailing whitespaces.
|
||||
* String.trim() trims all whitespaces (see kotlin/text/Strings.kt) while String.toFloat() uses
|
||||
* the same approach as java.lang.Float.parseFloat()
|
||||
*/
|
||||
@Test fun runTest() {
|
||||
convertToFloatingPoint()
|
||||
convertWithWhitespaces()
|
||||
trimWhitespaces()
|
||||
|
||||
println("OK")
|
||||
}
|
||||
|
||||
private fun convertToFloatingPoint() {
|
||||
assertEquals(expected = 3.14F, actual = " 3.14 ".toFloat(), message = "String float should be trimmed")
|
||||
assertEquals(expected = 3.14, actual = " 3.14 ".toDouble(), message = "String double should be trimmed")
|
||||
assertEquals(expected = 7.15F, actual = "\u0019 7.15 ".toFloat(), message = "String float should be trimmed")
|
||||
assertEquals(expected = 42.3, actual = "\n 42.3 ".toDouble(), message = "String double should be trimmed")
|
||||
}
|
||||
|
||||
private fun convertWithWhitespaces() {
|
||||
val s = "\u0009 \u000A 2.71 \u000D"
|
||||
assertEquals(expected = 2.71F, actual = s.toFloat(),
|
||||
message = "String should be cleared of LF, CR, TAB and converted to Float")
|
||||
assertEquals(expected = 2.71, actual = s.toDouble(),
|
||||
message = "String should be cleared of LF, CR, TAB and converted to Double")
|
||||
|
||||
// Special symbols should not be trimmed during String to Float/Double conversion
|
||||
assertFailsWith<NumberFormatException> { "\u202F3.14".toFloat() }
|
||||
assertFailsWith<NumberFormatException> { "\u20293.14".toDouble() }
|
||||
assertFailsWith<NumberFormatException> { "3.14\u200B".toDouble() }
|
||||
assertFailsWith<NumberFormatException> { "3.14\u200B ABC".toDouble() }
|
||||
}
|
||||
|
||||
private fun trimWhitespaces() {
|
||||
assertEquals(expected = "String", actual = " String".trim(), message = "Trim leading spaces")
|
||||
assertEquals(expected = "String ", actual = " String ".trimStart(), message = "Trim start")
|
||||
assertEquals(expected = " String", actual = " String \t ".trimEnd(), message = "Trim end")
|
||||
|
||||
assertEquals(expected = "String", actual = "\u0020 \u202FString\u2028\u2029".trim(),
|
||||
message = "Trim special whitespaces")
|
||||
assertEquals(expected = "\u1FFFString", actual = "\u0085 \u1FFFString".trim(),
|
||||
message = "Trim special whitespace but should left a unicode symbol")
|
||||
assertEquals(expected = "String\tSTR", actual = " \nString\tSTR ".trim(), message = "Trim newline")
|
||||
}
|
||||
@@ -0,0 +1,476 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
package runtime.text.utf8
|
||||
|
||||
import kotlin.test.*
|
||||
import kotlin.reflect.KClass
|
||||
import kotlinx.cinterop.toKString
|
||||
|
||||
// -------------------------------------- Utils --------------------------------------
|
||||
fun assertEquals(expected: ByteArray, actual: ByteArray, message: String) =
|
||||
assertTrue(expected.contentEquals(actual), message)
|
||||
|
||||
|
||||
fun checkUtf16to8(string: String, expected: IntArray, conversion: String.() -> ByteArray) {
|
||||
expected.forEach {
|
||||
assertTrue(it in Byte.MIN_VALUE..Byte.MAX_VALUE, "Expected array contains illegal values")
|
||||
}
|
||||
val expectedBytes = ByteArray(expected.size) { i -> expected[i].toByte() }
|
||||
val actual = string.conversion()
|
||||
assertEquals(expectedBytes, actual, """
|
||||
Assert failed for string: $string
|
||||
Expected: ${expected.joinToString()}
|
||||
Actual: ${actual.joinToString()}
|
||||
""".trimIndent())
|
||||
}
|
||||
|
||||
// Utils for checking successful UTF-16 to UTF-8 conversion.
|
||||
fun checkUtf16to8Replacing(string: String, expected: IntArray) {
|
||||
checkUtf16to8(string, expected) { encodeToByteArray() }
|
||||
}
|
||||
fun checkUtf16to8Throwing(string: String, expected: IntArray) {
|
||||
checkUtf16to8(string, expected) { encodeToByteArray(throwOnInvalidSequence = true) }
|
||||
}
|
||||
fun checkValidUtf16to8(string: String, expected: IntArray) {
|
||||
checkUtf16to8Replacing(string, expected)
|
||||
checkUtf16to8Throwing(string, expected)
|
||||
}
|
||||
|
||||
fun checkUtf16to8Replacing(string: String, expected: IntArray, start: Int, size: Int) {
|
||||
checkUtf16to8(string, expected) { encodeToByteArray(start, start + size) }
|
||||
}
|
||||
fun checkUtf16to8Throwing(string: String, expected: IntArray, start: Int, size: Int) {
|
||||
checkUtf16to8(string, expected) { encodeToByteArray(start, start + size, true) }
|
||||
}
|
||||
fun checkValidUtf16to8(string: String, expected: IntArray, start: Int, size: Int) {
|
||||
checkUtf16to8Replacing(string, expected, start, size)
|
||||
checkUtf16to8Throwing(string, expected, start, size)
|
||||
}
|
||||
|
||||
|
||||
// Utils for checking successful UTF-8 to UTF-16 conversion.
|
||||
fun checkUtf8to16(expected: String, array: IntArray, conversion: ByteArray.() -> String) {
|
||||
array.forEach {
|
||||
assertTrue(it in Byte.MIN_VALUE..Byte.MAX_VALUE, "Expected array contains illegal values")
|
||||
}
|
||||
val arrayBytes = ByteArray(array.size) { i -> array[i].toByte() }
|
||||
val actual = arrayBytes.conversion()
|
||||
assertEquals(expected, actual, """
|
||||
Assert failed for string: $expected
|
||||
Expected: $expected
|
||||
Actual: $actual
|
||||
""".trimIndent())
|
||||
}
|
||||
|
||||
fun checkZeroTerminatedUtf8to16Replacing(expected: String, array: IntArray) {
|
||||
checkUtf8to16(expected, array) { toKString() }
|
||||
checkUtf8to16(expected, array.copyOf(array.size + 1)) { toKString() }
|
||||
}
|
||||
fun checkUtf8to16Replacing(expected: String, array: IntArray) {
|
||||
checkUtf8to16(expected, array) { decodeToString() }
|
||||
checkZeroTerminatedUtf8to16Replacing(expected, array)
|
||||
}
|
||||
fun checkZeroTerminatedUtf8to16Throwing(expected: String, array: IntArray) {
|
||||
checkUtf8to16(expected, array) { toKString(throwOnInvalidSequence = true) }
|
||||
checkUtf8to16(expected, array.copyOf(array.size + 1)) { toKString(throwOnInvalidSequence = true) }
|
||||
}
|
||||
fun checkUtf8to16Throwing(expected: String, array: IntArray) {
|
||||
checkUtf8to16(expected, array) { decodeToString(throwOnInvalidSequence = true) }
|
||||
checkZeroTerminatedUtf8to16Throwing(expected, array)
|
||||
}
|
||||
fun checkValidUtf8to16(expected: String, array: IntArray) {
|
||||
checkUtf8to16Replacing(expected, array)
|
||||
checkUtf8to16Throwing(expected, array)
|
||||
}
|
||||
fun checkValidZeroTerminatedUtf8to16(expected: String, array: IntArray) {
|
||||
checkZeroTerminatedUtf8to16Replacing(expected, array)
|
||||
checkZeroTerminatedUtf8to16Throwing(expected, array)
|
||||
}
|
||||
|
||||
fun checkZeroTerminatedUtf8to16Replacing(expected: String, array: IntArray, start: Int, size: Int) {
|
||||
checkUtf8to16(expected, array) { toKString(start, start + size) }
|
||||
checkUtf8to16(expected, array.copyOf(array.size + 1)) { toKString(start, start + size) }
|
||||
}
|
||||
fun checkUtf8to16Replacing(expected: String, array: IntArray, start: Int, size: Int) {
|
||||
checkUtf8to16(expected, array) { decodeToString(start, start + size) }
|
||||
checkZeroTerminatedUtf8to16Replacing(expected, array, start, size)
|
||||
}
|
||||
fun checkZeroTerminatedUtf8to16Throwing(expected: String, array: IntArray, start: Int, size: Int) {
|
||||
checkUtf8to16(expected, array) { toKString(start, start + size, true) }
|
||||
checkUtf8to16(expected, array.copyOf(array.size + 1)) { toKString(start, start + size, true) }
|
||||
}
|
||||
fun checkUtf8to16Throwing(expected: String, array: IntArray, start: Int, size: Int) {
|
||||
checkUtf8to16(expected, array) { decodeToString(start, start + size, true) }
|
||||
checkZeroTerminatedUtf8to16Throwing(expected, array, start, size)
|
||||
}
|
||||
fun checkValidUtf8to16(expected: String, array: IntArray, start: Int, size: Int) {
|
||||
checkUtf8to16Replacing(expected, array, start, size)
|
||||
checkUtf8to16Throwing(expected, array, start, size)
|
||||
}
|
||||
fun checkValidZeroTerminatedUtf8to16(expected: String, array: IntArray, start: Int, size: Int) {
|
||||
checkZeroTerminatedUtf8to16Replacing(expected, array, start, size)
|
||||
checkZeroTerminatedUtf8to16Throwing(expected, array, start, size)
|
||||
}
|
||||
|
||||
|
||||
// Utils for checking malformed UTF-16 to UTF-8 conversion.
|
||||
fun <T: Any> checkThrows(e: KClass<T>, string: String, action: () -> Unit) {
|
||||
var exception: Throwable? = null
|
||||
try {
|
||||
action()
|
||||
} catch (e: Throwable) {
|
||||
exception = e
|
||||
}
|
||||
assertNotNull(exception, "No exception was thrown for string: $string")
|
||||
assertTrue(e.isInstance(exception),"""
|
||||
Wrong exception was thrown for string: $string
|
||||
Expected: ${e.qualifiedName}
|
||||
Actual: ${exception::class.qualifiedName}: $exception}
|
||||
""".trimIndent())
|
||||
}
|
||||
|
||||
fun checkUtf16to8Throws(string: String) {
|
||||
checkThrows(CharacterCodingException::class, string) { string.encodeToByteArray(throwOnInvalidSequence = true) }
|
||||
}
|
||||
fun checkUtf16to8Throws(string: String, start: Int, size: Int) {
|
||||
checkThrows(CharacterCodingException::class, string) { string.encodeToByteArray(start, start + size, true) }
|
||||
}
|
||||
|
||||
|
||||
// Utils for checking malformed UTF-8 to UTF-16 conversion.
|
||||
fun <T: Any> checkUtf8to16Throws(e: KClass<T>, string: String, array: IntArray, conversion: ByteArray.() -> String)
|
||||
= checkThrows(e, string) {
|
||||
array.forEach {
|
||||
assertTrue(it in Byte.MIN_VALUE..Byte.MAX_VALUE, "Expected array contains illegal values")
|
||||
}
|
||||
val arrayBytes = ByteArray(array.size) { i -> array[i].toByte() }
|
||||
arrayBytes.conversion()
|
||||
}
|
||||
|
||||
fun checkZeroTerminatedUtf8to16Throws(string: String, array: IntArray) {
|
||||
checkUtf8to16Throws(CharacterCodingException::class, string, array) { toKString(throwOnInvalidSequence = true) }
|
||||
checkUtf8to16Throws(CharacterCodingException::class, string, array.copyOf(array.size + 1)) { toKString(throwOnInvalidSequence = true) }
|
||||
}
|
||||
fun checkUtf8to16Throws(string: String, array: IntArray) {
|
||||
checkUtf8to16Throws(CharacterCodingException::class, string, array) { decodeToString(throwOnInvalidSequence = true) }
|
||||
checkZeroTerminatedUtf8to16Throws(string, array)
|
||||
}
|
||||
fun checkZeroTerminatedUtf8to16Throws(string: String, array: IntArray, start: Int, size: Int) {
|
||||
checkUtf8to16Throws(CharacterCodingException::class, string, array) { toKString(start, start + size, true) }
|
||||
checkUtf8to16Throws(CharacterCodingException::class, string, array.copyOf(array.size + 1)) { toKString(start, start + size, true) }
|
||||
}
|
||||
fun checkUtf8to16Throws(string: String, array: IntArray, start: Int, size: Int) {
|
||||
checkUtf8to16Throws(CharacterCodingException::class, string, array) { decodeToString(start, start + size, true) }
|
||||
checkZeroTerminatedUtf8to16Throws(string, array, start, size)
|
||||
}
|
||||
|
||||
|
||||
// Utils for checking String to floating-point number conversion.
|
||||
fun checkDoubleConversionThrows(string: String) = checkThrows(NumberFormatException::class, string) {
|
||||
string.toDouble()
|
||||
}
|
||||
|
||||
fun checkFloatConversionThrows(string: String) = checkThrows(NumberFormatException::class, string) {
|
||||
string.toFloat()
|
||||
}
|
||||
|
||||
|
||||
// Utils for checking invalid-bounds-exception thrown by UTF-16 to UTF-8 conversion.
|
||||
fun <T: Any> checkOutOfBoundsUtf16to8Replacing(e: KClass<T>, string: String, start: Int, size: Int) {
|
||||
checkThrows(e, string) { string.encodeToByteArray(start, start + size) }
|
||||
}
|
||||
fun <T: Any> checkOutOfBoundsUtf16to8Throwing(e: KClass<T>, string: String, start: Int, size: Int) {
|
||||
checkThrows(e, string) { string.encodeToByteArray(start, start + size, true) }
|
||||
}
|
||||
fun <T: Any> checkOutOfBoundsUtf16to8(e: KClass<T>, string: String, start: Int, size: Int) {
|
||||
checkOutOfBoundsUtf16to8Replacing(e, string, start, size)
|
||||
checkOutOfBoundsUtf16to8Throwing(e, string, start, size)
|
||||
}
|
||||
|
||||
|
||||
// Utils for checking invalid-bounds-exception thrown by UTF-8 to UTF-16 conversion.
|
||||
fun <T: Any> checkOutOfBoundsZeroTerminatedUtf8to16Replacing(e: KClass<T>, string: String, byteArray: ByteArray, start: Int, size: Int) {
|
||||
checkThrows(e, string) { byteArray.toKString(start, start + size) }
|
||||
}
|
||||
fun <T: Any> checkOutOfBoundsUtf8to16Replacing(e: KClass<T>, string: String, byteArray: ByteArray, start: Int, size: Int) {
|
||||
checkThrows(e, string) { byteArray.decodeToString(start, start + size) }
|
||||
checkOutOfBoundsZeroTerminatedUtf8to16Replacing(e, string, byteArray, start, size)
|
||||
}
|
||||
fun <T: Any> checkOutOfBoundsZeroTerminatedUtf8to16Throwing(e: KClass<T>, string: String, byteArray: ByteArray, start: Int, size: Int) {
|
||||
checkThrows(e, string) { byteArray.toKString(start, start + size, true) }
|
||||
}
|
||||
fun <T: Any> checkOutOfBoundsUtf8to16Throwing(e: KClass<T>, string: String, byteArray: ByteArray, start: Int, size: Int) {
|
||||
checkThrows(e, string) { byteArray.decodeToString(start, start + size, true) }
|
||||
checkOutOfBoundsZeroTerminatedUtf8to16Throwing(e, string, byteArray, start, size)
|
||||
}
|
||||
fun <T: Any> checkOutOfBoundsUtf8to16(e: KClass<T>, string: String, byteArray: ByteArray, start: Int, size: Int) {
|
||||
checkOutOfBoundsUtf8to16Replacing(e, string, byteArray, start, size)
|
||||
checkOutOfBoundsUtf8to16Throwing(e, string, byteArray, start, size)
|
||||
}
|
||||
fun <T: Any> checkOutOfBoundsZeroTerminatedUtf8to16(e: KClass<T>, string: String, byteArray: ByteArray, start: Int, size: Int) {
|
||||
checkOutOfBoundsZeroTerminatedUtf8to16Replacing(e, string, byteArray, start, size)
|
||||
checkOutOfBoundsZeroTerminatedUtf8to16Throwing(e, string, byteArray, start, size)
|
||||
}
|
||||
|
||||
|
||||
// Util for performing action on result of UTF-8 to UTF-16 conversion.
|
||||
fun convertUtf8to16(byteArray: ByteArray, action: (String) -> Unit) {
|
||||
byteArray.decodeToString().let { action(it) }
|
||||
byteArray.toKString().let { action(it) }
|
||||
}
|
||||
|
||||
// ------------------------- Test UTF-16 to UTF-8 conversion -------------------------
|
||||
fun test16to8() {
|
||||
// Valid strings.
|
||||
checkValidUtf16to8("Hello", intArrayOf('H'.toInt(), 'e'.toInt(), 'l'.toInt(), 'l'.toInt(), 'o'.toInt()))
|
||||
checkValidUtf16to8("Привет", intArrayOf(-48, -97, -47, -128, -48, -72, -48, -78, -48, -75, -47, -126))
|
||||
checkValidUtf16to8("\uD800\uDC00", intArrayOf(-16, -112, -128, -128))
|
||||
checkValidUtf16to8("", intArrayOf())
|
||||
|
||||
// Test manual conversion with replacement.
|
||||
// Illegal surrogate pair -> replace with default
|
||||
checkUtf16to8Replacing("\uDC00\uD800", intArrayOf(-17, -65, -67, -17, -65, -67))
|
||||
// Different kinds of input
|
||||
checkUtf16to8Replacing("\uD800\uDC001\uDC00\uD800",
|
||||
intArrayOf(-16, -112, -128, -128, '1'.toInt(), -17, -65, -67, -17, -65, -67))
|
||||
// Lone surrogate - replace with default
|
||||
checkUtf16to8Replacing("\uD80012", intArrayOf(-17, -65, -67, '1'.toInt(), '2'.toInt()))
|
||||
checkUtf16to8Replacing("\uDC0012", intArrayOf(-17, -65, -67, '1'.toInt(), '2'.toInt()))
|
||||
checkUtf16to8Replacing("12\uD800", intArrayOf('1'.toInt(), '2'.toInt(), -17, -65, -67))
|
||||
|
||||
// Test manual conversion with an exception if an input is invalid.
|
||||
// Illegal surrogate pair -> throw
|
||||
checkUtf16to8Throws("\uDC00\uD800")
|
||||
// Different kinds of input (including illegal one) -> throw
|
||||
checkUtf16to8Throws("\uD800\uDC001\uDC00\uD800")
|
||||
// Lone surrogate - throw
|
||||
checkUtf16to8Throws("\uD80012")
|
||||
checkUtf16to8Throws("\uDC0012")
|
||||
checkUtf16to8Throws("12\uD800")
|
||||
|
||||
// Test double parsing.
|
||||
assertEquals(4.2, "4.2".toDouble())
|
||||
// Illegal surrogate pair -> throw
|
||||
checkDoubleConversionThrows("\uDC00\uD800")
|
||||
// Different kinds of input (including illegal one) -> throw
|
||||
checkDoubleConversionThrows("\uD800\uDC001\uDC00\uD800")
|
||||
// Lone surrogate - throw
|
||||
checkDoubleConversionThrows("\uD80012")
|
||||
checkDoubleConversionThrows("\uDC0012")
|
||||
checkDoubleConversionThrows("12\uD800")
|
||||
|
||||
// Test float parsing.
|
||||
assertEquals(4.2F, "4.2".toFloat())
|
||||
// Illegal surrogate pair -> throw
|
||||
checkFloatConversionThrows("\uDC00\uD800")
|
||||
// Different kinds of input (including illegal one) -> throw
|
||||
checkFloatConversionThrows("\uD800\uDC001\uDC00\uD800")
|
||||
// Lone surrogate - throw
|
||||
checkFloatConversionThrows("\uD80012")
|
||||
checkFloatConversionThrows("\uDC0012")
|
||||
checkFloatConversionThrows("12\uD800")
|
||||
}
|
||||
|
||||
fun test16to8CustomBorders() {
|
||||
// Valid strings.
|
||||
checkValidUtf16to8("Hello!", intArrayOf('H'.toInt(), 'e'.toInt()), 0, 2)
|
||||
checkValidUtf16to8("Hello!", intArrayOf('e'.toInt(), 'l'.toInt()), 1, 2)
|
||||
checkValidUtf16to8("Hello!", intArrayOf('o'.toInt(), '!'.toInt()), 4, 2)
|
||||
checkValidUtf16to8("Hello!", intArrayOf(), 0, 0)
|
||||
checkValidUtf16to8("Hello!", intArrayOf(), 6, 0)
|
||||
|
||||
checkValidUtf16to8("\uD800\uDC00\uD800\uDC00\uD800\uDC00\uD800\uDC00",
|
||||
intArrayOf(-16, -112, -128, -128, -16, -112, -128, -128), 0, 4)
|
||||
checkValidUtf16to8("\uD800\uDC00\uD800\uDC00\uD800\uDC00\uD800\uDC00",
|
||||
intArrayOf(-16, -112, -128, -128, -16, -112, -128, -128), 2, 4)
|
||||
checkValidUtf16to8("\uD800\uDC00\uD800\uDC00\uD800\uDC00\uD800\uDC00",
|
||||
intArrayOf(-16, -112, -128, -128, -16, -112, -128, -128), 4, 4)
|
||||
|
||||
// Index out of bound
|
||||
checkOutOfBoundsUtf16to8(IndexOutOfBoundsException::class, "Hello", -1, 4)
|
||||
checkOutOfBoundsUtf16to8(IndexOutOfBoundsException::class, "Hello", 5, 10)
|
||||
checkOutOfBoundsUtf16to8(IndexOutOfBoundsException::class, "Hello", 2, 10)
|
||||
checkOutOfBoundsUtf16to8(IllegalArgumentException::class, "Hello", 3, -2)
|
||||
|
||||
// Test manual conversion with replacement and custom borders.
|
||||
// Illegal surrogate pair -> replace with default
|
||||
checkUtf16to8Replacing("\uDC00\uD80012",
|
||||
intArrayOf(-17, -65, -67, -17, -65, -67, '1'.toInt()), 0, 3)
|
||||
checkUtf16to8Replacing("1\uDC00\uD8002",
|
||||
intArrayOf(-17, -65, -67, -17, -65, -67, '2'.toInt()), 1, 3)
|
||||
checkUtf16to8Replacing("12\uDC00\uD800",
|
||||
intArrayOf('2'.toInt(), -17, -65, -67, -17, -65, -67), 1, 3)
|
||||
|
||||
// Lone surrogate - replace with default
|
||||
checkUtf16to8Replacing("1\uD800\uDC002", intArrayOf('1'.toInt(), -17, -65, -67), 0, 2)
|
||||
checkUtf16to8Replacing("1\uD800\uDC002", intArrayOf(-17, -65, -67, '2'.toInt()), 2, 2)
|
||||
|
||||
// Test manual conversion with an exception if an input is invalid and custom borders.
|
||||
// Illegal surrogate pair -> throw
|
||||
checkUtf16to8Throws("\uDC00\uD80012", 0, 3)
|
||||
checkUtf16to8Throws("1\uDC00\uD8002", 1, 3)
|
||||
checkUtf16to8Throws("12\uDC00\uD800", 1, 3)
|
||||
|
||||
// Lone surrogate -> throw
|
||||
checkUtf16to8Throws("1\uD800\uDC002", 0, 2)
|
||||
checkUtf16to8Throws("1\uD800\uDC002", 2, 2)
|
||||
}
|
||||
|
||||
fun testPrint() {
|
||||
// Valid strings.
|
||||
println("Hello")
|
||||
println("Привет")
|
||||
println("\uD800\uDC00")
|
||||
println("")
|
||||
|
||||
// Illegal surrogate pair -> default output
|
||||
println("\uDC00\uD800")
|
||||
// Lone surrogate -> default output
|
||||
println("\uD80012")
|
||||
println("\uDC0012")
|
||||
println("12\uD800")
|
||||
|
||||
// https://github.com/JetBrains/kotlin-native/issues/1091
|
||||
val array = byteArrayOf(0xF0.toByte(), 0x9F.toByte(), 0x98.toByte(), 0xA5.toByte())
|
||||
convertUtf8to16(array) { badString ->
|
||||
assertEquals(2, badString.length)
|
||||
println(badString)
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------- Test UTF-8 to UTF-16 conversion -------------------------
|
||||
fun test8to16() {
|
||||
// Valid strings.
|
||||
checkValidUtf8to16("Hello", intArrayOf('H'.toInt(), 'e'.toInt(), 'l'.toInt(), 'l'.toInt(), 'o'.toInt()))
|
||||
checkValidUtf8to16("Привет", intArrayOf(-48, -97, -47, -128, -48, -72, -48, -78, -48, -75, -47, -126))
|
||||
checkValidUtf8to16("\uD800\uDC00", intArrayOf(-16, -112, -128, -128))
|
||||
checkValidUtf8to16("", intArrayOf())
|
||||
|
||||
// Test manual conversion with replacement.
|
||||
// Incorrect UTF-8 lead character.
|
||||
checkUtf8to16Replacing("\uFFFD1", intArrayOf(-1, '1'.toInt()))
|
||||
|
||||
// Incomplete codepoint.
|
||||
checkUtf8to16Replacing("\uFFFD1", intArrayOf(-16, -97, -104, '1'.toInt()))
|
||||
checkUtf8to16Replacing("\uFFFD1\uFFFD", intArrayOf(-16, -97, -104, '1'.toInt(), -16, -97, -104))
|
||||
|
||||
// Test manual conversion with exception throwing
|
||||
// Incorrect UTF-8 lead character -> throw.
|
||||
checkUtf8to16Throws("\uFFFD1", intArrayOf(-1, '1'.toInt()))
|
||||
|
||||
// Incomplete codepoint -> throw.
|
||||
checkUtf8to16Throws("\uFFFD1", intArrayOf(-16, -97, -104, '1'.toInt()))
|
||||
checkUtf8to16Throws("\uFFFD1\uFFFD", intArrayOf(-16, -97, -104, '1'.toInt(), -16, -97, -104))
|
||||
}
|
||||
|
||||
fun test8to16CustomBorders() {
|
||||
// Valid strings.
|
||||
checkValidUtf8to16("He",
|
||||
intArrayOf('H'.toInt(), 'e'.toInt(), 'l'.toInt(), 'l'.toInt(), 'o'.toInt()),0, 2)
|
||||
checkValidUtf8to16("ll",
|
||||
intArrayOf('H'.toInt(), 'e'.toInt(), 'l'.toInt(), 'l'.toInt(), 'o'.toInt()), 2, 2)
|
||||
checkValidUtf8to16("lo",
|
||||
intArrayOf('H'.toInt(), 'e'.toInt(), 'l'.toInt(), 'l'.toInt(), 'o'.toInt()), 3, 2)
|
||||
checkValidUtf8to16("",
|
||||
intArrayOf('H'.toInt(), 'e'.toInt(), 'l'.toInt(), 'l'.toInt(), 'o'.toInt()), 0, 0)
|
||||
|
||||
checkValidUtf8to16("\uD800\uDC00\uD800\uDC00",
|
||||
intArrayOf(-16, -112, -128, -128, -16, -112, -128, -128, -16, -112, -128, -128, -16, -112, -128, -128),
|
||||
0, 8)
|
||||
checkValidUtf8to16("\uD800\uDC00\uD800\uDC00",
|
||||
intArrayOf(-16, -112, -128, -128, -16, -112, -128, -128, -16, -112, -128, -128, -16, -112, -128, -128),
|
||||
4, 8)
|
||||
checkValidUtf8to16("\uD800\uDC00\uD800\uDC00",
|
||||
intArrayOf(-16, -112, -128, -128, -16, -112, -128, -128, -16, -112, -128, -128, -16, -112, -128, -128),
|
||||
8, 8)
|
||||
|
||||
// Index out of bound
|
||||
val helloArray = byteArrayOf('H'.toByte(), 'e'.toByte(), 'l'.toByte(), 'l'.toByte(), 'o'.toByte())
|
||||
checkOutOfBoundsUtf8to16(IndexOutOfBoundsException::class, "Hello", helloArray, -1, 4)
|
||||
checkOutOfBoundsUtf8to16(IndexOutOfBoundsException::class, "Hello", helloArray, 5, 10)
|
||||
checkOutOfBoundsUtf8to16(IndexOutOfBoundsException::class, "Hello", helloArray, 2, 10)
|
||||
checkOutOfBoundsUtf8to16(IndexOutOfBoundsException::class, "Hello", helloArray, 10, 0)
|
||||
checkOutOfBoundsUtf8to16(IllegalArgumentException::class, "Hello", helloArray, 3, -2)
|
||||
|
||||
// Test manual conversion with replacement and custom borders.
|
||||
// Incorrect UTF-8 lead character.
|
||||
checkUtf8to16Replacing("\uFFFD1", intArrayOf(-1, '1'.toInt(), '2'.toInt()), 0, 2)
|
||||
checkUtf8to16Replacing("\uFFFD2", intArrayOf('1'.toInt(), -1, '2'.toInt(), '3'.toInt()), 1, 2)
|
||||
checkUtf8to16Replacing("2\uFFFD", intArrayOf('1'.toInt(), '2'.toInt(), -1), 1, 2)
|
||||
|
||||
// Incomplete codepoint.
|
||||
checkUtf8to16Replacing("\uFFFD1", intArrayOf(-16, -97, -104, '1'.toInt(), '2'.toInt()), 0, 4)
|
||||
checkUtf8to16Replacing("\uFFFD2", intArrayOf('1'.toInt(), -16, -97, -104, '2'.toInt(), '3'.toInt()), 1, 4)
|
||||
checkUtf8to16Replacing("2\uFFFD", intArrayOf('1'.toInt(), '2'.toInt(), -16, -97, -104), 1, 4)
|
||||
|
||||
// Test manual conversion with an exception if an input is invalid and custom borders.
|
||||
// Incorrect UTF-8 lead character.
|
||||
checkUtf8to16Throws("\uFFFD1", intArrayOf(-1, '1'.toInt(), '2'.toInt()), 0, 2)
|
||||
checkUtf8to16Throws("\uFFFD2", intArrayOf('1'.toInt(), -1, '2'.toInt(), '3'.toInt()), 1, 2)
|
||||
checkUtf8to16Throws("2\uFFFD", intArrayOf('1'.toInt(), '2'.toInt(), -1), 1, 2)
|
||||
|
||||
// Incomplete codepoint.
|
||||
checkUtf8to16Throws("\uFFFD1", intArrayOf(-16, -97, -104, '1'.toInt(), '2'.toInt()), 0, 4)
|
||||
checkUtf8to16Throws("\uFFFD2", intArrayOf('1'.toInt(), -16, -97, -104, '2'.toInt(), '3'.toInt()), 1, 4)
|
||||
checkUtf8to16Throws("2\uFFFD", intArrayOf('1'.toInt(), '2'.toInt(), -16, -97, -104), 1, 4)
|
||||
}
|
||||
|
||||
// ----------------- Test zero-terminated UTF-8 to UTF-16 conversion -----------------
|
||||
fun testZeroTerminated8To16() {
|
||||
// Valid strings.
|
||||
checkValidZeroTerminatedUtf8to16("Hell", intArrayOf('H'.toInt(), 'e'.toInt(), 'l'.toInt(), 'l'.toInt(), 0, 'o'.toInt()))
|
||||
checkValidZeroTerminatedUtf8to16("При", intArrayOf(-48, -97, -47, -128, -48, -72, 0, -48, -78, 0, -48, -75, -47, -126))
|
||||
checkValidZeroTerminatedUtf8to16("\uD800\uDC00", intArrayOf(-16, -112, -128, -128, 0, -16, -112, -128, -128))
|
||||
checkValidZeroTerminatedUtf8to16("", intArrayOf(0, 'H'.toInt()))
|
||||
|
||||
// Test manual conversion with replacement.
|
||||
// Incorrect UTF-8 lead character.
|
||||
checkZeroTerminatedUtf8to16Replacing("\uFFFD", intArrayOf(-1, 0, '1'.toInt()))
|
||||
|
||||
// Incomplete codepoint.
|
||||
checkZeroTerminatedUtf8to16Replacing("\uFFFD", intArrayOf(-16, -97, -104, 0, '1'.toInt()))
|
||||
checkZeroTerminatedUtf8to16Replacing("\uFFFD1", intArrayOf(-16, -97, -104, '1'.toInt(), 0, -16, -97, -104))
|
||||
|
||||
// Test manual conversion with exception throwing
|
||||
// Incorrect UTF-8 lead character -> throw.
|
||||
checkZeroTerminatedUtf8to16Throws("\uFFFD", intArrayOf(-1, 0, '1'.toInt()))
|
||||
|
||||
// Incomplete codepoint -> throw.
|
||||
checkZeroTerminatedUtf8to16Throws("\uFFFD", intArrayOf(-16, -97, -104, 0, '1'.toInt()))
|
||||
checkZeroTerminatedUtf8to16Throws("\uFFFD1", intArrayOf(-16, -97, -104, '1'.toInt(), 0, -16, -97, -104))
|
||||
}
|
||||
|
||||
fun testZeroTerminated8To16CustomBorders() {
|
||||
val array = intArrayOf('a'.toInt(), 'a'.toInt(), 'a'.toInt(), 0, 'b'.toInt(), 'b'.toInt(), 'b'.toInt(), 0)
|
||||
checkValidZeroTerminatedUtf8to16("aaa", array, 0, 5)
|
||||
checkValidZeroTerminatedUtf8to16("a", array, 2, 2)
|
||||
checkValidZeroTerminatedUtf8to16("", array, 3, 2)
|
||||
checkValidZeroTerminatedUtf8to16("bb", array, 4, 2)
|
||||
checkValidZeroTerminatedUtf8to16("bbb", array, 4, 3)
|
||||
checkValidZeroTerminatedUtf8to16("bbb", array, 4, 4)
|
||||
checkValidZeroTerminatedUtf8to16("bb", array, 5, 3)
|
||||
checkValidZeroTerminatedUtf8to16("b", array, 6, 2)
|
||||
checkValidZeroTerminatedUtf8to16("", array, 7, 1)
|
||||
checkValidZeroTerminatedUtf8to16("", array, 8, 0)
|
||||
|
||||
val byteArray = ByteArray(array.size) { array[it].toByte() }
|
||||
checkOutOfBoundsZeroTerminatedUtf8to16(IndexOutOfBoundsException::class, "aaa0bbb0", byteArray, -1, 4)
|
||||
checkOutOfBoundsZeroTerminatedUtf8to16(IndexOutOfBoundsException::class, "aaa0bbb0", byteArray, 8, 10)
|
||||
checkOutOfBoundsZeroTerminatedUtf8to16(IndexOutOfBoundsException::class, "aaa0bbb0", byteArray, 2, 10)
|
||||
checkOutOfBoundsZeroTerminatedUtf8to16(IndexOutOfBoundsException::class, "aaa0bbb0", byteArray, 10, 0)
|
||||
checkOutOfBoundsZeroTerminatedUtf8to16(IllegalArgumentException::class, "aaa0bbb0", byteArray, 3, -2)
|
||||
}
|
||||
|
||||
// ------------------------------------ Run tests ------------------------------------
|
||||
@Test fun runTest() {
|
||||
test16to8()
|
||||
test16to8CustomBorders()
|
||||
test8to16()
|
||||
test8to16CustomBorders()
|
||||
testZeroTerminated8To16()
|
||||
testZeroTerminated8To16CustomBorders()
|
||||
testPrint()
|
||||
}
|
||||
Reference in New Issue
Block a user