Skip to content

Commit 8694e97

Browse files
committed
Fix documentation, fix equality check, add tests
1 parent 06e2a41 commit 8694e97

File tree

8 files changed

+28
-30
lines changed

8 files changed

+28
-30
lines changed

kotlinx-coroutines-core/common/src/flow/terminal/Reduce.kt

+5-5
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ public suspend fun <T> Flow<T>.first(predicate: suspend (T) -> Boolean): T {
123123

124124
/**
125125
* The terminal operator that returns the first element emitted by the flow and then cancels flow's collection.
126-
* Returns [null] if the flow was empty.
126+
* Returns `null` if the flow was empty.
127127
*/
128128
public suspend fun <T : Any> Flow<T>.firstOrNull(): T? {
129129
var result: Any? = NULL
@@ -135,12 +135,12 @@ public suspend fun <T : Any> Flow<T>.firstOrNull(): T? {
135135
} catch (e: AbortFlowException) {
136136
// Do nothing
137137
}
138-
return result.takeUnless { it == NULL } as T?
138+
return result.takeUnless { it === NULL } as T?
139139
}
140140

141141
/**
142-
* The terminal operator that returns the first element emitted by the flow and then cancels flow's collection.
143-
* Returns [null] if the flow did not contain an element matching the [predicate].
142+
* The terminal operator that returns the first element emitted by the flow matching the given [predicate] and then cancels flow's collection.
143+
* Returns `null` if the flow did not contain an element matching the [predicate].
144144
*/
145145
public suspend fun <T : Any> Flow<T>.firstOrNull(predicate: suspend (T) -> Boolean): T? {
146146
var result: Any? = NULL
@@ -154,5 +154,5 @@ public suspend fun <T : Any> Flow<T>.firstOrNull(predicate: suspend (T) -> Boole
154154
} catch (e: AbortFlowException) {
155155
// Do nothing
156156
}
157-
return result.takeUnless { it == NULL } as T?
157+
return result.takeUnless { it === NULL } as T?
158158
}

kotlinx-coroutines-core/common/test/AsyncTest.kt

-6
Original file line numberDiff line numberDiff line change
@@ -210,12 +210,6 @@ class AsyncTest : TestBase() {
210210
finish(13)
211211
}
212212

213-
class BadClass {
214-
override fun equals(other: Any?): Boolean = error("equals")
215-
override fun hashCode(): Int = error("hashCode")
216-
override fun toString(): String = error("toString")
217-
}
218-
219213
@Test
220214
fun testDeferBadClass() = runTest {
221215
val bad = BadClass()

kotlinx-coroutines-core/common/test/TestBase.common.kt

+5
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,8 @@ public fun wrapperDispatcher(context: CoroutineContext): CoroutineContext {
8080

8181
public suspend fun wrapperDispatcher(): CoroutineContext = wrapperDispatcher(coroutineContext)
8282

83+
class BadClass {
84+
override fun equals(other: Any?): Boolean = error("equals")
85+
override fun hashCode(): Int = error("hashCode")
86+
override fun toString(): String = error("toString")
87+
}

kotlinx-coroutines-core/common/test/WithTimeoutOrNullTest.kt

-6
Original file line numberDiff line numberDiff line change
@@ -152,12 +152,6 @@ class WithTimeoutOrNullTest : TestBase() {
152152
assertSame(bad, result)
153153
}
154154

155-
class BadClass {
156-
override fun equals(other: Any?): Boolean = error("Should not be called")
157-
override fun hashCode(): Int = error("Should not be called")
158-
override fun toString(): String = error("Should not be called")
159-
}
160-
161155
@Test
162156
fun testNullOnTimeout() = runTest {
163157
expect(1)

kotlinx-coroutines-core/common/test/WithTimeoutTest.kt

-6
Original file line numberDiff line numberDiff line change
@@ -107,12 +107,6 @@ class WithTimeoutTest : TestBase() {
107107
assertSame(bad, result)
108108
}
109109

110-
class BadClass {
111-
override fun equals(other: Any?): Boolean = error("Should not be called")
112-
override fun hashCode(): Int = error("Should not be called")
113-
override fun toString(): String = error("Should not be called")
114-
}
115-
116110
@Test
117111
fun testExceptionOnTimeout() = runTest {
118112
expect(1)

kotlinx-coroutines-core/common/test/channels/RendezvousChannelTest.kt

-6
Original file line numberDiff line numberDiff line change
@@ -241,12 +241,6 @@ class RendezvousChannelTest : TestBase() {
241241
finish(12)
242242
}
243243

244-
class BadClass {
245-
override fun equals(other: Any?): Boolean = error("equals")
246-
override fun hashCode(): Int = error("hashCode")
247-
override fun toString(): String = error("toString")
248-
}
249-
250244
@Test
251245
fun testProduceBadClass() = runTest {
252246
val bad = BadClass()

kotlinx-coroutines-core/common/test/flow/terminal/FirstTest.kt

+10
Original file line numberDiff line numberDiff line change
@@ -150,4 +150,14 @@ class FirstTest : TestBase() {
150150
assertEquals(1, flow.firstOrNull())
151151
finish(2)
152152
}
153+
154+
@Test
155+
fun testBadClass() = runTest {
156+
val instance = BadClass()
157+
val flow = flowOf(instance)
158+
assertSame(instance, flow.first())
159+
assertSame(instance, flow.firstOrNull())
160+
assertSame(instance, flow.first { true })
161+
assertSame(instance, flow.firstOrNull { true })
162+
}
153163
}

kotlinx-coroutines-core/common/test/flow/terminal/SingleTest.kt

+8-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ class SingleTest : TestBase() {
1717

1818
assertEquals(239L, flow.single())
1919
assertEquals(239L, flow.singleOrNull())
20-
2120
}
2221

2322
@Test
@@ -63,4 +62,12 @@ class SingleTest : TestBase() {
6362
assertNull(flowOf<Int?>(null).single())
6463
assertFailsWith<NoSuchElementException> { flowOf<Int?>().single() }
6564
}
65+
66+
@Test
67+
fun testBadClass() = runTest {
68+
val instance = BadClass()
69+
val flow = flowOf(instance)
70+
assertSame(instance, flow.single())
71+
assertSame(instance, flow.singleOrNull())
72+
}
6673
}

0 commit comments

Comments
 (0)