Provide overloads both for Strings and CharSequences of removePrefix, removeSuffix, removeSurronding, trim* and pad*, replaceRange & removeRange

This commit is contained in:
Ilya Gorbunov
2015-11-04 06:04:31 +03:00
parent 2ed611e2c5
commit 62d6bcaa6d
3 changed files with 325 additions and 337 deletions
+196 -67
View File
@@ -9,9 +9,9 @@ import kotlin.text.MatchResult
import kotlin.text.Regex
/**
* Returns a string with leading and trailing characters matching the [predicate] trimmed.
* Returns a sub sequence of this char sequence having leading and trailing characters matching the [predicate] trimmed.
*/
inline public fun CharSequence.trim(predicate: (Char) -> Boolean): String {
inline public fun CharSequence.trim(predicate: (Char) -> Boolean): CharSequence {
var startIndex = 0
var endIndex = length() - 1
var startFound = false
@@ -34,24 +34,36 @@ inline public fun CharSequence.trim(predicate: (Char) -> Boolean): String {
}
}
return substring(startIndex, endIndex + 1)
return subSequence(startIndex, endIndex + 1)
}
/**
* Returns a string with leading characters matching the [predicate] trimmed.
* Returns a string with leading and trailing characters matching the [predicate] trimmed.
*/
inline public fun CharSequence.trimStart(predicate: (Char) -> Boolean): String {
inline public fun String.trim(predicate: (Char) -> Boolean): String
= (this as CharSequence).trim(predicate).toString()
/**
* Returns a sub sequence of this char sequence having leading characters matching the [predicate] trimmed.
*/
inline public fun CharSequence.trimStart(predicate: (Char) -> Boolean): CharSequence {
for (index in this.indices)
if (!predicate(this[index]))
return substring(index)
return subSequence(index, length)
return ""
}
/**
* Returns a string with trailing characters matching the [predicate] trimmed.
* Returns a string with leading characters matching the [predicate] trimmed.
*/
inline public fun CharSequence.trimEnd(predicate: (Char) -> Boolean): String {
inline public fun String.trimStart(predicate: (Char) -> Boolean): String
= (this as CharSequence).trimStart(predicate).toString()
/**
* Returns a sub sequence of this char sequence having trailing characters matching the [predicate] trimmed.
*/
inline public fun CharSequence.trimEnd(predicate: (Char) -> Boolean): CharSequence {
for (index in this.indices.reversed())
if (!predicate(this[index]))
return substring(0, index + 1)
@@ -60,77 +72,137 @@ inline public fun CharSequence.trimEnd(predicate: (Char) -> Boolean): String {
}
/**
* Returns a string with leading and trailing characters in the [chars] array trimmed.
* Returns a string with trailing characters matching the [predicate] trimmed.
*/
public fun CharSequence.trim(vararg chars: Char): String = trim { it in chars }
inline public fun String.trimEnd(predicate: (Char) -> Boolean): String
= (this as CharSequence).trimEnd(predicate).toString()
/**
* Returns a string with leading and trailing characters in the [chars] array trimmed.
* Returns a sub sequence of this char sequence having leading and trailing characters from the [chars] array trimmed.
*/
public fun CharSequence.trimStart(vararg chars: Char): String = trimStart { it in chars }
public fun CharSequence.trim(vararg chars: Char): CharSequence = trim { it in chars }
/**
* Returns a string with trailing characters in the [chars] array trimmed.
* Returns a string with leading and trailing characters from the [chars] array trimmed.
*/
public fun CharSequence.trimEnd(vararg chars: Char): String = trimEnd { it in chars }
public fun String.trim(vararg chars: Char): String = trim { it in chars }
/**
* Returns a sub sequence of this char sequence having leading and trailing characters from the [chars] array trimmed.
*/
public fun CharSequence.trimStart(vararg chars: Char): CharSequence = trimStart { it in chars }
/**
* Returns a string with leading and trailing characters from the [chars] array trimmed.
*/
public fun String.trimStart(vararg chars: Char): String = trimStart { it in chars }
/**
* Returns a sub sequence of this char sequence having trailing characters from the [chars] array trimmed.
*/
public fun CharSequence.trimEnd(vararg chars: Char): CharSequence = trimEnd { it in chars }
/**
* Returns a string with trailing characters from the [chars] array trimmed.
*/
public fun String.trimEnd(vararg chars: Char): String = trimEnd { it in chars }
/**
* Returns a sub sequence of this char sequence having leading and trailing whitespace trimmed.
*/
public fun CharSequence.trim(): CharSequence = trim { it.isWhitespace() }
/**
* Returns a string with leading and trailing whitespace trimmed.
*/
public fun CharSequence.trim(): String = trim { it.isWhitespace() }
public fun String.trim(): String = (this as CharSequence).trim().toString()
/**
* Returns a sub sequence of this char sequence having leading whitespace removed.
*/
public fun CharSequence.trimStart(): CharSequence = trimStart { it.isWhitespace() }
/**
* Returns a string with leading whitespace removed.
*/
public fun CharSequence.trimStart(): String = trimStart { it.isWhitespace() }
public fun String.trimStart(): String = (this as CharSequence).trimStart().toString()
/**
* Returns a sub sequence of this char sequence having trailing whitespace removed.
*/
public fun CharSequence.trimEnd(): CharSequence = trimEnd { it.isWhitespace() }
/**
* Returns a string with trailing whitespace removed.
*/
public fun CharSequence.trimEnd(): String = trimEnd { it.isWhitespace() }
public fun String.trimEnd(): String = (this as CharSequence).trimEnd().toString()
/**
* Left pad a String with a specified character or space.
* Returns a char sequence with content of this char sequence padded at the beginning
* to the specified [length] with the specified character or space.
*
* @param length the desired string length.
* @param padChar the character to pad string with, if it has length less than the [length] specified. Space is used by default.
* @returns Returns a string, of length at least [length], consisting of string prepended with [padChar] as many times.
* as are necessary to reach that length.
*/
public fun CharSequence.padStart(length: Int, padChar: Char = ' '): String {
public fun CharSequence.padStart(length: Int, padChar: Char = ' '): CharSequence {
if (length < 0)
throw IllegalArgumentException("String length $length is less than zero.")
if (length <= this.length())
return this.toString()
throw IllegalArgumentException("Desired length $length is less than zero.")
if (length <= this.length)
return this.subSequence(0, this.length)
val sb = StringBuilder(length)
for (i in 1..(length - this.length()))
for (i in 1..(length - this.length))
sb.append(padChar)
sb.append(this)
return sb.toString()
return sb
}
/**
* Right pad a String with a specified character or space.
* Pads the string to the specified [length] at the beginning with the specified character or space.
*
* @param length the desired string length.
* @param padChar the character to pad string with, if it has length less than the [length] specified. Space is used by default.
* @returns Returns a string, of length at least [length], consisting of string prepended with [padChar] as many times.
* as are necessary to reach that length.
*/
public fun CharSequence.padEnd(length: Int, padChar: Char = ' '): String {
public fun String.padStart(length: Int, padChar: Char = ' '): String
= (this as CharSequence).padStart(length, padChar).toString()
/**
* Returns a char sequence with content of this char sequence padded at the end
* to the specified [length] with the specified character or space.
*
* @param length the desired string length.
* @param padChar the character to pad string with, if it has length less than the [length] specified. Space is used by default.
* @returns Returns a string, of length at least [length], consisting of string prepended with [padChar] as many times.
* as are necessary to reach that length.
*/
public fun CharSequence.padEnd(length: Int, padChar: Char = ' '): CharSequence {
if (length < 0)
throw IllegalArgumentException("String length $length is less than zero.")
if (length <= this.length())
return this.toString()
throw IllegalArgumentException("Desired length $length is less than zero.")
if (length <= this.length)
return this.subSequence(0, this.length)
val sb = StringBuilder(length)
sb.append(this)
for (i in 1..(length - this.length()))
for (i in 1..(length - this.length))
sb.append(padChar)
return sb.toString()
return sb
}
/**
* Pads the string to the specified [length] at the end with the specified character or space.
*
* @param length the desired string length.
* @param padChar the character to pad string with, if it has length less than the [length] specified. Space is used by default.
* @returns Returns a string, of length at least [length], consisting of string prepended with [padChar] as many times.
* as are necessary to reach that length.
*/
public fun String.padEnd(length: Int, padChar: Char = ' '): String
= (this as CharSequence).padEnd(length, padChar).toString()
/**
* Returns `true` if this nullable char sequence is either `null` or empty.
*/
@@ -204,24 +276,6 @@ public fun CharSequence.hasSurrogatePairAt(index: Int): Boolean {
&& this[index + 1].isLowSurrogate()
}
/**
* Returns a subsequence obtained by taking the characters at the given [indices] in this sequence.
*/
public fun CharSequence.slice(indices: Iterable<Int>): CharSequence {
val sb = StringBuilder()
for (i in indices) {
sb.append(get(i))
}
return sb.toString()
}
/**
* Returns a subsequence of this sequence specified by given [range].
*/
public fun CharSequence.slice(range: IntRange): CharSequence {
return subSequence(range.start, range.end + 1) // inclusive
}
/**
* Returns a substring specified by the given [range].
*/
@@ -345,97 +399,172 @@ public fun String.substringAfterLast(delimiter: String, missingDelimiterValue: S
}
/**
* Returns a string with content of this char sequence where its part at the given range
* Returns a char sequence with content of this char sequence where its part at the given range
* is replaced with the [replacement] char sequence.
* @param firstIndex the index of the first character to be replaced.
* @param lastIndex the index of the first character after the replacement to keep in the string.
*/
public fun CharSequence.replaceRange(firstIndex: Int, lastIndex: Int, replacement: CharSequence): String {
public fun CharSequence.replaceRange(firstIndex: Int, lastIndex: Int, replacement: CharSequence): CharSequence {
if (lastIndex < firstIndex)
throw IndexOutOfBoundsException("Last index ($lastIndex) is less than first index ($firstIndex)")
val sb = StringBuilder()
sb.append(this, 0, firstIndex)
sb.append(replacement)
sb.append(this, lastIndex, length())
return sb.toString()
return sb
}
/**
* Returns a string with content of this char sequence where its part at the given [range]
* Replaces the part of the string at the given range with the [replacement] char sequence.
* @param firstIndex the index of the first character to be replaced.
* @param lastIndex the index of the first character after the replacement to keep in the string.
*/
public fun String.replaceRange(firstIndex: Int, lastIndex: Int, replacement: CharSequence): String
= (this as CharSequence).replaceRange(firstIndex, lastIndex, replacement).toString()
/**
* Returns a char sequence with content of this char sequence where its part at the given [range]
* is replaced with the [replacement] char sequence.
*
* The end index of the [range] is included in the part to be replaced.
*/
public fun CharSequence.replaceRange(range: IntRange, replacement: CharSequence): String = replaceRange(range.start, range.end + 1, replacement)
public fun CharSequence.replaceRange(range: IntRange, replacement: CharSequence): CharSequence
= replaceRange(range.start, range.end + 1, replacement)
/**
* Returns a string with content of this char sequence where its part at the given range is removed.
* Replace the part of string at the given [range] with the [replacement] string.
*
* The end index of the [range] is included in the part to be replaced.
*/
public fun String.replaceRange(range: IntRange, replacement: CharSequence): String
= replaceRange(range.start, range.end + 1, replacement)
/**
* Returns a char sequence with content of this char sequence where its part at the given range is removed.
*
* @param firstIndex the index of the first character to be removed.
* @param lastIndex the index of the first character after the removed part to keep in the string.
*
* [lastIndex] is not included in the removed part.
*/
public fun CharSequence.removeRange(firstIndex: Int, lastIndex: Int): String {
public fun CharSequence.removeRange(firstIndex: Int, lastIndex: Int): CharSequence {
if (lastIndex < firstIndex)
throw IndexOutOfBoundsException("Last index ($lastIndex) is less than first index ($firstIndex)")
if (lastIndex == firstIndex)
return this.toString()
return this.subSequence(0, length)
val sb = StringBuilder(length() - (lastIndex - firstIndex))
sb.append(this, 0, firstIndex)
sb.append(this, lastIndex, length())
return sb.toString()
return sb
}
/**
* Returns a string with content of this char sequence where its part at the given [range] is removed.
* Removes the part of a string at a given range.
* @param firstIndex the index of the first character to be removed.
* @param lastIndex the index of the first character after the removed part to keep in the string.
*
* [lastIndex] is not included in the removed part.
*/
public fun String.removeRange(firstIndex: Int, lastIndex: Int): String
= (this as CharSequence).removeRange(firstIndex, lastIndex).toString()
/**
* Returns a char sequence with content of this char sequence where its part at the given [range] is removed.
*
* The end index of the [range] is included in the removed part.
*/
public fun CharSequence.removeRange(range: Range<Int>): String = removeRange(range.start, range.end + 1)
public fun CharSequence.removeRange(range: IntRange): CharSequence = removeRange(range.start, range.end + 1)
/**
* Removes the part of a string at the given [range].
*
* The end index of the [range] is included in the removed part.
*/
public fun String.removeRange(range: IntRange): String = removeRange(range.start, range.end + 1)
/**
* If this char sequence starts with the given [prefix], returns a new char sequence
* with the prefix removed. Otherwise, returns a new char sequence with the same characters.
*/
public fun CharSequence.removePrefix(prefix: CharSequence): CharSequence {
if (startsWith(prefix)) {
return subSequence(prefix.length, length)
}
return subSequence(0, length)
}
/**
* If this string starts with the given [prefix], returns a copy of this string
* with the prefix removed. Otherwise, returns this string.
*/
public fun String.removePrefix(prefix: String): String {
public fun String.removePrefix(prefix: CharSequence): String {
if (startsWith(prefix)) {
return substring(prefix.length())
return substring(prefix.length)
}
return this
}
/**
* If this char sequence ends with the given [suffix], returns a new char sequence
* with the suffix removed. Otherwise, returns a new char sequence with the same characters.
*/
public fun CharSequence.removeSuffix(suffix: CharSequence): CharSequence {
if (endsWith(suffix)) {
return subSequence(0, length - suffix.length)
}
return subSequence(0, length)
}
/**
* If this string ends with the given [suffix], returns a copy of this string
* with the suffix removed. Otherwise, returns this string.
*/
public fun String.removeSuffix(suffix: String): String {
public fun String.removeSuffix(suffix: CharSequence): String {
if (endsWith(suffix)) {
return substring(0, length() - suffix.length())
return substring(0, length - suffix.length)
}
return this
}
/**
* When this char sequence starts with the given [prefix] and ends with the given [suffix],
* returns a new char sequence having both the given [prefix] and [suffix] removed.
* Otherwise returns a new char sequence with the same characters.
*/
public fun CharSequence.removeSurrounding(prefix: CharSequence, suffix: CharSequence): CharSequence {
if (startsWith(prefix) && endsWith(suffix)) {
return subSequence(prefix.length, length - suffix.length)
}
return subSequence(0, length)
}
/**
* Removes from a string both the given [prefix] and [suffix] if and only if
* it starts with the [prefix] and ends with the [suffix].
* Otherwise returns this string unchanged.
*/
public fun String.removeSurrounding(prefix: String, suffix: String): String {
public fun String.removeSurrounding(prefix: CharSequence, suffix: CharSequence): String {
if (startsWith(prefix) && endsWith(suffix)) {
return substring(prefix.length(), length() - suffix.length())
return substring(prefix.length, length - suffix.length)
}
return this
}
/**
* When this char sequence starts with and ends with the given [delimiter],
* returns a new char sequence having this [delimiter] removed both from the start and end.
* Otherwise returns a new char sequence with the same characters.
*/
public fun CharSequence.removeSurrounding(delimiter: CharSequence): CharSequence = removeSurrounding(delimiter, delimiter)
/**
* Removes the given [delimiter] string from both the start and the end of this string
* if and only if it starts with and ends with the [delimiter].
* Otherwise returns this string unchanged.
*/
public fun String.removeSurrounding(delimiter: String): String = removeSurrounding(delimiter, delimiter)
public fun String.removeSurrounding(delimiter: CharSequence): String = removeSurrounding(delimiter, delimiter)
/**
* Replace part of string before the first occurrence of given delimiter with the [replacement] string.
@@ -8,140 +8,6 @@ import java.util.NoSuchElementException
import kotlin.text.MatchResult
import kotlin.text.Regex
/**
* Returns the string with leading and trailing characters matching the [predicate] trimmed.
*/
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
inline public fun String.trim(predicate: (Char) -> Boolean): String {
var startIndex = 0
var endIndex = length() - 1
var startFound = false
while (startIndex <= endIndex) {
val index = if (!startFound) startIndex else endIndex
val match = predicate(this[index])
if (!startFound) {
if (!match)
startFound = true
else
startIndex += 1
}
else {
if (!match)
break
else
endIndex -= 1
}
}
return substring(startIndex, endIndex + 1)
}
/**
* Returns the string with leading characters matching the [predicate] trimmed.
*/
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
inline public fun String.trimStart(predicate: (Char) -> Boolean): String {
for (index in this.indices)
if (!predicate(this[index]))
return substring(index)
return ""
}
/**
* Returns the string with trailing characters matching the [predicate] trimmed.
*/
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
inline public fun String.trimEnd(predicate: (Char) -> Boolean): String {
for (index in this.indices.reversed())
if (!predicate(this[index]))
return substring(0, index + 1)
return ""
}
/**
* Returns the string with leading and trailing characters in the [chars] array trimmed.
*/
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
public fun String.trim(vararg chars: Char): String = trim { it in chars }
/**
* Returns the string with leading and trailing characters in the [chars] array trimmed.
*/
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
public fun String.trimStart(vararg chars: Char): String = trimStart { it in chars }
/**
* Returns the string with trailing characters in the [chars] array trimmed.
*/
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
public fun String.trimEnd(vararg chars: Char): String = trimEnd { it in chars }
/**
* Returns a string with leading and trailing whitespace trimmed.
*/
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
public fun String.trim(): String = trim { it.isWhitespace() }
/**
* Returns a string with leading whitespace removed.
*/
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
public fun String.trimStart(): String = trimStart { it.isWhitespace() }
/**
* Returns a string with trailing whitespace removed.
*/
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
public fun String.trimEnd(): String = trimEnd { it.isWhitespace() }
/**
* Left pad a String with a specified character or space.
*
* @param length the desired string length.
* @param padChar the character to pad string with, if it has length less than the [length] specified. Space is used by default.
* @returns Returns a string, of length at least [length], consisting of string prepended with [padChar] as many times.
* as are necessary to reach that length.
*/
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
public fun String.padStart(length: Int, padChar: Char = ' '): String {
if (length < 0)
throw IllegalArgumentException("String length $length is less than zero.")
if (length <= this.length())
return this
val sb = StringBuilder(length)
for (i in 1..(length - this.length()))
sb.append(padChar)
sb.append(this)
return sb.toString()
}
/**
* Right pad a String with a specified character or space.
*
* @param length the desired string length.
* @param padChar the character to pad string with, if it has length less than the [length] specified. Space is used by default.
* @returns Returns a string, of length at least [length], consisting of string prepended with [padChar] as many times.
* as are necessary to reach that length.
*/
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
public fun String.padEnd(length: Int, padChar: Char = ' '): String {
if (length < 0)
throw IllegalArgumentException("String length $length is less than zero.")
if (length <= this.length())
return this
val sb = StringBuilder(length)
sb.append(this)
for (i in 1..(length - this.length()))
sb.append(padChar)
return sb.toString()
}
/** Returns `true` if the string is not `null` and not empty */
@Deprecated("Use !isNullOrEmpty() or isNullOrEmpty().not() for nullable strings.", ReplaceWith("this != null && this.isNotEmpty()"), DeprecationLevel.ERROR)
@kotlin.jvm.JvmName("isNotEmptyNullable")
@@ -273,69 +139,7 @@ public fun String.substringAfterLast(delimiter: String, missingDelimiterValue: S
val index = lastIndexOf(delimiter)
return if (index == -1) missingDelimiterValue else substring(index + delimiter.length(), length())
}
*/
/**
* Replaces the part of the string at the given range with the [replacement] string.
* @param firstIndex the index of the first character to be replaced.
* @param lastIndex the index of the first character after the replacement to keep in the string.
*/
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
public fun String.replaceRange(firstIndex: Int, lastIndex: Int, replacement: String): String {
if (lastIndex < firstIndex)
throw IndexOutOfBoundsException("Last index ($lastIndex) is less than first index ($firstIndex)")
val sb = StringBuilder()
sb.append(this, 0, firstIndex)
sb.append(replacement)
sb.append(this, lastIndex, length())
return sb.toString()
}
/**
* Replace the part of string at the given [range] with the [replacement] string.
*
* The end index of the [range] is included in the part to be replaced.
*/
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
public fun String.replaceRange(range: IntRange, replacement: String): String = replaceRange(range.start, range.end + 1, replacement)
/**
* Removes the part of a string at a given range.
* @param firstIndex the index of the first character to be removed.
* @param lastIndex the index of the first character after the removed part to keep in the string.
*
* [lastIndex] is not included in the removed part.
*/
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
public fun String.removeRange(firstIndex: Int, lastIndex: Int): String {
if (lastIndex < firstIndex)
throw IndexOutOfBoundsException("Last index ($lastIndex) is less than first index ($firstIndex)")
if (lastIndex == firstIndex)
return this
val sb = StringBuilder(length() - (lastIndex - firstIndex))
sb.append(this, 0, firstIndex)
sb.append(this, lastIndex, length())
return sb.toString()
}
/**
* Removes the part of a string at the given [range].
*
* The end index of the [range] is included in the removed part.
*/
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
public fun String.removeRange(range: IntRange): String = removeRange(range.start, range.end + 1)
/*
/**
* Removes the given [delimiter] string from both the start and the end of this string
* if and only if it starts with and ends with the [delimiter].
* Otherwise returns this string unchanged.
*/
public fun String.removeSurrounding(delimiter: String): String = removeSurrounding(delimiter, delimiter)
/**
* Replace part of string before the first occurrence of given delimiter with the [replacement] string.
@@ -410,6 +214,30 @@ public fun String.replaceBeforeLast(delimiter: String, replacement: String, miss
}
*/
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
public fun String.replaceRange(firstIndex: Int, lastIndex: Int, replacement: String): String
= replaceRange(firstIndex, lastIndex, replacement)
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
public fun String.replaceRange(range: IntRange, replacement: String): String
= replaceRange(range.start, range.end + 1, replacement)
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
public fun String.removePrefix(prefix: String): String = removePrefix(prefix)
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
public fun String.removeSuffix(suffix: String): String = removeSuffix(suffix)
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
public fun String.removeSurrounding(prefix: String, suffix: String): String = removeSurrounding(prefix, suffix)
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
public fun String.removeSurrounding(delimiter: String): String = removeSurrounding(delimiter, delimiter)
/**
* Returns a new string obtained by replacing each substring of this string that matches the given regular expression
* with the given [replacement].
+105 -74
View File
@@ -25,8 +25,8 @@ fun withTwoCharSequenceArgs(f: ((String) -> CharSequence, (String) -> CharSequen
f(arg1Builder, arg2Builder)
}
fun assertContentEquals(expected: String, actual: CharSequence) {
assertEquals(expected, actual.toString())
fun assertContentEquals(expected: String, actual: CharSequence, message: String? = null) {
assertEquals(expected, actual.toString(), message)
}
// helper predicates available on both platforms
@@ -236,8 +236,8 @@ class StringTest {
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))
assertContentEquals("sa??e text", s.replaceRange(2, 5, replacement))
assertContentEquals("sa?? text", s.replaceRange(2..5, replacement))
assertFails {
s.replaceRange(5..2, replacement)
}
@@ -246,21 +246,21 @@ class StringTest {
}
// symmetry with indices
assertEquals(replacement.toString(), s.replaceRange(s.indices, replacement))
assertContentEquals(replacement.toString(), s.replaceRange(s.indices, replacement))
}
@test fun removeRange() = withOneCharSequenceArg("sample text") { s ->
assertEquals("sae text", s.removeRange(2, 5))
assertEquals("sa text", s.removeRange(2..5))
assertContentEquals("sae text", s.removeRange(2, 5))
assertContentEquals("sa text", s.removeRange(2..5))
assertEquals(s.toString(), s.removeRange(2,2))
assertContentEquals(s.toString(), s.removeRange(2,2))
// symmetry with indices
assertEquals("", s.removeRange(s.indices))
assertContentEquals("", s.removeRange(s.indices))
// symmetry with replaceRange
assertEquals(s.replaceRange(2, 5, ""), s.removeRange(2, 5))
assertEquals(s.replaceRange(2..5, ""), s.removeRange(2..5))
assertContentEquals(s.toString().replaceRange(2, 5, ""), s.removeRange(2, 5))
assertContentEquals(s.toString().replaceRange(2..5, ""), s.removeRange(2..5))
}
@test fun substringDelimited() {
@@ -318,43 +318,43 @@ class StringTest {
}
@test fun trimStart() = withOneCharSequenceArg { arg1 ->
fun String.trimStart(): String = arg1(this).trimStart()
assertEquals("", "".trimStart())
assertEquals("a", "a".trimStart())
assertEquals("a", " a".trimStart())
assertEquals("a", " a".trimStart())
assertEquals("a ", " a ".trimStart())
assertEquals("a b", " a b".trimStart())
assertEquals("a b ", " a b ".trimStart())
assertEquals("a", " \u00A0 a".trimStart())
fun String.trimStartCS(): CharSequence = arg1(this).trimStart()
assertContentEquals("", "".trimStartCS())
assertContentEquals("a", "a".trimStartCS())
assertContentEquals("a", " a".trimStartCS())
assertContentEquals("a", " a".trimStartCS())
assertContentEquals("a ", " a ".trimStartCS())
assertContentEquals("a b", " a b".trimStartCS())
assertContentEquals("a b ", " a b ".trimStartCS())
assertContentEquals("a", " \u00A0 a".trimStartCS())
assertEquals("a", "\ta".trimStart())
assertEquals("a", "\t\ta".trimStart())
assertEquals("a", "\ra".trimStart())
assertEquals("a", "\na".trimStart())
assertContentEquals("a", "\ta".trimStartCS())
assertContentEquals("a", "\t\ta".trimStartCS())
assertContentEquals("a", "\ra".trimStartCS())
assertContentEquals("a", "\na".trimStartCS())
assertEquals("a=", arg1("-=-=a=").trimStart('-','='))
assertEquals("123a", arg1("ab123a").trimStart { it < '0' || it > '9' }) // TODO: Use !it.isDigit when available in JS
assertContentEquals("a=", arg1("-=-=a=").trimStart('-','='))
assertContentEquals("123a", arg1("ab123a").trimStart { !it.isAsciiDigit() })
}
@test fun trimEnd() = withOneCharSequenceArg { arg1 ->
fun String.trimEnd(): String = arg1(this).trimEnd()
assertEquals("", "".trimEnd())
assertEquals("a", "a".trimEnd())
assertEquals("a", "a ".trimEnd())
assertEquals("a", "a ".trimEnd())
assertEquals(" a", " a ".trimEnd())
assertEquals("a b", "a b ".trimEnd())
assertEquals(" a b", " a b ".trimEnd())
assertEquals("a", "a \u00A0 ".trimEnd())
fun String.trimEndCS(): CharSequence = arg1(this).trimEnd()
assertContentEquals("", "".trimEndCS())
assertContentEquals("a", "a".trimEndCS())
assertContentEquals("a", "a ".trimEndCS())
assertContentEquals("a", "a ".trimEndCS())
assertContentEquals(" a", " a ".trimEndCS())
assertContentEquals("a b", "a b ".trimEndCS())
assertContentEquals(" a b", " a b ".trimEndCS())
assertContentEquals("a", "a \u00A0 ".trimEndCS())
assertEquals("a", "a\t".trimEnd())
assertEquals("a", "a\t\t".trimEnd())
assertEquals("a", "a\r".trimEnd())
assertEquals("a", "a\n".trimEnd())
assertContentEquals("a", "a\t".trimEndCS())
assertContentEquals("a", "a\t\t".trimEndCS())
assertContentEquals("a", "a\r".trimEndCS())
assertContentEquals("a", "a\n".trimEndCS())
assertEquals("=a", arg1("=a=-=-").trimEnd('-','='))
assertEquals("ab123", arg1("ab123a").trimEnd { it < '0' || it > '9' }) // TODO: Use !it.isDigit when available in JS
assertContentEquals("=a", arg1("=a=-=-").trimEnd('-','='))
assertContentEquals("ab123", arg1("ab123a").trimEnd { !it.isAsciiDigit() })
}
@test fun trimStartAndEnd() = withOneCharSequenceArg { arg1 ->
@@ -369,9 +369,9 @@ class StringTest {
" \u00A0 a \u00A0 "
)
for (example in examples.map { arg1(it) }) {
assertEquals(example.trim(), example.trimEnd().trimStart())
assertEquals(example.trim(), example.trimStart().trimEnd())
for ((source, example) in examples.map { it to arg1(it) }) {
assertContentEquals(source.trimEnd().trimStart(), example.trim())
assertContentEquals(source.trimStart().trimEnd(), example.trim())
}
val examplesForPredicate = arrayOf("123",
@@ -379,57 +379,88 @@ 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.map { arg1(it) }) {
assertEquals(example.trimStart(*trimChars).trimEnd(*trimChars), example.trim(*trimChars))
assertEquals(example.trimStart(trimPredicate).trimEnd(trimPredicate), example.trim(trimPredicate))
val trimPredicate = { it: Char -> !it.isAsciiDigit() }
for ((source, example) in examplesForPredicate.map { it to arg1(it) }) {
assertContentEquals(source.trimStart(*trimChars).trimEnd(*trimChars), example.trim(*trimChars))
assertContentEquals(source.trimStart(trimPredicate).trimEnd(trimPredicate), example.trim(trimPredicate))
}
}
@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", arg1("s").padStart(3, '-'))
val s = arg1("s")
assertContentEquals("s", s.padStart(0))
assertContentEquals("s", s.padStart(1))
assertContentEquals("--s", s.padStart(3, '-'))
assertContentEquals(" ", arg1("").padStart(2))
assertFails {
"s".padStart(-1)
s.padStart(-1)
}
}
@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--", arg1("s").padEnd(3, '-'))
val s = arg1("s")
assertContentEquals("s", s.padEnd(0))
assertContentEquals("s", s.padEnd(1))
assertContentEquals("s--", s.padEnd(3, '-'))
assertContentEquals(" ", arg1("").padEnd(2))
assertFails {
"s".padEnd(-1)
s.padEnd(-1)
}
}
@test fun removePrefix() {
assertEquals("fix", "prefix".removePrefix("pre"), "Removes prefix")
assertEquals("prefix", "preprefix".removePrefix("pre"), "Removes prefix once")
assertEquals("sample", "sample".removePrefix("value"))
@test fun removePrefix() = withOneCharSequenceArg("pre") { prefix ->
assertEquals("fix", "prefix".removePrefix(prefix), "Removes prefix")
assertEquals("prefix", "preprefix".removePrefix(prefix), "Removes prefix once")
assertEquals("sample", "sample".removePrefix(prefix))
assertEquals("sample", "sample".removePrefix(""))
}
@test fun removeSuffix() {
assertEquals("suf", "suffix".removeSuffix("fix"), "Removes suffix")
assertEquals("suffix", "suffixfix".removeSuffix("fix"), "Removes suffix once")
assertEquals("sample", "sample".removeSuffix("value"))
@test fun removeSuffix() = withOneCharSequenceArg("fix") { suffix ->
assertEquals("suf", "suffix".removeSuffix(suffix), "Removes suffix")
assertEquals("suffix", "suffixfix".removeSuffix(suffix), "Removes suffix once")
assertEquals("sample", "sample".removeSuffix(suffix))
assertEquals("sample", "sample".removeSuffix(""))
}
@test fun removeSurrounding() {
assertEquals("value", "<value>".removeSurrounding("<", ">"))
assertEquals("<value>", "<<value>>".removeSurrounding("<", ">"), "Removes surrounding once")
assertEquals("<value", "<value".removeSurrounding("<", ">"), "Only removes surrounding when both prefix and suffix present")
assertEquals("value>", "value>".removeSurrounding("<", ">"), "Only removes surrounding when both prefix and suffix present")
assertEquals("value", "value".removeSurrounding("<", ">"))
@test fun removeSurrounding() = withOneCharSequenceArg { arg1 ->
val pre = arg1("<")
val post = arg1(">")
assertEquals("value", "<value>".removeSurrounding(pre, post))
assertEquals("<value>", "<<value>>".removeSurrounding(pre, post), "Removes surrounding once")
assertEquals("<value", "<value".removeSurrounding(pre, post), "Only removes surrounding when both prefix and suffix present")
assertEquals("value>", "value>".removeSurrounding(pre, post), "Only removes surrounding when both prefix and suffix present")
assertEquals("value", "value".removeSurrounding(pre, post))
}
@test fun removePrefixCharSequence() = withTwoCharSequenceArgs { arg1, arg2 ->
fun String.removePrefix(prefix: String) = arg1(this).removePrefix(arg2(prefix))
val prefix = "pre"
assertContentEquals("fix", "prefix".removePrefix(prefix), "Removes prefix")
assertContentEquals("prefix", "preprefix".removePrefix(prefix), "Removes prefix once")
assertContentEquals("sample", "sample".removePrefix(prefix))
assertContentEquals("sample", "sample".removePrefix(""))
}
@test fun removeSuffixCharSequence() = withTwoCharSequenceArgs { arg1, arg2 ->
fun String.removeSuffix(suffix: String) = arg1(this).removeSuffix(arg2(suffix))
val suffix = "fix"
assertContentEquals("suf", "suffix".removeSuffix(suffix), "Removes suffix")
assertContentEquals("suffix", "suffixfix".removeSuffix(suffix), "Removes suffix once")
assertContentEquals("sample", "sample".removeSuffix(suffix))
assertContentEquals("sample", "sample".removeSuffix(""))
}
@test fun removeSurroundingCharSequence() = withTwoCharSequenceArgs { arg1, arg2 ->
fun String.removeSurrounding(prefix: String, postfix: String) = arg1(this).removeSurrounding(arg2(prefix), arg2(postfix))
assertContentEquals("value", "<value>".removeSurrounding("<", ">"))
assertContentEquals("<value>", "<<value>>".removeSurrounding("<", ">"), "Removes surrounding once")
assertContentEquals("<value", "<value".removeSurrounding("<", ">"), "Only removes surrounding when both prefix and suffix present")
assertContentEquals("value>", "value>".removeSurrounding("<", ">"), "Only removes surrounding when both prefix and suffix present")
assertContentEquals("value", "value".removeSurrounding("<", ">"))
}
/*
// unit test commented out until rangesDelimitiedBy would become public