@@ -83,4 +83,81 @@ class FirstTest : TestBase() {
83
83
assertEquals(1 , flow.first())
84
84
finish(2 )
85
85
}
86
+
87
+ @Test
88
+ fun testFirstOrNull () = runTest {
89
+ val flow = flowOf(1 , 2 , 3 )
90
+ assertEquals(1 , flow.firstOrNull())
91
+ }
92
+
93
+ @Test
94
+ fun testFirstOrNullWithPredicate () = runTest {
95
+ val flow = flowOf(1 , 2 , 3 )
96
+ assertEquals(1 , flow.firstOrNull { it > 0 })
97
+ assertEquals(2 , flow.firstOrNull { it > 1 })
98
+ assertNull(flow.firstOrNull { it > 3 })
99
+ }
100
+
101
+ @Test
102
+ fun testFirstOrNullCancellation () = runTest {
103
+ val latch = Channel <Unit >()
104
+ val flow = flow {
105
+ coroutineScope {
106
+ launch {
107
+ latch.send(Unit )
108
+ hang { expect(1 ) }
109
+ }
110
+ emit(1 )
111
+ emit(2 )
112
+ }
113
+ }
114
+
115
+
116
+ val result = flow.firstOrNull {
117
+ latch.receive()
118
+ true
119
+ }
120
+ assertEquals(1 , result)
121
+ finish(2 )
122
+ }
123
+
124
+ @Test
125
+ fun testFirstOrNullWithEmptyFlow () = runTest {
126
+ assertNull(emptyFlow<Int >().firstOrNull())
127
+ assertNull(emptyFlow<Int >().firstOrNull { true })
128
+ }
129
+
130
+ @Test
131
+ fun testFirstOrNullWhenErrorCancelsUpstream () = runTest {
132
+ val latch = Channel <Unit >()
133
+ val flow = flow {
134
+ coroutineScope {
135
+ launch {
136
+ latch.send(Unit )
137
+ hang { expect(1 ) }
138
+ }
139
+ emit(1 )
140
+ }
141
+ }
142
+
143
+ assertFailsWith<TestException > {
144
+ flow.firstOrNull {
145
+ latch.receive()
146
+ throw TestException ()
147
+ }
148
+ }
149
+
150
+ assertEquals(1 , flow.firstOrNull())
151
+ finish(2 )
152
+ }
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
+ }
86
163
}
0 commit comments