• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package com.google.common.base;
18 
19 import com.google.common.annotations.GwtCompatible;
20 import com.google.common.annotations.GwtIncompatible;
21 import com.google.common.collect.ImmutableMap;
22 import com.google.common.collect.Maps;
23 import com.google.common.testing.EqualsTester;
24 import com.google.common.testing.NullPointerTester;
25 import com.google.common.testing.SerializableTester;
26 
27 import junit.framework.TestCase;
28 
29 import java.io.Serializable;
30 import java.util.Map;
31 
32 /**
33  * Tests for {@link Functions}.
34  *
35  * @author Mike Bostock
36  * @author Vlad Patryshev
37  */
38 @GwtCompatible(emulated = true)
39 public class FunctionsTest extends TestCase {
40 
testIdentity_same()41   public void testIdentity_same() {
42     Function<String, String> identity = Functions.identity();
43     assertNull(identity.apply(null));
44     assertSame("foo", identity.apply("foo"));
45   }
46 
testIdentity_notSame()47   public void testIdentity_notSame() {
48     Function<Long, Long> identity = Functions.identity();
49     assertNotSame(new Long(135135L), identity.apply(new Long(135135L)));
50   }
51 
52   @GwtIncompatible("SerializableTester")
testIdentitySerializable()53   public void testIdentitySerializable() {
54     checkCanReserializeSingleton(Functions.identity());
55   }
56 
testToStringFunction_apply()57   public void testToStringFunction_apply() {
58     assertEquals("3", Functions.toStringFunction().apply(3));
59     assertEquals("hiya", Functions.toStringFunction().apply("hiya"));
60     assertEquals("I'm a string",
61         Functions.toStringFunction().apply(
62             new Object() {
63               @Override public String toString() {
64                 return "I'm a string";
65               }
66             }));
67     try {
68       Functions.toStringFunction().apply(null);
69       fail("expected NullPointerException");
70     } catch (NullPointerException e) {
71       // expected
72     }
73   }
74 
75   @GwtIncompatible("SerializableTester")
testToStringFunctionSerializable()76   public void testToStringFunctionSerializable() {
77     checkCanReserializeSingleton(Functions.toStringFunction());
78   }
79 
80   @GwtIncompatible("NullPointerTester")
testNullPointerExceptions()81   public void testNullPointerExceptions() throws Exception {
82     NullPointerTester tester = new NullPointerTester();
83     tester.testAllPublicStaticMethods(Functions.class);
84   }
85 
testForMapWithoutDefault()86   public void testForMapWithoutDefault() {
87     Map<String, Integer> map = Maps.newHashMap();
88     map.put("One", 1);
89     map.put("Three", 3);
90     map.put("Null", null);
91     Function<String, Integer> function = Functions.forMap(map);
92 
93     assertEquals(1, function.apply("One").intValue());
94     assertEquals(3, function.apply("Three").intValue());
95     assertNull(function.apply("Null"));
96 
97     try {
98       function.apply("Two");
99       fail();
100     } catch (IllegalArgumentException expected) {
101     }
102 
103     new EqualsTester()
104         .addEqualityGroup(function, Functions.forMap(map))
105         .addEqualityGroup(Functions.forMap(map, 42))
106         .testEquals();
107   }
108 
109   @GwtIncompatible("SerializableTester")
testForMapWithoutDefaultSerializable()110   public void testForMapWithoutDefaultSerializable() {
111     checkCanReserialize(Functions.forMap(ImmutableMap.of(1, 2)));
112   }
113 
testForMapWithDefault()114   public void testForMapWithDefault() {
115     Map<String, Integer> map = Maps.newHashMap();
116     map.put("One", 1);
117     map.put("Three", 3);
118     map.put("Null", null);
119     Function<String, Integer> function = Functions.forMap(map, 42);
120 
121     assertEquals(1, function.apply("One").intValue());
122     assertEquals(42, function.apply("Two").intValue());
123     assertEquals(3, function.apply("Three").intValue());
124     assertNull(function.apply("Null"));
125 
126     new EqualsTester()
127         .addEqualityGroup(function, Functions.forMap(map, 42))
128         .addEqualityGroup(Functions.forMap(map))
129         .addEqualityGroup(Functions.forMap(map, null))
130         .addEqualityGroup(Functions.forMap(map, 43))
131         .testEquals();
132   }
133 
134   @GwtIncompatible("SerializableTester")
testForMapWithDefault_includeSerializable()135   public void testForMapWithDefault_includeSerializable() {
136     Map<String, Integer> map = Maps.newHashMap();
137     map.put("One", 1);
138     map.put("Three", 3);
139     Function<String, Integer> function = Functions.forMap(map, 42);
140 
141     assertEquals(1, function.apply("One").intValue());
142     assertEquals(42, function.apply("Two").intValue());
143     assertEquals(3, function.apply("Three").intValue());
144 
145     new EqualsTester()
146         .addEqualityGroup(
147             function,
148             Functions.forMap(map, 42),
149             SerializableTester.reserialize(function))
150         .addEqualityGroup(Functions.forMap(map))
151         .addEqualityGroup(Functions.forMap(map, null))
152         .addEqualityGroup(Functions.forMap(map, 43))
153         .testEquals();
154   }
155 
156   @GwtIncompatible("SerializableTester")
testForMapWithDefaultSerializable()157   public void testForMapWithDefaultSerializable() {
158     checkCanReserialize(Functions.forMap(ImmutableMap.of(1, 2), 3));
159   }
160 
testForMapWithDefault_null()161   public void testForMapWithDefault_null() {
162     ImmutableMap<String, Integer> map = ImmutableMap.of("One", 1);
163     Function<String, Integer> function = Functions.forMap(map, null);
164 
165     assertEquals((Integer) 1, function.apply("One"));
166     assertNull(function.apply("Two"));
167 
168     // check basic sanity of equals and hashCode
169     new EqualsTester()
170         .addEqualityGroup(function)
171         .addEqualityGroup(Functions.forMap(map, 1))
172         .testEquals();
173   }
174 
175   @GwtIncompatible("SerializableTester")
testForMapWithDefault_null_compareWithSerializable()176   public void testForMapWithDefault_null_compareWithSerializable() {
177     ImmutableMap<String, Integer> map = ImmutableMap.of("One", 1);
178     Function<String, Integer> function = Functions.forMap(map, null);
179 
180     assertEquals((Integer) 1, function.apply("One"));
181     assertNull(function.apply("Two"));
182 
183     // check basic sanity of equals and hashCode
184     new EqualsTester()
185         .addEqualityGroup(function, SerializableTester.reserialize(function))
186         .addEqualityGroup(Functions.forMap(map, 1))
187         .testEquals();
188   }
189 
testForMapWildCardWithDefault()190   public void testForMapWildCardWithDefault() {
191     Map<String, Integer> map = Maps.newHashMap();
192     map.put("One", 1);
193     map.put("Three", 3);
194     Number number = Double.valueOf(42);
195     Function<String, Number> function = Functions.forMap(map, number);
196 
197     assertEquals(1, function.apply("One").intValue());
198     assertEquals(number, function.apply("Two"));
199     assertEquals(3L, function.apply("Three").longValue());
200   }
201 
testComposition()202   public void testComposition() {
203     Map<String, Integer> mJapaneseToInteger = Maps.newHashMap();
204     mJapaneseToInteger.put("Ichi", 1);
205     mJapaneseToInteger.put("Ni", 2);
206     mJapaneseToInteger.put("San", 3);
207     Function<String, Integer> japaneseToInteger =
208         Functions.forMap(mJapaneseToInteger);
209 
210     Map<Integer, String> mIntegerToSpanish = Maps.newHashMap();
211     mIntegerToSpanish.put(1, "Uno");
212     mIntegerToSpanish.put(3, "Tres");
213     mIntegerToSpanish.put(4, "Cuatro");
214     Function<Integer, String> integerToSpanish =
215         Functions.forMap(mIntegerToSpanish);
216 
217     Function<String, String> japaneseToSpanish =
218         Functions.compose(integerToSpanish, japaneseToInteger);
219 
220     assertEquals("Uno", japaneseToSpanish.apply("Ichi"));
221     try {
222       japaneseToSpanish.apply("Ni");
223       fail();
224     } catch (IllegalArgumentException e) {
225     }
226     assertEquals("Tres", japaneseToSpanish.apply("San"));
227     try {
228       japaneseToSpanish.apply("Shi");
229       fail();
230     } catch (IllegalArgumentException e) {
231     }
232 
233     new EqualsTester()
234         .addEqualityGroup(
235             japaneseToSpanish,
236             Functions.compose(integerToSpanish, japaneseToInteger))
237         .addEqualityGroup(japaneseToInteger)
238         .addEqualityGroup(integerToSpanish)
239         .addEqualityGroup(
240             Functions.compose(japaneseToInteger, integerToSpanish))
241         .testEquals();
242   }
243 
244   @GwtIncompatible("SerializableTester")
testComposition_includeReserializabled()245   public void testComposition_includeReserializabled() {
246     Map<String, Integer> mJapaneseToInteger = Maps.newHashMap();
247     mJapaneseToInteger.put("Ichi", 1);
248     mJapaneseToInteger.put("Ni", 2);
249     mJapaneseToInteger.put("San", 3);
250     Function<String, Integer> japaneseToInteger =
251         Functions.forMap(mJapaneseToInteger);
252 
253     Map<Integer, String> mIntegerToSpanish = Maps.newHashMap();
254     mIntegerToSpanish.put(1, "Uno");
255     mIntegerToSpanish.put(3, "Tres");
256     mIntegerToSpanish.put(4, "Cuatro");
257     Function<Integer, String> integerToSpanish =
258         Functions.forMap(mIntegerToSpanish);
259 
260     Function<String, String> japaneseToSpanish =
261         Functions.compose(integerToSpanish, japaneseToInteger);
262 
263     new EqualsTester()
264         .addEqualityGroup(
265             japaneseToSpanish,
266             Functions.compose(integerToSpanish, japaneseToInteger),
267             SerializableTester.reserialize(japaneseToSpanish))
268         .addEqualityGroup(japaneseToInteger)
269         .addEqualityGroup(integerToSpanish)
270         .addEqualityGroup(
271             Functions.compose(japaneseToInteger, integerToSpanish))
272         .testEquals();
273   }
274 
testCompositionWildcard()275   public void testCompositionWildcard() {
276     Map<String, Integer> mapJapaneseToInteger = Maps.newHashMap();
277     Function<String, Integer> japaneseToInteger =
278         Functions.forMap(mapJapaneseToInteger);
279 
280     Function<Object, String> numberToSpanish = Functions.constant("Yo no se");
281 
282     Function<String, String> japaneseToSpanish =
283         Functions.compose(numberToSpanish, japaneseToInteger);
284   }
285 
286   private static class HashCodeFunction implements Function<Object, Integer> {
287     @Override
apply(Object o)288     public Integer apply(Object o) {
289       return (o == null) ? 0 : o.hashCode();
290     }
291   }
292 
testComposeOfFunctionsIsAssociative()293   public void testComposeOfFunctionsIsAssociative() {
294     Map<Float, String> m = ImmutableMap.of(
295         4.0f, "A", 3.0f, "B", 2.0f, "C", 1.0f, "D");
296     Function<? super Integer, Boolean> h = Functions.constant(Boolean.TRUE);
297     Function<? super String, Integer> g = new HashCodeFunction();
298     Function<Float, String> f = Functions.forMap(m, "F");
299 
300     Function<Float, Boolean> c1 = Functions.compose(Functions.compose(h, g), f);
301     Function<Float, Boolean> c2 = Functions.compose(h, Functions.compose(g, f));
302 
303     // Might be nice (eventually) to have:
304     //     assertEquals(c1, c2);
305 
306     // But for now, settle for this:
307     assertEquals(c1.hashCode(), c2.hashCode());
308 
309     assertEquals(c1.apply(1.0f), c2.apply(1.0f));
310     assertEquals(c1.apply(5.0f), c2.apply(5.0f));
311   }
312 
testComposeOfPredicateAndFunctionIsAssociative()313   public void testComposeOfPredicateAndFunctionIsAssociative() {
314     Map<Float, String> m = ImmutableMap.of(
315         4.0f, "A", 3.0f, "B", 2.0f, "C", 1.0f, "D");
316     Predicate<? super Integer> h = Predicates.equalTo(42);
317     Function<? super String, Integer> g = new HashCodeFunction();
318     Function<Float, String> f = Functions.forMap(m, "F");
319 
320     Predicate<Float> p1 = Predicates.compose(Predicates.compose(h, g), f);
321     Predicate<Float> p2 = Predicates.compose(h, Functions.compose(g, f));
322 
323     // Might be nice (eventually) to have:
324     //     assertEquals(p1, p2);
325 
326     // But for now, settle for this:
327     assertEquals(p1.hashCode(), p2.hashCode());
328 
329     assertEquals(p1.apply(1.0f), p2.apply(1.0f));
330     assertEquals(p1.apply(5.0f), p2.apply(5.0f));
331   }
332 
testForPredicate()333   public void testForPredicate() {
334     Function<Object, Boolean> alwaysTrue =
335         Functions.forPredicate(Predicates.alwaysTrue());
336     Function<Object, Boolean> alwaysFalse =
337         Functions.forPredicate(Predicates.alwaysFalse());
338 
339     assertTrue(alwaysTrue.apply(0));
340     assertFalse(alwaysFalse.apply(0));
341 
342     new EqualsTester()
343         .addEqualityGroup(
344             alwaysTrue, Functions.forPredicate(Predicates.alwaysTrue()))
345         .addEqualityGroup(alwaysFalse)
346         .addEqualityGroup(Functions.identity())
347         .testEquals();
348   }
349 
350   @GwtIncompatible("SerializableTester")
testForPredicateSerializable()351   public void testForPredicateSerializable() {
352     checkCanReserialize(Functions.forPredicate(Predicates.equalTo(5)));
353   }
354 
testConstant()355   public void testConstant() {
356     Function<Object, Object> f = Functions.<Object>constant("correct");
357     assertEquals("correct", f.apply(new Object()));
358     assertEquals("correct", f.apply(null));
359 
360     Function<Object, String> g = Functions.constant(null);
361     assertEquals(null, g.apply(2));
362     assertEquals(null, g.apply(null));
363 
364     new EqualsTester()
365         .addEqualityGroup(f, Functions.constant("correct"))
366         .addEqualityGroup(Functions.constant("incorrect"))
367         .addEqualityGroup(Functions.toStringFunction())
368         .addEqualityGroup(g)
369         .testEquals();
370 
371     new EqualsTester()
372         .addEqualityGroup(g, Functions.constant(null))
373         .addEqualityGroup(Functions.constant("incorrect"))
374         .addEqualityGroup(Functions.toStringFunction())
375         .addEqualityGroup(f)
376         .testEquals();
377   }
378 
379   @GwtIncompatible("SerializableTester")
testConstantSerializable()380   public void testConstantSerializable() {
381     checkCanReserialize(Functions.constant(5));
382   }
383 
384   private static class CountingSupplier
385       implements Supplier<Integer>, Serializable {
386 
387     private static final long serialVersionUID = 0;
388 
389     private int value;
390 
391     @Override
get()392     public Integer get() {
393       return ++value;
394     }
395 
396     @Override
equals(Object obj)397     public boolean equals(Object obj) {
398       if (obj instanceof CountingSupplier) {
399         return this.value == ((CountingSupplier) obj).value;
400       }
401       return false;
402     }
403 
404     @Override
hashCode()405     public int hashCode() {
406       return value;
407     }
408   }
409 
testForSupplier()410   public void testForSupplier() {
411     Supplier<Integer> supplier = new CountingSupplier();
412     Function<Object, Integer> function = Functions.forSupplier(supplier);
413 
414     assertEquals(1, (int) function.apply(null));
415     assertEquals(2, (int) function.apply("foo"));
416 
417     new EqualsTester()
418         .addEqualityGroup(function, Functions.forSupplier(supplier))
419         .addEqualityGroup(Functions.forSupplier(new CountingSupplier()))
420         .addEqualityGroup(Functions.forSupplier(Suppliers.ofInstance(12)))
421         .addEqualityGroup(Functions.toStringFunction())
422         .testEquals();
423   }
424 
425   @GwtIncompatible("SerializableTester")
testForSupplierSerializable()426   public void testForSupplierSerializable() {
427     checkCanReserialize(Functions.forSupplier(new CountingSupplier()));
428   }
429 
430   @GwtIncompatible("SerializableTester")
checkCanReserialize(Function<? super Integer, Y> f)431   private <Y> void checkCanReserialize(Function<? super Integer, Y> f) {
432     Function<? super Integer, Y> g = SerializableTester.reserializeAndAssert(f);
433     for (int i = 1; i < 5; i++) {
434       // convoluted way to check that the same result happens from each
435       Y expected = null;
436       try {
437         expected = f.apply(i);
438       } catch (IllegalArgumentException e) {
439         try {
440           g.apply(i);
441           fail();
442         } catch (IllegalArgumentException ok) {
443           continue;
444         }
445       }
446       assertEquals(expected, g.apply(i));
447     }
448   }
449 
450   @GwtIncompatible("SerializableTester")
checkCanReserializeSingleton(Function<? super String, Y> f)451   private <Y> void checkCanReserializeSingleton(Function<? super String, Y> f) {
452     Function<? super String, Y> g = SerializableTester.reserializeAndAssert(f);
453     assertSame(f, g);
454     for (Integer i = 1; i < 5; i++) {
455       assertEquals(f.apply(i.toString()), g.apply(i.toString()));
456     }
457   }
458 
459 }
460