Commonize StringBuilder
This commit is contained in:
@@ -5,7 +5,9 @@
|
||||
|
||||
package test.text
|
||||
|
||||
import kotlin.random.Random
|
||||
import kotlin.test.*
|
||||
import kotlin.text.*
|
||||
|
||||
class StringBuilderTest {
|
||||
|
||||
@@ -26,7 +28,7 @@ class StringBuilderTest {
|
||||
@Test fun append() {
|
||||
// this test is needed for JS implementation
|
||||
assertEquals("em", buildString {
|
||||
append("element", 2, 4)
|
||||
appendRange("element", 2, 4)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -87,4 +89,398 @@ class StringBuilderTest {
|
||||
assertFailsWith<IndexOutOfBoundsException> { assertEquals('t', sb[-1]) }
|
||||
assertFailsWith<IndexOutOfBoundsException> { assertEquals('t', sb[4]) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun reverse() {
|
||||
StringBuilder("my reverse test").let { sb ->
|
||||
sb.reverse()
|
||||
assertEquals("tset esrever ym", sb.toString())
|
||||
|
||||
sb.append('\uD800')
|
||||
sb.append('\uDC00')
|
||||
|
||||
sb.insert(10, "\uDC01\uD801")
|
||||
sb.insert(0, "\uD802\uDC02")
|
||||
|
||||
sb.reverse()
|
||||
assertEquals("\uD800\uDC00my re\uD801\uDC01verse test\uD802\uDC02", sb.toString())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun appendChar() {
|
||||
val times = 100
|
||||
val expected = "a".repeat(times)
|
||||
|
||||
val sb = StringBuilder()
|
||||
repeat(times) { sb.append('a') }
|
||||
assertEquals(expected, sb.toString())
|
||||
|
||||
sb.append('\uD800')
|
||||
sb.append('\uDC00')
|
||||
assertEquals(expected + "\uD800\uDC00", sb.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun appendInt() {
|
||||
val times = 100
|
||||
val expected = (0 until times).fold("") { res, idx -> res + idx }
|
||||
|
||||
val sb = StringBuilder()
|
||||
repeat(times) { sb.append(it) }
|
||||
assertEquals(expected, sb.toString())
|
||||
|
||||
val cornerCase = listOf(0, -1, Int.MIN_VALUE, Int.MAX_VALUE)
|
||||
val expectedCornerCase = cornerCase.fold("") { res, e -> res + e }
|
||||
for (int in cornerCase) sb.append(int)
|
||||
assertEquals(expected + expectedCornerCase, sb.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun appendBoolean() {
|
||||
StringBuilder().append(true).append(false).append(true).append(true).let { sb ->
|
||||
assertEquals("truefalsetruetrue", sb.toString())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun appendString() {
|
||||
val times = 100
|
||||
val expected = "foo".repeat(times)
|
||||
|
||||
StringBuilder().let { sb ->
|
||||
repeat(times) { sb.append("foo") }
|
||||
assertEquals(expected, sb.toString())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun appendAny() {
|
||||
val myAny = object {
|
||||
override fun toString(): String = "It's My Any!"
|
||||
}
|
||||
|
||||
StringBuilder().let { sb ->
|
||||
sb.append(null as Any?)
|
||||
sb.append(myAny)
|
||||
assertEquals("nullIt's My Any!", sb.toString())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun appendCharArray() {
|
||||
StringBuilder().let { sb ->
|
||||
val times = 100
|
||||
val expected = "foo".repeat(times)
|
||||
|
||||
repeat(times) { sb.append(charArrayOf('f', 'o', 'o')) }
|
||||
assertEquals(expected, sb.toString())
|
||||
}
|
||||
|
||||
StringBuilder().let { sb ->
|
||||
val charArray = charArrayOf(
|
||||
'm', 'y', ' ', 'a', 'p', 'p', 'e', 'n', 'd', ' ', 'c', 'h', 'a', 'r', ' ', 'a', 'r', 'r', 'a', 'y', ' ', 't', 'e', 's', 't'
|
||||
)
|
||||
|
||||
String(charArray, 0, 1)
|
||||
|
||||
sb.appendRange(charArray, 0, charArray.size /*25*/)
|
||||
sb.appendRange(charArray, 0, 9)
|
||||
sb.appendRange(charArray, 15, 25)
|
||||
sb.appendRange(charArray, 9, 15)
|
||||
|
||||
assertEquals("my append char array testmy appendarray test char ", sb.toString())
|
||||
|
||||
assertFails { sb.appendRange(charArrayOf('_', '*', '#'), -1, 0) }
|
||||
assertFails { sb.appendRange(charArrayOf('_', '*', '#'), 0, 4) }
|
||||
assertFails { sb.appendRange(charArrayOf('_', '*', '#'), 2, 1) }
|
||||
assertFails { sb.appendRange(charArrayOf('_', '*', '#'), 2, -1) }
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun deleteChar() {
|
||||
StringBuilder("my delete test").let { sb ->
|
||||
sb.deleteAt(0)
|
||||
assertEquals("y delete test", sb.toString())
|
||||
sb.deleteAt(5)
|
||||
assertEquals("y delte test", sb.toString())
|
||||
sb.deleteAt(11)
|
||||
assertEquals("y delte tes", sb.toString())
|
||||
|
||||
assertFailsWith<IndexOutOfBoundsException> { sb.deleteAt(11) }
|
||||
assertFailsWith<IndexOutOfBoundsException> { sb.deleteAt(-1) }
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun deleteSubstring() {
|
||||
StringBuilder("my delete substring test").let { sb ->
|
||||
sb.deleteRange(0, 2)
|
||||
assertEquals(" delete substring test", sb.toString())
|
||||
sb.deleteRange(7, 17)
|
||||
assertEquals(" delete test", sb.toString())
|
||||
sb.deleteRange(8, 12)
|
||||
assertEquals(" delete ", sb.toString())
|
||||
sb.deleteRange(8, 12)
|
||||
assertEquals(" delete ", sb.toString())
|
||||
|
||||
assertFails { sb.deleteRange(-1, 1) }
|
||||
assertFails { sb.deleteRange(0, -1) }
|
||||
assertFails { sb.deleteRange(2, 1) }
|
||||
assertFails { sb.deleteRange(sb.length + 1, sb.length + 2) }
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun capacityTest() {
|
||||
assertEquals(100, StringBuilder(100).capacity())
|
||||
|
||||
StringBuilder("string builder from string capacity test").let { sb ->
|
||||
assertTrue(sb.capacity() >= sb.length)
|
||||
}
|
||||
|
||||
StringBuilder().let { sb ->
|
||||
assertTrue(sb.capacity() >= sb.length)
|
||||
repeat(Random.nextInt(17, 30)) { sb.append('c') }
|
||||
assertTrue(sb.capacity() >= sb.length)
|
||||
repeat(Random.nextInt(35, 62)) { sb.insert(0, "s") }
|
||||
sb.ensureCapacity(1)
|
||||
assertTrue(sb.capacity() >= sb.length)
|
||||
sb.ensureCapacity(sb.length * 10)
|
||||
assertTrue(sb.capacity() >= sb.length * 10)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun indexOf() {
|
||||
StringBuilder("my indexOf test").let { sb ->
|
||||
assertEquals(0, sb.indexOf(""))
|
||||
assertEquals(5, sb.indexOf("", 5))
|
||||
assertEquals(sb.length, sb.indexOf("", sb.length))
|
||||
assertEquals(sb.length, sb.indexOf("", 100)) // Java implementation, should be -1
|
||||
|
||||
assertEquals(6, sb.indexOf("e"))
|
||||
assertEquals(12, sb.indexOf("e", 7))
|
||||
assertEquals(-1, sb.indexOf("e", 13))
|
||||
assertEquals(-1, sb.indexOf("e", 100))
|
||||
|
||||
assertEquals(11, sb.indexOf("test"))
|
||||
assertEquals(11, sb.indexOf("test", 11))
|
||||
assertEquals(-1, sb.indexOf("test", 12))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun lastIndexOf() {
|
||||
StringBuilder("my lastIndexOf test").let { sb ->
|
||||
assertEquals(sb.length, sb.lastIndexOf(""))
|
||||
assertEquals(sb.length, sb.lastIndexOf("", 100))
|
||||
assertEquals(5, sb.lastIndexOf("", 5))
|
||||
assertEquals(0, sb.lastIndexOf("", 0))
|
||||
assertEquals(-1, sb.lastIndexOf("", -100))
|
||||
|
||||
assertEquals(16, sb.lastIndexOf("e"))
|
||||
assertEquals(10, sb.lastIndexOf("e", 15))
|
||||
assertEquals(-1, sb.lastIndexOf("e", 9))
|
||||
assertEquals(-1, sb.lastIndexOf("e", -100))
|
||||
|
||||
assertEquals(15, sb.lastIndexOf("test"))
|
||||
assertEquals(15, sb.lastIndexOf("test", 15))
|
||||
assertEquals(-1, sb.lastIndexOf("test", 14))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun insertBoolean() {
|
||||
StringBuilder().let { sb ->
|
||||
sb.insert(0, true)
|
||||
assertEquals("true", sb.toString())
|
||||
sb.insert(0, false)
|
||||
assertEquals("falsetrue", sb.toString())
|
||||
sb.insert(5, true)
|
||||
assertEquals("falsetruetrue", sb.toString())
|
||||
|
||||
assertFailsWith<IndexOutOfBoundsException> { sb.insert(-1, false) }
|
||||
assertFailsWith<IndexOutOfBoundsException> { sb.insert(sb.length + 1, false) }
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun insertChar() {
|
||||
StringBuilder("my insert char test").let { sb ->
|
||||
sb.insert(0, '_')
|
||||
assertEquals("_my insert char test", sb.toString())
|
||||
sb.insert(10, 'T')
|
||||
assertEquals("_my insertT char test", sb.toString())
|
||||
sb.insert(21, '_')
|
||||
assertEquals("_my insertT char test_", sb.toString())
|
||||
|
||||
assertFailsWith<IndexOutOfBoundsException> { sb.insert(-1, '_') }
|
||||
assertFailsWith<IndexOutOfBoundsException> { sb.insert(sb.length + 1, '_') }
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun insertCharArray() {
|
||||
StringBuilder("my insert CharArray test").let { sb ->
|
||||
sb.insert(0, charArrayOf('_'))
|
||||
assertEquals("_my insert CharArray test", sb.toString())
|
||||
sb.insert(10, charArrayOf('T'))
|
||||
assertEquals("_my insertT CharArray test", sb.toString())
|
||||
sb.insertRange(26, charArrayOf('_', '*', '#'), 0, 1)
|
||||
assertEquals("_my insertT CharArray test_", sb.toString())
|
||||
|
||||
assertFailsWith<IndexOutOfBoundsException> { sb.insert(-1, charArrayOf('_')) }
|
||||
assertFailsWith<IndexOutOfBoundsException> { sb.insert(sb.length + 1, charArrayOf('_')) }
|
||||
assertFails { sb.insertRange(0, charArrayOf('_', '*', '#'), -1, 0) }
|
||||
assertFails { sb.insertRange(0, charArrayOf('_', '*', '#'), 0, 4) }
|
||||
assertFails { sb.insertRange(0, charArrayOf('_', '*', '#'), 2, 1) }
|
||||
assertFails { sb.insertRange(0, charArrayOf('_', '*', '#'), 2, -1) }
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun insertCharSequence() {
|
||||
StringBuilder("my insert CharSequence test").let { sb ->
|
||||
sb.insert(0, "MMM" as CharSequence)
|
||||
assertEquals("MMMmy insert CharSequence test", sb.toString())
|
||||
sb.insert(12, StringBuilder("T"))
|
||||
assertEquals("MMMmy insertT CharSequence test", sb.toString())
|
||||
sb.insertRange(31, "_*#", 0, 1)
|
||||
assertEquals("MMMmy insertT CharSequence test_", sb.toString())
|
||||
sb.insertRange(0, null as CharSequence?, 0, 2)
|
||||
assertEquals("nuMMMmy insertT CharSequence test_", sb.toString())
|
||||
|
||||
assertFailsWith<IndexOutOfBoundsException> { sb.insert(-1, "_" as CharSequence) }
|
||||
assertFailsWith<IndexOutOfBoundsException> { sb.insert(sb.length + 1, StringBuilder("_")) }
|
||||
assertFails { sb.insertRange(0, null as CharSequence?, -1, 0) }
|
||||
assertFails { sb.insertRange(0, null as CharSequence?, 0, 5) }
|
||||
assertFails { sb.insertRange(0, null as CharSequence?, 2, 1) }
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun insertAny() {
|
||||
val myAny = object {
|
||||
override fun toString(): String = "It's My Any!"
|
||||
}
|
||||
|
||||
StringBuilder().let { sb ->
|
||||
sb.insert(0, null as Any?)
|
||||
sb.insert(2, myAny)
|
||||
assertEquals("nuIt's My Any!ll", sb.toString())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun insertString() {
|
||||
StringBuilder("my insert string test").let { sb ->
|
||||
sb.insert(0, "_")
|
||||
assertEquals("_my insert string test", sb.toString())
|
||||
sb.insert(10, "TtT")
|
||||
assertEquals("_my insertTtT string test", sb.toString())
|
||||
sb.insert(25, "_!_")
|
||||
assertEquals("_my insertTtT string test_!_", sb.toString())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun setLength() {
|
||||
StringBuilder("my setLength test").let { sb ->
|
||||
sb.setLength(17)
|
||||
assertEquals("my setLength test", sb.toString())
|
||||
sb.setLength(0)
|
||||
assertEquals("", sb.toString())
|
||||
sb.setLength(5)
|
||||
assertEquals("\u0000\u0000\u0000\u0000\u0000", sb.toString())
|
||||
|
||||
assertFails { sb.setLength(-1) }
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun substring() {
|
||||
StringBuilder("my substring test").let { sb ->
|
||||
assertEquals("my ", sb.substring(0, 3))
|
||||
assertEquals("substring", sb.substring(3, 12))
|
||||
assertEquals("ing test", sb.substring(9))
|
||||
assertEquals("ing test", sb.substring(9, 17))
|
||||
|
||||
assertFails { sb.substring(-1) }
|
||||
assertFails { sb.substring(0, -1) }
|
||||
assertFails { sb.substring(0, sb.length + 1) }
|
||||
assertFails { sb.substring(2, 1) }
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun trimToSize() {
|
||||
StringBuilder("my trimToSize test").let { sb ->
|
||||
assertEquals(18, sb.length)
|
||||
assertTrue(sb.capacity() >= sb.length)
|
||||
sb.append('1')
|
||||
sb.trimToSize()
|
||||
assertEquals(19, sb.length)
|
||||
assertTrue(sb.capacity() >= sb.length)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun set() {
|
||||
StringBuilder("my set test").let { sb ->
|
||||
sb[0] = 'M'
|
||||
assertEquals("My set test", sb.toString())
|
||||
sb[2] = 'm'
|
||||
assertEquals("Mymset test", sb.toString())
|
||||
sb[10] = 'T'
|
||||
assertEquals("Mymset tesT", sb.toString())
|
||||
|
||||
assertFailsWith<IndexOutOfBoundsException> { sb[-1] = '_' }
|
||||
assertFailsWith<IndexOutOfBoundsException> { sb[sb.length] = '_' }
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun setRange() {
|
||||
StringBuilder("my replace test").let { sb ->
|
||||
sb.setRange(0, 4, "R")
|
||||
assertEquals("Replace test", sb.toString())
|
||||
sb.setRange(7, 7, " empty string")
|
||||
assertEquals("Replace empty string test", sb.toString())
|
||||
sb.setRange(20, 25, "")
|
||||
assertEquals("Replace empty string", sb.toString())
|
||||
sb.setRange(20, 25, "")
|
||||
assertEquals("Replace empty string", sb.toString())
|
||||
|
||||
assertFails { sb.setRange(-1, 0, "") }
|
||||
assertFails { sb.setRange(0, -1, "") }
|
||||
assertFails { sb.setRange(2, 1, "") }
|
||||
assertFails { sb.setRange(sb.length + 1, sb.length + 2, "") }
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun toCharArray() {
|
||||
StringBuilder("my toCharArray test").let { sb ->
|
||||
val chars = CharArray(10) { '_' }
|
||||
|
||||
sb.toCharArray(chars, 8, 0, 2)
|
||||
assertEquals("________my", String(chars))
|
||||
sb.toCharArray(chars, 3, 6, 11)
|
||||
assertEquals("___harArmy", String(chars))
|
||||
sb.toCharArray(chars, 0, 16, 19)
|
||||
assertEquals("estharArmy", String(chars))
|
||||
|
||||
sb.setLength(5)
|
||||
|
||||
assertFails { sb.toCharArray(chars, -1, 0, 1) }
|
||||
assertFails { sb.toCharArray(chars, chars.size, 0, 1) }
|
||||
assertFails { sb.toCharArray(chars, 0, -1, 0) }
|
||||
assertFails { sb.toCharArray(chars, 0, 0, -1) }
|
||||
assertFails { sb.toCharArray(chars, 0, 2, 1) }
|
||||
assertFails { sb.toCharArray(chars, 0, 0, sb.length + 1) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user