| /* | |
| * Copyright 2010-2025 JetBrains s.r.o. and Kotlin Programming Language contributors. | |
| * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. | |
| */ | |
| package test.collections | |
| import test.collections.behaviors.* | |
| import kotlin.test.* | |
| class AbstractCollectionsTest { | |
| class ReadOnlyCollection : AbstractCollection<String>() { | |
| private val data = arrayOf("ok") | |
| override val size: Int get() = 1 | |
| override fun iterator(): Iterator<String> = data.iterator() | |
| } | |
| class ReadOnlySet : AbstractSet<String>() { | |
| private val data = arrayOf("ok") | |
| override val size: Int get() = 1 | |
| override fun iterator(): Iterator<String> = data.iterator() | |
| } | |
| class ReadOnlyList(override val size: Int = 1) : AbstractList<String>() { | |
| override fun get(index: Int): String = index.takeIf { it in indices }?.let { "ok" } ?: throw IndexOutOfBoundsException() | |
| } | |
| class ReadOnlyMap : AbstractMap<String, Int>() { | |
| override val entries: Set<Map.Entry<String, Int>> = mapOf("ok" to 42).entries | |
| } | |
| @Test | |
| fun abstractCollection() { | |
| val coll = ReadOnlyCollection() | |
| assertEquals(listOf("ok"), coll.toList()) | |
| compare(coll.toList(), coll) { | |
| collectionBehavior() | |
| } | |
| } | |
| @Test | |
| fun abstractSet() { | |
| val set = ReadOnlySet() | |
| assertEquals(1, set.size) | |
| assertTrue("ok" in set) | |
| compare(set.toSet(), set) { | |
| setBehavior() | |
| } | |
| } | |
| @Test | |
| fun abstractList() { | |
| val list = ReadOnlyList(4) | |
| assertEquals(listOf("ok", "ok", "ok", "ok"), list) | |
| compare(list.toList(), list) { | |
| listBehavior() | |
| } | |
| } | |
| @Test | |
| fun chainedSubList() { | |
| val list = object : AbstractList<Int>() { | |
| override val size = 5 | |
| override fun get(index: Int) = if (index in 0 until size) index else -1 | |
| } | |
| val subList = list.subList(0, 5).subList(1, 4) | |
| compare(listOf(1, 2, 3), subList) { | |
| listBehavior() | |
| } | |
| assertFailsWith<IndexOutOfBoundsException> { | |
| list.subList(1, 3).subList(0, 4) | |
| } | |
| assertFailsWith<IllegalArgumentException> { | |
| list.subList(1, 3).subList(3, 2) | |
| } | |
| } | |
| @Test | |
| fun abstractMap() { | |
| val map = ReadOnlyMap() | |
| assertEquals(1, map.size) | |
| assertTrue(map.contains("ok")) | |
| assertTrue(map.containsValue(42)) | |
| assertEquals(setOf("ok"), map.keys) | |
| assertEquals(listOf(42), map.values.toList()) | |
| compare(map.toMap(), map) { | |
| mapBehavior() | |
| } | |
| // values collection does not provide equals implementation | |
| assertNotEquals(map.values, ReadOnlyMap().values) | |
| } | |
| class MutColl(val storage: MutableCollection<String> = mutableListOf()) : AbstractMutableCollection<String>() { | |
| override val size: Int get() = storage.size | |
| override fun iterator(): MutableIterator<String> = storage.iterator() | |
| override fun add(element: String): Boolean = storage.add(element) | |
| } | |
| class MutList(val storage: MutableList<String> = mutableListOf()) : AbstractMutableList<String>() { | |
| override val size: Int get() = storage.size | |
| override fun get(index: Int): String = storage.get(index) | |
| override fun add(index: Int, element: String) = storage.add(index, element) | |
| override fun removeAt(index: Int): String = storage.removeAt(index) | |
| override fun set(index: Int, element: String): String = storage.set(index, element) | |
| } | |
| class MutSet(val storage: MutableSet<String> = mutableSetOf<String>()) : AbstractMutableSet<String>() { | |
| override val size: Int get() = storage.size | |
| override fun iterator(): MutableIterator<String> = storage.iterator() | |
| override fun add(element: String): Boolean = storage.add(element) | |
| } | |
| class MutMap(val storage: MutableMap<String, Int> = mutableMapOf()) : AbstractMutableMap<String, Int>() { | |
| override fun put(key: String, value: Int): Int? = storage.put(key, value) | |
| override val entries: MutableSet<MutableMap.MutableEntry<String, Int>> get() = storage.entries | |
| } | |
| @Test | |
| fun abstractMutableCollection() { | |
| val coll = MutColl() | |
| coll += "ok" | |
| coll += "test" | |
| coll.removeAll { it.length > 2 } | |
| assertEquals(1, coll.size) | |
| assertEquals(listOf("ok"), coll.toList()) | |
| compare(coll.storage, coll) { | |
| collectionBehavior() | |
| } | |
| } | |
| @Test | |
| fun abstractMutableList() { | |
| val list = MutList() | |
| list += "test" | |
| list += "ok" | |
| list += "element" | |
| val subList = list.subList(0, 2) | |
| subList.retainAll { it.length <= 2 } | |
| assertEquals(listOf("ok", "element"), list) | |
| assertFailsWith<IndexOutOfBoundsException> { list.addAll(-1, listOf()) } | |
| compare(list.storage, list) { | |
| listBehavior() | |
| } | |
| } | |
| @Test | |
| fun abstractMutableSet() { | |
| val set = MutSet() | |
| set.addAll(listOf("ok", "test", "element", "test")) | |
| set.removeAll { it.length < 4 } | |
| assertEquals(2, set.size) | |
| assertEquals(setOf("element", "test"), set) | |
| compare(set.storage, set) { | |
| setBehavior() | |
| } | |
| } | |
| @Test | |
| fun abstractMutableMap() { | |
| val map = MutMap() | |
| for (e in 'a'..'z') map[e.toString()] = e.code | |
| assertEquals(26, map.size) | |
| map.remove("a") | |
| map.keys.remove("b") | |
| map.keys.removeAll { it == "c" } | |
| map.values.remove('d'.code) | |
| assertTrue(map.containsKey("e")) | |
| assertTrue(map.containsValue('f'.code)) | |
| compare(map.storage, map) { | |
| mapBehavior() | |
| } | |
| // values collection does not provide equals implementation | |
| assertNotEquals(map.values, MutMap(map).values) | |
| } | |
| } |