contentEquals, contentHashCode, contentToString: Add js implementation and tests

#KT-13582
This commit is contained in:
Ilya Gorbunov
2016-09-23 16:01:18 +03:00
parent a868eecb1a
commit f3da656d6e
4 changed files with 423 additions and 9 deletions
@@ -552,6 +552,264 @@ public inline operator fun CharArray.plus(elements: CharArray): CharArray {
return this.asDynamic().concat(elements)
}
/**
* Returns `true` if the two specified arrays are *structurally* equal to one another,
* i.e. contain the same number of the same elements in the same order.
*/
@library("arrayEquals")
public infix fun <T> Array<out T>.contentEquals(other: Array<out T>): Boolean {
return noImpl
}
/**
* Returns `true` if the two specified arrays are *structurally* equal to one another,
* i.e. contain the same number of the same elements in the same order.
*/
@library("arrayEquals")
public infix fun ByteArray.contentEquals(other: ByteArray): Boolean {
return noImpl
}
/**
* Returns `true` if the two specified arrays are *structurally* equal to one another,
* i.e. contain the same number of the same elements in the same order.
*/
@library("arrayEquals")
public infix fun ShortArray.contentEquals(other: ShortArray): Boolean {
return noImpl
}
/**
* Returns `true` if the two specified arrays are *structurally* equal to one another,
* i.e. contain the same number of the same elements in the same order.
*/
@library("arrayEquals")
public infix fun IntArray.contentEquals(other: IntArray): Boolean {
return noImpl
}
/**
* Returns `true` if the two specified arrays are *structurally* equal to one another,
* i.e. contain the same number of the same elements in the same order.
*/
@library("arrayEquals")
public infix fun LongArray.contentEquals(other: LongArray): Boolean {
return noImpl
}
/**
* Returns `true` if the two specified arrays are *structurally* equal to one another,
* i.e. contain the same number of the same elements in the same order.
*/
@library("arrayEquals")
public infix fun FloatArray.contentEquals(other: FloatArray): Boolean {
return noImpl
}
/**
* Returns `true` if the two specified arrays are *structurally* equal to one another,
* i.e. contain the same number of the same elements in the same order.
*/
@library("arrayEquals")
public infix fun DoubleArray.contentEquals(other: DoubleArray): Boolean {
return noImpl
}
/**
* Returns `true` if the two specified arrays are *structurally* equal to one another,
* i.e. contain the same number of the same elements in the same order.
*/
@library("arrayEquals")
public infix fun BooleanArray.contentEquals(other: BooleanArray): Boolean {
return noImpl
}
/**
* Returns `true` if the two specified arrays are *structurally* equal to one another,
* i.e. contain the same number of the same elements in the same order.
*/
@library("arrayEquals")
public infix fun CharArray.contentEquals(other: CharArray): Boolean {
return noImpl
}
/**
* Returns `true` if the two specified arrays are *deeply* equal to one another,
* i.e. contain the same number of the same elements in the same order.
*
* If two corresponding elements are nested arrays, they are also compared deeply.
* If any of arrays contains itself on any nesting level the behavior is undefined.
*/
@library("arrayDeepEquals")
public infix fun <T> Array<out T>.contentDeepEquals(other: Array<out T>): Boolean {
return noImpl
}
/**
* Returns a string representation of the contents of the specified array as if it is [List].
*/
@library("arrayToString")
public fun <T> Array<out T>.contentToString(): String {
return noImpl
}
/**
* Returns a string representation of the contents of the specified array as if it is [List].
*/
@library("arrayToString")
public fun ByteArray.contentToString(): String {
return noImpl
}
/**
* Returns a string representation of the contents of the specified array as if it is [List].
*/
@library("arrayToString")
public fun ShortArray.contentToString(): String {
return noImpl
}
/**
* Returns a string representation of the contents of the specified array as if it is [List].
*/
@library("arrayToString")
public fun IntArray.contentToString(): String {
return noImpl
}
/**
* Returns a string representation of the contents of the specified array as if it is [List].
*/
@library("arrayToString")
public fun LongArray.contentToString(): String {
return noImpl
}
/**
* Returns a string representation of the contents of the specified array as if it is [List].
*/
@library("arrayToString")
public fun FloatArray.contentToString(): String {
return noImpl
}
/**
* Returns a string representation of the contents of the specified array as if it is [List].
*/
@library("arrayToString")
public fun DoubleArray.contentToString(): String {
return noImpl
}
/**
* Returns a string representation of the contents of the specified array as if it is [List].
*/
@library("arrayToString")
public fun BooleanArray.contentToString(): String {
return noImpl
}
/**
* Returns a string representation of the contents of the specified array as if it is [List].
*/
@library("arrayToString")
public fun CharArray.contentToString(): String {
return noImpl
}
/**
* Returns a string representation of the contents of this array as if it is [List].
*
* Nested arrays are treated as lists too.
*/
@library("arrayToString")
public fun <T> Array<out T>.contentDeepToString(): String {
return noImpl
}
/**
* Returns a hash code based on the contents of this array as if it is [List].
*/
@library("arrayHashCode")
public fun <T> Array<out T>.contentHashCode(): Int {
return noImpl
}
/**
* Returns a hash code based on the contents of this array as if it is [List].
*/
@library("arrayHashCode")
public fun ByteArray.contentHashCode(): Int {
return noImpl
}
/**
* Returns a hash code based on the contents of this array as if it is [List].
*/
@library("arrayHashCode")
public fun ShortArray.contentHashCode(): Int {
return noImpl
}
/**
* Returns a hash code based on the contents of this array as if it is [List].
*/
@library("arrayHashCode")
public fun IntArray.contentHashCode(): Int {
return noImpl
}
/**
* Returns a hash code based on the contents of this array as if it is [List].
*/
@library("arrayHashCode")
public fun LongArray.contentHashCode(): Int {
return noImpl
}
/**
* Returns a hash code based on the contents of this array as if it is [List].
*/
@library("arrayHashCode")
public fun FloatArray.contentHashCode(): Int {
return noImpl
}
/**
* Returns a hash code based on the contents of this array as if it is [List].
*/
@library("arrayHashCode")
public fun DoubleArray.contentHashCode(): Int {
return noImpl
}
/**
* Returns a hash code based on the contents of this array as if it is [List].
*/
@library("arrayHashCode")
public fun BooleanArray.contentHashCode(): Int {
return noImpl
}
/**
* Returns a hash code based on the contents of this array as if it is [List].
*/
@library("arrayHashCode")
public fun CharArray.contentHashCode(): Int {
return noImpl
}
/**
* 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.
*/
@library("arrayDeepHashCode")
public fun <T> Array<out T>.contentDeepHashCode(): Int {
return noImpl
}
/**
* Sorts the array in-place according to the order specified by the given [comparison] function.
*/
+38
View File
@@ -366,6 +366,44 @@
return true;
};
Kotlin.arrayDeepEquals = function (a, b) {
if (a === b) {
return true;
}
if (!Array.isArray(b) || a.length !== b.length) {
return false;
}
for (var i = 0, n = a.length; i < n; i++) {
if (Array.isArray(a[i])) {
if (!Kotlin.arrayDeepEquals(a[i], b[i])) {
return false;
}
} else if (!Kotlin.equals(a[i], b[i])) {
return false;
}
}
return true;
};
Kotlin.arrayHashCode = function (arr) {
var result = 1;
for (var i = 0, n = arr.length; i < n; i++) {
result = ((31 * result | 0) + Kotlin.hashCode(arr[i])) | 0;
}
return result;
};
Kotlin.arrayDeepHashCode = function (arr) {
var result = 1;
for (var i = 0, n = arr.length; i < n; i++) {
var e = arr[i];
result = ((31 * result | 0) + (Array.isArray(e) ? Kotlin.arrayDeepHashCode(e) : Kotlin.hashCode(arr[i]))) | 0;
}
return result;
};
var BaseOutput = Kotlin.createClassNow(null, null, {
println: function (a) {
if (typeof a !== "undefined") this.print(a);
@@ -23,15 +23,15 @@ 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, message); assertEquals(expected.toList(), actual.toList(), message) }
fun assertArrayNotSameButEquals(expected: IntArray, actual: IntArray, message: String = "") { assertTrue(expected !== actual, message); assertEquals(expected.toList(), actual.toList(), message) }
fun assertArrayNotSameButEquals(expected: LongArray, actual: LongArray, message: String = "") { assertTrue(expected !== actual, message); assertEquals(expected.toList(), actual.toList(), message) }
fun assertArrayNotSameButEquals(expected: ShortArray, actual: ShortArray, message: String = "") { assertTrue(expected !== actual, message); assertEquals(expected.toList(), actual.toList(), message) }
fun assertArrayNotSameButEquals(expected: ByteArray, actual: ByteArray, message: String = "") { assertTrue(expected !== actual, message); assertEquals(expected.toList(), actual.toList(), message) }
fun assertArrayNotSameButEquals(expected: DoubleArray, actual: DoubleArray, message: String = "") { assertTrue(expected !== actual, message); assertEquals(expected.toList(), actual.toList(), message) }
fun assertArrayNotSameButEquals(expected: FloatArray, actual: FloatArray, message: String = "") { assertTrue(expected !== actual, message); assertEquals(expected.toList(), actual.toList(), message) }
fun assertArrayNotSameButEquals(expected: CharArray, actual: CharArray, message: String = "") { assertTrue(expected !== actual, message); assertEquals(expected.toList(), actual.toList(), message) }
fun assertArrayNotSameButEquals(expected: BooleanArray, actual: BooleanArray, message: String = "") { assertTrue(expected !== actual, message); assertEquals(expected.toList(), actual.toList(), 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 {
@@ -203,6 +203,45 @@ class ArraysTest {
assertEquals(false, arr[1])
}
@test fun contentEquals() {
val arr1 = arrayOf("a", 1, null)
val arr2 = arrayOf(*arr1)
assertTrue(arr1 contentEquals arr2)
val arr3 = arr2.reversedArray()
assertFalse(arr1 contentEquals arr3)
}
@test fun contentDeepEquals() {
val arr1 = arrayOf("a", 1, intArrayOf(2))
val arr2 = arrayOf("a", 1, intArrayOf(2))
assertFalse(arr1 contentEquals arr2)
assertTrue(arr1 contentDeepEquals arr2)
arr2[2] = arr1
assertFalse(arr1 contentDeepEquals arr2)
}
@test fun contentToString() {
val arr = arrayOf("a", 1, null)
assertEquals(arr.asList().toString(), arr.contentToString())
}
@test fun contentDeepToString() {
val arr = arrayOf("aa", 1, null, charArrayOf('d'))
assertEquals("[aa, 1, null, [d]]", arr.contentDeepToString())
}
@test fun contentHashCode() {
val arr = arrayOf("a", 1, null)
assertEquals(arr.asList().hashCode(), arr.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())
}
@test fun min() {
expect(null, { arrayOf<Int>().min() })
expect(1, { arrayOf(1).min() })
@@ -165,6 +165,85 @@ fun specialJS(): List<GenericFunction> {
}
}
templates add f("contentEquals(other: SELF)") {
only(ArraysOfObjects, ArraysOfPrimitives)
infix(true)
doc {
"""
Returns `true` if the two specified arrays are *structurally* equal to one another,
i.e. contain the same number of the same elements in the same order.
"""
}
annotations("""@library("arrayEquals")""")
returns("Boolean")
body { "return noImpl" }
}
templates add f("contentDeepEquals(other: SELF)") {
only(ArraysOfObjects)
infix(true)
doc {
"""
Returns `true` if the two specified arrays are *deeply* equal to one another,
i.e. contain the same number of the same elements in the same order.
If two corresponding elements are nested arrays, they are also compared deeply.
If any of arrays contains itself on any nesting level the behavior is undefined.
"""
}
annotations("""@library("arrayDeepEquals")""")
returns("Boolean")
body { "return noImpl" }
}
templates add f("contentToString()") {
only(ArraysOfObjects, ArraysOfPrimitives)
doc { "Returns a string representation of the contents of the specified array as if it is [List]." }
annotations("""@library("arrayToString")""")
returns("String")
body { "return noImpl" }
}
templates add f("contentDeepToString()") {
only(ArraysOfObjects)
doc {
"""
Returns a string representation of the contents of this array as if it is [List].
Nested arrays are treated as lists too.
"""
}
annotations("""@library("arrayToString")""") // arrayToString is already deep
returns("String")
body { "return noImpl" }
}
templates add f("contentHashCode()") {
only(ArraysOfObjects, ArraysOfPrimitives)
doc {
"Returns a hash code based on the contents of this array as if it is [List]."
}
annotations("""@library("arrayHashCode")""")
returns("Int")
body { "return noImpl" }
}
templates add f("contentDeepHashCode()") {
only(ArraysOfObjects)
doc {
"""
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.
"""
}
annotations("""@library("arrayDeepHashCode")""")
returns("Int")
body { "return noImpl" }
}
templates add f("sort(comparison: (T, T) -> Int)") {
only(ArraysOfObjects, ArraysOfPrimitives)
exclude(PrimitiveType.Boolean)