package kotlinx.coroutines.flow import kotlinx.coroutines.testing.* import kotlinx.coroutines.* import kotlinx.coroutines.channels.* import kotlinx.coroutines.flow.internal.* import kotlin.test.* class FirstTest : TestBase() { @Test fun testFirst() = runTest { val flow = flowOf(1, 2, 3) assertEquals(1, flow.first()) } @Test fun testNulls() = runTest { val flow = flowOf(null, 1) assertNull(flow.first()) assertNull(flow.first { it == null }) assertEquals(1, flow.first { it != null }) } @Test fun testFirstWithPredicate() = runTest { val flow = flowOf(1, 2, 3) assertEquals(1, flow.first { it > 0 }) assertEquals(2, flow.first { it > 1 }) assertFailsWith { flow.first { it > 3 } } } @Test fun testFirstCancellation() = runTest { val latch = Channel() val flow = flow { coroutineScope { launch { latch.send(Unit) hang { expect(1) } } emit(1) emit(2) } } val result = flow.first { latch.receive() true } assertEquals(1, result) finish(2) } @Test fun testEmptyFlow() = runTest { assertFailsWith { emptyFlow().first() } assertFailsWith { emptyFlow().first { true } } } @Test fun testErrorCancelsUpstream() = runTest { val latch = Channel() val flow = flow { coroutineScope { launch { latch.send(Unit) hang { expect(1) } } emit(1) } } assertFailsWith { flow.first { latch.receive() throw TestException() } } assertEquals(1, flow.first()) finish(2) } @Test fun testFirstOrNull() = runTest { val flow = flowOf(1, 2, 3) assertEquals(1, flow.firstOrNull()) } @Test fun testFirstOrNullWithPredicate() = runTest { val flow = flowOf(1, 2, 3) assertEquals(1, flow.firstOrNull { it > 0 }) assertEquals(2, flow.firstOrNull { it > 1 }) assertNull(flow.firstOrNull { it > 3 }) } @Test fun testFirstOrNullCancellation() = runTest { val latch = Channel() val flow = flow { coroutineScope { launch { latch.send(Unit) hang { expect(1) } } emit(1) emit(2) } } val result = flow.firstOrNull { latch.receive() true } assertEquals(1, result) finish(2) } @Test fun testFirstOrNullWithEmptyFlow() = runTest { assertNull(emptyFlow().firstOrNull()) assertNull(emptyFlow().firstOrNull { true }) } @Test fun testFirstOrNullWithNullElement() = runTest { assertNull(flowOf(null).firstOrNull()) assertNull(flowOf(null).firstOrNull { true }) } @Test fun testFirstOrNullWhenErrorCancelsUpstream() = runTest { val latch = Channel() val flow = flow { coroutineScope { launch { latch.send(Unit) hang { expect(1) } } emit(1) } } assertFailsWith { flow.firstOrNull { latch.receive() throw TestException() } } assertEquals(1, flow.firstOrNull()) finish(2) } @Test fun testBadClass() = runTest { val instance = BadClass() val flow = flowOf(instance) assertSame(instance, flow.first()) assertSame(instance, flow.firstOrNull()) assertSame(instance, flow.first { true }) assertSame(instance, flow.firstOrNull { true }) } @Test fun testAbortFlowException() = runTest { val flow = flow { throw AbortFlowException(NopCollector) // Emulate cancellation } assertFailsWith { flow.first() } } }