contentEquals, contentHashCode, contentToString: Add js implementation and tests
#KT-13582
This commit is contained in:
@@ -552,6 +552,264 @@ public inline operator fun CharArray.plus(elements: CharArray): CharArray {
|
|||||||
return this.asDynamic().concat(elements)
|
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.
|
* Sorts the array in-place according to the order specified by the given [comparison] function.
|
||||||
*/
|
*/
|
||||||
|
|||||||
+38
@@ -366,6 +366,44 @@
|
|||||||
return true;
|
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, {
|
var BaseOutput = Kotlin.createClassNow(null, null, {
|
||||||
println: function (a) {
|
println: function (a) {
|
||||||
if (typeof a !== "undefined") this.print(a);
|
if (typeof a !== "undefined") this.print(a);
|
||||||
|
|||||||
@@ -23,15 +23,15 @@ import kotlin.test.*
|
|||||||
import org.junit.Test as test
|
import org.junit.Test as test
|
||||||
import kotlin.comparisons.*
|
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 <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, message); assertEquals(expected.toList(), actual.toList(), 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, message); assertEquals(expected.toList(), actual.toList(), 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, message); assertEquals(expected.toList(), actual.toList(), 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, message); assertEquals(expected.toList(), actual.toList(), 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, message); assertEquals(expected.toList(), actual.toList(), 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, message); assertEquals(expected.toList(), actual.toList(), 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, message); assertEquals(expected.toList(), actual.toList(), 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, message); assertEquals(expected.toList(), actual.toList(), message) }
|
fun assertArrayNotSameButEquals(expected: BooleanArray, actual: BooleanArray, message: String = "") { assertTrue(expected !== actual && expected contentEquals actual, message); }
|
||||||
|
|
||||||
|
|
||||||
class ArraysTest {
|
class ArraysTest {
|
||||||
@@ -203,6 +203,45 @@ class ArraysTest {
|
|||||||
assertEquals(false, arr[1])
|
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() {
|
@test fun min() {
|
||||||
expect(null, { arrayOf<Int>().min() })
|
expect(null, { arrayOf<Int>().min() })
|
||||||
expect(1, { arrayOf(1).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)") {
|
templates add f("sort(comparison: (T, T) -> Int)") {
|
||||||
only(ArraysOfObjects, ArraysOfPrimitives)
|
only(ArraysOfObjects, ArraysOfPrimitives)
|
||||||
exclude(PrimitiveType.Boolean)
|
exclude(PrimitiveType.Boolean)
|
||||||
|
|||||||
Reference in New Issue
Block a user