blob: e84d4c7b77f35292a4034e2557f3b29c705bfb9c [file] [log] [blame]
Vsevolod Tolstopyatovd5478b62019-06-06 11:43:31 +03001/*
2 * Copyright 2016-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3 */
4
5package kotlinx.coroutines.flow
6
7import kotlinx.coroutines.*
8import kotlinx.coroutines.channels.*
9import kotlin.test.*
10
11class FirstTest : TestBase() {
12 @Test
13 fun testFirst() = runTest {
14 val flow = flowOf(1, 2, 3)
15 assertEquals(1, flow.first())
16 }
17
18 @Test
19 fun testNulls() = runTest {
20 val flow = flowOf(null, 1)
21 assertNull(flow.first())
22 assertNull(flow.first { it == null })
23 assertEquals(1, flow.first { it != null })
24 }
25
26 @Test
27 fun testFirstWithPredicate() = runTest {
28 val flow = flowOf(1, 2, 3)
29 assertEquals(1, flow.first { it > 0 })
30 assertEquals(2, flow.first { it > 1 })
31 assertFailsWith<NoSuchElementException> { flow.first { it > 3 } }
32 }
33
34 @Test
35 fun testFirstCancellation() = runTest {
36 val latch = Channel<Unit>()
37 val flow = flow {
38 coroutineScope {
39 launch {
40 latch.send(Unit)
41 hang { expect(1) }
42 }
43 emit(1)
44 emit(2)
45 }
46 }
47
48
49 val result = flow.first {
50 latch.receive()
51 true
52 }
53 assertEquals(1, result)
54 finish(2)
55 }
56
57 @Test
58 fun testEmptyFlow() = runTest {
59 assertFailsWith<NoSuchElementException> { emptyFlow<Int>().first() }
60 assertFailsWith<NoSuchElementException> { emptyFlow<Int>().first { true } }
61 }
62
63 @Test
64 fun testErrorCancelsUpstream() = runTest {
65 val latch = Channel<Unit>()
66 val flow = flow {
67 coroutineScope {
68 launch {
69 latch.send(Unit)
70 hang { expect(1) }
71 }
72 emit(1)
73 }
74 }
75
76 assertFailsWith<TestException> {
77 flow.first {
78 latch.receive()
79 throw TestException()
80 }
81 }
82
83 assertEquals(1, flow.first())
84 finish(2)
85 }
86}