JS: Array.toString is const, Array.contentToString is shallow, Array.contentDeepToString is deep and self-reference aware

#KT-13582
This commit is contained in:
Ilya Gorbunov
2016-09-23 21:21:07 +03:00
parent f3da656d6e
commit dceec89572
6 changed files with 87 additions and 58 deletions
+5 -3
View File
@@ -5163,8 +5163,8 @@ public inline infix fun <T> Array<out T>.contentDeepEquals(other: Array<out T>):
/**
* Returns a hash code based on the contents of this array as if it is [List].
*
* Nested arrays are treated as lists too.
*
* If any of arrays contains itself on any nesting level the behavior is undefined.
*/
@kotlin.jvm.JvmVersion
@@ -5174,9 +5174,11 @@ public inline fun <T> Array<out T>.contentDeepHashCode(): Int {
}
/**
* Returns a string representation of the contents of this array as if it is [List].
*
* Returns a string representation of the contents of this array as if it is a [List].
* Nested arrays are treated as lists too.
*
* If any of arrays contains itself on any nesting level that reference
* is rendered as `"[...]"` to prevent recursion.
*/
@kotlin.jvm.JvmVersion
@kotlin.internal.InlineOnly
+32 -14
View File
@@ -23,19 +23,23 @@ import kotlin.test.*
import org.junit.Test as test
import kotlin.comparisons.*
fun <T> assertArrayNotSameButEquals(expected: Array<out T>, actual: Array<out T>, message: String = "") { assertTrue(expected !== actual && expected contentEquals actual, message); }
fun assertArrayNotSameButEquals(expected: IntArray, actual: IntArray, message: String = "") { assertTrue(expected !== actual && expected contentEquals actual, message); }
fun assertArrayNotSameButEquals(expected: LongArray, actual: LongArray, message: String = "") { assertTrue(expected !== actual && expected contentEquals actual, message); }
fun assertArrayNotSameButEquals(expected: ShortArray, actual: ShortArray, message: String = "") { assertTrue(expected !== actual && expected contentEquals actual, message); }
fun assertArrayNotSameButEquals(expected: ByteArray, actual: ByteArray, message: String = "") { assertTrue(expected !== actual && expected contentEquals actual, message); }
fun assertArrayNotSameButEquals(expected: DoubleArray, actual: DoubleArray, message: String = "") { assertTrue(expected !== actual && expected contentEquals actual, message); }
fun assertArrayNotSameButEquals(expected: FloatArray, actual: FloatArray, message: String = "") { assertTrue(expected !== actual && expected contentEquals actual, message); }
fun assertArrayNotSameButEquals(expected: CharArray, actual: CharArray, message: String = "") { assertTrue(expected !== actual && expected contentEquals actual, message); }
fun assertArrayNotSameButEquals(expected: BooleanArray, actual: BooleanArray, message: String = "") { assertTrue(expected !== actual && expected contentEquals actual, message); }
fun <T> assertArrayNotSameButEquals(expected: Array<out T>, actual: Array<out T>, message: String = "") { assertTrue(expected !== actual && expected contentEquals actual, message) }
fun assertArrayNotSameButEquals(expected: IntArray, actual: IntArray, message: String = "") { assertTrue(expected !== actual && expected contentEquals actual, message) }
fun assertArrayNotSameButEquals(expected: LongArray, actual: LongArray, message: String = "") { assertTrue(expected !== actual && expected contentEquals actual, message) }
fun assertArrayNotSameButEquals(expected: ShortArray, actual: ShortArray, message: String = "") { assertTrue(expected !== actual && expected contentEquals actual, message) }
fun assertArrayNotSameButEquals(expected: ByteArray, actual: ByteArray, message: String = "") { assertTrue(expected !== actual && expected contentEquals actual, message) }
fun assertArrayNotSameButEquals(expected: DoubleArray, actual: DoubleArray, message: String = "") { assertTrue(expected !== actual && expected contentEquals actual, message) }
fun assertArrayNotSameButEquals(expected: FloatArray, actual: FloatArray, message: String = "") { assertTrue(expected !== actual && expected contentEquals actual, message) }
fun assertArrayNotSameButEquals(expected: CharArray, actual: CharArray, message: String = "") { assertTrue(expected !== actual && expected contentEquals actual, message) }
fun assertArrayNotSameButEquals(expected: BooleanArray, actual: BooleanArray, message: String = "") { assertTrue(expected !== actual && expected contentEquals actual, message) }
class ArraysTest {
data class Value(val value: Int) {
override fun hashCode(): Int = value
}
@test fun orEmptyNull() {
val x: Array<String>? = null
val y: Array<out String>? = null
@@ -230,15 +234,29 @@ class ArraysTest {
assertEquals("[aa, 1, null, [d]]", arr.contentDeepToString())
}
@test fun contentDeepToStringNoRecursion() {
// a[b[a, b]]
val b = arrayOfNulls<Any>(2)
val a = arrayOf(b)
b[0] = a
b[1] = b
a.toString()
assertTrue(true, "toString does not cycle")
a.contentToString()
assertTrue(true, "contentToString does not cycle")
val result = a.contentDeepToString()
assertEquals("[[[...], [...]]]", result)
}
@test fun contentHashCode() {
val arr = arrayOf("a", 1, null)
assertEquals(arr.asList().hashCode(), arr.contentHashCode())
val arr = arrayOf("a", 1, null, Value(5))
assertEquals(listOf(*arr).hashCode(), arr.contentHashCode())
assertEquals((1*31 + 2)*31 + 3, arrayOf(Value(2), Value(3)).contentHashCode())
}
@test fun contentDeepHashCode() {
val arr = arrayOf<Any?>("aa", 1, null, charArrayOf('d'))
val list = arr.map { if (it is CharArray) it.asList() else it }
assertEquals(list.hashCode(), arr.contentDeepHashCode())
val arr = arrayOf(null, Value(2), arrayOf(Value(3)))
assertEquals(((1*31 + 0)*31 + 2) * 31 + (1 * 31 + 3), arr.contentDeepHashCode())
}