All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonTest.flow.terminal.FirstTest.kt Maven / Gradle / Ivy

There is a newer version: 1.9.0
Show newest version
/*
 * Copyright 2016-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
 */

package kotlinx.coroutines.flow

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() }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy