Home | History | Annotate | Download | only in reflect
      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 }
   1665