@@ -10,7 +10,9 @@ import tests.contract.collectionBehavior
10
10
import tests.contract.compare
11
11
import tests.contract.mapBehavior
12
12
import tests.contract.setBehavior
13
+ import tests.remove
13
14
import tests.stress.IntWrapper
15
+ import tests.stress.ObjectWrapper
14
16
import kotlin.test.*
15
17
16
18
class ImmutableHashMapTest : ImmutableMapTest () {
@@ -285,17 +287,35 @@ abstract class ImmutableMapTest {
285
287
@Test fun noOperation () {
286
288
immutableMapOf<String , String >().toPersistentMap().testNoOperation({ clear() }, { clear() })
287
289
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()) })
299
319
}
300
320
301
321
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 {
306
326
assertSame(this , buildResult)
307
327
}
308
328
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
+
309
337
310
338
@Test
311
339
fun covariantTyping () {
0 commit comments