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