Skip to content

Commit 998929a

Browse files
Abduqodiri Qurbonzodaigoriakovlev
Abduqodiri Qurbonzoda
authored andcommitted
Improve ImmutableMapTest.noOperation test
1 parent c2aec04 commit 998929a

File tree

2 files changed

+43
-11
lines changed

2 files changed

+43
-11
lines changed

core/commonTest/src/contract/map/ImmutableMapTest.kt

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ import tests.contract.collectionBehavior
1010
import tests.contract.compare
1111
import tests.contract.mapBehavior
1212
import tests.contract.setBehavior
13+
import tests.remove
1314
import tests.stress.IntWrapper
15+
import tests.stress.ObjectWrapper
1416
import kotlin.test.*
1517

1618
class ImmutableHashMapTest : ImmutableMapTest() {
@@ -285,17 +287,35 @@ abstract class ImmutableMapTest {
285287
@Test fun noOperation() {
286288
immutableMapOf<String, String>().toPersistentMap().testNoOperation({ clear() }, { clear() })
287289

288-
val instance = Any()
289-
val instance2 = Any()
290-
291-
val map = immutableMapOf("x" to instance, null to "x").toPersistentMap()
292-
with(map) {
293-
testNoOperation({ remove("y") }, { remove("y") })
294-
testNoOperation({ remove("x", instance2) }, { remove("x", instance2) })
295-
testNoOperation({ put("x", instance) }, { put("x", instance) })
296-
testNoOperation({ putAll(this) }, { putAll(this) })
297-
testNoOperation({ putAll(emptyMap()) }, { putAll(emptyMap()) })
298-
}
290+
val key = ObjectWrapper("x", "x".hashCode())
291+
val equalKey = ObjectWrapper("x", "x".hashCode()) // equalKey == key && equalKey !== key
292+
val notEqualKey = ObjectWrapper("y", "x".hashCode()) // notEqualKey != key && notEqualKey.hashCode == key.hashCode
293+
val value = ObjectWrapper(1, 1)
294+
val equalValue = ObjectWrapper(1, 1) // equalValue == value && equalValue !== value
295+
val notEqualValue = ObjectWrapper(2, 2) // notEqualValue != value
296+
297+
/*
298+
To avoid changes to a persistent map:
299+
* remove(key):
300+
no key in map is equal (==) to the given key
301+
* remove(key, value):
302+
the above, or the value for the found key is not equal (!=) to the given value
303+
* put(key, value):
304+
map has a key equal (==) to the given key, and the value for the found key is the same (===) as the given value
305+
*/
306+
val map = immutableMapOf(key to value, null to "x").toPersistentMap()
307+
308+
map.testNoOperation({ remove(notEqualKey) }, { remove(notEqualKey) })
309+
map.testNotNoOperation({ remove(equalKey) }, { remove(equalKey) })
310+
311+
map.testNoOperation({ remove(key, notEqualValue) }, { remove(key, notEqualValue) })
312+
map.testNotNoOperation({ remove(key, equalValue) }, { remove(key, equalValue) })
313+
314+
map.testNoOperation({ put(equalKey, value) }, { put(equalKey, value) })
315+
map.testNotNoOperation({ put(equalKey, equalValue) }, { put(equalKey, equalValue) })
316+
317+
map.testNoOperation({ putAll(this) }, { putAll(this) })
318+
map.testNoOperation({ putAll(emptyMap()) }, { putAll(emptyMap()) })
299319
}
300320

301321
fun <K, V> PersistentMap<K, V>.testNoOperation(persistent: PersistentMap<K, V>.() -> PersistentMap<K, V>, mutating: MutableMap<K, V>.() -> Unit) {
@@ -306,6 +326,14 @@ abstract class ImmutableMapTest {
306326
assertSame(this, buildResult)
307327
}
308328

329+
fun <K, V> PersistentMap<K, V>.testNotNoOperation(persistent: PersistentMap<K, V>.() -> PersistentMap<K, V>, mutating: MutableMap<K, V>.() -> Unit) {
330+
val result = this.persistent()
331+
val buildResult = this.mutate(mutating)
332+
// Ensure mutating operations do not return the same instance
333+
assertNotSame(this, result)
334+
assertNotSame(this, buildResult)
335+
}
336+
309337

310338
@Test
311339
fun covariantTyping() {

core/commonTest/src/stress/ObjectWrapper.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ class ObjectWrapper<K: Comparable<K>>(
2727
override fun compareTo(other: ObjectWrapper<K>): Int {
2828
return obj.compareTo(other.obj)
2929
}
30+
31+
override fun toString(): String {
32+
return "ObjectWrapper($obj, hashCode = $hashCode)"
33+
}
3034
}
3135

3236
typealias IntWrapper = ObjectWrapper<Int>

0 commit comments

Comments
 (0)