1/*
2 * Copyright (C) 2005 The Guava Authors
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.google.common.base;
18
19import static com.google.common.base.CharMatcher.WHITESPACE;
20
21import com.google.common.annotations.GwtCompatible;
22import com.google.common.annotations.GwtIncompatible;
23import com.google.common.collect.ImmutableSet;
24import com.google.common.testing.EqualsTester;
25import com.google.common.testing.NullPointerTester;
26import com.google.common.testing.SerializableTester;
27
28import junit.framework.TestCase;
29
30import java.io.Serializable;
31import java.util.ArrayList;
32import java.util.Arrays;
33import java.util.Collection;
34import java.util.Collections;
35import java.util.Iterator;
36import java.util.List;
37import java.util.regex.Pattern;
38
39/**
40 * Unit test for {@link Predicates}.
41 *
42 * @author Kevin Bourrillion
43 */
44@GwtCompatible(emulated = true)
45public class PredicatesTest extends TestCase {
46  private static final Predicate<Integer> TRUE = Predicates.alwaysTrue();
47  private static final Predicate<Integer> FALSE = Predicates.alwaysFalse();
48  private static final Predicate<Integer> NEVER_REACHED =
49      new Predicate<Integer>() {
50    @Override
51    public boolean apply(Integer i) {
52      fail("This predicate should never have been evaluated");
53      return false;
54    }
55  };
56
57  /** Instantiable predicate with reasonable hashCode() and equals() methods. */
58  static class IsOdd implements Predicate<Integer>, Serializable {
59    private static final long serialVersionUID = 0x150ddL;
60    @Override
61    public boolean apply(Integer i) {
62      return (i.intValue() & 1) == 1;
63    }
64    @Override public int hashCode() {
65      return 0x150dd;
66    }
67    @Override public boolean equals(Object obj) {
68      return obj instanceof IsOdd;
69    }
70    @Override public String toString() {
71      return "IsOdd";
72    }
73  }
74
75  /**
76   * Generates a new Predicate per call.
77   *
78   * <p>Creating a new Predicate each time helps catch cases where code is
79   * using {@code x == y} instead of {@code x.equals(y)}.
80   */
81  private static IsOdd isOdd() {
82    return new IsOdd();
83  }
84
85  /*
86   * Tests for Predicates.alwaysTrue().
87   */
88
89  public void testAlwaysTrue_apply() {
90    assertEvalsToTrue(Predicates.alwaysTrue());
91  }
92
93  public void testAlwaysTrue_equality() throws Exception {
94    new EqualsTester()
95        .addEqualityGroup(TRUE, Predicates.alwaysTrue())
96        .addEqualityGroup(isOdd())
97        .addEqualityGroup(Predicates.alwaysFalse())
98        .testEquals();
99  }
100
101  @GwtIncompatible("SerializableTester")
102  public void testAlwaysTrue_serialization() {
103    checkSerialization(Predicates.alwaysTrue());
104  }
105
106  /*
107   * Tests for Predicates.alwaysFalse().
108   */
109
110  public void testAlwaysFalse_apply() throws Exception {
111    assertEvalsToFalse(Predicates.alwaysFalse());
112  }
113
114  public void testAlwaysFalse_equality() throws Exception {
115    new EqualsTester()
116        .addEqualityGroup(FALSE, Predicates.alwaysFalse())
117        .addEqualityGroup(isOdd())
118        .addEqualityGroup(Predicates.alwaysTrue())
119        .testEquals();
120  }
121
122  @GwtIncompatible("SerializableTester")
123  public void testAlwaysFalse_serialization() {
124    checkSerialization(Predicates.alwaysFalse());
125  }
126
127  /*
128   * Tests for Predicates.not(predicate).
129   */
130
131  public void testNot_apply() {
132    assertEvalsToTrue(Predicates.not(FALSE));
133    assertEvalsToFalse(Predicates.not(TRUE));
134    assertEvalsLikeOdd(Predicates.not(Predicates.not(isOdd())));
135  }
136
137  public void testNot_equality() {
138    new EqualsTester()
139        .addEqualityGroup(Predicates.not(isOdd()), Predicates.not(isOdd()))
140        .addEqualityGroup(Predicates.not(TRUE))
141        .addEqualityGroup(isOdd())
142        .testEquals();
143  }
144
145  public void testNot_equalityForNotOfKnownValues() {
146    new EqualsTester()
147        .addEqualityGroup(TRUE, Predicates.alwaysTrue())
148        .addEqualityGroup(FALSE)
149        .addEqualityGroup(Predicates.not(TRUE))
150        .testEquals();
151
152    new EqualsTester()
153        .addEqualityGroup(FALSE, Predicates.alwaysFalse())
154        .addEqualityGroup(TRUE)
155        .addEqualityGroup(Predicates.not(FALSE))
156        .testEquals();
157
158    new EqualsTester()
159        .addEqualityGroup(Predicates.isNull(), Predicates.isNull())
160        .addEqualityGroup(Predicates.notNull())
161        .addEqualityGroup(Predicates.not(Predicates.isNull()))
162        .testEquals();
163
164    new EqualsTester()
165        .addEqualityGroup(Predicates.notNull(), Predicates.notNull())
166        .addEqualityGroup(Predicates.isNull())
167        .addEqualityGroup(Predicates.not(Predicates.notNull()))
168        .testEquals();
169  }
170
171  @GwtIncompatible("SerializableTester")
172  public void testNot_serialization() {
173    checkSerialization(Predicates.not(isOdd()));
174  }
175
176  /*
177   * Tests for all the different flavors of Predicates.and().
178   */
179
180  @SuppressWarnings("unchecked")
181  public void testAnd_applyNoArgs() {
182    assertEvalsToTrue(Predicates.and());
183  }
184
185  @SuppressWarnings("unchecked")
186  public void testAnd_equalityNoArgs() {
187    new EqualsTester()
188        .addEqualityGroup(Predicates.and(), Predicates.and())
189        .addEqualityGroup(Predicates.and(FALSE))
190        .addEqualityGroup(Predicates.or())
191        .testEquals();
192  }
193
194  @GwtIncompatible("SerializableTester")
195  @SuppressWarnings("unchecked")
196  public void testAnd_serializationNoArgs() {
197    checkSerialization(Predicates.and());
198  }
199
200  @SuppressWarnings("unchecked")
201  public void testAnd_applyOneArg() {
202    assertEvalsLikeOdd(Predicates.and(isOdd()));
203  }
204
205  @SuppressWarnings("unchecked")
206  public void testAnd_equalityOneArg() {
207    Object[] notEqualObjects = {Predicates.and(NEVER_REACHED, FALSE)};
208    new EqualsTester()
209        .addEqualityGroup(
210            Predicates.and(NEVER_REACHED), Predicates.and(NEVER_REACHED))
211        .addEqualityGroup(notEqualObjects)
212        .addEqualityGroup(Predicates.and(isOdd()))
213        .addEqualityGroup(Predicates.and())
214        .addEqualityGroup(Predicates.or(NEVER_REACHED))
215        .testEquals();
216  }
217
218  @GwtIncompatible("SerializableTester")
219  @SuppressWarnings("unchecked")
220  public void testAnd_serializationOneArg() {
221    checkSerialization(Predicates.and(isOdd()));
222  }
223
224  public void testAnd_applyBinary() {
225    assertEvalsLikeOdd(Predicates.and(isOdd(), TRUE));
226    assertEvalsLikeOdd(Predicates.and(TRUE, isOdd()));
227    assertEvalsToFalse(Predicates.and(FALSE, NEVER_REACHED));
228  }
229
230  @SuppressWarnings("unchecked")
231  public void testAnd_equalityBinary() {
232    new EqualsTester()
233        .addEqualityGroup(
234            Predicates.and(TRUE, NEVER_REACHED),
235            Predicates.and(TRUE, NEVER_REACHED))
236        .addEqualityGroup(Predicates.and(NEVER_REACHED, TRUE))
237        .addEqualityGroup(Predicates.and(TRUE))
238        .addEqualityGroup(Predicates.or(TRUE, NEVER_REACHED))
239        .testEquals();
240  }
241
242  @GwtIncompatible("SerializableTester")
243  public void testAnd_serializationBinary() {
244    checkSerialization(Predicates.and(TRUE, isOdd()));
245  }
246
247  @SuppressWarnings("unchecked")
248  public void testAnd_applyTernary() {
249    assertEvalsLikeOdd(Predicates.and(isOdd(), TRUE, TRUE));
250    assertEvalsLikeOdd(Predicates.and(TRUE, isOdd(), TRUE));
251    assertEvalsLikeOdd(Predicates.and(TRUE, TRUE, isOdd()));
252    assertEvalsToFalse(Predicates.and(TRUE, FALSE, NEVER_REACHED));
253  }
254
255  @SuppressWarnings("unchecked")
256  public void testAnd_equalityTernary() {
257    new EqualsTester()
258        .addEqualityGroup(
259            Predicates.and(TRUE, isOdd(), NEVER_REACHED),
260            Predicates.and(TRUE, isOdd(), NEVER_REACHED))
261        .addEqualityGroup(Predicates.and(isOdd(), NEVER_REACHED, TRUE))
262        .addEqualityGroup(Predicates.and(TRUE))
263        .addEqualityGroup(Predicates.or(TRUE, isOdd(), NEVER_REACHED))
264        .testEquals();
265  }
266
267  @GwtIncompatible("SerializableTester")
268  @SuppressWarnings("unchecked")
269  public void testAnd_serializationTernary() {
270    checkSerialization(Predicates.and(TRUE, isOdd(), FALSE));
271  }
272
273  @SuppressWarnings("unchecked")
274  public void testAnd_applyIterable() {
275    Collection<Predicate<Integer>> empty = Arrays.asList();
276    assertEvalsToTrue(Predicates.and(empty));
277    assertEvalsLikeOdd(Predicates.and(Arrays.asList(isOdd())));
278    assertEvalsLikeOdd(Predicates.and(Arrays.asList(TRUE, isOdd())));
279    assertEvalsToFalse(Predicates.and(Arrays.asList(FALSE, NEVER_REACHED)));
280  }
281
282  @SuppressWarnings("unchecked")
283  public void testAnd_equalityIterable() {
284    new EqualsTester()
285        .addEqualityGroup(
286            Predicates.and(Arrays.asList(TRUE, NEVER_REACHED)),
287            Predicates.and(Arrays.asList(TRUE, NEVER_REACHED)),
288            Predicates.and(TRUE, NEVER_REACHED))
289        .addEqualityGroup(Predicates.and(FALSE, NEVER_REACHED))
290        .addEqualityGroup(Predicates.or(TRUE, NEVER_REACHED))
291        .testEquals();
292  }
293
294  @GwtIncompatible("SerializableTester")
295  @SuppressWarnings("unchecked")
296  public void testAnd_serializationIterable() {
297    checkSerialization(Predicates.and(Arrays.asList(TRUE, FALSE)));
298  }
299
300  @SuppressWarnings("unchecked")
301  public void testAnd_arrayDefensivelyCopied() {
302    Predicate[] array = {Predicates.alwaysFalse()};
303    Predicate<Object> predicate = Predicates.and(array);
304    assertFalse(predicate.apply(1));
305    array[0] = Predicates.alwaysTrue();
306    assertFalse(predicate.apply(1));
307  }
308
309  @SuppressWarnings("unchecked")
310  public void testAnd_listDefensivelyCopied() {
311    List list = new ArrayList<Predicate>();
312    Predicate<Object> predicate = Predicates.and(list);
313    assertTrue(predicate.apply(1));
314    list.add(Predicates.alwaysFalse());
315    assertTrue(predicate.apply(1));
316  }
317
318  @SuppressWarnings("unchecked")
319  public void testAnd_iterableDefensivelyCopied() {
320    final List list = new ArrayList<Predicate>();
321    Iterable iterable = new Iterable<Predicate>() {
322      @Override
323      public Iterator<Predicate> iterator() {
324        return list.iterator();
325      }
326    };
327    Predicate<Object> predicate = Predicates.and(iterable);
328    assertTrue(predicate.apply(1));
329    list.add(Predicates.alwaysFalse());
330    assertTrue(predicate.apply(1));
331  }
332
333  /*
334   * Tests for all the different flavors of Predicates.or().
335   */
336
337  @SuppressWarnings("unchecked")
338  public void testOr_applyNoArgs() {
339    assertEvalsToFalse(Predicates.or());
340  }
341
342  @SuppressWarnings("unchecked")
343  public void testOr_equalityNoArgs() {
344    new EqualsTester()
345        .addEqualityGroup(Predicates.or(), Predicates.or())
346        .addEqualityGroup(Predicates.or(TRUE))
347        .addEqualityGroup(Predicates.and())
348        .testEquals();
349  }
350
351  @GwtIncompatible("SerializableTester")
352  @SuppressWarnings("unchecked")
353  public void testOr_serializationNoArgs() {
354    checkSerialization(Predicates.or());
355  }
356
357  @SuppressWarnings("unchecked")
358  public void testOr_applyOneArg() {
359    assertEvalsToTrue(Predicates.or(TRUE));
360    assertEvalsToFalse(Predicates.or(FALSE));
361  }
362
363  @SuppressWarnings("unchecked")
364  public void testOr_equalityOneArg() {
365    new EqualsTester()
366        .addEqualityGroup(
367            Predicates.or(NEVER_REACHED), Predicates.or(NEVER_REACHED))
368        .addEqualityGroup(Predicates.or(NEVER_REACHED, TRUE))
369        .addEqualityGroup(Predicates.or(TRUE))
370        .addEqualityGroup(Predicates.or())
371        .addEqualityGroup(Predicates.and(NEVER_REACHED))
372        .testEquals();
373  }
374
375  @GwtIncompatible("SerializableTester")
376  @SuppressWarnings("unchecked")
377  public void testOr_serializationOneArg() {
378    checkSerialization(Predicates.or(isOdd()));
379  }
380
381  public void testOr_applyBinary() {
382    Predicate<Integer> falseOrFalse = Predicates.or(FALSE, FALSE);
383    Predicate<Integer> falseOrTrue = Predicates.or(FALSE, TRUE);
384    Predicate<Integer> trueOrAnything = Predicates.or(TRUE, NEVER_REACHED);
385
386    assertEvalsToFalse(falseOrFalse);
387    assertEvalsToTrue(falseOrTrue);
388    assertEvalsToTrue(trueOrAnything);
389  }
390
391  @SuppressWarnings("unchecked")
392  public void testOr_equalityBinary() {
393    new EqualsTester()
394        .addEqualityGroup(
395            Predicates.or(FALSE, NEVER_REACHED),
396            Predicates.or(FALSE, NEVER_REACHED))
397        .addEqualityGroup(Predicates.or(NEVER_REACHED, FALSE))
398        .addEqualityGroup(Predicates.or(TRUE))
399        .addEqualityGroup(Predicates.and(FALSE, NEVER_REACHED))
400        .testEquals();
401  }
402
403  @GwtIncompatible("SerializableTester")
404  public void testOr_serializationBinary() {
405    checkSerialization(Predicates.or(isOdd(), TRUE));
406  }
407
408  @SuppressWarnings("unchecked")
409  public void testOr_applyTernary() {
410    assertEvalsLikeOdd(Predicates.or(isOdd(), FALSE, FALSE));
411    assertEvalsLikeOdd(Predicates.or(FALSE, isOdd(), FALSE));
412    assertEvalsLikeOdd(Predicates.or(FALSE, FALSE, isOdd()));
413    assertEvalsToTrue(Predicates.or(FALSE, TRUE, NEVER_REACHED));
414  }
415
416  @SuppressWarnings("unchecked")
417  public void testOr_equalityTernary() {
418    new EqualsTester()
419        .addEqualityGroup(
420            Predicates.or(FALSE, NEVER_REACHED, TRUE),
421            Predicates.or(FALSE, NEVER_REACHED, TRUE))
422        .addEqualityGroup(Predicates.or(TRUE, NEVER_REACHED, FALSE))
423        .addEqualityGroup(Predicates.or(TRUE))
424        .addEqualityGroup(Predicates.and(FALSE, NEVER_REACHED, TRUE))
425        .testEquals();
426  }
427
428  @GwtIncompatible("SerializableTester")
429  @SuppressWarnings("unchecked")
430  public void testOr_serializationTernary() {
431    checkSerialization(Predicates.or(FALSE, isOdd(), TRUE));
432  }
433
434  @SuppressWarnings("unchecked")
435  public void testOr_applyIterable() {
436    Predicate<Integer> vacuouslyFalse =
437        Predicates.or(Collections.<Predicate<Integer>>emptyList());
438    Predicate<Integer> troo = Predicates.or(Collections.singletonList(TRUE));
439    /*
440     * newLinkedList() takes varargs. TRUE and FALSE are both instances of
441     * Predicate<Integer>, so the call is safe.
442     */
443    Predicate<Integer> trueAndFalse = Predicates.or(Arrays.asList(TRUE, FALSE));
444
445    assertEvalsToFalse(vacuouslyFalse);
446    assertEvalsToTrue(troo);
447    assertEvalsToTrue(trueAndFalse);
448  }
449
450  @SuppressWarnings("unchecked")
451  public void testOr_equalityIterable() {
452    new EqualsTester()
453        .addEqualityGroup(
454            Predicates.or(Arrays.asList(FALSE, NEVER_REACHED)),
455            Predicates.or(Arrays.asList(FALSE, NEVER_REACHED)),
456            Predicates.or(FALSE, NEVER_REACHED))
457        .addEqualityGroup(Predicates.or(TRUE, NEVER_REACHED))
458        .addEqualityGroup(Predicates.and(FALSE, NEVER_REACHED))
459        .testEquals();
460  }
461
462  @GwtIncompatible("SerializableTester")
463  @SuppressWarnings("unchecked")
464  public void testOr_serializationIterable() {
465    Predicate<Integer> pre = Predicates.or(Arrays.asList(TRUE, FALSE));
466    Predicate<Integer> post = SerializableTester.reserializeAndAssert(pre);
467    assertEquals(pre.apply(0), post.apply(0));
468  }
469
470  @SuppressWarnings("unchecked")
471  public void testOr_arrayDefensivelyCopied() {
472    Predicate[] array = {Predicates.alwaysFalse()};
473    Predicate<Object> predicate = Predicates.or(array);
474    assertFalse(predicate.apply(1));
475    array[0] = Predicates.alwaysTrue();
476    assertFalse(predicate.apply(1));
477  }
478
479  @SuppressWarnings("unchecked")
480  public void testOr_listDefensivelyCopied() {
481    List list = new ArrayList<Predicate>();
482    Predicate<Object> predicate = Predicates.or(list);
483    assertFalse(predicate.apply(1));
484    list.add(Predicates.alwaysTrue());
485    assertFalse(predicate.apply(1));
486  }
487
488  @SuppressWarnings("unchecked")
489  public void testOr_iterableDefensivelyCopied() {
490    final List list = new ArrayList<Predicate>();
491    Iterable iterable = new Iterable<Predicate>() {
492      @Override
493      public Iterator<Predicate> iterator() {
494        return list.iterator();
495      }
496    };
497    Predicate<Object> predicate = Predicates.or(iterable);
498    assertFalse(predicate.apply(1));
499    list.add(Predicates.alwaysTrue());
500    assertFalse(predicate.apply(1));
501  }
502
503  /*
504   * Tests for Predicates.equalTo(x).
505   */
506
507  public void testIsEqualTo_apply() {
508    Predicate<Integer> isOne = Predicates.equalTo(1);
509
510    assertTrue(isOne.apply(1));
511    assertFalse(isOne.apply(2));
512    assertFalse(isOne.apply(null));
513  }
514
515  public void testIsEqualTo_equality() {
516    new EqualsTester()
517        .addEqualityGroup(Predicates.equalTo(1), Predicates.equalTo(1))
518        .addEqualityGroup(Predicates.equalTo(2))
519        .addEqualityGroup(Predicates.equalTo(null))
520        .testEquals();
521  }
522
523  @GwtIncompatible("SerializableTester")
524  public void testIsEqualTo_serialization() {
525    checkSerialization(Predicates.equalTo(1));
526  }
527
528  public void testIsEqualToNull_apply() {
529    Predicate<Integer> isNull = Predicates.equalTo(null);
530    assertTrue(isNull.apply(null));
531    assertFalse(isNull.apply(1));
532  }
533
534  public void testIsEqualToNull_equality() {
535    new EqualsTester()
536        .addEqualityGroup(Predicates.equalTo(null), Predicates.equalTo(null))
537        .addEqualityGroup(Predicates.equalTo(1))
538        .addEqualityGroup(Predicates.equalTo("null"))
539        .testEquals();
540  }
541
542  @GwtIncompatible("SerializableTester")
543  public void testIsEqualToNull_serialization() {
544    checkSerialization(Predicates.equalTo(null));
545  }
546
547  /**
548   * Tests for Predicates.instanceOf(x).
549   * TODO: Fix the comment style after fixing annotation stripper to remove
550   * comments properly.  Currently, all tests before the comments are removed
551   * as well.
552   */
553
554  @GwtIncompatible("Predicates.instanceOf")
555  public void testIsInstanceOf_apply() {
556    Predicate<Object> isInteger = Predicates.instanceOf(Integer.class);
557
558    assertTrue(isInteger.apply(1));
559    assertFalse(isInteger.apply(2.0f));
560    assertFalse(isInteger.apply(""));
561    assertFalse(isInteger.apply(null));
562  }
563
564  @GwtIncompatible("Predicates.instanceOf")
565  public void testIsInstanceOf_subclass() {
566    Predicate<Object> isNumber = Predicates.instanceOf(Number.class);
567
568    assertTrue(isNumber.apply(1));
569    assertTrue(isNumber.apply(2.0f));
570    assertFalse(isNumber.apply(""));
571    assertFalse(isNumber.apply(null));
572  }
573
574  @GwtIncompatible("Predicates.instanceOf")
575  public void testIsInstanceOf_interface() {
576    Predicate<Object> isComparable = Predicates.instanceOf(Comparable.class);
577
578    assertTrue(isComparable.apply(1));
579    assertTrue(isComparable.apply(2.0f));
580    assertTrue(isComparable.apply(""));
581    assertFalse(isComparable.apply(null));
582  }
583
584  @GwtIncompatible("Predicates.instanceOf")
585  public void testIsInstanceOf_equality() {
586    new EqualsTester()
587        .addEqualityGroup(
588            Predicates.instanceOf(Integer.class),
589            Predicates.instanceOf(Integer.class))
590        .addEqualityGroup(Predicates.instanceOf(Number.class))
591        .addEqualityGroup(Predicates.instanceOf(Float.class))
592        .testEquals();
593  }
594
595  @GwtIncompatible("Predicates.instanceOf, SerializableTester")
596  public void testIsInstanceOf_serialization() {
597    checkSerialization(Predicates.instanceOf(Integer.class));
598  }
599
600  @GwtIncompatible("Predicates.assignableFrom")
601  public void testIsAssignableFrom_apply() {
602    Predicate<Class<?>> isInteger = Predicates.assignableFrom(Integer.class);
603
604    assertTrue(isInteger.apply(Integer.class));
605    assertFalse(isInteger.apply(Float.class));
606
607    try {
608      isInteger.apply(null);
609      fail();
610    } catch(NullPointerException expected) {}
611  }
612
613  @GwtIncompatible("Predicates.assignableFrom")
614  public void testIsAssignableFrom_subclass() {
615    Predicate<Class<?>> isNumber = Predicates.assignableFrom(Number.class);
616
617    assertTrue(isNumber.apply(Integer.class));
618    assertTrue(isNumber.apply(Float.class));
619  }
620
621  @GwtIncompatible("Predicates.assignableFrom")
622  public void testIsAssignableFrom_interface() {
623    Predicate<Class<?>> isComparable =
624        Predicates.assignableFrom(Comparable.class);
625
626    assertTrue(isComparable.apply(Integer.class));
627    assertTrue(isComparable.apply(Float.class));
628  }
629
630  @GwtIncompatible("Predicates.assignableFrom")
631  public void testIsAssignableFrom_equality() {
632    new EqualsTester()
633        .addEqualityGroup(
634            Predicates.assignableFrom(Integer.class),
635            Predicates.assignableFrom(Integer.class))
636        .addEqualityGroup(Predicates.assignableFrom(Number.class))
637        .addEqualityGroup(Predicates.assignableFrom(Float.class))
638        .testEquals();
639  }
640
641  @GwtIncompatible("Predicates.assignableFrom, SerializableTester")
642  public void testIsAssignableFrom_serialization() {
643    Predicate<Class<?>> predicate =
644        Predicates.assignableFrom(Integer.class);
645    Predicate<Class<?>> reserialized =
646        SerializableTester.reserializeAndAssert(predicate);
647
648    assertEvalsLike(predicate, reserialized, Integer.class);
649    assertEvalsLike(predicate, reserialized, Float.class);
650    assertEvalsLike(predicate, reserialized, null);
651  }
652
653  /*
654   * Tests for Predicates.isNull()
655   */
656
657  public void testIsNull_apply() {
658    Predicate<Integer> isNull = Predicates.isNull();
659    assertTrue(isNull.apply(null));
660    assertFalse(isNull.apply(1));
661  }
662
663  public void testIsNull_equality() {
664    new EqualsTester()
665        .addEqualityGroup(Predicates.isNull(), Predicates.isNull())
666        .addEqualityGroup(Predicates.notNull())
667        .testEquals();
668  }
669
670  @GwtIncompatible("SerializableTester")
671  public void testIsNull_serialization() {
672    Predicate<String> pre = Predicates.isNull();
673    Predicate<String> post = SerializableTester.reserializeAndAssert(pre);
674    assertEquals(pre.apply("foo"), post.apply("foo"));
675    assertEquals(pre.apply(null), post.apply(null));
676  }
677
678  public void testNotNull_apply() {
679    Predicate<Integer> notNull = Predicates.notNull();
680    assertFalse(notNull.apply(null));
681    assertTrue(notNull.apply(1));
682  }
683
684  public void testNotNull_equality() {
685    new EqualsTester()
686        .addEqualityGroup(Predicates.notNull(), Predicates.notNull())
687        .addEqualityGroup(Predicates.isNull())
688        .testEquals();
689  }
690
691  @GwtIncompatible("SerializableTester")
692  public void testNotNull_serialization() {
693    checkSerialization(Predicates.notNull());
694  }
695
696  public void testIn_apply() {
697    Collection<Integer> nums = Arrays.asList(1, 5);
698    Predicate<Integer> isOneOrFive = Predicates.in(nums);
699
700    assertTrue(isOneOrFive.apply(1));
701    assertTrue(isOneOrFive.apply(5));
702    assertFalse(isOneOrFive.apply(3));
703    assertFalse(isOneOrFive.apply(null));
704  }
705
706  public void testIn_equality() {
707    Collection<Integer> nums = ImmutableSet.of(1, 5);
708    Collection<Integer> sameOrder = ImmutableSet.of(1, 5);
709    Collection<Integer> differentOrder = ImmutableSet.of(5, 1);
710    Collection<Integer> differentNums = ImmutableSet.of(1, 3, 5);
711
712    new EqualsTester()
713        .addEqualityGroup(Predicates.in(nums), Predicates.in(nums),
714            Predicates.in(sameOrder), Predicates.in(differentOrder))
715        .addEqualityGroup(Predicates.in(differentNums))
716        .testEquals();
717  }
718
719  @GwtIncompatible("SerializableTester")
720  public void testIn_serialization() {
721    checkSerialization(Predicates.in(Arrays.asList(1, 2, 3, null)));
722  }
723
724  public void testIn_handlesNullPointerException() {
725    class CollectionThatThrowsNPE<T> extends ArrayList<T> {
726      private static final long serialVersionUID = 1L;
727
728      @Override public boolean contains(Object element) {
729        Preconditions.checkNotNull(element);
730        return super.contains(element);
731      }
732    }
733    Collection<Integer> nums = new CollectionThatThrowsNPE<Integer>();
734    Predicate<Integer> isFalse = Predicates.in(nums);
735    assertFalse(isFalse.apply(null));
736  }
737
738  public void testIn_handlesClassCastException() {
739    class CollectionThatThrowsCCE<T> extends ArrayList<T> {
740      private static final long serialVersionUID = 1L;
741
742      @Override public boolean contains(Object element) {
743        throw new ClassCastException("");
744      }
745    }
746    Collection<Integer> nums = new CollectionThatThrowsCCE<Integer>();
747    nums.add(3);
748    Predicate<Integer> isThree = Predicates.in(nums);
749    assertFalse(isThree.apply(3));
750  }
751
752  /*
753   * Tests that compilation will work when applying explicit types.
754   */
755  @SuppressWarnings("unused")
756  public void testIn_compilesWithExplicitSupertype() {
757    Collection<Number> nums = ImmutableSet.of();
758    Predicate<Number> p1 = Predicates.in(nums);
759    Predicate<Object> p2 = Predicates.<Object>in(nums);
760    // The next two lines are not expected to compile.
761    // Predicate<Integer> p3 = Predicates.in(nums);
762    // Predicate<Integer> p4 = Predicates.<Integer>in(nums);
763  }
764
765  @GwtIncompatible("NullPointerTester")
766  public void testNullPointerExceptions() throws Exception {
767    NullPointerTester tester = new NullPointerTester();
768    tester.testAllPublicStaticMethods(Predicates.class);
769  }
770
771  @SuppressWarnings("unchecked") // varargs
772  @GwtIncompatible("SerializbleTester")
773  public void testCascadingSerialization() throws Exception {
774    // Eclipse says Predicate<Integer>; javac says Predicate<Object>.
775    Predicate<? super Integer> nasty = Predicates.not(Predicates.and(
776        Predicates.or(
777            Predicates.equalTo((Object) 1), Predicates.equalTo(null),
778            Predicates.alwaysFalse(), Predicates.alwaysTrue(),
779            Predicates.isNull(), Predicates.notNull(),
780            Predicates.in(Arrays.asList(1)))));
781    assertEvalsToFalse(nasty);
782
783    Predicate<? super Integer> stillNasty =
784        SerializableTester.reserializeAndAssert(nasty);
785
786    assertEvalsToFalse(stillNasty);
787  }
788
789  // enum singleton pattern
790  private enum TrimStringFunction implements Function<String, String> {
791    INSTANCE;
792
793    @Override
794    public String apply(String string) {
795      return WHITESPACE.trimFrom(string);
796    }
797  }
798
799  public void testCompose() {
800    Function<String, String> trim = TrimStringFunction.INSTANCE;
801    Predicate<String> equalsFoo = Predicates.equalTo("Foo");
802    Predicate<String> equalsBar = Predicates.equalTo("Bar");
803    Predicate<String> trimEqualsFoo = Predicates.compose(equalsFoo, trim);
804    Function<String, String> identity = Functions.identity();
805
806    assertTrue(trimEqualsFoo.apply("Foo"));
807    assertTrue(trimEqualsFoo.apply("   Foo   "));
808    assertFalse(trimEqualsFoo.apply("Foo-b-que"));
809
810    new EqualsTester()
811        .addEqualityGroup(trimEqualsFoo, Predicates.compose(equalsFoo, trim))
812        .addEqualityGroup(equalsFoo)
813        .addEqualityGroup(trim)
814        .addEqualityGroup(Predicates.compose(equalsFoo, identity))
815        .addEqualityGroup(Predicates.compose(equalsBar, trim))
816        .testEquals();
817  }
818
819  @GwtIncompatible("SerializableTester")
820  public void testComposeSerialization() {
821    Function<String, String> trim = TrimStringFunction.INSTANCE;
822    Predicate<String> equalsFoo = Predicates.equalTo("Foo");
823    Predicate<String> trimEqualsFoo = Predicates.compose(equalsFoo, trim);
824    SerializableTester.reserializeAndAssert(trimEqualsFoo);
825  }
826
827  /**
828   * Tests for Predicates.contains(Pattern) and .containsPattern(String).
829   * We assume the regex level works, so there are only trivial tests of that
830   * aspect.
831   * TODO: Fix comment style once annotation stripper is fixed.
832   */
833
834  @GwtIncompatible("Predicates.containsPattern")
835  public void testContainsPattern_apply() {
836    Predicate<CharSequence> isFoobar =
837        Predicates.containsPattern("^Fo.*o.*bar$");
838    assertTrue(isFoobar.apply("Foxyzoabcbar"));
839    assertFalse(isFoobar.apply("Foobarx"));
840  }
841
842  @GwtIncompatible("Predicates.containsPattern")
843  public void testContains_apply() {
844    Predicate<CharSequence> isFoobar =
845        Predicates.contains(Pattern.compile("^Fo.*o.*bar$"));
846
847    assertTrue(isFoobar.apply("Foxyzoabcbar"));
848    assertFalse(isFoobar.apply("Foobarx"));
849  }
850
851  @GwtIncompatible("NullPointerTester")
852  public void testContainsPattern_nulls() throws Exception {
853    NullPointerTester tester = new NullPointerTester();
854    Predicate<CharSequence> isWooString = Predicates.containsPattern("Woo");
855
856    tester.testAllPublicInstanceMethods(isWooString);
857  }
858
859  @GwtIncompatible("NullPointerTester")
860  public void testContains_nulls() throws Exception {
861    NullPointerTester tester = new NullPointerTester();
862    Predicate<CharSequence> isWooPattern =
863        Predicates.contains(Pattern.compile("Woo"));
864
865    tester.testAllPublicInstanceMethods(isWooPattern);
866  }
867
868  @GwtIncompatible("SerializableTester")
869  public void testContainsPattern_serialization() {
870    Predicate<CharSequence> pre = Predicates.containsPattern("foo");
871    Predicate<CharSequence> post = SerializableTester.reserializeAndAssert(pre);
872    assertEquals(pre.apply("foo"), post.apply("foo"));
873  }
874
875  @GwtIncompatible("java.util.regex.Pattern")
876  public void testContains_equals() {
877    new EqualsTester()
878        .addEqualityGroup(
879            Predicates.contains(Pattern.compile("foo")),
880            Predicates.containsPattern("foo"))
881        .addEqualityGroup(
882            Predicates.contains(
883                Pattern.compile("foo", Pattern.CASE_INSENSITIVE)))
884        .addEqualityGroup(
885            Predicates.containsPattern("bar"))
886        .testEquals();
887      }
888
889  public void assertEqualHashCode(
890      Predicate<? super Integer> expected, Predicate<? super Integer> actual) {
891    assertEquals(actual.toString() + " should hash like " + expected.toString(),
892        expected.hashCode(), actual.hashCode());
893  }
894
895  public void testHashCodeForBooleanOperations() {
896    Predicate<Integer> p1 = Predicates.isNull();
897    Predicate<Integer> p2 = isOdd();
898
899    // Make sure that hash codes are not computed per-instance.
900    assertEqualHashCode(
901        Predicates.not(p1),
902        Predicates.not(p1));
903
904    assertEqualHashCode(
905        Predicates.and(p1, p2),
906        Predicates.and(p1, p2));
907
908    assertEqualHashCode(
909        Predicates.or(p1, p2),
910        Predicates.or(p1, p2));
911
912    // While not a contractual requirement, we'd like the hash codes for ands
913    // & ors of the same predicates to not collide.
914    assertTrue(Predicates.and(p1, p2).hashCode() != Predicates.or(p1, p2).hashCode());
915  }
916
917  private static void assertEvalsToTrue(Predicate<? super Integer> predicate) {
918    assertTrue(predicate.apply(0));
919    assertTrue(predicate.apply(1));
920    assertTrue(predicate.apply(null));
921  }
922
923  private static void assertEvalsToFalse(Predicate<? super Integer> predicate) {
924    assertFalse(predicate.apply(0));
925    assertFalse(predicate.apply(1));
926    assertFalse(predicate.apply(null));
927  }
928
929  private static void assertEvalsLikeOdd(Predicate<? super Integer> predicate) {
930    assertEvalsLike(isOdd(), predicate);
931  }
932
933  private static void assertEvalsLike(
934      Predicate<? super Integer> expected,
935      Predicate<? super Integer> actual) {
936    assertEvalsLike(expected, actual, 0);
937    assertEvalsLike(expected, actual, 1);
938    assertEvalsLike(expected, actual, null);
939  }
940
941  private static <T> void assertEvalsLike(
942      Predicate<? super T> expected,
943      Predicate<? super T> actual,
944      T input) {
945    Boolean expectedResult = null;
946    RuntimeException expectedRuntimeException = null;
947    try {
948      expectedResult = expected.apply(input);
949    } catch (RuntimeException e) {
950      expectedRuntimeException = e;
951    }
952
953    Boolean actualResult = null;
954    RuntimeException actualRuntimeException = null;
955    try {
956      actualResult = actual.apply(input);
957    } catch (RuntimeException e) {
958      actualRuntimeException = e;
959    }
960
961    assertEquals(expectedResult, actualResult);
962    if (expectedRuntimeException != null) {
963      assertNotNull(actualRuntimeException);
964      assertEquals(
965          expectedRuntimeException.getClass(),
966          actualRuntimeException.getClass());
967    }
968  }
969
970  @GwtIncompatible("SerializableTester")
971  private static void checkSerialization(Predicate<? super Integer> predicate) {
972    Predicate<? super Integer> reserialized =
973        SerializableTester.reserializeAndAssert(predicate);
974    assertEvalsLike(predicate, reserialized);
975  }
976}
977