Skip to content

Commit 86bbbc4

Browse files
author
Abduqodiri Qurbonzoda
committed
Fix iterator.next() behavior in some places
1 parent 456a7ac commit 86bbbc4

File tree

3 files changed

+40
-49
lines changed

3 files changed

+40
-49
lines changed

kotlinx-collections-immutable/src/main/kotlin/kotlinx/collections/immutable/implementations/immutableSet/PersistentHashSetIterator.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ internal open class PersistentHashSetIterator<E>(node: TrieNode<E>) : Iterator<E
7070
}
7171

7272
override fun next(): E {
73-
assert(hasNext())
73+
if (!hasNext)
74+
throw NoSuchElementException()
7475

7576
val result = path[pathLastIndex].nextElement()
7677
ensureNextElementIsReady()

kotlinx-collections-immutable/src/main/kotlin/kotlinx/collections/immutable/implementations/persistentOrderedSet/PersistentOrderedSetIterator.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ internal open class PersistentOrderedSetIterator<E>(private var nextElement: E?,
2525
}
2626

2727
override fun next(): E {
28-
assert(hasNext())
28+
if (!hasNext())
29+
throw NoSuchElementException()
30+
2931
val result = nextElement as E
3032
index++
3133
nextElement = map[result]!!.next

kotlinx-collections-immutable/tests/src/test/kotlin/kotlinx.collections.immutable/contractTests/immutableSet/ImmutableSetTest.kt

Lines changed: 35 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -17,76 +17,64 @@
1717
package kotlinx.collections.immutable.contractTests.immutableSet
1818

1919
import kotlinx.collections.immutable.*
20+
import kotlinx.collections.immutable.contractTests.compare
21+
import kotlinx.collections.immutable.contractTests.setBehavior
2022
import org.junit.Test
2123
import kotlin.test.*
2224

23-
class ImmutableSetTest : ImmutableSetTestBase() {
24-
override fun <T> immutableSetOf(vararg elements: T) = persistentSetOf(*elements)
25-
}
26-
2725
class ImmutableHashSetTest : ImmutableSetTestBase() {
2826
override fun <T> immutableSetOf(vararg elements: T) = persistentHashSetOf(*elements)
29-
30-
override fun empty() {
31-
val empty1 = immutableSetOf<Int>()
32-
val empty2 = immutableSetOf<String>()
33-
assertEquals<ImmutableSet<Any>>(empty1, empty2)
34-
assertEquals<Set<Any>>(setOf(), empty1)
35-
// assertTrue(empty1 === empty2) // fails to implement this property
36-
}
37-
38-
override fun noOperation() {
39-
// immutableSetOf<Int>().testNoOperation({ clear() }, { clear() }) // fails to implement this property
40-
41-
val list = "abcxyz12".toList().toPersistentSet()
42-
with(list) {
43-
testNoOperation({ add('a') }, { add('a') })
44-
testNoOperation({ addAll(listOf('a', 'b')) }, { addAll(listOf('a', 'b')) })
45-
testNoOperation({ remove('d') }, { remove('d') })
46-
testNoOperation({ removeAll(listOf('d', 'e')) }, { removeAll(listOf('d', 'e')) })
47-
testNoOperation({ removeAll { it.isUpperCase() } }, { removeAll { it.isUpperCase() } })
48-
}
49-
}
27+
}
28+
class ImmutableOrderedSetTest : ImmutableSetTestBase() {
29+
override fun <T> immutableSetOf(vararg elements: T) = persistentSetOf(*elements)
30+
override fun <T> compareSets(expected: Set<T>, actual: Set<T>) = compare(expected, actual) { setBehavior(ordered = true) }
5031
}
5132

5233
abstract class ImmutableSetTestBase {
5334

5435
abstract fun <T> immutableSetOf(vararg elements: T): PersistentSet<T>
36+
fun <T> immutableSetOf(elements: Collection<T>) = immutableSetOf<T>() + elements
37+
38+
open fun <T> compareSets(expected: Set<T>, actual: Set<T>) = compareSetsUnordered(expected, actual)
39+
fun <T> compareSetsUnordered(expected: Set<T>, actual: Set<T>) = compare(expected, actual) { setBehavior(ordered = false) }
5540

5641
@Test open fun empty() {
5742
val empty1 = immutableSetOf<Int>()
5843
val empty2 = immutableSetOf<String>()
5944
assertEquals<ImmutableSet<Any>>(empty1, empty2)
6045
assertEquals<Set<Any>>(setOf(), empty1)
6146
assertTrue(empty1 === empty2)
47+
48+
compareSets(emptySet(), empty1)
6249
}
6350

6451
@Test fun ofElements() {
6552
val set0 = setOf("a", "d", 1, null)
6653
val set1 = immutableSetOf("a", "d", 1, null)
6754
val set2 = immutableSetOf("a", "d", 1, null)
6855

69-
assertEquals(set0, set1)
70-
assertEquals(set1, set2)
56+
compareSets(set0, set1)
57+
compareSets(set1, set2)
7158
}
7259

7360
@Test fun toImmutable() {
7461
val original = setOf("a", "bar", "cat", null)
62+
val immOriginal = immutableSetOf(original)
63+
compareSets(original, immOriginal)
7564

76-
val set = original.toMutableSet() // copy
77-
var immSet = set.toPersistentSet()
65+
val hashSet = HashSet(original) // copy
66+
var immSet = immutableSetOf(hashSet)
7867
val immSet2 = immSet.toImmutableSet()
7968
assertTrue(immSet2 === immSet)
8069

81-
assertEquals<Set<*>>(set, immSet) // problem
82-
assertEquals(set.toString(), immSet.toString())
83-
assertEquals(set.hashCode(), immSet.hashCode())
70+
compareSetsUnordered(original, immSet)
71+
compareSetsUnordered(hashSet, immSet)
8472

85-
set.remove("a")
86-
assertNotEquals<Set<*>>(set, immSet)
73+
hashSet.remove("a")
74+
assertNotEquals<Set<*>>(hashSet, immSet)
8775

8876
immSet = immSet.remove("a")
89-
assertEquals<Set<*>>(set, immSet) // problem
77+
compareSetsUnordered(hashSet, immSet)
9078
}
9179

9280
@Test fun addElements() {
@@ -96,14 +84,14 @@ abstract class ImmutableSetTestBase {
9684
set = set + "y"
9785
set += "z"
9886
set += arrayOf("1", "2").asIterable()
99-
assertEquals("xyz12".map { it.toString() }.toSet(), set)
87+
compareSets("xyz12".map { it.toString() }.toSet(), set)
10088
}
10189

10290

10391
@Test fun removeElements() {
104-
val set = "abcxyz12".toList().toPersistentSet()
92+
val set = immutableSetOf("abcxyz12".toList())
10593
fun expectSet(content: String, set: ImmutableSet<Char>) {
106-
assertEquals(content.toSet(), set)
94+
compareSets(content.toSet(), set)
10795
}
10896

10997
expectSet("abcyz12", set.remove('x'))
@@ -112,19 +100,21 @@ abstract class ImmutableSetTestBase {
112100
expectSet("abcy12", set - setOf('x', 'z'))
113101
expectSet("abcxyz", set.removeAll { it.isDigit() })
114102

115-
assertEquals(emptySet<Char>(), set - set)
116-
assertEquals(emptySet<Char>(), set.clear())
103+
compareSets(emptySet(), set - set)
104+
compareSets(emptySet(), set.clear())
117105
}
118106

119107
@Test fun builder() {
120108
val builder = immutableSetOf<Char>().builder()
121109
"abcxaxyz12".toCollection(builder)
122110
val set = builder.build()
123-
assertEquals<Set<*>>(set, builder)
111+
compareSets(set, builder)
124112
assertTrue(set === builder.build(), "Building the same set without modifications")
125113

126114
val set2 = builder.toImmutableSet()
127115
assertTrue(set2 === set, "toImmutable calls build()")
116+
val set3 = builder.toPersistentSet()
117+
assertTrue(set3 === set, "toPersistent calls build()")
128118

129119
with(set) {
130120
testMutation { add('K') }
@@ -139,22 +129,20 @@ abstract class ImmutableSetTestBase {
139129
}
140130

141131
fun <T> PersistentSet<T>.testMutation(operation: MutableSet<T>.() -> Unit) {
142-
val mutable = this.toMutableSet()
132+
val mutable = HashSet(this) as MutableSet<T>
143133
val builder = this.builder()
144134

145135
operation(mutable)
146136
operation(builder)
147137

148-
assertEquals(mutable, builder)
149-
assertEquals<Set<*>>(mutable, builder.build())
138+
compareSetsUnordered(mutable, builder)
139+
compareSetsUnordered(mutable, builder.build())
150140
}
151141

152-
153-
154142
@Test open fun noOperation() {
155143
immutableSetOf<Int>().testNoOperation({ clear() }, { clear() })
156144

157-
val set = "abcxyz12".asIterable().toPersistentSet()
145+
val set = immutableSetOf("abcxyz12".toList())
158146
with(set) {
159147
testNoOperation({ add('a') }, { add('a') })
160148
testNoOperation({ addAll(listOf('a', 'b')) }, { addAll(listOf('a', 'b')) })

0 commit comments

Comments
 (0)