View Javadoc
1   /*
2    * Copyright (C) 2007 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.reflect;
18  
19  import static com.google.common.truth.Truth.assertThat;
20  
21  import com.google.common.base.Function;
22  import com.google.common.collect.ImmutableList;
23  import com.google.common.collect.ImmutableMap;
24  import com.google.common.collect.ImmutableSet;
25  import com.google.common.collect.Maps;
26  import com.google.common.primitives.Primitives;
27  import com.google.common.testing.EqualsTester;
28  import com.google.common.testing.NullPointerTester;
29  import com.google.common.testing.SerializableTester;
30  import com.google.common.truth.CollectionSubject;
31  
32  import junit.framework.TestCase;
33  
34  import java.io.Serializable;
35  import java.lang.reflect.Constructor;
36  import java.lang.reflect.GenericArrayType;
37  import java.lang.reflect.Method;
38  import java.lang.reflect.ParameterizedType;
39  import java.lang.reflect.Type;
40  import java.util.ArrayList;
41  import java.util.Collection;
42  import java.util.Collections;
43  import java.util.List;
44  import java.util.Map;
45  
46  /**
47   * Test cases for {@link TypeToken}.
48   *
49   * @author Sven Mawson
50   * @author Ben Yu
51   */
52  public class TypeTokenTest extends TestCase {
53  
54    private abstract static class StringList implements List<String> {}
55  
56    private abstract static class IntegerList implements List<Integer> {}
57  
58    public void testValueEqualityNotInstanceEquality() {
59      TypeToken<List<String>> a = new TypeToken<List<String>>() {};
60      TypeToken<List<String>> b = new TypeToken<List<String>>() {};
61      assertEquals(a, b);
62    }
63  
64    public <T> void testVariableTypeTokenNotAllowed() {
65      try {
66        new TypeToken<T>() {};
67        fail();
68      } catch (IllegalStateException expected) {}
69    }
70  
71    public void testRawTypeIsCorrect() {
72      TypeToken<List<String>> token = new TypeToken<List<String>>() {};
73      assertEquals(List.class, token.getRawType());
74    }
75  
76    public void testTypeIsCorrect() {
77      TypeToken<List<String>> token = new TypeToken<List<String>>() {};
78      assertEquals(StringList.class.getGenericInterfaces()[0], token.getType());
79    }
80  
81    @SuppressWarnings("rawtypes") // Trying to test TypeToken.of(List.class)
82    public void testGetClass() {
83      TypeToken<List> token = TypeToken.of(List.class);
84      assertEquals(new TypeToken<List>() {}, token);
85    }
86  
87    public void testGetType() {
88      TypeToken<?> t = TypeToken.of(StringList.class.getGenericInterfaces()[0]);
89      assertEquals(new TypeToken<List<String>>() {}, t);
90    }
91  
92    public void testNonStaticLocalClass() {
93      class Local<T> {}
94      TypeToken<Local<String>> type = new TypeToken<Local<String>>() {};
95      assertEquals(Types.newParameterizedType(Local.class, String.class),
96          type.getType());
97      assertEquals(new Local<String>() {}.getClass().getGenericSuperclass(), type.getType());
98    }
99  
100   public void testStaticLocalClass() {
101     doTestStaticLocalClass();
102   }
103 
104   private static void doTestStaticLocalClass() {
105     class Local<T> {}
106     TypeToken<Local<String>> type = new TypeToken<Local<String>>() {};
107     assertEquals(Types.newParameterizedType(Local.class, String.class),
108         type.getType());
109     assertEquals(new Local<String>() {}.getClass().getGenericSuperclass(), type.getType());
110   }
111 
112   public void testGenericArrayType() throws Exception {
113     TypeToken<List<String>[]> token = new TypeToken<List<String>[]>() {};
114     assertEquals(List[].class, token.getRawType());
115     assertTrue(token.getType() instanceof GenericArrayType);
116   }
117 
118   public void testMultiDimensionalGenericArrayType() throws Exception {
119     TypeToken<List<Long>[][][]> token = new TypeToken<List<Long>[][][]>() {};
120     assertEquals(List[][][].class, token.getRawType());
121     assertTrue(token.getType() instanceof GenericArrayType);
122   }
123 
124   public <T> void testGenericVariableTypeArrays() throws Exception {
125     assertEquals("T[]", new TypeToken<T[]>() {}.toString());
126   }
127 
128   public void testResolveType() throws Exception {
129     Method getFromList = List.class.getMethod("get", int.class);
130     TypeToken<?> returnType = new TypeToken<List<String>>() {}
131         .resolveType(getFromList.getGenericReturnType());
132     assertEquals(String.class, returnType.getType());
133   }
134 
135   public <F extends Enum<F> & Function<String, Integer> & Iterable<Long>>
136   void testResolveType_fromTypeVariable() throws Exception {
137     TypeToken<?> f = TypeToken.of(new TypeCapture<F>() {}.capture());
138     assertEquals(String.class,
139         f.resolveType(Function.class.getTypeParameters()[0]).getType());
140     assertEquals(Integer.class,
141         f.resolveType(Function.class.getTypeParameters()[1]).getType());
142     assertEquals(Long.class,
143         f.resolveType(Iterable.class.getTypeParameters()[0]).getType());
144   }
145 
146   public <E extends Comparable<Iterable<String>> & Iterable<Integer>>
147   void testResolveType_fromTypeVariable_onlyDirectBoundsAreUsed() throws Exception {
148     TypeToken<?> e = TypeToken.of(new TypeCapture<E>() {}.capture());
149     assertEquals(Integer.class,
150         e.resolveType(Iterable.class.getTypeParameters()[0]).getType());
151   }
152 
153   public void testResolveType_fromWildcard() throws Exception {
154     ParameterizedType withWildcardType = (ParameterizedType)
155         new TypeCapture<Comparable<? extends Iterable<String>>>() {}.capture();
156     TypeToken<?> wildcardType = TypeToken.of(withWildcardType.getActualTypeArguments()[0]);
157     assertEquals(String.class,
158         wildcardType.resolveType(Iterable.class.getTypeParameters()[0]).getType());
159   }
160 
161   public void testGetTypes_noSuperclass() {
162     TypeToken<Object>.TypeSet types = new TypeToken<Object>() {}.getTypes();
163     assertThat(types).has().item(TypeToken.of(Object.class));
164     assertThat(types.rawTypes()).has().item(Object.class);
165     assertThat(types.interfaces()).isEmpty();
166     assertThat(types.interfaces().rawTypes()).isEmpty();
167     assertThat(types.classes()).has().item(TypeToken.of(Object.class));
168     assertThat(types.classes().rawTypes()).has().item(Object.class);
169   }
170 
171   public void testGetTypes_fromInterface() {
172     TypeToken<Interface1>.TypeSet types = new TypeToken<Interface1>() {}.getTypes();
173     assertThat(types).has().item(TypeToken.of(Interface1.class));
174     assertThat(types.rawTypes()).has().item(Interface1.class);
175     assertThat(types.interfaces()).has().item(TypeToken.of(Interface1.class));
176     assertThat(types.interfaces().rawTypes()).has().item(Interface1.class);
177     assertThat(types.classes()).isEmpty();
178     assertThat(types.classes().rawTypes()).isEmpty();
179   }
180 
181   public void testGetTypes_fromPrimitive() {
182     TypeToken<Integer>.TypeSet types = TypeToken.of(int.class).getTypes();
183     assertThat(types).has().item(TypeToken.of(int.class));
184     assertThat(types.rawTypes()).has().item(int.class);
185     assertThat(types.interfaces()).isEmpty();
186     assertThat(types.interfaces().rawTypes()).isEmpty();
187     assertThat(types.classes()).has().item(TypeToken.of(int.class));
188     assertThat(types.classes().rawTypes()).has().item(int.class);
189   }
190 
191   public void testGetTypes_withInterfacesAndSuperclasses() {
192     abstract class Class2 extends Class1 implements Interface12 {}
193     abstract class Class3<T> extends Class2 implements Interface3<T> {}
194     TypeToken<Class3<String>>.TypeSet types = new TypeToken<Class3<String>>() {}.getTypes();
195     makeUnmodifiable(types).has().exactly(
196         new TypeToken<Class3<String>>() {},
197         new TypeToken<Interface3<String>>() {},
198         new TypeToken<Iterable<String>>() {},
199         TypeToken.of(Class2.class),
200         TypeToken.of(Interface12.class),
201         TypeToken.of(Interface1.class),
202         TypeToken.of(Interface2.class),
203         TypeToken.of(Class1.class),
204         TypeToken.of(Object.class));
205     makeUnmodifiable(types.interfaces()).has().exactly(
206         new TypeToken<Interface3<String>>() {},
207         TypeToken.of(Interface12.class),
208         TypeToken.of(Interface1.class),
209         TypeToken.of(Interface2.class),
210         new TypeToken<Iterable<String>>() {});
211     makeUnmodifiable(types.classes()).has().exactly(
212         new TypeToken<Class3<String>>() {},
213         TypeToken.of(Class2.class),
214         TypeToken.of(Class1.class),
215         TypeToken.of(Object.class));
216     assertSubtypeFirst(types);
217   }
218 
219   public void testGetTypes_rawTypes_withInterfacesAndSuperclasses() {
220     abstract class Class2 extends Class1 implements Interface12 {}
221     abstract class Class3<T> extends Class2 implements Interface3<T> {}
222     TypeToken<Class3<String>>.TypeSet types = new TypeToken<Class3<String>>() {}.getTypes();
223     makeUnmodifiable(types.rawTypes()).has().exactly(
224         Class3.class, Interface3.class,
225         Iterable.class,
226         Class2.class,
227         Interface12.class,
228         Interface1.class,
229         Interface2.class,
230         Class1.class,
231         Object.class);
232     makeUnmodifiable(types.interfaces().rawTypes()).has().exactly(
233         Interface3.class,
234         Interface12.class,
235         Interface1.class,
236         Interface2.class,
237         Iterable.class);
238     makeUnmodifiable(types.classes().rawTypes()).has().exactly(
239         Class3.class,
240         Class2.class,
241         Class1.class,
242         Object.class);
243     assertSubtypeFirst(types);
244   }
245 
246   public <A extends Class1 & Interface1, B extends A>
247   void testGetTypes_ignoresTypeVariablesByDefault() {
248     TypeToken<?>.TypeSet types = TypeToken.of(new TypeCapture<B>() {}.capture()).getTypes();
249     makeUnmodifiable(types).has().exactly(
250         TypeToken.of(Interface1.class), TypeToken.of(Class1.class),
251         TypeToken.of(Object.class));
252     assertSubtypeFirst(types);
253     makeUnmodifiable(types.interfaces())
254         .has().exactly(TypeToken.of(Interface1.class))
255         .inOrder();
256     makeUnmodifiable(types.classes())
257         .has().exactly(TypeToken.of(Class1.class), TypeToken.of(Object.class))
258         .inOrder();
259   }
260 
261   public <A extends Class1 & Interface1, B extends A>
262   void testGetTypes_rawTypes_ignoresTypeVariablesByDefault() {
263     TypeToken<?>.TypeSet types = TypeToken.of(new TypeCapture<B>() {}.capture()).getTypes();
264     makeUnmodifiable(types.rawTypes())
265         .has().exactly(Interface1.class, Class1.class, Object.class);
266     makeUnmodifiable(types.interfaces().rawTypes())
267         .has().exactly(Interface1.class)
268         .inOrder();
269     makeUnmodifiable(types.classes().rawTypes())
270         .has().exactly(Class1.class, Object.class)
271         .inOrder();
272   }
273 
274   public <A extends Interface1 & Interface2 & Interface3<String>>
275   void testGetTypes_manyBounds() {
276     TypeToken<?>.TypeSet types = TypeToken.of(new TypeCapture<A>() {}.capture()).getTypes();
277     makeUnmodifiable(types.rawTypes())
278         .has().exactly(Interface1.class, Interface2.class, Interface3.class, Iterable.class);
279   }
280 
281   private static void assertSubtypeFirst(TypeToken<?>.TypeSet types) {
282     assertSubtypeTokenBeforeSupertypeToken(types);
283     assertSubtypeTokenBeforeSupertypeToken(types.interfaces());
284     assertSubtypeTokenBeforeSupertypeToken(types.classes());
285     assertSubtypeBeforeSupertype(types.rawTypes());
286     assertSubtypeBeforeSupertype(types.interfaces().rawTypes());
287     assertSubtypeBeforeSupertype(types.classes().rawTypes());
288   }
289 
290   private static void assertSubtypeTokenBeforeSupertypeToken(
291       Iterable<? extends TypeToken<?>> types) {
292     int i = 0;
293     for (TypeToken<?> left : types) {
294       int j = 0;
295       for (TypeToken<?> right : types) {
296         if (left.isAssignableFrom(right)) {
297           assertTrue(left + " should be after " + right, i >= j);
298         }
299         j++;
300       }
301       i++;
302     }
303   }
304 
305   private static void assertSubtypeBeforeSupertype(Iterable<? extends Class<?>> types) {
306     int i = 0;
307     for (Class<?> left : types) {
308       int j = 0;
309       for (Class<?> right : types) {
310         if (left.isAssignableFrom(right)) {
311           assertTrue(left + " should be after " + right, i >= j);
312         }
313         j++;
314       }
315       i++;
316     }
317   }
318 
319   // Tests to make sure assertSubtypeBeforeSupertype() works.
320 
321   public void testAssertSubtypeTokenBeforeSupertypeToken_empty() {
322     assertSubtypeTokenBeforeSupertypeToken(ImmutableList.<TypeToken<?>>of());
323   }
324 
325   public void testAssertSubtypeTokenBeforeSupertypeToken_oneType() {
326     assertSubtypeTokenBeforeSupertypeToken(ImmutableList.of(TypeToken.of(String.class)));
327   }
328 
329   public void testAssertSubtypeTokenBeforeSupertypeToken_subtypeFirst() {
330     assertSubtypeTokenBeforeSupertypeToken(
331         ImmutableList.of(TypeToken.of(String.class), TypeToken.of(CharSequence.class)));
332   }
333 
334   public void testAssertSubtypeTokenBeforeSupertypeToken_supertypeFirst() {
335     try {
336       assertSubtypeTokenBeforeSupertypeToken(
337           ImmutableList.of(TypeToken.of(CharSequence.class), TypeToken.of(String.class)));
338     } catch (AssertionError expected) {
339       return;
340     }
341     fail();
342   }
343 
344   public void testAssertSubtypeTokenBeforeSupertypeToken_duplicate() {
345     try {
346       assertSubtypeTokenBeforeSupertypeToken(
347           ImmutableList.of(TypeToken.of(String.class), TypeToken.of(String.class)));
348     } catch (AssertionError expected) {
349       return;
350     }
351     fail();
352   }
353 
354   public void testAssertSubtypeBeforeSupertype_empty() {
355     assertSubtypeBeforeSupertype(ImmutableList.<Class<?>>of());
356   }
357 
358   public void testAssertSubtypeBeforeSupertype_oneType() {
359     assertSubtypeBeforeSupertype(ImmutableList.of(String.class));
360   }
361 
362   public void testAssertSubtypeBeforeSupertype_subtypeFirst() {
363     assertSubtypeBeforeSupertype(
364         ImmutableList.of(String.class, CharSequence.class));
365   }
366 
367   public void testAssertSubtypeBeforeSupertype_supertypeFirst() {
368     try {
369       assertSubtypeBeforeSupertype(
370           ImmutableList.of(CharSequence.class, String.class));
371     } catch (AssertionError expected) {
372       return;
373     }
374     fail();
375   }
376 
377   public void testAssertSubtypeBeforeSupertype_duplicate() {
378     try {
379       assertSubtypeBeforeSupertype(
380           ImmutableList.of(String.class, String.class));
381     } catch (AssertionError expected) {
382       return;
383     }
384     fail();
385   }
386 
387   public void testGetGenericSuperclass_noSuperclass() {
388     assertNull(new TypeToken<Object>() {}.getGenericSuperclass());
389     assertEquals(TypeToken.of(Object.class),
390         new TypeToken<Object[]>() {}.getGenericSuperclass());
391     assertNull(new TypeToken<List<String>>() {}.getGenericSuperclass());
392     assertEquals(TypeToken.of(Object.class),
393         new TypeToken<List<String>[]>() {}.getGenericSuperclass());
394   }
395 
396   public void testGetGenericSuperclass_withSuperclass() {
397     TypeToken<? super ArrayList<String>> superToken =
398         new TypeToken<ArrayList<String>>() {}.getGenericSuperclass();
399     assertEquals(ArrayList.class.getSuperclass(), superToken.getRawType());
400     assertEquals(String.class,
401         ((ParameterizedType) superToken.getType()).getActualTypeArguments()[0]);
402     assertEquals(TypeToken.of(Base.class), TypeToken.of(Sub.class).getGenericSuperclass());
403     assertEquals(TypeToken.of(Object.class), TypeToken.of(Sub[].class).getGenericSuperclass());
404   }
405 
406   public <T> void testGetGenericSuperclass_typeVariable_unbounded() {
407     assertEquals(TypeToken.of(Object.class),
408         TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericSuperclass());
409     assertEquals(TypeToken.of(Object.class), new TypeToken<T[]>() {}.getGenericSuperclass());
410   }
411 
412   public <T extends ArrayList<String> & CharSequence>
413   void testGetGenericSuperclass_typeVariable_boundIsClass() {
414     assertEquals(new TypeToken<ArrayList<String>>() {},
415         TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericSuperclass());
416     assertEquals(TypeToken.of(Object.class), new TypeToken<T[]>() {}.getGenericSuperclass());
417   }
418 
419   public <T extends Enum<T> & CharSequence>
420   void testGetGenericSuperclass_typeVariable_boundIsFBoundedClass() {
421     assertEquals(new TypeToken<Enum<T>>() {},
422         TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericSuperclass());
423     assertEquals(TypeToken.of(Object.class), new TypeToken<T[]>() {}.getGenericSuperclass());
424   }
425 
426   public <T extends List<String> & CharSequence>
427   void testGetGenericSuperclass_typeVariable_boundIsInterface() {
428     assertNull(TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericSuperclass());
429     assertEquals(TypeToken.of(Object.class), new TypeToken<T[]>() {}.getGenericSuperclass());
430   }
431 
432   public <T extends ArrayList<String> & CharSequence, T1 extends T>
433   void testGetGenericSuperclass_typeVariable_boundIsTypeVariableAndClass() {
434     assertEquals(TypeToken.of(new TypeCapture<T>() {}.capture()),
435         TypeToken.of(new TypeCapture<T1>() {}.capture()).getGenericSuperclass());
436     assertEquals(TypeToken.of(Object.class), new TypeToken<T[]>() {}.getGenericSuperclass());
437   }
438 
439   public <T extends List<String> & CharSequence, T1 extends T>
440   void testGetGenericSuperclass_typeVariable_boundIsTypeVariableAndInterface() {
441     assertNull(TypeToken.of(new TypeCapture<T1>() {}.capture()).getGenericSuperclass());
442     assertEquals(TypeToken.of(Object.class), new TypeToken<T1[]>() {}.getGenericSuperclass());
443   }
444 
445   public void testGetGenericSuperclass_wildcard_lowerBounded() {
446     assertEquals(TypeToken.of(Object.class),
447         TypeToken.of(Types.supertypeOf(String.class)).getGenericSuperclass());
448     assertEquals(new TypeToken<Object>() {},
449         TypeToken.of(Types.supertypeOf(String[].class)).getGenericSuperclass());
450     assertEquals(new TypeToken<Object>() {},
451         TypeToken.of(Types.supertypeOf(CharSequence.class)).getGenericSuperclass());
452   }
453 
454   public void testGetGenericSuperclass_wildcard_boundIsClass() {
455     assertEquals(TypeToken.of(Object.class),
456         TypeToken.of(Types.subtypeOf(Object.class)).getGenericSuperclass());
457     assertEquals(new TypeToken<Object[]>() {},
458         TypeToken.of(Types.subtypeOf(Object[].class)).getGenericSuperclass());
459   }
460 
461   public void testGetGenericSuperclass_wildcard_boundIsInterface() {
462     assertNull(TypeToken.of(Types.subtypeOf(CharSequence.class)).getGenericSuperclass());
463     assertEquals(new TypeToken<CharSequence[]>() {},
464         TypeToken.of(Types.subtypeOf(CharSequence[].class)).getGenericSuperclass());
465   }
466 
467   public <T> void testGetGenericInterfaces_typeVariable_unbounded() {
468     assertThat(TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericInterfaces()).isEmpty();
469     assertHasArrayInterfaces(new TypeToken<T[]>() {});
470   }
471 
472   public <T extends NoInterface> void testGetGenericInterfaces_typeVariable_boundIsClass() {
473     assertThat(TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericInterfaces()).isEmpty();
474     assertHasArrayInterfaces(new TypeToken<T[]>() {});
475   }
476 
477   public <T extends NoInterface&Iterable<String>>
478   void testGetGenericInterfaces_typeVariable_boundsAreClassWithInterface() {
479     makeUnmodifiable(TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericInterfaces())
480         .has().exactly(new TypeToken<Iterable<String>>() {});
481     assertHasArrayInterfaces(new TypeToken<T[]>() {});
482   }
483 
484   public <T extends CharSequence&Iterable<String>>
485   void testGetGenericInterfaces_typeVariable_boundsAreInterfaces() {
486     makeUnmodifiable(TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericInterfaces())
487         .has().exactly(TypeToken.of(CharSequence.class), new TypeToken<Iterable<String>>() {});
488     assertHasArrayInterfaces(new TypeToken<T[]>() {});
489   }
490 
491   public <T extends CharSequence&Iterable<T>>
492   void testGetGenericInterfaces_typeVariable_boundsAreFBoundedInterfaces() {
493     makeUnmodifiable(TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericInterfaces())
494         .has().exactly(TypeToken.of(CharSequence.class), new TypeToken<Iterable<T>>() {});
495     assertHasArrayInterfaces(new TypeToken<T[]>() {});
496   }
497 
498   public <T extends Base&Iterable<T>>
499   void testGetGenericInterfaces_typeVariable_boundsAreClassWithFBoundedInterface() {
500     makeUnmodifiable(TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericInterfaces())
501         .has().exactly(new TypeToken<Iterable<T>>() {});
502     assertHasArrayInterfaces(new TypeToken<T[]>() {});
503   }
504 
505   public <T extends NoInterface, T1 extends T, T2 extends T1>
506   void testGetGenericInterfaces_typeVariable_boundIsTypeVariableAndClass() {
507     assertThat(TypeToken.of(new TypeCapture<T2>() {}.capture()).getGenericInterfaces()).isEmpty();
508     assertHasArrayInterfaces(new TypeToken<T2[]>() {});
509   }
510 
511   public <T extends Iterable<T>, T1 extends T, T2 extends T1>
512   void testGetGenericInterfaces_typeVariable_boundIsTypeVariableAndInterface() {
513     makeUnmodifiable(TypeToken.of(new TypeCapture<T2>() {}.capture()).getGenericInterfaces())
514         .has().exactly(TypeToken.of(new TypeCapture<T1>() {}.capture()));
515     assertHasArrayInterfaces(new TypeToken<T2[]>() {});
516   }
517 
518   public void testGetGenericInterfaces_wildcard_lowerBounded() {
519     assertThat(TypeToken.of(Types.supertypeOf(String.class)).getGenericInterfaces()).isEmpty();
520     assertThat(TypeToken.of(Types.supertypeOf(String[].class)).getGenericInterfaces()).isEmpty();
521   }
522 
523   public void testGetGenericInterfaces_wildcard_boundIsClass() {
524     assertThat(TypeToken.of(Types.subtypeOf(Object.class)).getGenericInterfaces()).isEmpty();
525     assertThat(TypeToken.of(Types.subtypeOf(Object[].class)).getGenericInterfaces()).isEmpty();
526   }
527 
528   public void testGetGenericInterfaces_wildcard_boundIsInterface() {
529     TypeToken<Iterable<String>> interfaceType = new TypeToken<Iterable<String>>() {};
530     makeUnmodifiable(TypeToken.of(Types.subtypeOf(interfaceType.getType())).getGenericInterfaces())
531         .has().exactly(interfaceType);
532     assertHasArrayInterfaces(new TypeToken<Iterable<String>[]>() {});
533   }
534 
535   public void testGetGenericInterfaces_noInterface() {
536     assertThat(new TypeToken<NoInterface>() {}.getGenericInterfaces()).isEmpty();
537     assertHasArrayInterfaces(new TypeToken<NoInterface[]>() {});
538   }
539 
540   public void testGetGenericInterfaces_withInterfaces() {
541     Map<Class<?>, Type> interfaceMap = Maps.newHashMap();
542     for (TypeToken<?> interfaceType:
543         new TypeToken<Implementation<Integer, String>>() {}.getGenericInterfaces()) {
544       interfaceMap.put(interfaceType.getRawType(), interfaceType.getType());
545     }
546     assertEquals(ImmutableMap.of(
547             Iterable.class, new TypeToken<Iterable<String>>() {}.getType(),
548             Map.class, new TypeToken<Map<Integer, String>>() {}.getType()),
549         interfaceMap);
550   }
551 
552   private interface Interface1 {}
553   private interface Interface2 {}
554   private interface Interface3<T> extends Iterable<T> {}
555   private interface Interface12 extends Interface1, Interface2 {}
556   private static class Class1 implements Interface1 {}
557 
558   private static final class NoInterface {}
559 
560   private abstract static class Implementation<K, V>
561       implements Iterable<V>, Map<K, V> {}
562 
563   private abstract static class First<T> {}
564 
565   private abstract static class Second<D> extends First<D> {}
566 
567   private abstract static class Third<T, D> extends Second<T> {}
568 
569   private abstract static class Fourth<T, D> extends Third<D, T> {}
570 
571   private static class ConcreteIS extends Fourth<Integer, String> {}
572 
573   private static class ConcreteSI extends Fourth<String, Integer> {}
574 
575   public void testAssignableClassToClass() {
576     @SuppressWarnings("rawtypes") // To test TypeToken<List>
577     TypeToken<List> tokL = new TypeToken<List>() {};
578     assertTrue(tokL.isAssignableFrom(List.class));
579     assertTrue(tokL.isAssignableFrom(ArrayList.class));
580     assertFalse(tokL.isAssignableFrom(List[].class));
581 
582     TypeToken<Number> tokN = new TypeToken<Number>() {};
583     assertTrue(tokN.isAssignableFrom(Number.class));
584     assertTrue(tokN.isAssignableFrom(Integer.class));
585   }
586 
587   public <T> void testAssignableParameterizedTypeToObject() {
588     assertTrue(TypeToken.of(Object.class).isAssignableFrom(
589         TypeToken.of(new TypeCapture<T>() {}.capture())));
590     assertFalse(TypeToken.of(int.class).isAssignableFrom(
591         TypeToken.of(new TypeCapture<T>() {}.capture())));
592   }
593 
594   public <T, T1 extends T> void testAssignableGenericArrayToGenericArray() {
595     assertTrue(new TypeToken<T[]>() {}.isAssignableFrom(new TypeToken<T[]>() {}));
596     assertTrue(new TypeToken<T[]>() {}.isAssignableFrom(new TypeToken<T1[]>() {}));
597     assertFalse(new TypeToken<T[]>() {}.isAssignableFrom(new TypeToken<T[][]>() {}));
598   }
599 
600   public void testAssignableWildcardBoundedByArrayToArrayClass() throws Exception {
601     Type wildcardType = Types.subtypeOf(Object[].class);
602     assertTrue(TypeToken.of(Object[].class).isAssignableFrom(wildcardType));
603     assertTrue(TypeToken.of(Object.class).isAssignableFrom(wildcardType));
604     assertTrue(TypeToken.of(wildcardType).isAssignableFrom(wildcardType));
605     assertFalse(TypeToken.of(int[].class).isAssignableFrom(wildcardType));
606   }
607 
608   public void testAssignableArrayClassToBoundedWildcard() throws Exception {
609     TypeToken<?> upperBounded = TypeToken.of(Types.subtypeOf(Object[].class));
610     TypeToken<?> lowerBounded = TypeToken.of(Types.supertypeOf(Object[].class));
611     assertTrue(upperBounded.isAssignableFrom(Object[].class));
612     assertTrue(upperBounded.isAssignableFrom(Object[][].class));
613     assertTrue(upperBounded.isAssignableFrom(String[].class));
614     assertTrue(lowerBounded.isAssignableFrom(Object[].class));
615     assertTrue(lowerBounded.isAssignableFrom(Object.class));
616     assertFalse(lowerBounded.isAssignableFrom(Object[][].class));
617     assertFalse(lowerBounded.isAssignableFrom(String[].class));
618   }
619 
620   public void testAssignableWildcardBoundedByIntArrayToArrayClass() throws Exception {
621     Type wildcardType = Types.subtypeOf(int[].class);
622     assertTrue(TypeToken.of(int[].class).isAssignableFrom(wildcardType));
623     assertTrue(TypeToken.of(Object.class).isAssignableFrom(wildcardType));
624     assertTrue(TypeToken.of(wildcardType).isAssignableFrom(wildcardType));
625     assertFalse(TypeToken.of(Object[].class).isAssignableFrom(wildcardType));
626   }
627 
628   public void testAssignableWildcardToWildcard() throws Exception {
629     TypeToken<?> upperBounded = TypeToken.of(Types.subtypeOf(Object[].class));
630     TypeToken<?> lowerBounded = TypeToken.of(Types.supertypeOf(Object[].class));
631     assertFalse(lowerBounded.isAssignableFrom(upperBounded));
632     assertTrue(lowerBounded.isAssignableFrom(lowerBounded));
633     assertTrue(upperBounded.isAssignableFrom(upperBounded));
634     assertFalse(upperBounded.isAssignableFrom(lowerBounded));
635   }
636 
637   public <T> void testAssignableGenericArrayToArrayClass() {
638     assertTrue(TypeToken.of(Object[].class).isAssignableFrom(new TypeToken<T[]>() {}));
639     assertTrue(TypeToken.of(Object[].class).isAssignableFrom(new TypeToken<T[][]>() {}));
640     assertTrue(TypeToken.of(Object[][].class).isAssignableFrom(new TypeToken<T[][]>() {}));
641   }
642 
643   public void testAssignableParameterizedTypeToClass() {
644     @SuppressWarnings("rawtypes") // Trying to test raw class
645     TypeToken<List> tokL = new TypeToken<List>() {};
646     assertTrue(tokL.isAssignableFrom(StringList.class));
647     assertTrue(tokL.isAssignableFrom(
648         StringList.class.getGenericInterfaces()[0]));
649 
650     @SuppressWarnings("rawtypes") // Trying to test raw class
651     TypeToken<Second> tokS = new TypeToken<Second>() {};
652     assertTrue(tokS.isAssignableFrom(Second.class));
653     assertTrue(tokS.isAssignableFrom(Third.class.getGenericSuperclass()));
654   }
655 
656   public void testAssignableArrayToClass() throws Exception {
657     @SuppressWarnings("rawtypes") // Trying to test raw class
658     TypeToken<List[]> tokL = new TypeToken<List[]>() {};
659     assertTrue(tokL.isAssignableFrom(List[].class));
660     assertFalse(tokL.isAssignableFrom(List.class));
661 
662     @SuppressWarnings("rawtypes") // Trying to test raw class
663     TypeToken<Second[]> tokS = new TypeToken<Second[]>() {};
664     assertTrue(tokS.isAssignableFrom(Second[].class));
665     assertTrue(tokS.isAssignableFrom(Third[].class));
666   }
667 
668   @SuppressWarnings("rawtypes") // Trying to test raw class
669   public void testAssignableTokenToClass() {
670     TypeToken<List> tokL = new TypeToken<List>() {};
671     assertTrue(tokL.isAssignableFrom(new TypeToken<List>() {}));
672     assertTrue(tokL.isAssignableFrom(new TypeToken<List<String>>() {}));
673     assertTrue(tokL.isAssignableFrom(new TypeToken<List<?>>() {}));
674 
675     TypeToken<Second> tokS = new TypeToken<Second>() {};
676     assertTrue(tokS.isAssignableFrom(new TypeToken<Second>() {}));
677     assertTrue(tokS.isAssignableFrom(new TypeToken<Third>() {}));
678     assertTrue(tokS.isAssignableFrom(
679         new TypeToken<Third<String, Integer>>() {}));
680 
681     TypeToken<List[]> tokA = new TypeToken<List[]>() {};
682     assertTrue(tokA.isAssignableFrom(new TypeToken<List[]>() {}));
683     assertTrue(tokA.isAssignableFrom(new TypeToken<List<String>[]>() {}));
684     assertTrue(tokA.isAssignableFrom(new TypeToken<List<?>[]>() {}));
685   }
686 
687   public void testAssignableClassToType() {
688     TypeToken<List<String>> tokenL = new TypeToken<List<String>>() {};
689     assertTrue(tokenL.isAssignableFrom(StringList.class));
690     assertFalse(tokenL.isAssignableFrom(List.class));
691 
692     TypeToken<First<String>> tokenF = new TypeToken<First<String>>() {};
693     assertTrue(tokenF.isAssignableFrom(ConcreteIS.class));
694     assertFalse(tokenF.isAssignableFrom(ConcreteSI.class));
695   }
696 
697   public void testAssignableClassToArrayType() {
698     TypeToken<List<String>[]> tokenL = new TypeToken<List<String>[]>() {};
699     assertTrue(tokenL.isAssignableFrom(StringList[].class));
700     assertFalse(tokenL.isAssignableFrom(List[].class));
701   }
702 
703   public void testAssignableParameterizedTypeToType() {
704     TypeToken<List<String>> tokenL = new TypeToken<List<String>>() {};
705     assertTrue(tokenL.isAssignableFrom(
706         StringList.class.getGenericInterfaces()[0]));
707     assertFalse(tokenL.isAssignableFrom(
708         IntegerList.class.getGenericInterfaces()[0]));
709 
710     TypeToken<First<String>> tokenF = new TypeToken<First<String>>() {};
711     assertTrue(tokenF.isAssignableFrom(
712         ConcreteIS.class.getGenericSuperclass()));
713     assertFalse(tokenF.isAssignableFrom(
714         ConcreteSI.class.getGenericSuperclass()));
715   }
716 
717   public void testGenericArrayTypeToArrayType() throws Exception {
718     TypeToken<List<String>[]> tokL = new TypeToken<List<String>[]>() {};
719     TypeToken<ArrayList<String>[]> token =
720         new TypeToken<ArrayList<String>[]>() {};
721     assertTrue(tokL.isAssignableFrom(tokL.getType()));
722     assertTrue(tokL.isAssignableFrom(token.getType()));
723   }
724 
725   public void testAssignableTokenToType() {
726     TypeToken<List<String>> tokenL = new TypeToken<List<String>>() {};
727     assertTrue(tokenL.isAssignableFrom(new TypeToken<List<String>>() {}));
728     assertTrue(tokenL.isAssignableFrom(new TypeToken<ArrayList<String>>() {}));
729     assertTrue(tokenL.isAssignableFrom(new TypeToken<StringList>() {}));
730 
731     TypeToken<First<String>> tokenF = new TypeToken<First<String>>() {};
732     assertTrue(tokenF.isAssignableFrom(new TypeToken<Second<String>>() {}));
733     assertTrue(tokenF.isAssignableFrom(
734         new TypeToken<Third<String, Integer>>() {}));
735     assertFalse(tokenF.isAssignableFrom(
736         new TypeToken<Third<Integer, String>>() {}));
737     assertTrue(tokenF.isAssignableFrom(
738         new TypeToken<Fourth<Integer, String>>() {}));
739     assertFalse(tokenF.isAssignableFrom(
740         new TypeToken<Fourth<String, Integer>>() {}));
741     assertTrue(tokenF.isAssignableFrom(new TypeToken<ConcreteIS>() {}));
742     assertFalse(tokenF.isAssignableFrom(new TypeToken<ConcreteSI>() {}));
743   }
744 
745   public void testAssignableWithWildcards() {
746     TypeToken<?> unboundedToken = new TypeToken<List<?>>() {};
747     TypeToken<?> upperBoundToken = new TypeToken<List<? extends Number>>() {};
748     TypeToken<?> lowerBoundToken = new TypeToken<List<? super Number>>() {};
749     TypeToken<?> concreteToken = new TypeToken<List<Number>>() {};
750     TypeToken<?> subtypeToken = new TypeToken<List<Integer>>() {};
751     TypeToken<?> supertypeToken = new TypeToken<List<Serializable>>() {};
752     List<TypeToken<?>> allTokens = ImmutableList.of(
753         unboundedToken, upperBoundToken, lowerBoundToken,
754         concreteToken, subtypeToken, supertypeToken);
755 
756     for (TypeToken<?> typeToken : allTokens) {
757       assertTrue(typeToken.toString(), unboundedToken.isAssignableFrom(typeToken));
758     }
759 
760     assertFalse(upperBoundToken.isAssignableFrom(unboundedToken));
761     assertTrue(upperBoundToken.isAssignableFrom(upperBoundToken));
762     assertFalse(upperBoundToken.isAssignableFrom(lowerBoundToken));
763     assertTrue(upperBoundToken.isAssignableFrom(concreteToken));
764     assertTrue(upperBoundToken.isAssignableFrom(subtypeToken));
765     assertFalse(upperBoundToken.isAssignableFrom(supertypeToken));
766 
767     assertFalse(lowerBoundToken.isAssignableFrom(unboundedToken));
768     assertFalse(lowerBoundToken.isAssignableFrom(upperBoundToken));
769     assertTrue(lowerBoundToken.isAssignableFrom(lowerBoundToken));
770     assertTrue(lowerBoundToken.isAssignableFrom(concreteToken));
771     assertFalse(lowerBoundToken.isAssignableFrom(subtypeToken));
772     assertTrue(lowerBoundToken.isAssignableFrom(supertypeToken));
773 
774     for (TypeToken<?> typeToken : allTokens) {
775       assertEquals(typeToken.toString(),
776           typeToken == concreteToken, concreteToken.isAssignableFrom(typeToken));
777     }
778 
779     for (TypeToken<?> typeToken : allTokens) {
780       assertEquals(typeToken.toString(),
781           typeToken == subtypeToken, subtypeToken.isAssignableFrom(typeToken));
782     }
783 
784     for (TypeToken<?> typeToken : allTokens) {
785       assertEquals(typeToken.toString(),
786           typeToken == supertypeToken, supertypeToken.isAssignableFrom(typeToken));
787     }
788   }
789 
790   public <N1 extends Number, N2 extends Number, N11 extends N1>
791       void testIsAssignableFrom_typeVariable() {
792     assertAssignable(TypeToken.of(new TypeCapture<N1>() {}.capture()),
793         TypeToken.of(new TypeCapture<N1>() {}.capture()));
794     assertNotAssignable(new TypeToken<List<N11>>() {},
795         new TypeToken<List<N1>>() {});
796     assertNotAssignable(new TypeToken<Number>() {},
797         TypeToken.of(new TypeCapture<N1>() {}.capture()));
798     assertAssignable(TypeToken.of(new TypeCapture<N11>() {}.capture()),
799         TypeToken.of(new TypeCapture<N1>() {}.capture()));
800     assertNotAssignable(TypeToken.of(new TypeCapture<N2>() {}.capture()),
801         TypeToken.of(new TypeCapture<N1>() {}.capture()));
802   }
803 
804   public <N1 extends Number, N2 extends Number, N11 extends N1>
805       void testIsAssignableFrom_equalWildcardTypes() {
806     assertAssignable(new TypeToken<List<? extends N1>>() {},
807         new TypeToken<List<? extends N1>>() {});
808     assertAssignable(new TypeToken<List<? super N1>>() {},
809         new TypeToken<List<? super N1>>() {});
810     assertAssignable(new TypeToken<List<? extends Number>>() {},
811         new TypeToken<List<? extends Number>>() {});
812     assertAssignable(new TypeToken<List<? super Number>>() {},
813         new TypeToken<List<? super Number>>() {});
814   }
815 
816   public <N> void testIsAssignableFrom_wildcard_noBound() {
817     assertAssignable(new TypeToken<List<? super N>>() {},
818         new TypeToken<List<?>>() {});
819     assertAssignable(new TypeToken<List<N>>() {},
820         new TypeToken<List<?>>() {});
821   }
822 
823   public <N1 extends Number, N2 extends Number, N11 extends N1>
824       void testIsAssignableFrom_wildcardType_upperBoundMatch() {
825     // ? extends T
826     assertAssignable(new TypeToken<List<N11>>() {},
827         new TypeToken<List<? extends N1>>() {});
828     assertNotAssignable(new TypeToken<List<N1>>() {},
829         new TypeToken<List<? extends N11>>() {});
830     assertNotAssignable(new TypeToken<List<Number>>() {},
831         new TypeToken<List<? extends N11>>() {});
832 
833     // ? extends Number
834     assertAssignable(new TypeToken<List<N1>>() {},
835         new TypeToken<List<? extends Number>>() {});
836     assertAssignable(new TypeToken<ArrayList<N1>>() {},
837         new TypeToken<List<? extends Number>>() {});
838     assertAssignable(new TypeToken<List<? extends N11>>() {},
839         new TypeToken<List<? extends Number>>() {});
840   }
841 
842   public <N1 extends Number, N2 extends Number, N11 extends N1>
843       void testIsAssignableFrom_wildcardType_lowerBoundMatch() {
844     // ? super T
845     assertAssignable(new TypeToken<List<N1>>() {},
846         new TypeToken<List<? super N11>>() {});
847     assertAssignable(new TypeToken<ArrayList<Number>>() {},
848         new TypeToken<List<? super N1>>() {});
849     assertNotAssignable(new TypeToken<ArrayList<? super N11>>() {},
850         new TypeToken<List<? super Number>>() {});
851     assertAssignable(new TypeToken<ArrayList<? super N1>>() {},
852         new TypeToken<List<? super N11>>() {});
853     assertAssignable(new TypeToken<ArrayList<? super Number>>() {},
854         new TypeToken<List<? super N11>>() {});
855 
856     // ? super Number
857     assertNotAssignable(new TypeToken<ArrayList<N11>>() {},
858         new TypeToken<List<? super Number>>() {});
859     assertAssignable(new TypeToken<ArrayList<Number>>() {},
860         new TypeToken<List<? super Number>>() {});
861     assertAssignable(new TypeToken<ArrayList<Object>>() {},
862         new TypeToken<List<? super Number>>() {});
863   }
864 
865   public <L extends List<R>, R extends List<L>>
866       void testIsAssignableFrom_recursiveTypeVariableBounds() {
867     assertAssignable(TypeToken.of(new TypeCapture<L>() {}.capture()),
868         TypeToken.of(new TypeCapture<L>() {}.capture()));
869     assertNotAssignable(TypeToken.of(new TypeCapture<R>() {}.capture()),
870         TypeToken.of(new TypeCapture<L>() {}.capture()));
871     assertAssignable(TypeToken.of(new TypeCapture<L>() {}.capture()),
872         new TypeToken<List<R>>() {});
873   }
874 
875   public void testIsAssignableFrom_resolved() {
876     assertFalse(Assignability.of().isAssignable());
877     assertTrue(new Assignability<Integer, Integer>() {}.isAssignable());
878     assertTrue(new Assignability<Integer, Object>() {}.isAssignable());
879     assertFalse(new Assignability<Integer, String>() {}.isAssignable());
880     TypeTokenTest.<Number, Integer>assignabilityTestWithTypeVariables();
881   }
882 
883   private static <N1 extends Number, N11 extends N1>
884       void assignabilityTestWithTypeVariables() {
885     assertTrue(new Assignability<N11, N1>() {}.isAssignable());
886     assertTrue(new Assignability<N11, Number>() {}.isAssignable());
887     assertFalse(new Assignability<Number, N11>() {}.isAssignable());
888   }
889 
890   public void testIsArray_arrayClasses() {
891     assertTrue(TypeToken.of(Object[].class).isArray());
892     assertTrue(TypeToken.of(Object[][].class).isArray());
893     assertTrue(TypeToken.of(char[].class).isArray());
894     assertTrue(TypeToken.of(char[][].class).isArray());
895     assertTrue(TypeToken.of(byte[].class).isArray());
896     assertTrue(TypeToken.of(short[].class).isArray());
897     assertTrue(TypeToken.of(int[].class).isArray());
898     assertTrue(TypeToken.of(long[].class).isArray());
899     assertTrue(TypeToken.of(float[].class).isArray());
900     assertTrue(TypeToken.of(double[].class).isArray());
901     assertFalse(TypeToken.of(Object.class).isArray());
902     assertFalse(TypeToken.of(void.class).isArray());
903   }
904 
905   public <T> void testIsArray_genericArrayClasses() {
906     assertFalse(TypeToken.of(new TypeCapture<T>() {}.capture()).isArray());
907     assertTrue(new TypeToken<T[]>() {}.isArray());
908     assertTrue(new TypeToken<T[][]>() {}.isArray());
909   }
910 
911   public void testIsArray_wildcardType() throws Exception {
912     assertTrue(TypeToken.of(Types.subtypeOf(Object[].class)).isArray());
913     assertTrue(TypeToken.of(Types.subtypeOf(int[].class)).isArray());
914     assertFalse(TypeToken.of(Types.subtypeOf(Object.class)).isArray());
915     assertFalse(TypeToken.of(Types.supertypeOf(Object[].class)).isArray());
916   }
917 
918   public <T extends Integer> void testPrimitiveWrappingAndUnwrapping() {
919     for (Class<?> type : Primitives.allPrimitiveTypes()) {
920       assertIsPrimitive(TypeToken.of(type));
921     }
922     for (Class<?> type : Primitives.allWrapperTypes()) {
923       assertIsWrapper(TypeToken.of(type));
924     }
925     assertNotPrimitiveNorWrapper(TypeToken.of(String.class));
926     assertNotPrimitiveNorWrapper(TypeToken.of(Object[].class));
927     assertNotPrimitiveNorWrapper(TypeToken.of(Types.subtypeOf(Object.class)));
928     assertNotPrimitiveNorWrapper(new TypeToken<List<String>>() {});
929     assertNotPrimitiveNorWrapper(TypeToken.of(new TypeCapture<T>() {}.capture()));
930   }
931 
932   public void testGetComponentType_arrayClasses() {
933     assertEquals(Object.class, TypeToken.of(Object[].class).getComponentType().getType());
934     assertEquals(Object[].class, TypeToken.of(Object[][].class).getComponentType().getType());
935     assertEquals(char.class, TypeToken.of(char[].class).getComponentType().getType());
936     assertEquals(char[].class, TypeToken.of(char[][].class).getComponentType().getType());
937     assertEquals(byte.class, TypeToken.of(byte[].class).getComponentType().getType());
938     assertEquals(short.class, TypeToken.of(short[].class).getComponentType().getType());
939     assertEquals(int.class, TypeToken.of(int[].class).getComponentType().getType());
940     assertEquals(long.class, TypeToken.of(long[].class).getComponentType().getType());
941     assertEquals(float.class, TypeToken.of(float[].class).getComponentType().getType());
942     assertEquals(double.class, TypeToken.of(double[].class).getComponentType().getType());
943     assertNull(TypeToken.of(Object.class).getComponentType());
944     assertNull(TypeToken.of(void.class).getComponentType());
945   }
946 
947   public <T> void testGetComponentType_genericArrayClasses() {
948     assertNull(TypeToken.of(new TypeCapture<T>() {}.capture()).getComponentType());
949     assertEquals(TypeToken.of(new TypeCapture<T>() {}.capture()),
950         new TypeToken<T[]>() {}.getComponentType());
951     assertEquals(new TypeToken<T[]>() {}, new TypeToken<T[][]>() {}.getComponentType());
952   }
953 
954   public void testGetComponentType_wildcardType() throws Exception {
955     assertEquals(Types.subtypeOf(Object.class),
956         TypeToken.of(Types.subtypeOf(Object[].class)).getComponentType().getType());
957     assertEquals(Types.subtypeOf(Object[].class),
958         Types.newArrayType(
959             TypeToken.of(Types.subtypeOf(Object[].class)).getComponentType().getType()));
960     assertEquals(int.class,
961         TypeToken.of(Types.subtypeOf(int[].class)).getComponentType().getType());
962     assertNull(TypeToken.of(Types.subtypeOf(Object.class)).getComponentType());
963     assertNull(TypeToken.of(Types.supertypeOf(Object[].class)).getComponentType());
964   }
965 
966   private interface NumberList<T extends Number> {}
967 
968   public void testImplicitUpperBoundForWildcards() {
969     assertAssignable(
970         new TypeToken<NumberList<? extends Number>>() {},
971         new TypeToken<NumberList<?>>() {});
972     assertAssignable(
973         new TypeToken<NumberList<? super Integer>>() {},
974         new TypeToken<NumberList<?>>() {});
975   }
976 
977   public <T extends Readable & Appendable> void testMultiBound() {
978     assertAssignable(new TypeToken<List<T>>() {},
979         new TypeToken<List<? extends Readable>>() {});
980     assertAssignable(new TypeToken<List<T>>() {},
981         new TypeToken<List<? extends Appendable>>() {});
982   }
983 
984   public void testToGenericType() {
985     assertEquals(TypeToken.of(String.class), TypeToken.toGenericType(String.class));
986     assertEquals(new TypeToken<int[]>() {}, TypeToken.toGenericType(int[].class));
987     @SuppressWarnings("rawtypes") // Iterable.class
988     TypeToken<? extends Iterable> genericType = TypeToken.toGenericType(Iterable.class);
989     assertEquals(Iterable.class, genericType.getRawType());
990     assertEquals(Types.newParameterizedType(Iterable.class, Iterable.class.getTypeParameters()[0]),
991         genericType.getType());
992   }
993 
994   private interface ListIterable<T> extends Iterable<List<T>> {}
995   private interface StringListIterable extends ListIterable<String> {}
996   private interface ListArrayIterable<T> extends Iterable<List<T>[]> {}
997   private interface StringListArrayIterable extends ListIterable<String> {}
998 
999   public void testGetSupertype_withTypeVariable() {
1000     ParameterizedType expectedType = Types.newParameterizedType(Iterable.class,
1001         Types.newParameterizedType(List.class, ListIterable.class.getTypeParameters()[0]));
1002     assertEquals(expectedType,
1003         TypeToken.of(ListIterable.class).getSupertype(Iterable.class).getType());
1004   }
1005 
1006   public void testGetSupertype_withoutTypeVariable() {
1007     ParameterizedType expectedType = Types.newParameterizedType(Iterable.class,
1008         Types.newParameterizedType(List.class, String.class));
1009     assertEquals(expectedType,
1010         TypeToken.of(StringListIterable.class).getSupertype(Iterable.class).getType());
1011   }
1012 
1013   public void testGetSupertype_chained() {
1014     @SuppressWarnings("unchecked") // StringListIterable extensd ListIterable<String>
1015     TypeToken<ListIterable<String>> listIterableType = (TypeToken<ListIterable<String>>)
1016         TypeToken.of(StringListIterable.class).getSupertype(ListIterable.class);
1017     ParameterizedType expectedType = Types.newParameterizedType(Iterable.class,
1018         Types.newParameterizedType(List.class, String.class));
1019     assertEquals(expectedType, listIterableType.getSupertype(Iterable.class).getType());
1020   }
1021 
1022   public void testGetSupertype_withArray() {
1023     assertEquals(new TypeToken<Iterable<List<String>>[]>() {},
1024         TypeToken.of(StringListIterable[].class).getSupertype(Iterable[].class));
1025     assertEquals(int[].class, TypeToken.of(int[].class).getSupertype(int[].class).getType());
1026     assertEquals(Object.class, TypeToken.of(int[].class).getSupertype(Object.class).getType());
1027     assertEquals(int[][].class, TypeToken.of(int[][].class).getSupertype(int[][].class).getType());
1028     assertEquals(Object[].class,
1029         TypeToken.of(String[].class).getSupertype(Object[].class).getType());
1030     assertEquals(Object.class, TypeToken.of(String[].class).getSupertype(Object.class).getType());
1031   }
1032 
1033   public void testGetSupertype_fromWildcard() {
1034     @SuppressWarnings("unchecked") // can't do new TypeToken<? extends ...>() {}
1035     TypeToken<? extends List<String>> type = (TypeToken<? extends List<String>>)
1036         TypeToken.of(Types.subtypeOf(new TypeToken<List<String>>() {}.getType()));
1037     assertEquals(new TypeToken<Iterable<String>>() {}, type.getSupertype(Iterable.class));
1038   }
1039 
1040   public <T extends Iterable<String>> void testGetSupertype_fromTypeVariable() {
1041     @SuppressWarnings("unchecked") // to construct TypeToken<T> from TypeToken.of()
1042     TypeToken<T> typeVariableToken = (TypeToken<T>) TypeToken.of(new TypeCapture<T>() {}.capture());
1043     assertEquals(new TypeToken<Iterable<String>>() {},
1044         typeVariableToken.getSupertype(Iterable.class));
1045   }
1046 
1047   @SuppressWarnings("rawtypes") // purpose is to test raw type
1048   public void testGetSupertype_fromRawClass() {
1049     assertEquals(Types.newParameterizedType(Iterable.class, List.class.getTypeParameters()[0]),
1050         new TypeToken<List>() {}.getSupertype(Iterable.class).getType());
1051   }
1052 
1053   @SuppressWarnings({"rawtypes", "unchecked"}) // purpose is to test raw type
1054   public void testGetSupertype_notSupertype() {
1055     try {
1056       new TypeToken<List<String>>() {}.getSupertype((Class) String.class);
1057       fail();
1058     } catch (IllegalArgumentException expected) {}
1059   }
1060 
1061   public void testGetSupertype_fromArray() {
1062     assertEquals(new TypeToken<Iterable<String>[]>() {},
1063         new TypeToken<List<String>[]>() {}.getSupertype(Iterable[].class));
1064   }
1065 
1066   private interface ListMap<K, V> extends Map<K, List<V>> {}
1067 
1068   public void testGetSupertype_fullyGenericType() {
1069     ParameterizedType expectedType = Types.newParameterizedType(Map.class,
1070         ListMap.class.getTypeParameters()[0],
1071         Types.newParameterizedType(List.class, ListMap.class.getTypeParameters()[1]));
1072     assertEquals(expectedType,
1073         TypeToken.of(ListMap.class).getSupertype(Map.class).getType());
1074   }
1075 
1076   public void testGetSupertype_fullySpecializedType() {
1077     Type expectedType = new TypeToken<Map<String, List<Object>>>() {}.getType();
1078     assertEquals(expectedType,
1079         new TypeToken<ListMap<String, Object>>() {}.getSupertype(Map.class).getType());
1080   }
1081 
1082   private interface StringListMap<V> extends ListMap<String, V> {}
1083 
1084   public <V> void testGetSupertype_partiallySpecializedType() {
1085     Type expectedType = new TypeToken<Map<String, List<V>>>() {}.getType();
1086     assertEquals(expectedType,
1087         new TypeToken<StringListMap<V>>() {}.getSupertype(Map.class).getType());
1088   }
1089 
1090   public void testGetSubtype_withTypeVariable() {
1091     assertEquals(new TypeToken<ListIterable<String>>() {},
1092         new TypeToken<Iterable<List<String>>>() {}.getSubtype(ListIterable.class));
1093     assertEquals(new TypeToken<ListArrayIterable<String>>() {},
1094         new TypeToken<Iterable<List<String>[]>>() {}.getSubtype(ListArrayIterable.class));
1095     assertEquals(new TypeToken<ListArrayIterable<String>[]>() {},
1096         new TypeToken<Iterable<List<String>[]>[]>() {}.getSubtype(ListArrayIterable[].class));
1097   }
1098 
1099   public void testGetSubtype_withoutTypeVariable() {
1100     assertEquals(StringListIterable.class,
1101         TypeToken.of(Iterable.class).getSubtype(StringListIterable.class).getType());
1102     assertEquals(StringListIterable[].class,
1103         TypeToken.of(Iterable[].class).getSubtype(StringListIterable[].class).getType());
1104     assertEquals(TypeToken.of(StringListArrayIterable.class),
1105         new TypeToken<Iterable<List<String>>>() {}.getSubtype(StringListArrayIterable.class));
1106     assertEquals(TypeToken.of(StringListArrayIterable[].class),
1107         new TypeToken<Iterable<List<String>>[]>() {}.getSubtype(StringListArrayIterable[].class));
1108   }
1109 
1110   public void testGetSubtype_withArray() {
1111     assertEquals(TypeToken.of(StringListIterable[].class),
1112         TypeToken.of(Iterable[].class).getSubtype(StringListIterable[].class));
1113     assertEquals(TypeToken.of(String[].class),
1114         TypeToken.of(Object[].class).getSubtype(String[].class));
1115     assertEquals(TypeToken.of(int[].class),
1116         TypeToken.of(Object.class).getSubtype(int[].class));
1117   }
1118 
1119   public void testGetSubtype_fromWildcard() {
1120     @SuppressWarnings("unchecked") // can't do new TypeToken<? extends ...>() {}
1121     TypeToken<? super Iterable<String>> type = (TypeToken<? super Iterable<String>>)
1122         TypeToken.of(Types.supertypeOf(new TypeToken<Iterable<String>>() {}.getType()));
1123     assertEquals(new TypeToken<List<String>>() {}, type.getSubtype(List.class));
1124   }
1125 
1126   public void testGetSubtype_fromWildcard_lowerBoundNotSupertype() {
1127     @SuppressWarnings("unchecked") // can't do new TypeToken<? extends ...>() {}
1128     TypeToken<? super Iterable<String>> type = (TypeToken<? super Iterable<String>>)
1129         TypeToken.of(Types.supertypeOf(new TypeToken<ImmutableList<String>>() {}.getType()));
1130     try {
1131       type.getSubtype(List.class);
1132       fail();
1133     } catch (IllegalArgumentException expected) {}
1134   }
1135 
1136   public void testGetSubtype_fromWildcard_upperBounded() {
1137     @SuppressWarnings("unchecked") // can't do new TypeToken<? extends ...>() {}
1138     TypeToken<? extends Iterable<String>> type = (TypeToken<? extends Iterable<String>>)
1139         TypeToken.of(Types.subtypeOf(new TypeToken<Iterable<String>>() {}.getType()));
1140     try {
1141       type.getSubtype(Iterable.class);
1142       fail();
1143     } catch (IllegalArgumentException expected) {}
1144   }
1145 
1146   public <T extends Iterable<String>> void testGetSubtype_fromTypeVariable() {
1147     try {
1148       TypeToken.of(new TypeCapture<T>() {}.capture()).getSubtype(List.class);
1149       fail();
1150     } catch (IllegalArgumentException expected) {}
1151   }
1152 
1153   @SuppressWarnings("rawtypes") // purpose is to test raw type
1154   public void testGetSubtype_fromRawClass() {
1155     assertEquals(List.class, new TypeToken<Iterable>() {}.getSubtype(List.class).getType());
1156   }
1157 
1158   public void testGetSubtype_fromArray() {
1159     assertEquals(new TypeToken<List<String>[]>() {},
1160         new TypeToken<Iterable<String>[]>() {}.getSubtype(List[].class));
1161   }
1162 
1163   @SuppressWarnings("unchecked") // To construct TypeToken<T> with TypeToken.of()
1164   public <T> void testWhere_circleRejected() {
1165     TypeToken<List<T>> type = new TypeToken<List<T>>() {};
1166     try {
1167       type.where(new TypeParameter<T>() {},
1168           (TypeToken<T>) TypeToken.of(new TypeCapture<T>() {}.capture()));
1169       fail();
1170     } catch (IllegalArgumentException expected) {}
1171   }
1172 
1173   public void testWhere() {
1174     assertEquals(
1175         new TypeToken<Map<String, Integer>>() {},
1176         mapOf(String.class, Integer.class));
1177     assertEquals(new TypeToken<int[]>() {}, arrayOf(int.class));
1178     assertEquals(int[].class, arrayOf(int.class).getRawType());
1179   }
1180 
1181   @SuppressWarnings("unused") // used by reflection
1182   private static class Holder<T> {
1183     T element;
1184     List<T> list;
1185     List<T>[] matrix;
1186 
1187     void setList(List<T> list) {
1188       this.list = list;
1189     }
1190   }
1191 
1192   public void testWildcardCaptured_methodParameter_upperBound() throws Exception {
1193     TypeToken<Holder<?>> type = new TypeToken<Holder<?>>() {};
1194     TypeToken<?> parameterType = type.resolveType(
1195         Holder.class.getDeclaredMethod("setList", List.class).getGenericParameterTypes()[0]);
1196     assertEquals(List.class, parameterType.getRawType());
1197     assertFalse(parameterType.getType().toString(),
1198         parameterType.isAssignableFrom(new TypeToken<List<Integer>>() {}));
1199   }
1200 
1201   public void testWildcardCaptured_field_upperBound() throws Exception {
1202     TypeToken<Holder<?>> type = new TypeToken<Holder<?>>() {};
1203     TypeToken<?> matrixType = type.resolveType(
1204         Holder.class.getDeclaredField("matrix").getGenericType());
1205     assertEquals(List[].class, matrixType.getRawType());
1206     assertThat(matrixType.getType())
1207         .isNotEqualTo(new TypeToken<List<?>[]>() {}.getType());
1208   }
1209 
1210   public void testArrayClassPreserved() {
1211     assertEquals(int[].class, TypeToken.of(int[].class).getType());
1212     assertEquals(int[][].class, TypeToken.of(int[][].class).getType());
1213     assertEquals(String[].class, TypeToken.of(String[].class).getType());
1214     assertEquals(Integer.class, new TypeToken<Integer>() {}.getType());
1215     assertEquals(Integer.class, TypeToken.of(Integer.class).getType());
1216   }
1217 
1218   public void testMethod_getOwnerType() throws NoSuchMethodException {
1219     Method sizeMethod = List.class.getMethod("size");
1220     assertEquals(TypeToken.of(List.class),
1221         TypeToken.of(List.class).method(sizeMethod).getOwnerType());
1222     assertEquals(new TypeToken<List<String>>() {},
1223         new TypeToken<List<String>>() {}.method(sizeMethod).getOwnerType());
1224   }
1225 
1226   public void testMethod_notDeclaredByType() throws NoSuchMethodException {
1227     Method sizeMethod = Map.class.getMethod("size");
1228     try {
1229       TypeToken.of(List.class).method(sizeMethod);
1230       fail();
1231     } catch (IllegalArgumentException expected) {}
1232   }
1233 
1234   public void testMethod_declaredBySuperclass() throws Exception {
1235     Method toStringMethod = Object.class.getMethod("toString");
1236     ImmutableList<String> list = ImmutableList.of("foo");
1237     assertEquals(list.toString(), TypeToken.of(List.class).method(toStringMethod).invoke(list));
1238   }
1239 
1240   public <T extends Number & List<String>> void testMethod_returnType_resolvedAgainstTypeBound()
1241       throws NoSuchMethodException {
1242     Method getMethod = List.class.getMethod("get", int.class);
1243     Invokable<T, String> invokable = new TypeToken<T>(getClass()) {}
1244         .method(getMethod)
1245         .returning(String.class);
1246     assertEquals(TypeToken.of(String.class), invokable.getReturnType());
1247   }
1248 
1249   public <T extends List<String>> void testMethod_parameterTypes()
1250       throws NoSuchMethodException {
1251     Method setMethod = List.class.getMethod("set", int.class, Object.class);
1252     Invokable<T, ?> invokable = new TypeToken<T>(getClass()) {}.method(setMethod);
1253     ImmutableList<Parameter> params = invokable.getParameters();
1254     assertEquals(2, params.size());
1255     assertEquals(TypeToken.of(int.class), params.get(0).getType());
1256     assertEquals(TypeToken.of(String.class), params.get(1).getType());
1257   }
1258 
1259   public void testMethod_equals() throws NoSuchMethodException {
1260     Method getMethod = List.class.getMethod("get", int.class);
1261     Method setMethod = List.class.getMethod("set", int.class, Object.class);
1262     new EqualsTester()
1263         .addEqualityGroup(Invokable.from(getMethod), Invokable.from(getMethod))
1264         .addEqualityGroup(Invokable.from(setMethod))
1265         .addEqualityGroup(new TypeToken<List<Integer>>() {}.method(getMethod))
1266         .addEqualityGroup(new TypeToken<List<String>>() {}.method(getMethod))
1267         .addEqualityGroup(new TypeToken<List<Integer>>() {}.method(setMethod))
1268         .addEqualityGroup(new TypeToken<List<String>>() {}.method(setMethod))
1269         .testEquals();
1270   }
1271 
1272   private interface Loser<E extends Throwable> {
1273     void lose() throws E;
1274   }
1275 
1276   public <T extends Loser<AssertionError>> void testMethod_exceptionTypes()
1277       throws NoSuchMethodException {
1278     Method failMethod = Loser.class.getMethod("lose");
1279     Invokable<T, ?> invokable = new TypeToken<T>(getClass()) {}.method(failMethod);
1280     assertThat(invokable.getExceptionTypes()).has().item(TypeToken.of(AssertionError.class));
1281   }
1282 
1283   public void testConstructor_getOwnerType() throws NoSuchMethodException {
1284     @SuppressWarnings("rawtypes") // raw class ArrayList.class
1285     Constructor<ArrayList> constructor = ArrayList.class.getConstructor();
1286     assertEquals(TypeToken.of(ArrayList.class),
1287         TypeToken.of(ArrayList.class).constructor(constructor).getOwnerType());
1288     assertEquals(new TypeToken<ArrayList<String>>() {},
1289         new TypeToken<ArrayList<String>>() {}.constructor(constructor).getOwnerType());
1290   }
1291 
1292   public void testConstructor_notDeclaredByType() throws NoSuchMethodException {
1293     Constructor<String> constructor = String.class.getConstructor();
1294     try {
1295       TypeToken.of(Object.class).constructor(constructor);
1296       fail();
1297     } catch (IllegalArgumentException expected) {}
1298   }
1299 
1300   public void testConstructor_declaredBySuperclass() throws NoSuchMethodException {
1301     Constructor<Object> constructor = Object.class.getConstructor();
1302     try {
1303       TypeToken.of(String.class).constructor(constructor);
1304       fail();
1305     } catch (IllegalArgumentException expected) {}
1306   }
1307 
1308   public void testConstructor_equals() throws NoSuchMethodException {
1309     Constructor<?> defaultConstructor = ArrayList.class.getConstructor();
1310     Constructor<?> oneArgConstructor = ArrayList.class.getConstructor(int.class);
1311     new EqualsTester()
1312         .addEqualityGroup(Invokable.from(defaultConstructor), Invokable.from(defaultConstructor))
1313         .addEqualityGroup(Invokable.from(oneArgConstructor))
1314         .addEqualityGroup(new TypeToken<ArrayList<Integer>>() {}.constructor(defaultConstructor))
1315         .addEqualityGroup(new TypeToken<ArrayList<String>>() {}.constructor(defaultConstructor))
1316         .addEqualityGroup(new TypeToken<ArrayList<Integer>>() {}.constructor(oneArgConstructor))
1317         .addEqualityGroup(new TypeToken<ArrayList<String>>() {}.constructor(oneArgConstructor))
1318         .testEquals();
1319   }
1320 
1321   private static class Container<T> {
1322     @SuppressWarnings("unused")
1323     public Container(T data) {}
1324   }
1325 
1326   public <T extends Container<String>> void testConstructor_parameterTypes()
1327       throws NoSuchMethodException {
1328     @SuppressWarnings("rawtypes") // Reflection API skew
1329     Constructor<Container> constructor = Container.class.getConstructor(Object.class);
1330     Invokable<T, ?> invokable = new TypeToken<T>(getClass()) {}.constructor(constructor);
1331     ImmutableList<Parameter> params = invokable.getParameters();
1332     assertEquals(1, params.size());
1333     assertEquals(TypeToken.of(String.class), params.get(0).getType());
1334   }
1335 
1336   private static class CannotConstruct<E extends Throwable> {
1337     @SuppressWarnings("unused")
1338     public CannotConstruct() throws E {}
1339   }
1340 
1341   public <T extends CannotConstruct<AssertionError>> void testConstructor_exceptionTypes()
1342       throws NoSuchMethodException {
1343     @SuppressWarnings("rawtypes") // Reflection API skew
1344     Constructor<CannotConstruct> constructor = CannotConstruct.class.getConstructor();
1345     Invokable<T, ?> invokable = new TypeToken<T>(getClass()) {}.constructor(constructor);
1346     assertThat(invokable.getExceptionTypes()).has().item(TypeToken.of(AssertionError.class));
1347   }
1348 
1349   public void testRejectTypeVariable_class() {
1350     assertNoTypeVariable(String.class);
1351     assertNoTypeVariable(String[].class);
1352     assertNoTypeVariable(int[].class);
1353   }
1354 
1355   public void testRejectTypeVariable_parameterizedType() {
1356     assertNoTypeVariable(new TypeCapture<Iterable<String>>() {}.capture());
1357   }
1358 
1359   public void testRejectTypeVariable_wildcardType() {
1360     assertNoTypeVariable(
1361         new TypeCapture<Iterable<? extends String>>() {}.capture());
1362     assertNoTypeVariable(
1363         new TypeCapture<Iterable<? super String>>() {}.capture());
1364   }
1365 
1366   public void testRejectTypeVariable_genericArrayType() {
1367     assertNoTypeVariable(
1368         new TypeCapture<Iterable<? extends String>[]>() {}.capture());
1369   }
1370 
1371   public <T> void testRejectTypeVariable_withTypeVariable() {
1372     assertHasTypeVariable(new TypeCapture<T>() {}.capture());
1373     assertHasTypeVariable(new TypeCapture<T[]>() {}.capture());
1374     assertHasTypeVariable(new TypeCapture<Iterable<T>>() {}.capture());
1375     assertHasTypeVariable(new TypeCapture<Map<String, T>>() {}.capture());
1376     assertHasTypeVariable(
1377         new TypeCapture<Map<String, ? extends T>>() {}.capture());
1378     assertHasTypeVariable(
1379         new TypeCapture<Map<String, ? super T[]>>() {}.capture());
1380   }
1381 
1382   private static class From<K> {
1383     class To<V> {
1384       Type type() {
1385         return new TypeToken<To<V>>(getClass()) {}.getType();
1386       }
1387     }
1388   }
1389 
1390   public <T> void testRejectTypeVariable_withOwnerType() {
1391     // Neither has subclass
1392     assertHasTypeVariable(new From<Integer>().new To<String>().type());
1393     assertHasTypeVariable(new From<T>().new To<String>().type());
1394     assertHasTypeVariable(new From<Integer>().new To<T>().type());
1395 
1396     // Owner is subclassed
1397     assertHasTypeVariable(new From<Integer>() {}.new To<String>().type());
1398     assertHasTypeVariable(new From<T>() {}.new To<String>().type());
1399 
1400     // Inner is subclassed
1401     assertNoTypeVariable(new From<Integer>().new To<String>() {}.type());
1402     assertHasTypeVariable(new From<Integer>().new To<T>() {}.type());
1403     assertHasTypeVariable(new From<T>().new To<String>() {}.type());
1404 
1405     // both subclassed
1406     assertHasTypeVariable(new From<T>() {}.new To<String>() {}.type());
1407     assertNoTypeVariable(new From<Integer>() {}.new To<String>() {}.type());
1408     assertHasTypeVariable(new From<Integer>() {}.new To<T>() {}.type());
1409   }
1410 
1411   private static void assertHasTypeVariable(Type type) {
1412     try {
1413       TypeToken.of(type).rejectTypeVariables();
1414       fail("Should contain TypeVariable");
1415     } catch (IllegalArgumentException expected) {}
1416   }
1417 
1418   private static void assertNoTypeVariable(Type type) {
1419     TypeToken.of(type).rejectTypeVariables();
1420   }
1421 
1422   private abstract static class RawTypeConsistencyTester<T extends Enum<T> & CharSequence> {
1423     abstract T returningT();
1424     abstract void acceptT(T t);
1425     abstract <X extends T> X returningX();
1426     abstract <X> void acceptX(X x);
1427     abstract <T2 extends Enum<T2> & CharSequence> T2 returningT2();
1428     abstract <T2 extends CharSequence&Iterable<T2>> void acceptT2(T2 t2);
1429 
1430     static void verifyConsitentRawType() {
1431       for (Method method : RawTypeConsistencyTester.class.getDeclaredMethods()) {
1432         assertEquals(method.getReturnType(), TypeToken.getRawType(method.getGenericReturnType()));
1433         for (int i = 0; i < method.getParameterTypes().length; i++) {
1434           assertEquals(method.getParameterTypes()[i],
1435               TypeToken.getRawType(method.getGenericParameterTypes()[i]));
1436         }
1437       }
1438     }
1439   }
1440 
1441   public void testRawTypes() throws Exception {
1442     RawTypeConsistencyTester.verifyConsitentRawType();
1443     assertEquals(Object.class, TypeToken.getRawType(Types.subtypeOf(Object.class)));
1444     assertEquals(CharSequence.class, TypeToken.getRawType(Types.subtypeOf(CharSequence.class)));
1445     assertEquals(Object.class, TypeToken.getRawType(Types.supertypeOf(CharSequence.class)));
1446   }
1447 
1448   private abstract static class IKnowMyType<T> {
1449     TypeToken<T> type() {
1450       return new TypeToken<T>(getClass()) {};
1451     }
1452   }
1453 
1454   public void testTypeResolution() {
1455     assertEquals(String.class,
1456         new IKnowMyType<String>() {}.type().getType());
1457     assertEquals(new TypeToken<Map<String, Integer>>() {},
1458         new IKnowMyType<Map<String, Integer>>() {}.type());
1459   }
1460 
1461   public <A extends Iterable<? extends String>, B extends A> void testSerializable() {
1462     reserialize(TypeToken.of(String.class));
1463     reserialize(TypeToken.of(String.class).getTypes());
1464     reserialize(TypeToken.of(String.class).getTypes().classes());
1465     reserialize(TypeToken.of(String.class).getTypes().interfaces());
1466     reserialize(TypeToken.of(String.class).getTypes().rawTypes());
1467     reserialize(TypeToken.of(String.class).getTypes().classes().rawTypes());
1468     reserialize(TypeToken.of(String.class).getTypes().interfaces().rawTypes());
1469     reserialize(new TypeToken<int[]>() {});
1470     reserialize(new TypeToken<Map<String, Integer>>() {});
1471     reserialize(new IKnowMyType<Map<? super String, ? extends int[]>>() {}.type());
1472     reserialize(TypeToken.of(new TypeCapture<B>() {}.capture()).getTypes().rawTypes());
1473     try {
1474       SerializableTester.reserialize(TypeToken.of(new TypeCapture<B>() {}.capture()));
1475       fail();
1476     } catch (RuntimeException expected) {}
1477   }
1478 
1479   public <A> void testSerializable_typeVariableNotSupported() {
1480     try {
1481       new ITryToSerializeMyTypeVariable<String>().go();
1482       fail();
1483     } catch (RuntimeException expected) {}
1484   }
1485 
1486   private static class ITryToSerializeMyTypeVariable<T> {
1487     void go() {
1488       SerializableTester.reserialize(TypeToken.of(new TypeCapture<T>() {}.capture()));
1489     }
1490   }
1491 
1492   private static <T> T reserialize(T object) {
1493     T copy = SerializableTester.reserialize(object);
1494     new EqualsTester()
1495         .addEqualityGroup(object, copy)
1496         .testEquals();
1497     return copy;
1498   }
1499 
1500   public void testTypeResolutionAfterReserialized() {
1501     reserialize(new TypeToken<String>() {});
1502     reserialize(new TypeToken<Map<String, Integer>>() {});
1503     TypeToken<Map<String, Integer>> reserialized = reserialize(
1504         new TypeToken<Map<String, Integer>>() {});
1505     assertEquals(reserialized, substitute(reserialized, String.class));
1506   }
1507 
1508   private static <T, X> TypeToken<T> substitute(TypeToken<T> type, Class<X> arg) {
1509     return type.where(new TypeParameter<X>() {}, arg);
1510   }
1511 
1512   private abstract static class ToReproduceGenericSignatureFormatError<V> {
1513     private abstract class BaseOuter {
1514       abstract class BaseInner {}
1515     }
1516     private abstract class SubOuter extends BaseOuter {
1517       private abstract class SubInner extends BaseInner {}
1518     }
1519   }
1520 
1521   // For Guava bug http://code.google.com/p/guava-libraries/issues/detail?id=1025
1522   public void testDespiteGenericSignatureFormatError() {
1523     ImmutableSet.copyOf(
1524         TypeToken.of(ToReproduceGenericSignatureFormatError.SubOuter.SubInner.class)
1525             .getTypes()
1526             .rawTypes());
1527   }
1528 
1529   private abstract static class Entry<K, V> {
1530     TypeToken<K> keyType() {
1531       return new TypeToken<K>(getClass()) {};
1532     }
1533     TypeToken<V> valueType() {
1534       return new TypeToken<V>(getClass()) {};
1535     }
1536   }
1537 
1538   // The A and B type parameters are used inside the test to test type variable
1539   public <A, B> void testEquals() {
1540     new EqualsTester()
1541         .addEqualityGroup(
1542             TypeToken.of(String.class),
1543             TypeToken.of(String.class),
1544             new Entry<String, Integer>() {}.keyType(),
1545             new Entry<Integer, String>() {}.valueType(),
1546             new TypeToken<String>() {},
1547             new TypeToken<String>() {})
1548         .addEqualityGroup(
1549             TypeToken.of(Integer.class),
1550             new TypeToken<Integer>() {},
1551             new Entry<Integer, String>() {}.keyType(),
1552             new Entry<String, Integer>() {}.valueType())
1553         .addEqualityGroup(
1554             new TypeToken<List<String>>() {},
1555             new TypeToken<List<String>>() {})
1556         .addEqualityGroup(
1557             new TypeToken<List<?>>() {},
1558             new TypeToken<List<?>>() {})
1559         .addEqualityGroup(
1560             new TypeToken<Map<A, ?>>() {},
1561             new TypeToken<Map<A, ?>>() {})
1562         .addEqualityGroup(
1563             new TypeToken<Map<B, ?>>() {})
1564         .addEqualityGroup(
1565             TypeToken.of(new TypeCapture<A>() {}.capture()),
1566             TypeToken.of(new TypeCapture<A>() {}.capture()))
1567         .addEqualityGroup(TypeToken.of(new TypeCapture<B>() {}.capture()))
1568         .testEquals();
1569   }
1570 
1571   // T is used inside to test type variable
1572   public <T> void testToString() {
1573     assertEquals(String.class.getName(), new TypeToken<String>() {}.toString());
1574     assertEquals("T", TypeToken.of(new TypeCapture<T>() {}.capture()).toString());
1575     assertEquals("java.lang.String", new Entry<String, Integer>() {}.keyType().toString());
1576   }
1577 
1578   private static <K, V> TypeToken<Map<K, V>> mapOf(Class<K> keyType, Class<V> valueType) {
1579     return new TypeToken<Map<K, V>>() {}
1580         .where(new TypeParameter<K>() {}, keyType)
1581         .where(new TypeParameter<V>() {}, valueType);
1582   }
1583 
1584   private static <T> TypeToken<T[]> arrayOf(Class<T> componentType) {
1585     return new TypeToken<T[]>() {}
1586         .where(new TypeParameter<T>() {}, componentType);
1587   }
1588 
1589   public <T> void testNulls() {
1590     new NullPointerTester()
1591         .testAllPublicStaticMethods(TypeToken.class);
1592     new NullPointerTester()
1593         .setDefault(TypeParameter.class, new TypeParameter<T>() {})
1594         .testAllPublicInstanceMethods(TypeToken.of(String.class));
1595   }
1596 
1597   private static class Assignability<From, To> {
1598 
1599     boolean isAssignable() {
1600       return new TypeToken<To>(getClass()) {}.isAssignableFrom(new TypeToken<From>(getClass()) {});
1601     }
1602 
1603     static <From, To> Assignability<From, To> of() {
1604       return new Assignability<From, To>();
1605     }
1606   }
1607 
1608   private static void assertAssignable(TypeToken<?> from, TypeToken<?> to) {
1609     assertTrue(
1610         from.getType() + " is expected to be assignable to " + to.getType(),
1611         to.isAssignableFrom(from));
1612   }
1613 
1614   private static void assertNotAssignable(TypeToken<?> from, TypeToken<?> to) {
1615     assertFalse(
1616         from.getType() + " shouldn't be assignable to " + to.getType(),
1617         to.isAssignableFrom(from));
1618   }
1619 
1620   private static void assertHasArrayInterfaces(TypeToken<?> arrayType) {
1621     assertEquals(arrayInterfaces(), ImmutableSet.copyOf(arrayType.getGenericInterfaces()));
1622   }
1623 
1624   private static ImmutableSet<TypeToken<?>> arrayInterfaces() {
1625     ImmutableSet.Builder<TypeToken<?>> builder = ImmutableSet.builder();
1626     for (Class<?> interfaceType : Object[].class.getInterfaces()) {
1627       builder.add(TypeToken.of(interfaceType));
1628     }
1629     return builder.build();
1630   }
1631 
1632   private static void assertIsPrimitive(TypeToken<?> type) {
1633     assertTrue(type.isPrimitive());
1634     assertNotWrapper(type);
1635     assertEquals(TypeToken.of(Primitives.wrap((Class<?>) type.getType())), type.wrap());
1636   }
1637 
1638   private static void assertNotPrimitive(TypeToken<?> type) {
1639     assertFalse(type.isPrimitive());
1640     assertSame(type, type.wrap());
1641   }
1642 
1643   private static void assertIsWrapper(TypeToken<?> type) {
1644     assertNotPrimitive(type);
1645     assertEquals(TypeToken.of(Primitives.unwrap((Class<?>) type.getType())), type.unwrap());
1646   }
1647 
1648   private static void assertNotWrapper(TypeToken<?> type) {
1649     assertSame(type, type.unwrap());
1650   }
1651 
1652   private static void assertNotPrimitiveNorWrapper(TypeToken<?> type) {
1653     assertNotPrimitive(type);
1654     assertNotWrapper(type);
1655   }
1656 
1657   private interface BaseInterface {}
1658   private static class Base implements BaseInterface {}
1659   private static class Sub extends Base {}
1660 
1661   private static CollectionSubject<?, Object, ?> makeUnmodifiable(Collection<?> actual) {
1662     return assertThat(Collections.<Object>unmodifiableCollection(actual));
1663   }
1664 }