Repository: Kotlin/kotlinx.coroutines
File: kotlinx-coroutines-core/common/test/flow/operators/TimeoutTest.kt (Kotlin)

Code before:
    }

    @Test
    fun testEmpty() = withVirtualTime {
        val flow = emptyFlow<Any?>().timeout(1.milliseconds)
        assertNull(flow.singleOrNull())
        finish(1)
    }

    @Test
    fun testScalar() = withVirtualTime {
        val flow = flowOf(1, 2, 3).timeout(1.milliseconds)
        assertEquals(listOf(1, 2, 3), flow.toList())
        finish(1)
    }

    @Test
    fun testUpstreamError() = testUpstreamError(TestException())

    @Test
    fun testUpstreamErrorTimeoutException() = testUpstreamError(TimeoutCancellationException(0, Job()))

    @Test
    fun testUpstreamErrorCancellationException() = testUpstreamError(CancellationException(""))

    private inline fun <reified T: Throwable> testUpstreamError(cause: T) = runTest {
        try {
            // Workaround for JS legacy bug
            flow {
                emit(1)
                throw cause
            }.timeout(1000.milliseconds).collect()
            expectUnreached()
        } catch (e: Throwable) {
            assertIs<T>(e)
            finish(1)
        }
    }

    @Test
    fun testDownstreamError() = runTest {
        val flow = flow {
            expect(1)
            emit(1)
            hang { expect(3) }
            expectUnreached()
        }.timeout(100.milliseconds).map {
            expect(2)
            yield()
            throw TestException()
        }

Review comment (suggestion):
I looked through the file, and it seems that everywhere, `withVirtualTime` is used. Is there a reason not to do that here? Then, we would be okay with 1 millisecond, too.

Code after:
    }

    @Test
    fun testEmpty() = withVirtualTime {
        val flow = emptyFlow<Any?>().timeout(1.milliseconds)
        assertNull(flow.singleOrNull())
        finish(1)
    }

    @Test
    fun testScalar() = withVirtualTime {
        val flow = flowOf(1, 2, 3).timeout(1.milliseconds)
        assertEquals(listOf(1, 2, 3), flow.toList())
        finish(1)
    }

    @Test
    fun testUpstreamError() = testUpstreamError(TestException())

    @Test
    fun testUpstreamErrorTimeoutException() = testUpstreamError(TimeoutCancellationException(0, Job()))

    @Test
    fun testUpstreamErrorCancellationException() = testUpstreamError(CancellationException(""))

    private inline fun <reified T: Throwable> testUpstreamError(cause: T) = runTest {
        try {
            // Workaround for JS legacy bug
            flow {
                emit(1)
                throw cause
            }.timeout(1000.milliseconds).collect()
            expectUnreached()
        } catch (e: Throwable) {
            assertTrue { e is T }
            finish(1)
        }
    }

    @Test
    fun testUpstreamExceptionsTakingPriority() = withVirtualTime {
        val flow = flow<Unit> {
            expect(2)
            withContext(NonCancellable) {
                delay(2.milliseconds)
            }
            assertFalse(currentCoroutineContext().isActive) // cancelled already
            expect(3)
            throw TestException()
        }.timeout(1.milliseconds)
        expect(1)