1
1
package rx .operators ;
2
2
3
- import static org .mockito .Mockito .mock ;
4
- import static org .mockito .Mockito .never ;
5
- import static org .mockito .Mockito .times ;
6
- import static org .mockito .Mockito .verify ;
7
- import static rx .util .functions .Functions .alwaysTrue ;
3
+ import static org .mockito .Mockito .*;
4
+ import static rx .util .functions .Functions .*;
8
5
9
6
import java .util .concurrent .atomic .AtomicBoolean ;
10
7
23
20
public final class OperationAny {
24
21
25
22
/**
26
- * Returns an {@link Observable} that emits <code>true</code> if the source
27
- * {@link Observable} is not empty, otherwise <code>false</code>.
23
+ * Returns an {@link Observable} that emits <code>true</code> if the source {@link Observable} is not empty, otherwise <code>false</code>.
28
24
*
29
25
* @param source
30
26
* The source {@link Observable} to check if not empty.
31
27
* @return A subscription function for creating the target Observable.
32
28
*/
33
- public static <T > OnSubscribeFunc <Boolean > any (
34
- Observable <? extends T > source ) {
35
- return new Any <T >(source , alwaysTrue ());
29
+ public static <T > OnSubscribeFunc <Boolean > any (Observable <? extends T > source ) {
30
+ return new Any <T >(source , alwaysTrue (), false );
31
+ }
32
+
33
+ public static <T > OnSubscribeFunc <Boolean > isEmpty (Observable <? extends T > source ) {
34
+ return new Any <T >(source , alwaysTrue (), true );
36
35
}
37
36
38
37
/**
39
38
* Returns an {@link Observable} that emits <code>true</code> if any element
40
39
* of the source {@link Observable} satisfies the given condition, otherwise
41
- * <code>false</code>. Note: always emit <code>false</code> if the source
42
- * {@link Observable} is empty.
40
+ * <code>false</code>. Note: always emit <code>false</code> if the source {@link Observable} is empty.
43
41
*
44
42
* @param source
45
43
* The source {@link Observable} to check if any element
@@ -48,42 +46,43 @@ public static <T> OnSubscribeFunc<Boolean> any(
48
46
* The condition to test every element.
49
47
* @return A subscription function for creating the target Observable.
50
48
*/
51
- public static <T > OnSubscribeFunc <Boolean > any (
52
- Observable <? extends T > source , Func1 <? super T , Boolean > predicate ) {
53
- return new Any <T >(source , predicate );
49
+ public static <T > OnSubscribeFunc <Boolean > any (Observable <? extends T > source , Func1 <? super T , Boolean > predicate ) {
50
+ return new Any <T >(source , predicate , false );
51
+ }
52
+
53
+ public static <T > OnSubscribeFunc <Boolean > exists (Observable <? extends T > source , Func1 <? super T , Boolean > predicate ) {
54
+ return any (source , predicate );
54
55
}
55
56
56
57
private static class Any <T > implements OnSubscribeFunc <Boolean > {
57
58
58
59
private final Observable <? extends T > source ;
59
60
private final Func1 <? super T , Boolean > predicate ;
61
+ private final boolean returnOnEmpty ;
60
62
61
- private Any (Observable <? extends T > source ,
62
- Func1 <? super T , Boolean > predicate ) {
63
+ private Any (Observable <? extends T > source , Func1 <? super T , Boolean > predicate , boolean returnOnEmpty ) {
63
64
this .source = source ;
64
65
this .predicate = predicate ;
66
+ this .returnOnEmpty = returnOnEmpty ;
65
67
}
66
68
67
69
@ Override
68
70
public Subscription onSubscribe (final Observer <? super Boolean > observer ) {
69
71
final SafeObservableSubscription subscription = new SafeObservableSubscription ();
70
72
return subscription .wrap (source .subscribe (new Observer <T >() {
71
73
72
- private final AtomicBoolean hasEmitted = new AtomicBoolean (
73
- false );
74
+ private final AtomicBoolean hasEmitted = new AtomicBoolean (false );
74
75
75
76
@ Override
76
77
public void onNext (T value ) {
77
78
try {
78
79
if (hasEmitted .get () == false ) {
79
80
if (predicate .call (value ) == true
80
81
&& hasEmitted .getAndSet (true ) == false ) {
81
- observer .onNext (true );
82
+ observer .onNext (! returnOnEmpty );
82
83
observer .onCompleted ();
83
- // this will work if the sequence is
84
- // asynchronous, it
85
- // will have no effect on a synchronous
86
- // observable
84
+ // this will work if the sequence is asynchronous, it
85
+ // will have no effect on a synchronous observable
87
86
subscription .unsubscribe ();
88
87
}
89
88
}
@@ -104,7 +103,7 @@ public void onError(Throwable ex) {
104
103
@ Override
105
104
public void onCompleted () {
106
105
if (!hasEmitted .get ()) {
107
- observer .onNext (false );
106
+ observer .onNext (returnOnEmpty );
108
107
observer .onCompleted ();
109
108
}
110
109
}
@@ -125,8 +124,21 @@ public void testAnyWithTwoItems() {
125
124
observable .subscribe (aObserver );
126
125
verify (aObserver , never ()).onNext (false );
127
126
verify (aObserver , times (1 )).onNext (true );
128
- verify (aObserver , never ()).onError (
129
- org .mockito .Matchers .any (Throwable .class ));
127
+ verify (aObserver , never ()).onError (org .mockito .Matchers .any (Throwable .class ));
128
+ verify (aObserver , times (1 )).onCompleted ();
129
+ }
130
+
131
+ @ Test
132
+ public void testIsEmptyWithTwoItems () {
133
+ Observable <Integer > w = Observable .from (1 , 2 );
134
+ Observable <Boolean > observable = Observable .create (isEmpty (w ));
135
+
136
+ @ SuppressWarnings ("unchecked" )
137
+ Observer <Boolean > aObserver = mock (Observer .class );
138
+ observable .subscribe (aObserver );
139
+ verify (aObserver , never ()).onNext (true );
140
+ verify (aObserver , times (1 )).onNext (false );
141
+ verify (aObserver , never ()).onError (org .mockito .Matchers .any (Throwable .class ));
130
142
verify (aObserver , times (1 )).onCompleted ();
131
143
}
132
144
@@ -140,8 +152,21 @@ public void testAnyWithOneItem() {
140
152
observable .subscribe (aObserver );
141
153
verify (aObserver , never ()).onNext (false );
142
154
verify (aObserver , times (1 )).onNext (true );
143
- verify (aObserver , never ()).onError (
144
- org .mockito .Matchers .any (Throwable .class ));
155
+ verify (aObserver , never ()).onError (org .mockito .Matchers .any (Throwable .class ));
156
+ verify (aObserver , times (1 )).onCompleted ();
157
+ }
158
+
159
+ @ Test
160
+ public void testIsEmptyWithOneItem () {
161
+ Observable <Integer > w = Observable .from (1 );
162
+ Observable <Boolean > observable = Observable .create (isEmpty (w ));
163
+
164
+ @ SuppressWarnings ("unchecked" )
165
+ Observer <Boolean > aObserver = mock (Observer .class );
166
+ observable .subscribe (aObserver );
167
+ verify (aObserver , never ()).onNext (true );
168
+ verify (aObserver , times (1 )).onNext (false );
169
+ verify (aObserver , never ()).onError (org .mockito .Matchers .any (Throwable .class ));
145
170
verify (aObserver , times (1 )).onCompleted ();
146
171
}
147
172
@@ -155,8 +180,21 @@ public void testAnyWithEmpty() {
155
180
observable .subscribe (aObserver );
156
181
verify (aObserver , times (1 )).onNext (false );
157
182
verify (aObserver , never ()).onNext (true );
158
- verify (aObserver , never ()).onError (
159
- org .mockito .Matchers .any (Throwable .class ));
183
+ verify (aObserver , never ()).onError (org .mockito .Matchers .any (Throwable .class ));
184
+ verify (aObserver , times (1 )).onCompleted ();
185
+ }
186
+
187
+ @ Test
188
+ public void testIsEmptyWithEmpty () {
189
+ Observable <Integer > w = Observable .empty ();
190
+ Observable <Boolean > observable = Observable .create (isEmpty (w ));
191
+
192
+ @ SuppressWarnings ("unchecked" )
193
+ Observer <Boolean > aObserver = mock (Observer .class );
194
+ observable .subscribe (aObserver );
195
+ verify (aObserver , times (1 )).onNext (true );
196
+ verify (aObserver , never ()).onNext (false );
197
+ verify (aObserver , never ()).onError (org .mockito .Matchers .any (Throwable .class ));
160
198
verify (aObserver , times (1 )).onCompleted ();
161
199
}
162
200
@@ -177,11 +215,31 @@ public Boolean call(Integer t1) {
177
215
observable .subscribe (aObserver );
178
216
verify (aObserver , never ()).onNext (false );
179
217
verify (aObserver , times (1 )).onNext (true );
180
- verify (aObserver , never ()).onError (
181
- org .mockito .Matchers .any (Throwable .class ));
218
+ verify (aObserver , never ()).onError (org .mockito .Matchers .any (Throwable .class ));
182
219
verify (aObserver , times (1 )).onCompleted ();
183
220
}
184
221
222
+ @ Test
223
+ public void testExists1 () {
224
+ Observable <Integer > w = Observable .from (1 , 2 , 3 );
225
+ Observable <Boolean > observable = Observable .create (exists (w ,
226
+ new Func1 <Integer , Boolean >() {
227
+
228
+ @ Override
229
+ public Boolean call (Integer t1 ) {
230
+ return t1 < 2 ;
231
+ }
232
+ }));
233
+
234
+ @ SuppressWarnings ("unchecked" )
235
+ Observer <Boolean > aObserver = mock (Observer .class );
236
+ observable .subscribe (aObserver );
237
+ verify (aObserver , never ()).onNext (false );
238
+ verify (aObserver , times (1 )).onNext (true );
239
+ verify (aObserver , never ()).onError (org .mockito .Matchers .any (Throwable .class ));
240
+ verify (aObserver , times (1 )).onCompleted ();
241
+ }
242
+
185
243
@ Test
186
244
public void testAnyWithPredicate2 () {
187
245
Observable <Integer > w = Observable .from (1 , 2 , 3 );
@@ -199,8 +257,7 @@ public Boolean call(Integer t1) {
199
257
observable .subscribe (aObserver );
200
258
verify (aObserver , times (1 )).onNext (false );
201
259
verify (aObserver , never ()).onNext (true );
202
- verify (aObserver , never ()).onError (
203
- org .mockito .Matchers .any (Throwable .class ));
260
+ verify (aObserver , never ()).onError (org .mockito .Matchers .any (Throwable .class ));
204
261
verify (aObserver , times (1 )).onCompleted ();
205
262
}
206
263
@@ -222,8 +279,7 @@ public Boolean call(Integer t1) {
222
279
observable .subscribe (aObserver );
223
280
verify (aObserver , times (1 )).onNext (false );
224
281
verify (aObserver , never ()).onNext (true );
225
- verify (aObserver , never ()).onError (
226
- org .mockito .Matchers .any (Throwable .class ));
282
+ verify (aObserver , never ()).onError (org .mockito .Matchers .any (Throwable .class ));
227
283
verify (aObserver , times (1 )).onCompleted ();
228
284
}
229
285
}
0 commit comments