Decommonize collection builder implementations
This commit is contained in:
@@ -6,35 +6,55 @@ import test.collections.behaviors.setBehavior
|
||||
import kotlin.test.*
|
||||
|
||||
class ContainerBuilderTest {
|
||||
private fun <E> mutableCollectionOperations(e: E) = listOf<MutableCollection<E>.() -> Unit>(
|
||||
{ add(e) },
|
||||
{ addAll(listOf(e)) },
|
||||
{ remove(e) },
|
||||
{ removeAll(listOf(e)) },
|
||||
{ retainAll(listOf(e)) },
|
||||
{ clear() },
|
||||
{ iterator().apply { next() }.remove() }
|
||||
private fun <E> mutableCollectionOperations(present: E, absent: E) = listOf<Pair<String, MutableCollection<E>.() -> Unit>>(
|
||||
"add(present)" to { add(present) },
|
||||
"add(absent)" to { add(absent) },
|
||||
|
||||
"addAll(listOf(present))" to { addAll(listOf(present)) },
|
||||
"addAll(listOf(absent))" to { addAll(listOf(absent)) },
|
||||
"addAll(emptyList())" to { addAll(emptyList()) },
|
||||
|
||||
"remove(present)" to { remove(present) },
|
||||
"remove(absent)" to { remove(absent) },
|
||||
|
||||
"removeAll(listOf(present))" to { removeAll(listOf(present)) },
|
||||
"removeAll(emptyList())" to { removeAll(emptyList()) },
|
||||
"removeAll(this.toList())" to { removeAll(this.toList()) },
|
||||
|
||||
"retainAll(listOf(present))" to { retainAll(listOf(present)) },
|
||||
"retainAll(emptyList())" to { retainAll(emptyList()) },
|
||||
"retainAll(this.toList())" to { retainAll(this.toList()) },
|
||||
|
||||
"clear()" to { clear() },
|
||||
|
||||
"iterator().apply { next() }.remove()" to { iterator().apply { next() }.remove() }
|
||||
)
|
||||
|
||||
private fun <E> mutableListOperations(e: E) = mutableCollectionOperations(e) + listOf<MutableList<E>.() -> Unit>(
|
||||
{ add(0, e) },
|
||||
{ addAll(0, listOf(e)) },
|
||||
{ removeAt(0) },
|
||||
{ set(0, e) },
|
||||
{ listIterator().apply { next() }.remove() },
|
||||
{ listIterator(0).apply { next() }.remove() },
|
||||
{ listIterator().add(e) }
|
||||
private fun <E> mutableListOperations(present: E, absent: E) = mutableCollectionOperations(present, absent) + listOf<Pair<String, MutableList<E>.() -> Unit>>(
|
||||
"add(0, present)" to { add(0, present) },
|
||||
"addAll(0, listOf(present))" to { addAll(0, listOf(present)) },
|
||||
"addAll(0, emptyList())" to { addAll(0, emptyList()) },
|
||||
"removeAt(0)" to { removeAt(0) },
|
||||
"set(0, present)" to { set(0, present) },
|
||||
"listIterator().apply { next() }.remove()" to { listIterator().apply { next() }.remove() },
|
||||
"listIterator(0).apply { next() }.remove()" to { listIterator(0).apply { next() }.remove() },
|
||||
"listIterator().apply { next() }.set(present)" to { listIterator().apply { next() }.set(present) },
|
||||
"listIterator().add(present)" to { listIterator().add(present) }
|
||||
)
|
||||
|
||||
private fun <E> mutableSetOperations(e: E): List<MutableSet<E>.() -> Unit> = mutableCollectionOperations(e)
|
||||
private fun <E> mutableSetOperations(present: E, absent: E) = mutableCollectionOperations(present, absent) + listOf<Pair<String, MutableSet<E>.() -> Unit>>(
|
||||
// check java.util.AbstractSet.removeAll optimisation
|
||||
"removeAll(List(this.size) { absent })" to { removeAll(List(this.size) { absent }) }
|
||||
)
|
||||
|
||||
private fun <K, V> mutableMapOperations(k: K, v: V) = listOf<MutableMap<K, V>.() -> Unit>(
|
||||
{ put(k, v) },
|
||||
{ remove(k) },
|
||||
{ putAll(mapOf(k to v)) },
|
||||
{ clear() },
|
||||
{ entries.first().setValue(v) },
|
||||
{ entries.iterator().next().setValue(v) }
|
||||
private fun <K, V> mutableMapOperations(k: K, v: V) = listOf<Pair<String, MutableMap<K, V>.() -> Unit>>(
|
||||
"put(k, v)" to { put(k, v) },
|
||||
"remove(k)" to { remove(k) },
|
||||
"putAll(mapOf(k to v))" to { putAll(mapOf(k to v)) },
|
||||
"putAll(emptyMap())" to { putAll(emptyMap()) },
|
||||
"clear()" to { clear() },
|
||||
"entries.first().setValue(v)" to { entries.first().setValue(v) },
|
||||
"entries.iterator().next().setValue(v)" to { entries.iterator().next().setValue(v) }
|
||||
)
|
||||
|
||||
@Test
|
||||
@@ -44,10 +64,14 @@ class ContainerBuilderTest {
|
||||
add('c')
|
||||
}
|
||||
|
||||
val y = buildList(4) {
|
||||
val subList: MutableList<Char>
|
||||
|
||||
val y = buildList<Char>(4) {
|
||||
add('a')
|
||||
addAll(x)
|
||||
add('d')
|
||||
|
||||
subList = subList(0, 4)
|
||||
}
|
||||
|
||||
compare(listOf('a', 'b', 'c', 'd'), y) { listBehavior() }
|
||||
@@ -60,9 +84,10 @@ class ContainerBuilderTest {
|
||||
}
|
||||
|
||||
assertTrue(y is MutableList<Char>)
|
||||
for (operation in mutableListOperations('a')) {
|
||||
assertFailsWith<UnsupportedOperationException> { y.operation() }
|
||||
assertFailsWith<UnsupportedOperationException> { y.subList(1, 3).operation() }
|
||||
for ((fName, operation) in mutableListOperations('b', 'x')) {
|
||||
assertFailsWith<UnsupportedOperationException>("y.$fName") { y.operation() }
|
||||
assertFailsWith<UnsupportedOperationException>("y.subList(1, 3).$fName") { y.subList(1, 3).operation() }
|
||||
assertFailsWith<UnsupportedOperationException>("subList.$fName") { subList.operation() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,10 +115,12 @@ class ContainerBuilderTest {
|
||||
val subSubList = subList.subList(2, 4)
|
||||
// buffer reallocation should happen
|
||||
repeat(20) { subSubList.add('x') }
|
||||
repeat(20) { subSubList.add(subSubList.size - 2 * it, 'y') }
|
||||
|
||||
compare("ab123${"x".repeat(20)}e".toList(), this) { listBehavior() }
|
||||
compare("b123${"x".repeat(20)}".toList(), subList) { listBehavior() }
|
||||
compare("23${"x".repeat(20)}".toList(), subSubList) { listBehavior() }
|
||||
val addedChars = "xy".repeat(20)
|
||||
compare("ab123${addedChars}e".toList(), this) { listBehavior() }
|
||||
compare("b123$addedChars".toList(), subList) { listBehavior() }
|
||||
compare("23$addedChars".toList(), subSubList) { listBehavior() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,8 +145,8 @@ class ContainerBuilderTest {
|
||||
}
|
||||
|
||||
assertTrue(y is MutableSet<Char>)
|
||||
for (operation in mutableSetOperations('b')) {
|
||||
assertFailsWith<UnsupportedOperationException> { y.operation() }
|
||||
for ((fName, operation) in mutableSetOperations('b', 'x')) {
|
||||
assertFailsWith<UnsupportedOperationException>("y.$fName") { y.operation() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,17 +172,23 @@ class ContainerBuilderTest {
|
||||
}
|
||||
|
||||
assertTrue(y is MutableMap<Char, Int>)
|
||||
for (operation in mutableMapOperations('a', 0)) {
|
||||
assertFailsWith<UnsupportedOperationException> { y.operation() }
|
||||
for ((fName, operation) in mutableMapOperations('a', 1) + mutableMapOperations('x', 10)) {
|
||||
assertFailsWith<UnsupportedOperationException>("y.$fName") { y.operation() }
|
||||
}
|
||||
for (operation in mutableSetOperations('a')) {
|
||||
assertFailsWith<UnsupportedOperationException> { y.keys.operation() }
|
||||
for ((fName, operation) in mutableSetOperations('a', 'x')) {
|
||||
assertFailsWith<UnsupportedOperationException>("y.keys.$fName") { y.keys.operation() }
|
||||
}
|
||||
for (operation in mutableCollectionOperations(1)) {
|
||||
assertFailsWith<UnsupportedOperationException> { y.values.operation() }
|
||||
for ((fName, operation) in mutableCollectionOperations(1, 10)) {
|
||||
assertFailsWith<UnsupportedOperationException>("y.values.$fName") { y.values.operation() }
|
||||
}
|
||||
for (operation in mutableSetOperations(y.entries.first())) {
|
||||
assertFailsWith<UnsupportedOperationException> { y.entries.operation() }
|
||||
val presentEntry = y.entries.first()
|
||||
val absentEntry: MutableMap.MutableEntry<Char, Int> = object : MutableMap.MutableEntry<Char, Int> {
|
||||
override val key: Char get() = 'x'
|
||||
override val value: Int get() = 10
|
||||
override fun setValue(newValue: Int): Int = fail("Unreachable")
|
||||
}
|
||||
for ((fName, operation) in mutableSetOperations(presentEntry, absentEntry)) {
|
||||
assertFailsWith<UnsupportedOperationException>("y.entries.$fName") { y.entries.operation() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user