1
1
package com.mvcoding.mvp
2
2
3
- import com.nhaarman.mockito_kotlin.mock
4
- import com.nhaarman.mockito_kotlin.whenever
3
+ import com.nhaarman.mockitokotlin2.mock
4
+ import com.nhaarman.mockitokotlin2.whenever
5
+ import io.reactivex.*
6
+ import org.junit.Before
5
7
import org.junit.Test
6
- import rx.Observable
7
- import rx.Observable.just
8
8
import kotlin.test.assertFalse
9
+ import kotlin.test.assertTrue
9
10
10
11
class PresenterTest {
11
- val view = mock<Presenter .View >()
12
- val presenter: Presenter <Presenter .View > = object : Presenter <Presenter .View >() {
12
+ private val view = mock<Presenter .View >()
13
+ private val presenter: Presenter <Presenter .View > = object : Presenter <Presenter .View >() {}
14
+ private val viewForTest = mock<ViewForTest >()
15
+
16
+ @Before
17
+ fun setUp () {
18
+ whenever(viewForTest.observable()).thenReturn(Observable .never())
19
+ whenever(viewForTest.observableOnNext()).thenReturn(Observable .never())
20
+ whenever(viewForTest.observableOnNextOnError()).thenReturn(Observable .never())
21
+ whenever(viewForTest.observableOnNextOnErrorOnComplete()).thenReturn(Observable .never())
22
+ whenever(viewForTest.flowable()).thenReturn(Flowable .never())
23
+ whenever(viewForTest.flowableOnNext()).thenReturn(Flowable .never())
24
+ whenever(viewForTest.flowableOnNextOnError()).thenReturn(Flowable .never())
25
+ whenever(viewForTest.flowableOnNextOnErrorOnComplete()).thenReturn(Flowable .never())
26
+ whenever(viewForTest.single()).thenReturn(Single .never())
27
+ whenever(viewForTest.singleOnSuccess()).thenReturn(Single .never())
28
+ whenever(viewForTest.singleOnSuccessOnError()).thenReturn(Single .never())
29
+ whenever(viewForTest.maybe()).thenReturn(Maybe .never())
30
+ whenever(viewForTest.maybeOnSuccess()).thenReturn(Maybe .never())
31
+ whenever(viewForTest.maybeOnSuccessOnError()).thenReturn(Maybe .never())
32
+ whenever(viewForTest.maybeOnSuccessOnErrorOnComplete()).thenReturn(Maybe .never())
13
33
}
14
34
15
35
@Test(expected = IllegalStateException ::class )
16
- fun throwsIllegalStateExceptionWhenViewIsAlreadyAttached () {
36
+ fun `throws error when view is already attached` () {
17
37
presenter attach view
18
38
presenter attach view
19
39
}
20
40
21
41
@Test(expected = IllegalStateException ::class )
22
- fun throwsIllegalStateExceptionWhenViewWasNotAttached () {
42
+ fun `throws error when view was not attached` () {
23
43
presenter detach view
24
44
}
25
45
26
46
@Test(expected = IllegalStateException ::class )
27
- fun throwsIllegalStateExceptionWhenViewWasAlreadyDetached () {
47
+ fun `throws error when view was already detached` () {
28
48
presenter attach view
29
49
presenter detach view
30
50
presenter detach view
31
51
}
32
52
33
53
@Test(expected = IllegalStateException ::class )
34
- fun throwsIllegalStateExceptionWhenTryingToDetachDifferentView () {
54
+ fun `throws error when trying to detach different view` () {
35
55
presenter attach view
36
- presenter detach mock< Presenter . View > ()
56
+ presenter detach mock()
37
57
}
38
58
39
59
@Test
40
- fun subscribeUntilDetachUnsubscribesAfterDetach () {
60
+ fun `subscribe until detach disposes observable after detach` () {
41
61
val presenter = PresenterForTest ()
42
- val view = mock<ViewForTest >()
43
- var isSubscribed = false
44
- val events = just(Unit ).doOnSubscribe { isSubscribed = true }.doOnUnsubscribe { isSubscribed = false }
45
- whenever(view.events()).thenReturn(events)
46
62
47
- presenter attach view
48
- presenter detach view
63
+ var observableIsDisposed = true
64
+ var observableOnNextIsDisposed = true
65
+ var observableOnNextOnErrorIsDisposed = true
66
+ var observableOnNextOnErrorOnCompleteIsDisposed = true
67
+
68
+ val observable = Observable .create<Unit > { }.doOnSubscribe { observableIsDisposed = false }.doFinally { observableIsDisposed = true }
69
+ val observableOnNext = Observable .create<Unit > { }.doOnSubscribe { observableOnNextIsDisposed = false }.doFinally { observableOnNextIsDisposed = true }
70
+ val observableOnNextOnError = Observable .create<Unit > { }.doOnSubscribe { observableOnNextOnErrorIsDisposed = false }.doFinally { observableOnNextOnErrorIsDisposed = true }
71
+ val observableOnNextOnErrorOnComplete = Observable .create<Unit > { }.doOnSubscribe { observableOnNextOnErrorOnCompleteIsDisposed = false }.doFinally { observableOnNextOnErrorOnCompleteIsDisposed = true }
72
+
73
+ whenever(viewForTest.observable()).thenReturn(observable)
74
+ whenever(viewForTest.observableOnNext()).thenReturn(observableOnNext)
75
+ whenever(viewForTest.observableOnNextOnError()).thenReturn(observableOnNextOnError)
76
+ whenever(viewForTest.observableOnNextOnErrorOnComplete()).thenReturn(observableOnNextOnErrorOnComplete)
77
+
78
+ presenter attach viewForTest
79
+ assertFalse { observableIsDisposed }
80
+ assertFalse { observableOnNextIsDisposed }
81
+ assertFalse { observableOnNextOnErrorIsDisposed }
82
+ assertFalse { observableOnNextOnErrorOnCompleteIsDisposed }
83
+
84
+ presenter detach viewForTest
85
+ assertTrue { observableIsDisposed }
86
+ assertTrue { observableOnNextIsDisposed }
87
+ assertTrue { observableOnNextOnErrorIsDisposed }
88
+ assertTrue { observableOnNextOnErrorOnCompleteIsDisposed }
89
+ }
90
+
91
+ @Test
92
+ fun `subscribe until detach disposes flowable after detach` () {
93
+ val presenter = PresenterForTest ()
94
+
95
+ var flowableIsDisposed = true
96
+ var flowableOnNextIsDisposed = true
97
+ var flowableOnNextOnErrorIsDisposed = true
98
+ var flowableOnNextOnErrorOnCompleteIsDisposed = true
99
+
100
+ val flowable = Flowable .create<Unit >({}, BackpressureStrategy .DROP ).doOnSubscribe { flowableIsDisposed = false }.doFinally { flowableIsDisposed = true }
101
+ val flowableOnNext = Flowable .create<Unit >({}, BackpressureStrategy .DROP ).doOnSubscribe { flowableOnNextIsDisposed = false }.doFinally { flowableOnNextIsDisposed = true }
102
+ val flowableOnNextOnError = Flowable .create<Unit >({}, BackpressureStrategy .DROP ).doOnSubscribe { flowableOnNextOnErrorIsDisposed = false }.doFinally { flowableOnNextOnErrorIsDisposed = true }
103
+ val flowableOnNextOnErrorOnComplete = Flowable .create<Unit >({}, BackpressureStrategy .DROP ).doOnSubscribe { flowableOnNextOnErrorOnCompleteIsDisposed = false }.doFinally { flowableOnNextOnErrorOnCompleteIsDisposed = true }
104
+
105
+ whenever(viewForTest.flowable()).thenReturn(flowable)
106
+ whenever(viewForTest.flowableOnNext()).thenReturn(flowableOnNext)
107
+ whenever(viewForTest.flowableOnNextOnError()).thenReturn(flowableOnNextOnError)
108
+ whenever(viewForTest.flowableOnNextOnErrorOnComplete()).thenReturn(flowableOnNextOnErrorOnComplete)
109
+
110
+ presenter attach viewForTest
111
+ assertFalse { flowableIsDisposed }
112
+ assertFalse { flowableOnNextIsDisposed }
113
+ assertFalse { flowableOnNextOnErrorIsDisposed }
114
+ assertFalse { flowableOnNextOnErrorOnCompleteIsDisposed }
115
+
116
+ presenter detach viewForTest
117
+ assertTrue { flowableIsDisposed }
118
+ assertTrue { flowableOnNextIsDisposed }
119
+ assertTrue { flowableOnNextOnErrorIsDisposed }
120
+ assertTrue { flowableOnNextOnErrorOnCompleteIsDisposed }
121
+ }
122
+
123
+ @Test
124
+ fun `subscribe until detach disposes single after detach` () {
125
+ val presenter = PresenterForTest ()
126
+
127
+ var singleIsDisposed = true
128
+ var singleOnNextIsDisposed = true
129
+ var singleOnNextOnErrorIsDisposed = true
130
+
131
+ val single = Single .create<Unit > { }.doOnSubscribe { singleIsDisposed = false }.doFinally { singleIsDisposed = true }
132
+ val singleOnNext = Single .create<Unit > { }.doOnSubscribe { singleOnNextIsDisposed = false }.doFinally { singleOnNextIsDisposed = true }
133
+ val singleOnNextOnError = Single .create<Unit > { }.doOnSubscribe { singleOnNextOnErrorIsDisposed = false }.doFinally { singleOnNextOnErrorIsDisposed = true }
134
+
135
+ whenever(viewForTest.single()).thenReturn(single)
136
+ whenever(viewForTest.singleOnSuccess()).thenReturn(singleOnNext)
137
+ whenever(viewForTest.singleOnSuccessOnError()).thenReturn(singleOnNextOnError)
138
+
139
+ presenter attach viewForTest
140
+ assertFalse { singleIsDisposed }
141
+ assertFalse { singleOnNextIsDisposed }
142
+ assertFalse { singleOnNextOnErrorIsDisposed }
143
+
144
+ presenter detach viewForTest
145
+ assertTrue { singleIsDisposed }
146
+ assertTrue { singleOnNextIsDisposed }
147
+ assertTrue { singleOnNextOnErrorIsDisposed }
148
+ }
149
+
150
+ @Test
151
+ fun `subscribe until detach disposes maybe after detach` () {
152
+ val presenter = PresenterForTest ()
153
+
154
+ var maybeIsDisposed = true
155
+ var maybeOnNextIsDisposed = true
156
+ var maybeOnNextOnErrorIsDisposed = true
157
+ var maybeOnNextOnErrorOnCompleteIsDisposed = true
158
+
159
+ val maybe = Maybe .create<Unit > { }.doOnSubscribe { maybeIsDisposed = false }.doFinally { maybeIsDisposed = true }
160
+ val maybeOnNext = Maybe .create<Unit > { }.doOnSubscribe { maybeOnNextIsDisposed = false }.doFinally { maybeOnNextIsDisposed = true }
161
+ val maybeOnNextOnError = Maybe .create<Unit > { }.doOnSubscribe { maybeOnNextOnErrorIsDisposed = false }.doFinally { maybeOnNextOnErrorIsDisposed = true }
162
+ val maybeOnNextOnErrorOnComplete = Maybe .create<Unit > { }.doOnSubscribe { maybeOnNextOnErrorOnCompleteIsDisposed = false }.doFinally { maybeOnNextOnErrorOnCompleteIsDisposed = true }
163
+
164
+ whenever(viewForTest.maybe()).thenReturn(maybe)
165
+ whenever(viewForTest.maybeOnSuccess()).thenReturn(maybeOnNext)
166
+ whenever(viewForTest.maybeOnSuccessOnError()).thenReturn(maybeOnNextOnError)
167
+ whenever(viewForTest.maybeOnSuccessOnErrorOnComplete()).thenReturn(maybeOnNextOnErrorOnComplete)
168
+
169
+ presenter attach viewForTest
170
+ assertFalse { maybeIsDisposed }
171
+ assertFalse { maybeOnNextIsDisposed }
172
+ assertFalse { maybeOnNextOnErrorIsDisposed }
173
+ assertFalse { maybeOnNextOnErrorOnCompleteIsDisposed }
49
174
50
- assertFalse { isSubscribed }
175
+ presenter detach viewForTest
176
+ assertTrue { maybeIsDisposed }
177
+ assertTrue { maybeOnNextIsDisposed }
178
+ assertTrue { maybeOnNextOnErrorIsDisposed }
179
+ assertTrue { maybeOnNextOnErrorOnCompleteIsDisposed }
51
180
}
52
181
53
182
interface ViewForTest : Presenter .View {
54
- fun events (): Observable <Unit >
183
+ fun observable (): Observable <Unit >
184
+ fun observableOnNext (): Observable <Unit >
185
+ fun observableOnNextOnError (): Observable <Unit >
186
+ fun observableOnNextOnErrorOnComplete (): Observable <Unit >
187
+ fun flowable (): Flowable <Unit >
188
+ fun flowableOnNext (): Flowable <Unit >
189
+ fun flowableOnNextOnError (): Flowable <Unit >
190
+ fun flowableOnNextOnErrorOnComplete (): Flowable <Unit >
191
+ fun single (): Single <Unit >
192
+ fun singleOnSuccess (): Single <Unit >
193
+ fun singleOnSuccessOnError (): Single <Unit >
194
+ fun maybe (): Maybe <Unit >
195
+ fun maybeOnSuccess (): Maybe <Unit >
196
+ fun maybeOnSuccessOnError (): Maybe <Unit >
197
+ fun maybeOnSuccessOnErrorOnComplete (): Maybe <Unit >
55
198
}
56
199
57
200
class PresenterForTest : Presenter <ViewForTest >() {
58
201
override fun onViewAttached (view : ViewForTest ) {
59
202
super .onViewAttached(view)
60
- view.events().subscribeUntilDetached { }
203
+ view.observable().subscribeUntilDetached()
204
+ view.observableOnNext().subscribeUntilDetached()
205
+ view.observableOnNextOnError().subscribeUntilDetached()
206
+ view.observableOnNextOnErrorOnComplete().subscribeUntilDetached()
207
+ view.flowable().subscribeUntilDetached()
208
+ view.flowableOnNext().subscribeUntilDetached()
209
+ view.flowableOnNextOnError().subscribeUntilDetached()
210
+ view.flowableOnNextOnErrorOnComplete().subscribeUntilDetached()
211
+ view.single().subscribeUntilDetached()
212
+ view.singleOnSuccess().subscribeUntilDetached()
213
+ view.singleOnSuccessOnError().subscribeUntilDetached()
214
+ view.maybe().subscribeUntilDetached()
215
+ view.maybeOnSuccess().subscribeUntilDetached()
216
+ view.maybeOnSuccessOnError().subscribeUntilDetached()
217
+ view.maybeOnSuccessOnErrorOnComplete().subscribeUntilDetached()
61
218
}
62
219
}
63
220
}
0 commit comments