Skip to content

Commit ee3d423

Browse files
committed
Employ collection comparison DSL to cover more cases.
1 parent 103fbdf commit ee3d423

File tree

3 files changed

+187
-16
lines changed

3 files changed

+187
-16
lines changed
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
/*
2+
* Copyright 2010-2015 JetBrains s.r.o.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package test.collections.behaviors
18+
19+
import test.collections.CompareContext
20+
21+
public fun <T> CompareContext<List<T>>.listBehavior() {
22+
equalityBehavior()
23+
collectionBehavior()
24+
compareProperty( { listIterator() }, { listIteratorBehavior() })
25+
compareProperty( { listIterator(0) }, { listIteratorBehavior() })
26+
compareProperty( { listIterator(size / 2) }, { listIteratorBehavior() })
27+
28+
propertyFails { listIterator(-1) }
29+
propertyFails { listIterator(size + 1) }
30+
31+
for (index in expected.indices)
32+
propertyEquals { this[index] }
33+
34+
propertyFails { this[size] }
35+
36+
propertyEquals { indexOf(elementAtOrNull(0)) }
37+
propertyEquals { lastIndexOf(elementAtOrNull(0)) }
38+
39+
propertyFails { subList(0, size + 1)}
40+
propertyFails { subList(-1, 0)}
41+
propertyEquals { subList(0, size) }
42+
}
43+
44+
public fun <T> CompareContext<ListIterator<T>>.listIteratorBehavior() {
45+
listIteratorProperties()
46+
47+
while (expected.hasNext()) {
48+
propertyEquals { next() }
49+
listIteratorProperties()
50+
}
51+
propertyFails { next() }
52+
53+
while (expected.hasPrevious()) {
54+
propertyEquals { previous() }
55+
listIteratorProperties()
56+
}
57+
propertyFails { previous() }
58+
}
59+
60+
public fun CompareContext<ListIterator<*>>.listIteratorProperties() {
61+
propertyEquals { hasNext() }
62+
propertyEquals { hasPrevious() }
63+
propertyEquals { nextIndex() }
64+
propertyEquals { previousIndex() }
65+
}
66+
67+
public fun <T> CompareContext<Iterator<T>>.iteratorBehavior() {
68+
propertyEquals { hasNext() }
69+
70+
while (expected.hasNext()) {
71+
propertyEquals { next() }
72+
propertyEquals { hasNext() }
73+
}
74+
propertyFails { next() }
75+
}
76+
77+
public fun <T> CompareContext<Set<T>>.setBehavior(objectName: String = "", ordered: Boolean) {
78+
equalityBehavior(objectName, ordered)
79+
collectionBehavior(objectName, ordered)
80+
81+
propertyEquals { containsAll(actual) }
82+
propertyEquals { containsAll(expected) }
83+
}
84+
85+
86+
87+
88+
public fun <K, V> CompareContext<Map<K, V>>.mapBehavior(ordered: Boolean) {
89+
propertyEquals { size }
90+
propertyEquals { isEmpty() }
91+
equalityBehavior(ordered = ordered)
92+
93+
(object {}).let { propertyEquals { containsKey(it as Any?) } }
94+
95+
if (expected.isEmpty().not())
96+
propertyEquals { contains(keys.first()) }
97+
98+
propertyEquals { containsKey(keys.firstOrNull()) }
99+
propertyEquals { containsValue(values.firstOrNull()) }
100+
propertyEquals { get(null as Any?) }
101+
102+
compareProperty( { keys }, { setBehavior("keySet", ordered) } )
103+
compareProperty( { entries }, { setBehavior("entrySet", ordered) } )
104+
compareProperty( { values }, { collectionBehavior("values", ordered) })
105+
}
106+
107+
108+
public fun <T> CompareContext<T>.equalityBehavior(objectName: String = "", ordered: Boolean = true) {
109+
val prefix = objectName + if (objectName.isNotEmpty()) "." else ""
110+
equals(objectName)
111+
propertyEquals(prefix + "hashCode") { hashCode() }
112+
if (ordered)
113+
propertyEquals(prefix + "toString") { toString() }
114+
}
115+
116+
117+
public fun <T> CompareContext<Collection<T>>.collectionBehavior(objectName: String = "", ordered: Boolean = true) {
118+
val prefix = objectName + if (objectName.isNotEmpty()) "." else ""
119+
propertyEquals (prefix + "size") { size }
120+
propertyEquals (prefix + "isEmpty") { isEmpty() }
121+
122+
(object {}).let { propertyEquals { contains(it as Any?) } }
123+
propertyEquals { contains(firstOrNull()) }
124+
propertyEquals { containsAll(this) }
125+
if (ordered) {
126+
compareProperty({iterator()}, { iteratorBehavior() })
127+
}
128+
}
129+
130+
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package test.collections
2+
3+
import kotlin.test.*
4+
5+
public fun <T> compare(expected: T, actual: T, block:CompareContext<T>.() -> Unit) {
6+
CompareContext(expected, actual).block()
7+
}
8+
9+
public class CompareContext<out T>(public val expected: T, public val actual: T) {
10+
11+
public fun equals(message: String = "") {
12+
assertEquals(expected, actual, message)
13+
}
14+
public fun <P> propertyEquals(message: String = "", getter: T.() -> P) {
15+
assertEquals(expected.getter(), actual.getter(), message)
16+
}
17+
public fun propertyFails(getter: T.() -> Unit) { assertFailEquals({expected.getter()}, {actual.getter()}) }
18+
public fun <P> compareProperty(getter: T.() -> P, block: CompareContext<P>.() -> Unit) {
19+
compare(expected.getter(), actual.getter(), block)
20+
}
21+
22+
private fun assertFailEquals(expected: () -> Unit, actual: () -> Unit) {
23+
val expectedFail = assertFails(expected)
24+
val actualFail = assertFails(actual)
25+
//assertEquals(expectedFail != null, actualFail != null)
26+
assertTypeEquals(expectedFail, actualFail)
27+
}
28+
29+
public fun assertTypeEquals(expected: Any?, actual: Any?) {
30+
assertEquals(expected?.javaClass, actual?.javaClass)
31+
}
32+
}

kotlinx-collections-immutable/tests/src/test/kotlin/kotlinx.collections.immutable/ImmutableMapTest.kt

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package kotlinx.collections.immutable
22

33
import org.junit.Test
4+
import test.collections.behaviors.*
5+
import test.collections.compare
46
import java.util.*
57
import kotlin.test.*
68

@@ -9,33 +11,39 @@ class ImmutableHashMapTest : ImmutableMapTest() {
911
}
1012
class ImmutableOrderedMapTest : ImmutableMapTest() {
1113
override fun <K, V> immutableMapOf(vararg pairs: Pair<K, V>): ImmutableMap<K, V> = kotlinx.collections.immutable.immutableMapOf(*pairs)
14+
override fun <K, V> compareMaps(expected: Map<K, V>, actual: Map<K, V>) = compare(expected, actual) { mapBehavior(ordered = true) }
1215

1316
@Test fun iterationOrder() {
1417
var map = immutableMapOf("x" to null, "y" to 1)
15-
assertEquals(listOf("x", "y"), map.keys.toList())
18+
compare(setOf("x", "y"), map.keys) { setBehavior(ordered = true) }
1619

1720
map += "x" to 1
18-
assertEquals(listOf("x", "y"), map.keys.toList())
21+
compare(setOf("x", "y"), map.keys) { setBehavior(ordered = true) }
1922

2023
map = map.remove("x")
2124
map += "x" to 2
22-
assertEquals(listOf("y", "x"), map.keys.toList())
23-
assertEquals(listOf(1, 2), map.values.toList())
24-
assertEquals(listOf("y" to 1, "x" to 2), map.toList())
25+
compare(setOf("y", "x"), map.keys) { setBehavior(ordered = true) }
26+
compare(listOf(1, 2), map.values) { collectionBehavior(ordered = true) }
27+
compare(mapOf("y" to 1, "x" to 2).entries, map.entries) { setBehavior(ordered = true) }
2528
}
2629
}
2730

2831
abstract class ImmutableMapTest {
2932

3033
abstract fun <K, V> immutableMapOf(vararg pairs: Pair<K, V>): ImmutableMap<K, V>
3134

35+
open fun <K, V> compareMaps(expected: Map<K, V>, actual: Map<K, V>) = compareMapsUnordered(expected, actual)
36+
fun <K, V> compareMapsUnordered(expected: Map<K, V>, actual: Map<K, V>) = compare(expected, actual) { mapBehavior(ordered = false) }
37+
3238

3339
@Test fun empty() {
3440
val empty1 = immutableMapOf<Int, String>()
3541
val empty2 = immutableMapOf<String, Int>()
3642
assertEquals<ImmutableMap<*, *>>(empty1, empty2)
3743
assertEquals(mapOf<Int, String>(), empty1)
3844
assertTrue(empty1 === empty2)
45+
46+
compareMaps(emptyMap(), empty1)
3947
}
4048

4149

@@ -44,25 +52,24 @@ abstract class ImmutableMapTest {
4452
val map1 = immutableMapOf("x" to 1, "y" to null, null to 2)
4553
val map2 = immutableMapOf("x" to 1, "y" to null, null to 2)
4654

47-
assertEquals(map0, map1)
48-
assertEquals(map1, map2)
55+
compareMaps(map0, map1)
56+
compareMaps(map1, map2)
4957
}
5058

5159

5260
@Test fun toImmutable() {
5361
val original = mapOf("x" to 1, "y" to null, null to 2)
62+
val immOriginal = original.toImmutableMap()
63+
compareMaps(original, immOriginal)
64+
5465

5566
val map = HashMap(original) // copy
5667
var immMap = map.toImmutableMap()
5768
val immMap2 = immMap.toImmutableMap()
5869
assertTrue(immMap2 === immMap)
5970

60-
assertEquals<Map<*, *>>(map, immMap) // problem
61-
// assertEquals(map.toString(), immMap.toString()) // order sensitive
62-
assertEquals(map.hashCode(), immMap.hashCode())
63-
assertEquals<Set<*>>(map.keys, immMap.keys)
64-
assertEquals<Set<*>>(map.entries, immMap.entries)
65-
assertEquals(map.values.toSet(), immMap.values.toSet())
71+
compareMapsUnordered(original, immMap)
72+
compareMapsUnordered(map, immMap)
6673

6774
map.remove(null)
6875
assertNotEquals<Map<*, *>>(map, immMap)
@@ -79,8 +86,10 @@ abstract class ImmutableMapTest {
7986
map = map.putAll(arrayOf("x" to null))
8087
map = map + ("y" to null)
8188
map += "y" to 1
89+
assertEquals(mapOf("x" to null, "y" to 1), map)
90+
8291
map += map
83-
map += map.map { it.key + "!" to it.value }
92+
map += map.map { it.key + "!" to it.value }
8493

8594
assertEquals(map.size, map.entries.size)
8695

@@ -128,8 +137,8 @@ abstract class ImmutableMapTest {
128137
operation(mutable)
129138
operation(builder)
130139

131-
assertEquals(mutable, builder)
132-
assertEquals<Map<*, *>>(mutable, builder.build())
140+
compareMapsUnordered(mutable, builder)
141+
compareMapsUnordered(mutable, builder.build())
133142
}
134143

135144
@Test fun noOperation() {

0 commit comments

Comments
 (0)