From d021a324aa234b8984fb2746720b914922603ad5 Mon Sep 17 00:00:00 2001 From: Ilya Gorbunov Date: Tue, 27 Oct 2015 06:30:39 +0300 Subject: [PATCH] Test CharSequence extension methods both for String and StringBuilder --- libraries/stdlib/test/text/StringJVMTest.kt | 189 ++++++++-------- libraries/stdlib/test/text/StringTest.kt | 229 +++++++++++++------- 2 files changed, 248 insertions(+), 170 deletions(-) diff --git a/libraries/stdlib/test/text/StringJVMTest.kt b/libraries/stdlib/test/text/StringJVMTest.kt index d3ea5381709..6e26d8c27bd 100644 --- a/libraries/stdlib/test/text/StringJVMTest.kt +++ b/libraries/stdlib/test/text/StringJVMTest.kt @@ -6,18 +6,6 @@ import kotlin.test.* import org.junit.Test as test class StringJVMTest { - @test fun stringBuilderIterator() { - var sum = 0 - val sb = StringBuilder() - for(c in "239") - sb.append(c) - - println(sb) - - for(c in sb) - sum += (c.toInt() - '0'.toInt()) - assertTrue(sum == 14) - } @test fun orEmpty() { val s: String? = "hey" @@ -51,14 +39,12 @@ class StringJVMTest { assertEquals(77.toLong(), "77".toLong()) } - @test fun count() { - val text = "hello there\tfoo\nbar" + @test fun count() = withOneCharSequenceArg("hello there\tfoo\nbar") { text -> val whitespaceCount = text.count { it.isWhitespace() } assertEquals(3, whitespaceCount) } - @test fun testSplitByChar() { - val s = "ab\n[|^$&\\]^cd" + @test fun testSplitByChar() = withOneCharSequenceArg("ab\n[|^$&\\]^cd") { s -> var list = s.split('b'); assertEquals(2, list.size()) assertEquals("a", list[0]) @@ -68,11 +54,10 @@ class StringJVMTest { assertEquals("cd", list[2]) list = s.split('.') assertEquals(1, list.size()) - assertEquals(s, list[0]) + assertEquals(s.toString(), list[0]) } - @test fun testSplitByPattern() { - val s = "ab1cd2def3" + @test fun testSplitByPattern() = withOneCharSequenceArg("ab1cd2def3") { s -> val isDigit = "\\d".toRegex() assertEquals(listOf("ab", "cd", "def", ""), s.split(isDigit)) assertEquals(listOf("ab", "cd", "def3"), s.split(isDigit, 3)) @@ -85,7 +70,9 @@ class StringJVMTest { } } - @test fun repeat() { + @test fun repeat() = withOneCharSequenceArg { arg1 -> + fun String.repeat(n: Int): String = arg1(this).repeat(n) + assertFails { "foo".repeat(-1) } assertEquals("", "foo".repeat(0)) assertEquals("foo", "foo".repeat(1)) @@ -93,25 +80,28 @@ class StringJVMTest { assertEquals("foofoofoo", "foo".repeat(3)) } - @test fun filter() { - assertEquals("acdca", "abcdcba".filter { !it.equals('b') }) - assertEquals("1234", "a1b2c3d4".filter { it.isDigit() }) + @test fun filter() = withOneCharSequenceArg { arg1 -> + assertEquals("acdca", arg1("abcdcba").filter { !it.equals('b') }) + assertEquals("1234", arg1("a1b2c3d4").filter { it.isDigit() }) } - @test fun filterNot() { - assertEquals("acdca", "abcdcba".filterNot { it.equals('b') }) - assertEquals("abcd", "a1b2c3d4".filterNot { it.isDigit() }) + @test fun filterNot() = withOneCharSequenceArg { arg1 -> + assertEquals("acdca", arg1("abcdcba").filterNot { it.equals('b') }) + assertEquals("abcd", arg1("a1b2c3d4").filterNot { it.isDigit() }) } - @test fun forEach() { - val data = "abcd1234" + @test fun forEach() = withOneCharSequenceArg("abcd1234") { data -> var count = 0 - data.forEach{ count++ } - assertEquals(data.length(), count) + val sb = StringBuilder() + data.forEach { + count++ + sb.append(it) + } + assertEquals(data.length, count) + assertEquals(data.toString(), sb.toString()) } - @test fun all() { - val data = "AbCd" + @test fun all() = withOneCharSequenceArg("AbCd") { data -> assertTrue { data.all { it.isJavaIdentifierPart() } } @@ -120,8 +110,7 @@ class StringJVMTest { } } - @test fun any() { - val data = "a1bc" + @test fun any() = withOneCharSequenceArg("a1bc") { data -> assertTrue { data.any() { it.isDigit() } } @@ -137,114 +126,109 @@ class StringJVMTest { assertEquals("", sb.toString()) } - @test fun find() { - val data = "a1b2c3" + @test fun find() = withOneCharSequenceArg("a1b2c3") { data -> assertEquals('1', data.first { it.isDigit() }) assertNull(data.firstOrNull { it.isUpperCase() }) } - @test fun findNot() { - val data = "1a2b3c" + @test fun findNot() = withOneCharSequenceArg("1a2b3c") { data -> assertEquals('a', data.filterNot { it.isDigit() }.firstOrNull()) assertNull(data.filterNot { it.isJavaIdentifierPart() }.firstOrNull()) } - @test fun partition() { - val data = "a1b2c3" + @test fun partition() = withOneCharSequenceArg("a1b2c3") { data -> val pair = data.partition { it.isDigit() } assertEquals("123", pair.first, "pair.first") assertEquals("abc", pair.second, "pair.second") } - @test fun map() { - assertEquals(listOf('a', 'b', 'c'), "abc".map { it }) + @test fun map() = withOneCharSequenceArg { arg1 -> + assertEquals(listOf('a', 'b', 'c'), arg1("abc").map { it }) - assertEquals(listOf(true, false, true), "AbC".map { it.isUpperCase() }) + assertEquals(listOf(true, false, true), arg1("AbC").map { it.isUpperCase() }) - assertEquals(listOf(), "".map { it.isUpperCase() }) + assertEquals(listOf(), arg1("").map { it.isUpperCase() }) - assertEquals(listOf(97, 98, 99), "abc".map { it.toInt() }) + assertEquals(listOf(97, 98, 99), arg1("abc").map { it.toInt() }) } - @test fun mapTo() { + @test fun mapTo() = withOneCharSequenceArg { arg1 -> val result1 = arrayListOf() - val return1 = "abc".mapTo(result1, { it }) + val return1 = arg1("abc").mapTo(result1, { it }) assertEquals(result1, return1) assertEquals(arrayListOf('a', 'b', 'c'), result1) val result2 = arrayListOf() - val return2 = "AbC".mapTo(result2, { it.isUpperCase() }) + val return2 = arg1("AbC").mapTo(result2, { it.isUpperCase() }) assertEquals(result2, return2) assertEquals(arrayListOf(true, false, true), result2) val result3 = arrayListOf() - val return3 = "".mapTo(result3, { it.isUpperCase() }) + val return3 = arg1("").mapTo(result3, { it.isUpperCase() }) assertEquals(result3, return3) assertEquals(arrayListOf(), result3) val result4 = arrayListOf() - val return4 = "abc".mapTo(result4, { it.toInt() }) + val return4 = arg1("abc").mapTo(result4, { it.toInt() }) assertEquals(result4, return4) assertEquals(arrayListOf(97, 98, 99), result4) } - @test fun flatMap() { - val data = "abcd" - val result = data.flatMap { listOf(it) } - assertEquals(data.length(), result.count()) - assertEquals(data.toCharList(), result) + @test fun flatMap() = withOneCharSequenceArg("abcd") { data -> + val result = data.flatMap { ('a'..it) + ' ' } + assertEquals("a ab abc abcd ".toCharList(), result) } - @test fun fold() { + @test fun fold() = withOneCharSequenceArg { arg1 -> // calculate number of digits in the string - val data = "a1b2c3def" + val data = arg1("a1b2c3def") val result = data.fold(0, { digits, c -> if(c.isDigit()) digits + 1 else digits } ) assertEquals(3, result) //simulate all method - assertEquals(true, "ABCD".fold(true, { r, c -> r && c.isUpperCase() })) + assertEquals(true, arg1("ABCD").fold(true, { r, c -> r && c.isUpperCase() })) //get string back - assertEquals(data, data.fold("", { s, c -> s + c })) + assertEquals(data.toString(), data.fold("", { s, c -> s + c })) } - @test fun foldRight() { + @test fun foldRight() = withOneCharSequenceArg { arg1 -> // calculate number of digits in the string - val data = "a1b2c3def" + val data = arg1("a1b2c3def") val result = data.foldRight(0, { c, digits -> if(c.isDigit()) digits + 1 else digits }) assertEquals(3, result) //simulate all method - assertEquals(true, "ABCD".foldRight(true, { c, r -> r && c.isUpperCase() })) + assertEquals(true, arg1("ABCD").foldRight(true, { c, r -> r && c.isUpperCase() })) //get string back - assertEquals(data, data.foldRight("", { s, c -> "" + s + c })) + assertEquals(data.toString(), data.foldRight("", { s, c -> "" + s + c })) } - @test fun reduce() { + @test fun reduce() = withOneCharSequenceArg { arg1 -> // get the smallest character(by char value) - assertEquals('a', "bacfd".reduce { v, c -> if (v > c) c else v }) + assertEquals('a', arg1("bacfd").reduce { v, c -> if (v > c) c else v }) assertFailsWith(UnsupportedOperationException::class) { - "".reduce { a, b -> '\n' } + arg1("").reduce { a, b -> '\n' } } } - @test fun reduceRight() { + @test fun reduceRight() = withOneCharSequenceArg { arg1 -> // get the smallest character(by char value) - assertEquals('a', "bacfd".reduceRight { c, v -> if (v > c) c else v }) + assertEquals('a', arg1("bacfd").reduceRight { c, v -> if (v > c) c else v }) assertFailsWith(UnsupportedOperationException::class) { - "".reduceRight { a, b -> '\n' } + arg1("").reduceRight { a, b -> '\n' } } } - @test fun groupBy() { + @test fun groupBy() = withOneCharSequenceArg("abAbaABcD") { data -> // group characters by their case - val data = "abAbaABcD" val result = data.groupBy { it.isLowerCase() } - assertEquals(2, result.size()) - assertEquals(listOf('a','b','b','a','c'), result.get(true)) + assertEquals(2, result.size) + assertEquals(listOf('a','b','b','a','c'), result[true]) + assertEquals(listOf('A','A','B','D'), result[false]) } @test fun joinToString() { @@ -271,6 +255,8 @@ class StringJVMTest { assertEquals("[v-e-r-y-l-o-n-g-s-t-r-oops]", result2) } + + @test fun dropWhile() { val data = "ab1cd2" assertEquals("1cd2", data.dropWhile { it.isJavaIdentifierStart() }) @@ -278,6 +264,13 @@ class StringJVMTest { assertEquals("ab1cd2", data.dropWhile { false }) } + @test fun dropWhileCharSequence() = withOneCharSequenceArg("ab1cd2") { data -> + assertContentEquals("1cd2", data.dropWhile { it.isJavaIdentifierStart() }) + assertContentEquals("", data.dropWhile { true }) + assertContentEquals("ab1cd2", data.dropWhile { false }) + } + + @test fun drop() { val data = "abcd1234" assertEquals("d1234", data.drop(3)) @@ -287,6 +280,14 @@ class StringJVMTest { assertEquals("", data.drop(data.length() + 5)) } + @test fun dropCharSequence() = withOneCharSequenceArg("abcd1234") { data -> + assertContentEquals("d1234", data.drop(3)) + assertFails { + data.drop(-2) + } + assertContentEquals("", data.drop(data.length() + 5)) + } + @test fun takeWhile() { val data = "ab1cd2" assertEquals("ab", data.takeWhile { it.isJavaIdentifierStart() }) @@ -294,6 +295,12 @@ class StringJVMTest { assertEquals("ab1cd2", data.takeWhile { true }) } + @test fun takeWhileCharSequence() = withOneCharSequenceArg("ab1cd2") { data -> + assertContentEquals("ab", data.takeWhile { it.isJavaIdentifierStart() }) + assertContentEquals("", data.takeWhile { false }) + assertContentEquals("ab1cd2", data.takeWhile { true }) + } + @test fun take() { val data = "abcd1234" assertEquals("abc", data.take(3)) @@ -303,6 +310,14 @@ class StringJVMTest { assertEquals(data, data.take(data.length() + 42)) } + @test fun takeCharSequence() = withOneCharSequenceArg("abcd1234") { data -> + assertEquals("abc", data.take(3)) + assertFails { + data.take(-7) + } + assertContentEquals(data.toString(), data.take(data.length + 42)) + } + @test fun formatter() { assertEquals("12", "%d%d".format(1, 2)) @@ -318,32 +333,28 @@ class StringJVMTest { assertEquals(String(s.toByteArray()), String(s.toByteArray(defaultCharset.name()))) } - @test fun testReplaceAllClosure() { - val s = "test123zzz" + @test fun testReplaceAllClosure() = withOneCharSequenceArg("test123zzz") { s -> val result = s.replace("\\d+".toRegex()) { mr -> "[" + mr.value + "]" } assertEquals("test[123]zzz", result) } - @test fun testReplaceAllClosureAtStart() { - val s = "123zzz" + @test fun testReplaceAllClosureAtStart() = withOneCharSequenceArg("123zzz") { s -> val result = s.replace("\\d+".toRegex()) { mr -> "[" + mr.value + "]" } assertEquals("[123]zzz", result) } - @test fun testReplaceAllClosureAtEnd() { - val s = "test123" + @test fun testReplaceAllClosureAtEnd() = withOneCharSequenceArg("test123") { s -> val result = s.replace("\\d+".toRegex()) { mr -> "[" + mr.value + "]" } assertEquals("test[123]", result) } - @test fun testReplaceAllClosureEmpty() { - val s = "" + @test fun testReplaceAllClosureEmpty() = withOneCharSequenceArg("") { s -> val result = s.replace("\\d+".toRegex()) { mr -> "x" } @@ -351,23 +362,21 @@ class StringJVMTest { } - @test fun slice() { + @test fun slice() = withOneCharSequenceArg { arg1 -> val iter = listOf(4, 3, 0, 1) - val builder = StringBuilder() - builder.append("ABCD") - builder.append("abcd") + val data = arg1("ABCDabcd") // ABCDabcd // 01234567 - assertEquals("BCDabc", builder.slice(1..6).toString()) - assertEquals("baD", builder.slice(5 downTo 3).toString()) - assertEquals("aDAB", builder.slice(iter).toString()) + assertEquals("BCDabc", data.slice(1..6).toString()) + assertEquals("baD", data.slice(5 downTo 3).toString()) + assertEquals("aDAB", data.slice(iter).toString()) assertFails { - "abc".slice(listOf(1,4)) + arg1("abc").slice(listOf(1,4)) } assertFails { - builder.slice(listOf(10)) + data.slice(listOf(10)) } } diff --git a/libraries/stdlib/test/text/StringTest.kt b/libraries/stdlib/test/text/StringTest.kt index 95499bf46a6..2ca9f5ac071 100644 --- a/libraries/stdlib/test/text/StringTest.kt +++ b/libraries/stdlib/test/text/StringTest.kt @@ -6,9 +6,32 @@ import org.junit.Test as test // could not be local inside isEmptyAndBlank, because non-toplevel declarations is not yet supported for JS class IsEmptyCase(val value: String?, val isNull: Boolean = false, val isEmpty: Boolean = false, val isBlank: Boolean = false) +fun createString(content: String): CharSequence = content +fun createStringBuilder(content: String): CharSequence = StringBuilder((content as Any).toString()) // required for Rhino JS + + +val charSequenceBuilders = listOf(::createString, ::createStringBuilder) + +fun withOneCharSequenceArg(f: ((String) -> CharSequence) -> Unit) { + for (arg1Builder in charSequenceBuilders) f(arg1Builder) +} + +fun withOneCharSequenceArg(arg1: String, f: (CharSequence) -> Unit) + = withOneCharSequenceArg { arg1Builder -> f(arg1Builder(arg1)) } + +fun withTwoCharSequenceArgs(f: ((String) -> CharSequence, (String) -> CharSequence) -> Unit) { + for (arg1Builder in charSequenceBuilders) + for (arg2Builder in charSequenceBuilders) + f(arg1Builder, arg2Builder) +} + +fun assertContentEquals(expected: String, actual: CharSequence) { + assertEquals(expected, actual.toString()) +} + class StringTest { - @test fun isEmptyAndBlank() { + @test fun isEmptyAndBlank() = withOneCharSequenceArg { arg1 -> val cases = listOf( IsEmptyCase(null, isNull = true), @@ -18,14 +41,14 @@ class StringTest { ) for (case in cases) { - assertEquals(case.isNull || case.isEmpty, case.value.isNullOrEmpty(), "failed for case '${case.value}'") - assertEquals(case.isNull || case.isBlank, case.value.isNullOrBlank(), "failed for case '${case.value}'") - if (case.value != null) + val value = case.value?.let { arg1(it) } + assertEquals(case.isNull || case.isEmpty, value.isNullOrEmpty(), "failed for case '$value'") + assertEquals(case.isNull || case.isBlank, value.isNullOrBlank(), "failed for case '$value'") + if (value != null) { - assertEquals(case.isEmpty, case.value.isEmpty(), "failed for case '${case.value}'") - assertEquals(case.isBlank, case.value.isBlank(), "failed for case '${case.value}'") + assertEquals(case.isEmpty, value.isEmpty(), "failed for case '$value'") + assertEquals(case.isBlank, value.isBlank(), "failed for case '$value'") } - } } @@ -43,6 +66,23 @@ class StringTest { assertTrue("abcd".startsWith("aB", ignoreCase = true)) } + @test fun startsWithStringForCharSequence() = withTwoCharSequenceArgs { arg1, arg2 -> + fun String.startsWithCs(prefix: String, ignoreCase: Boolean = false): Boolean = + arg1(this).startsWith(arg2(prefix), ignoreCase) + + assertTrue("abcd".startsWithCs("ab")) + assertTrue("abcd".startsWithCs("abcd")) + assertTrue("abcd".startsWithCs("a")) + assertFalse("abcd".startsWithCs("abcde")) + assertFalse("abcd".startsWithCs("b")) + assertFalse("".startsWithCs("a")) + assertTrue("some".startsWithCs("")) + assertTrue("".startsWithCs("")) + + assertFalse("abcd".startsWithCs("aB", ignoreCase = false)) + assertTrue("abcd".startsWithCs("aB", ignoreCase = true)) + } + @test fun endsWithString() { assertTrue("abcd".endsWith("d")) assertTrue("abcd".endsWith("abcd")) @@ -54,7 +94,24 @@ class StringTest { assertTrue("".endsWith("")) } - @test fun startsWithChar() { + @test fun endsWithStringForCharSequence() = withTwoCharSequenceArgs { arg1, arg2 -> + fun String.endsWithCs(suffix: String, ignoreCase: Boolean = false): Boolean = + arg1(this).endsWith(arg2(suffix), ignoreCase) + + assertTrue("abcd".endsWithCs("d")) + assertTrue("abcd".endsWithCs("abcd")) + assertFalse("abcd".endsWithCs("b")) + assertFalse("strö".endsWithCs("RÖ", ignoreCase = false)) + assertTrue("strö".endsWithCs("RÖ", ignoreCase = true)) + assertFalse("".endsWithCs("a")) + assertTrue("some".endsWithCs("")) + assertTrue("".endsWithCs("")) + } + + @test fun startsWithChar() = withOneCharSequenceArg { arg1 -> + fun String.startsWith(char: Char, ignoreCase: Boolean = false): Boolean = + arg1(this).startsWith(char, ignoreCase) + assertTrue("abcd".startsWith('a')) assertFalse("abcd".startsWith('b')) assertFalse("abcd".startsWith('A', ignoreCase = false)) @@ -62,7 +119,10 @@ class StringTest { assertFalse("".startsWith('a')) } - @test fun endsWithChar() { + @test fun endsWithChar() = withOneCharSequenceArg { arg1 -> + fun String.endsWith(char: Char, ignoreCase: Boolean = false): Boolean = + arg1(this).endsWith(char, ignoreCase) + assertTrue("abcd".endsWith('d')) assertFalse("abcd".endsWith('b')) assertFalse("strö".endsWith('Ö', ignoreCase = false)) @@ -70,7 +130,10 @@ class StringTest { assertFalse("".endsWith('a')) } - @test fun commonPrefix() { + @test fun commonPrefix() = withTwoCharSequenceArgs { arg1, arg2 -> + fun String.commonPrefixWith(other: String, ignoreCase: Boolean = false): String = + arg1(this).commonPrefixWith(arg2(other), ignoreCase) + assertEquals("", "".commonPrefixWith("")) assertEquals("", "any".commonPrefixWith("")) assertEquals("", "".commonPrefixWith("any")) @@ -84,10 +147,12 @@ class StringTest { val dth55 = "\uD83C\uDC59" // domino tile horizontal 5-5 assertEquals("", dth54.commonPrefixWith(dth55)) assertEquals(dth54, "$dth54$dth54".commonPrefixWith("$dth54$dth55")) - } - @test fun commonSuffix() { + @test fun commonSuffix() = withTwoCharSequenceArgs { arg1, arg2 -> + fun String.commonSuffixWith(other: String, ignoreCase: Boolean = false): String = + arg1(this).commonSuffixWith(arg2(other), ignoreCase) + assertEquals("", "".commonSuffixWith("")) assertEquals("", "any".commonSuffixWith("")) assertEquals("", "".commonSuffixWith("any")) @@ -127,39 +192,44 @@ class StringTest { assertEquals("edab", "abcde".slice(iter)) } - @test fun reverse() { + @test fun reverse() = withOneCharSequenceArg { arg1 -> + fun String.reversed(): String = arg1(this).reversed() + assertEquals("dcba", "abcd".reversed()) assertEquals("4321", "1234".reversed()) assertEquals("", "".reversed()) } - @test fun indices() { - assertEquals(0..4, "abcde".indices) - assertEquals(0..0, "a".indices) - assertTrue("".indices.isEmpty()) + @test fun indices() = withOneCharSequenceArg { arg1 -> + fun String.indices(): IntRange = arg1(this).indices + + assertEquals(0..4, "abcde".indices()) + assertEquals(0..0, "a".indices()) + assertTrue("".indices().isEmpty()) } - @test fun replaceRange() { - val s = "sample text" - assertEquals("sa??e text", s.replaceRange(2, 5, "??")) - assertEquals("sa?? text", s.replaceRange(2..5, "??")) + @test fun replaceRange() = withTwoCharSequenceArgs { arg1, arg2 -> + val s = arg1("sample text") + val replacement = arg2("??") + + assertEquals("sa??e text", s.replaceRange(2, 5, replacement)) + assertEquals("sa?? text", s.replaceRange(2..5, replacement)) assertFails { - s.replaceRange(5..2, "??") + s.replaceRange(5..2, replacement) } assertFails { - s.replaceRange(5, 2, "??") + s.replaceRange(5, 2, replacement) } // symmetry with indices - assertEquals("??", s.replaceRange(s.indices, "??")) + assertEquals(replacement.toString(), s.replaceRange(s.indices, replacement)) } - @test fun removeRange() { - val s = "sample text" + @test fun removeRange() = withOneCharSequenceArg("sample text") { s -> assertEquals("sae text", s.removeRange(2, 5)) assertEquals("sa text", s.removeRange(2..5)) - assertEquals(s, s.removeRange(2,2)) + assertEquals(s.toString(), s.removeRange(2,2)) // symmetry with indices assertEquals("", s.removeRange(s.indices)) @@ -216,14 +286,15 @@ class StringTest { assertEquals("xxx", s.replaceBeforeLast("=", "/new/path", "xxx")) } - @test fun stringIterator() { + @test fun stringIterator() = withOneCharSequenceArg("239") { data -> var sum = 0 - for(c in "239") - sum += (c.toInt() - '0'.toInt()) + for(c in data) + sum += (c - '0') assertTrue(sum == 14) } - @test fun trimStart() { + @test fun trimStart() = withOneCharSequenceArg { arg1 -> + fun String.trimStart(): String = arg1(this).trimStart() assertEquals("", "".trimStart()) assertEquals("a", "a".trimStart()) assertEquals("a", " a".trimStart()) @@ -238,11 +309,12 @@ class StringTest { assertEquals("a", "\ra".trimStart()) assertEquals("a", "\na".trimStart()) - assertEquals("a=", "-=-=a=".trimStart('-','=')) - assertEquals("123a", "ab123a".trimStart { it < '0' || it > '9' }) // TODO: Use !it.isDigit when available in JS + assertEquals("a=", arg1("-=-=a=").trimStart('-','=')) + assertEquals("123a", arg1("ab123a").trimStart { it < '0' || it > '9' }) // TODO: Use !it.isDigit when available in JS } - @test fun trimEnd() { + @test fun trimEnd() = withOneCharSequenceArg { arg1 -> + fun String.trimEnd(): String = arg1(this).trimEnd() assertEquals("", "".trimEnd()) assertEquals("a", "a".trimEnd()) assertEquals("a", "a ".trimEnd()) @@ -257,11 +329,11 @@ class StringTest { assertEquals("a", "a\r".trimEnd()) assertEquals("a", "a\n".trimEnd()) - assertEquals("=a", "=a=-=-".trimEnd('-','=')) - assertEquals("ab123", "ab123a".trimEnd { it < '0' || it > '9' }) // TODO: Use !it.isDigit when available in JS + assertEquals("=a", arg1("=a=-=-").trimEnd('-','=')) + assertEquals("ab123", arg1("ab123a").trimEnd { it < '0' || it > '9' }) // TODO: Use !it.isDigit when available in JS } - @test fun trimStartAndEnd() { + @test fun trimStartAndEnd() = withOneCharSequenceArg { arg1 -> val examples = arrayOf("a", " a ", " a ", @@ -273,7 +345,7 @@ class StringTest { " \u00A0 a \u00A0 " ) - for (example in examples) { + for (example in examples.map { arg1(it) }) { assertEquals(example.trim(), example.trimEnd().trimStart()) assertEquals(example.trim(), example.trimStart().trimEnd()) } @@ -284,27 +356,29 @@ class StringTest { val trimChars = charArrayOf('-', '=') val trimPredicate = { it: Char -> it < '0' || it > '9' } // TODO: Use !it.isDigit when available in JS - for (example in examplesForPredicate) { + for (example in examplesForPredicate.map { arg1(it) }) { assertEquals(example.trimStart(*trimChars).trimEnd(*trimChars), example.trim(*trimChars)) assertEquals(example.trimStart(trimPredicate).trimEnd(trimPredicate), example.trim(trimPredicate)) } } - @test fun padStart() { + @test fun padStart() = withOneCharSequenceArg { arg1 -> + fun String.padStart(length: Int): String = arg1(this).padStart(length) assertEquals("s", "s".padStart(0)) assertEquals("s", "s".padStart(1)) assertEquals(" ", "".padStart(2)) - assertEquals("--s", "s".padStart(3, '-')) + assertEquals("--s", arg1("s").padStart(3, '-')) assertFails { "s".padStart(-1) } } - @test fun padEnd() { + @test fun padEnd() = withOneCharSequenceArg { arg1 -> + fun String.padEnd(length: Int): String = arg1(this).padEnd(length) assertEquals("s", "s".padEnd(0)) assertEquals("s", "s".padEnd(1)) assertEquals(" ", "".padEnd(2)) - assertEquals("s--", "s".padEnd(3, '-')) + assertEquals("s--", arg1("s").padEnd(3, '-')) assertFails { "s".padEnd(-1) } @@ -350,33 +424,34 @@ class StringTest { */ - @test fun split() { - assertEquals(listOf(""), "".split(";")) - assertEquals(listOf("test"), "test".split(*charArrayOf()), "empty list of delimiters, none matched -> entire string returned") - assertEquals(listOf("test"), "test".split(*arrayOf()), "empty list of delimiters, none matched -> entire string returned") + @test fun split() = withOneCharSequenceArg { arg1 -> + operator fun String.unaryPlus(): CharSequence = arg1(this) - assertEquals(listOf("abc", "def", "123;456"), "abc;def,123;456".split(';', ',', limit = 3)) - assertEquals(listOf("abc", "def", "123", "456"), "abc
def
123
456".split("
", ignoreCase = true)) + assertEquals(listOf(""), (+"").split(";")) + assertEquals(listOf("test"), (+"test").split(*charArrayOf()), "empty list of delimiters, none matched -> entire string returned") + assertEquals(listOf("test"), (+"test").split(*arrayOf()), "empty list of delimiters, none matched -> entire string returned") - assertEquals(listOf("abc", "def", "123", "456"), "abc=-def==123=456".split("==", "=-", "=")) + assertEquals(listOf("abc", "def", "123;456"), (+"abc;def,123;456").split(';', ',', limit = 3)) + assertEquals(listOf("abc", "def", "123", "456"), (+"abc
def
123
456").split("
", ignoreCase = true)) - assertEquals(listOf("", "a", "b", "c", ""), "abc".split("")) - assertEquals(listOf("", "a", "b", "b", "a", ""), "abba".split("", "a")) - assertEquals(listOf("", "", "b", "b", "", ""), "abba".split("a", "")) + assertEquals(listOf("abc", "def", "123", "456"), (+"abc=-def==123=456").split("==", "=-", "=")) + + assertEquals(listOf("", "a", "b", "c", ""), (+"abc").split("")) + assertEquals(listOf("", "a", "b", "b", "a", ""), (+"abba").split("", "a")) + assertEquals(listOf("", "", "b", "b", "", ""), (+"abba").split("a", "")) } - @test fun splitToLines() { - val string = "first line\rsecond line\nthird line\r\nlast line" + @test fun splitToLines() = withOneCharSequenceArg { arg1 -> + val string = arg1("first line\rsecond line\nthird line\r\nlast line") assertEquals(listOf("first line", "second line", "third line", "last line"), string.lines()) - val singleLine = "single line" - assertEquals(listOf(singleLine), singleLine.lines()) + val singleLine = arg1("single line") + assertEquals(listOf(singleLine.toString()), singleLine.lines()) } - @test fun indexOfAnyChar() { - val string = "abracadabra" + @test fun indexOfAnyChar() = withOneCharSequenceArg("abracadabra") { string -> val chars = charArrayOf('d', 'b') assertEquals(1, string.indexOfAny(chars)) assertEquals(6, string.indexOfAny(chars, startIndex = 2)) @@ -389,8 +464,7 @@ class StringTest { assertEquals(-1, string.indexOfAny(charArrayOf())) } - @test fun indexOfAnyCharIgnoreCase() { - val string = "abraCadabra" + @test fun indexOfAnyCharIgnoreCase() = withOneCharSequenceArg("abraCadabra") { string -> val chars = charArrayOf('B', 'c') assertEquals(1, string.indexOfAny(chars, ignoreCase = true)) assertEquals(4, string.indexOfAny(chars, startIndex = 2, ignoreCase = true)) @@ -401,8 +475,7 @@ class StringTest { assertEquals(-1, string.lastIndexOfAny(chars, startIndex = 0, ignoreCase = true)) } - @test fun indexOfAnyString() { - val string = "abracadabra" + @test fun indexOfAnyString() = withOneCharSequenceArg("abracadabra") { string -> val substrings = listOf("rac", "ra") assertEquals(2, string.indexOfAny(substrings)) assertEquals(9, string.indexOfAny(substrings, startIndex = 3)) @@ -418,8 +491,7 @@ class StringTest { assertEquals(-1, string.indexOfAny(listOf())) } - @test fun indexOfAnyStringIgnoreCase() { - val string = "aBraCadaBrA" + @test fun indexOfAnyStringIgnoreCase() = withOneCharSequenceArg("aBraCadaBrA") { string -> val substrings = listOf("rAc", "Ra") assertEquals(2, string.indexOfAny(substrings, ignoreCase = true)) @@ -431,8 +503,7 @@ class StringTest { assertEquals(-1, string.lastIndexOfAny(substrings, startIndex = 1, ignoreCase = true)) } - @test fun findAnyOfStrings() { - val string = "abracadabra" + @test fun findAnyOfStrings() = withOneCharSequenceArg("abracadabra") { string -> val substrings = listOf("rac", "ra") assertEquals(2 to "rac", string.findAnyOf(substrings)) assertEquals(9 to "ra", string.findAnyOf(substrings, startIndex = 3)) @@ -448,8 +519,7 @@ class StringTest { assertEquals(null, string.findAnyOf(listOf())) } - @test fun findAnyOfStringsIgnoreCase() { - val string = "aBraCadaBrA" + @test fun findAnyOfStringsIgnoreCase() = withOneCharSequenceArg("aBraCadaBrA") { string -> val substrings = listOf("rAc", "Ra") assertEquals(2 to substrings[0], string.findAnyOf(substrings, ignoreCase = true)) @@ -461,8 +531,7 @@ class StringTest { assertEquals(null, string.findLastAnyOf(substrings, startIndex = 1, ignoreCase = true)) } - @test fun indexOfChar() { - val string = "bcedef" + @test fun indexOfChar() = withOneCharSequenceArg("bcedef") { string -> assertEquals(-1, string.indexOf('a')) assertEquals(2, string.indexOf('e')) assertEquals(2, string.indexOf('e', 2)) @@ -477,8 +546,7 @@ class StringTest { } - @test fun indexOfCharIgnoreCase() { - val string = "bCEdef" + @test fun indexOfCharIgnoreCase() = withOneCharSequenceArg("bCEdef") { string -> assertEquals(-1, string.indexOf('a', ignoreCase = true)) assertEquals(2, string.indexOf('E', ignoreCase = true)) assertEquals(2, string.indexOf('e', 2, ignoreCase = true)) @@ -493,8 +561,7 @@ class StringTest { } } - @test fun indexOfString() { - val string = "bceded" + @test fun indexOfString() = withOneCharSequenceArg("bceded") { string -> for (index in string.indices) assertEquals(index, string.indexOf("", index)) assertEquals(1, string.indexOf("ced")) @@ -502,8 +569,7 @@ class StringTest { assertEquals(-1, string.indexOf("abcdefgh")) } - @test fun indexOfStringIgnoreCase() { - val string = "bceded" + @test fun indexOfStringIgnoreCase() = withOneCharSequenceArg("bceded") { string -> for (index in string.indices) assertEquals(index, string.indexOf("", index, ignoreCase = true)) assertEquals(1, string.indexOf("cEd", ignoreCase = true)) @@ -512,17 +578,20 @@ class StringTest { } - @test fun contains() { + @test fun contains() = withTwoCharSequenceArgs { arg1, arg2 -> + operator fun String.contains(other: String): Boolean = arg1(this).contains(arg2(other)) + operator fun String.contains(other: Char): Boolean = arg1(this).contains(other) + assertTrue("pl" in "sample") assertFalse("PL" in "sample") - assertTrue("sömple".contains("Ö", ignoreCase = true)) + assertTrue(arg1("sömple").contains(arg2("Ö"), ignoreCase = true)) assertTrue("" in "sample") assertTrue("" in "") assertTrue('ö' in "sömple") assertFalse('Ö' in "sömple") - assertTrue("sömple".contains('Ö', ignoreCase = true)) + assertTrue(arg1("sömple").contains('Ö', ignoreCase = true)) } @test fun equalsIgnoreCase() {