From ebe578dbc5ff72988b336087a320106bd12d0b61 Mon Sep 17 00:00:00 2001 From: Ilya Gorbunov Date: Fri, 15 May 2015 19:51:30 +0300 Subject: [PATCH] Tests to ensure the behavior of the specialized empty List, Set, Map implementations is same as of non-specialized ones. --- js/js.libraries/test/core/assertTypeEquals.kt | 22 +++ .../test/collections/CollectionJVMTest.kt | 6 + .../stdlib/test/collections/CollectionTest.kt | 133 ++++++++++++++++++ 3 files changed, 161 insertions(+) create mode 100644 js/js.libraries/test/core/assertTypeEquals.kt diff --git a/js/js.libraries/test/core/assertTypeEquals.kt b/js/js.libraries/test/core/assertTypeEquals.kt new file mode 100644 index 00000000000..1d9cbdc17e9 --- /dev/null +++ b/js/js.libraries/test/core/assertTypeEquals.kt @@ -0,0 +1,22 @@ +/* + * Copyright 2010-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package kotlin.test + +public fun assertTypeEquals(expected: Any?, actual: Any?) { + //TODO: find analogue + //assertEquals(expected?.javaClass, actual?.javaClass) +} \ No newline at end of file diff --git a/libraries/stdlib/test/collections/CollectionJVMTest.kt b/libraries/stdlib/test/collections/CollectionJVMTest.kt index 7b34b6fe356..5d8b7d0f546 100644 --- a/libraries/stdlib/test/collections/CollectionJVMTest.kt +++ b/libraries/stdlib/test/collections/CollectionJVMTest.kt @@ -151,6 +151,7 @@ class CollectionJVMTest { test fun emptySetIsSerializable() = testSingletonSerialization(emptySet()) + test fun emptyMapIsSerializable() = testSingletonSerialization(emptyMap()) private fun testSingletonSerialization(value: Any) { val outputStream = ByteArrayOutputStream() @@ -168,3 +169,8 @@ class CollectionJVMTest { assertTrue(value === result) } } + + +public fun assertTypeEquals(expected: Any?, actual: Any?) { + assertEquals(expected?.javaClass, actual?.javaClass) +} diff --git a/libraries/stdlib/test/collections/CollectionTest.kt b/libraries/stdlib/test/collections/CollectionTest.kt index 14855edc77c..e274a83956b 100644 --- a/libraries/stdlib/test/collections/CollectionTest.kt +++ b/libraries/stdlib/test/collections/CollectionTest.kt @@ -520,4 +520,137 @@ class CollectionTest { assertEquals(d, 4) assertEquals(e, 5) } + + + test fun specialLists() { + compare(arrayListOf(), listOf()) { listBehavior() } + compare(arrayListOf(), emptyList()) { listBehavior() } + compare(arrayListOf("value"), listOf("value")) { listBehavior() } + } + + test fun specialSets() { + compare(linkedSetOf(), setOf()) { setBehavior() } + compare(hashSetOf(), emptySet()) { setBehavior() } + compare(listOf("value").toMutableSet(), setOf("value")) { setBehavior() } + } + + test fun specialMaps() { + compare(hashMapOf(), mapOf()) { mapBehavior() } + compare(linkedMapOf(), emptyMap()) { mapBehavior() } + compare(linkedMapOf(2 to 3), mapOf(2 to 3)) { mapBehavior() } + } + + private fun CompareContext>.listBehavior() { + equalityBehavior() + collectionBehavior() + compareProperty( { listIterator() }, { listIteratorBehavior() }) + compareProperty( { listIterator(0) }, { listIteratorBehavior() }) + + propertyFails { listIterator(-1) } + propertyFails { listIterator(size() + 1) } + + for (index in expected.indices) + propertyEquals { this[index] } + + propertyFails { this[size()] } + + propertyEquals { indexOf(elementAtOrNull(0)) } + propertyEquals { lastIndexOf(elementAtOrNull(0)) } + + propertyFails { subList(0, size() + 1)} + propertyFails { subList(-1, 0)} + propertyEquals { subList(0, size()) } + } + + private fun CompareContext>.listIteratorBehavior() { + listIteratorProperties() + + while (expected.hasNext()) { + propertyEquals { next() } + listIteratorProperties() + } + propertyFails { next() } + + while (expected.hasPrevious()) { + propertyEquals { previous() } + listIteratorProperties() + } + propertyFails { previous() } + } + + private fun CompareContext>.listIteratorProperties() { + propertyEquals { hasNext() } + propertyEquals { hasPrevious() } + propertyEquals { nextIndex() } + propertyEquals { previousIndex() } + } + + private fun CompareContext>.iteratorBehavior() { + propertyEquals { hasNext() } + + while (expected.hasNext()) { + propertyEquals { next() } + propertyEquals { hasNext() } + } + propertyFails { next() } + } + + private fun CompareContext>.setBehavior(objectName: String = "") { + equalityBehavior(objectName) + collectionBehavior(objectName) + compareProperty({ iterator() }, { iteratorBehavior() }) + } + + private fun CompareContext>.mapBehavior() { + equalityBehavior() + propertyEquals { size() } + propertyEquals { isEmpty() } + + (object {}).let { propertyEquals { containsKey(it)} } + + if (expected.isEmpty().not()) + propertyEquals { contains(keySet().first()) } + + compareProperty( { keySet() }, { setBehavior("keySet") } ) + compareProperty( { entrySet() }, { setBehavior("entrySet") } ) + compareProperty( { values() }, { collectionBehavior("values") }) + } + + private fun CompareContext.equalityBehavior(objectName: String = "") { + val prefix = objectName + if (objectName.isNotEmpty()) "." else "" + equals(objectName) + propertyEquals(prefix + "hashCode") { hashCode() } + propertyEquals(prefix + "toString") { toString() } + } + + + private fun CompareContext>.collectionBehavior(objectName: String = "") { + val prefix = objectName + if (objectName.isNotEmpty()) "." else "" + propertyEquals (prefix + "size") { size() } + propertyEquals (prefix + "isEmpty") { isEmpty() } + + (object {}).let { propertyEquals { contains(it)} } + propertyEquals { contains(firstOrNull()) } + propertyEquals { containsAll(this) } + } + +} + +private fun compare(expected: T, actual: T, block: CompareContext.() -> Unit) = CompareContext(expected, actual).block() + +private class CompareContext(public val expected: T, public val actual: T) { + + public fun equals(message: String = "") { assertEquals(expected, actual, message) } + public fun propertyEquals

(message: String = "", getter: T.() -> P) { assertEquals(expected.getter(), actual.getter(), message) } + public fun propertyFails(getter: T.() -> Unit) { assertFailEquals({expected.getter()}, {actual.getter()}) } + public fun compareProperty

(getter: T.() -> P, block: CompareContext

.() -> Unit) { + compare(expected.getter(), actual.getter(), block) + } + + private fun assertFailEquals(expected: () -> Unit, actual: () -> Unit) { + val expectedFail = fails(expected) + val actualFail = fails(actual) + //assertEquals(expectedFail != null, actualFail != null) + assertTypeEquals(expectedFail, actualFail) + } }