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 testValueEqualityNotInstanceEquality()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 testVariableTypeTokenNotAllowed()64 public <T> void testVariableTypeTokenNotAllowed() { 65 try { 66 new TypeToken<T>() {}; 67 fail(); 68 } catch (IllegalStateException expected) {} 69 } 70 testRawTypeIsCorrect()71 public void testRawTypeIsCorrect() { 72 TypeToken<List<String>> token = new TypeToken<List<String>>() {}; 73 assertEquals(List.class, token.getRawType()); 74 } 75 testTypeIsCorrect()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) testGetClass()82 public void testGetClass() { 83 TypeToken<List> token = TypeToken.of(List.class); 84 assertEquals(new TypeToken<List>() {}, token); 85 } 86 testGetType()87 public void testGetType() { 88 TypeToken<?> t = TypeToken.of(StringList.class.getGenericInterfaces()[0]); 89 assertEquals(new TypeToken<List<String>>() {}, t); 90 } 91 testNonStaticLocalClass()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 testStaticLocalClass()100 public void testStaticLocalClass() { 101 doTestStaticLocalClass(); 102 } 103 doTestStaticLocalClass()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 testGenericArrayType()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 testMultiDimensionalGenericArrayType()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 testGenericVariableTypeArrays()124 public <T> void testGenericVariableTypeArrays() throws Exception { 125 assertEquals("T[]", new TypeToken<T[]>() {}.toString()); 126 } 127 testResolveType()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>> testResolveType_fromTypeVariable()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>> testResolveType_fromTypeVariable_onlyDirectBoundsAreUsed()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 testResolveType_fromWildcard()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 testGetTypes_noSuperclass()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 testGetTypes_fromInterface()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 testGetTypes_fromPrimitive()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 testGetTypes_withInterfacesAndSuperclasses()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 testGetTypes_rawTypes_withInterfacesAndSuperclasses()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> testGetTypes_ignoresTypeVariablesByDefault()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> testGetTypes_rawTypes_ignoresTypeVariablesByDefault()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>> testGetTypes_manyBounds()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 assertSubtypeFirst(TypeToken<?>.TypeSet types)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 assertSubtypeTokenBeforeSupertypeToken( Iterable<? extends TypeToken<?>> types)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 assertSubtypeBeforeSupertype(Iterable<? extends Class<?>> types)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 testAssertSubtypeTokenBeforeSupertypeToken_empty()321 public void testAssertSubtypeTokenBeforeSupertypeToken_empty() { 322 assertSubtypeTokenBeforeSupertypeToken(ImmutableList.<TypeToken<?>>of()); 323 } 324 testAssertSubtypeTokenBeforeSupertypeToken_oneType()325 public void testAssertSubtypeTokenBeforeSupertypeToken_oneType() { 326 assertSubtypeTokenBeforeSupertypeToken(ImmutableList.of(TypeToken.of(String.class))); 327 } 328 testAssertSubtypeTokenBeforeSupertypeToken_subtypeFirst()329 public void testAssertSubtypeTokenBeforeSupertypeToken_subtypeFirst() { 330 assertSubtypeTokenBeforeSupertypeToken( 331 ImmutableList.of(TypeToken.of(String.class), TypeToken.of(CharSequence.class))); 332 } 333 testAssertSubtypeTokenBeforeSupertypeToken_supertypeFirst()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 testAssertSubtypeTokenBeforeSupertypeToken_duplicate()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 testAssertSubtypeBeforeSupertype_empty()354 public void testAssertSubtypeBeforeSupertype_empty() { 355 assertSubtypeBeforeSupertype(ImmutableList.<Class<?>>of()); 356 } 357 testAssertSubtypeBeforeSupertype_oneType()358 public void testAssertSubtypeBeforeSupertype_oneType() { 359 assertSubtypeBeforeSupertype(ImmutableList.of(String.class)); 360 } 361 testAssertSubtypeBeforeSupertype_subtypeFirst()362 public void testAssertSubtypeBeforeSupertype_subtypeFirst() { 363 assertSubtypeBeforeSupertype( 364 ImmutableList.of(String.class, CharSequence.class)); 365 } 366 testAssertSubtypeBeforeSupertype_supertypeFirst()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 testAssertSubtypeBeforeSupertype_duplicate()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 testGetGenericSuperclass_noSuperclass()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 testGetGenericSuperclass_withSuperclass()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 testGetGenericSuperclass_typeVariable_unbounded()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> testGetGenericSuperclass_typeVariable_boundIsClass()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> testGetGenericSuperclass_typeVariable_boundIsFBoundedClass()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> testGetGenericSuperclass_typeVariable_boundIsInterface()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> testGetGenericSuperclass_typeVariable_boundIsTypeVariableAndClass()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> testGetGenericSuperclass_typeVariable_boundIsTypeVariableAndInterface()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 testGetGenericSuperclass_wildcard_lowerBounded()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 testGetGenericSuperclass_wildcard_boundIsClass()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 testGetGenericSuperclass_wildcard_boundIsInterface()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 testGetGenericInterfaces_typeVariable_unbounded()467 public <T> void testGetGenericInterfaces_typeVariable_unbounded() { 468 assertThat(TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericInterfaces()).isEmpty(); 469 assertHasArrayInterfaces(new TypeToken<T[]>() {}); 470 } 471 testGetGenericInterfaces_typeVariable_boundIsClass()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>> testGetGenericInterfaces_typeVariable_boundsAreClassWithInterface()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>> testGetGenericInterfaces_typeVariable_boundsAreInterfaces()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>> testGetGenericInterfaces_typeVariable_boundsAreFBoundedInterfaces()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>> testGetGenericInterfaces_typeVariable_boundsAreClassWithFBoundedInterface()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> testGetGenericInterfaces_typeVariable_boundIsTypeVariableAndClass()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> testGetGenericInterfaces_typeVariable_boundIsTypeVariableAndInterface()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 testGetGenericInterfaces_wildcard_lowerBounded()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 testGetGenericInterfaces_wildcard_boundIsClass()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 testGetGenericInterfaces_wildcard_boundIsInterface()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 testGetGenericInterfaces_noInterface()535 public void testGetGenericInterfaces_noInterface() { 536 assertThat(new TypeToken<NoInterface>() {}.getGenericInterfaces()).isEmpty(); 537 assertHasArrayInterfaces(new TypeToken<NoInterface[]>() {}); 538 } 539 testGetGenericInterfaces_withInterfaces()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 testAssignableClassToClass()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 testAssignableParameterizedTypeToObject()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 testAssignableGenericArrayToGenericArray()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 testAssignableWildcardBoundedByArrayToArrayClass()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 testAssignableArrayClassToBoundedWildcard()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 testAssignableWildcardBoundedByIntArrayToArrayClass()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 testAssignableWildcardToWildcard()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 testAssignableGenericArrayToArrayClass()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 testAssignableParameterizedTypeToClass()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 testAssignableArrayToClass()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 testAssignableTokenToClass()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 testAssignableClassToType()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 testAssignableClassToArrayType()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 testAssignableParameterizedTypeToType()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 testGenericArrayTypeToArrayType()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 testAssignableTokenToType()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 testAssignableWithWildcards()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> testIsAssignableFrom_typeVariable()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> testIsAssignableFrom_equalWildcardTypes()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 testIsAssignableFrom_wildcard_noBound()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> testIsAssignableFrom_wildcardType_upperBoundMatch()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> testIsAssignableFrom_wildcardType_lowerBoundMatch()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>> testIsAssignableFrom_recursiveTypeVariableBounds()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 testIsAssignableFrom_resolved()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> assignabilityTestWithTypeVariables()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 testIsArray_arrayClasses()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 testIsArray_genericArrayClasses()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 testIsArray_wildcardType()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 testPrimitiveWrappingAndUnwrapping()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 testGetComponentType_arrayClasses()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 testGetComponentType_genericArrayClasses()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 testGetComponentType_wildcardType()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 testImplicitUpperBoundForWildcards()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 testMultiBound()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 testToGenericType()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 testGetSupertype_withTypeVariable()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 testGetSupertype_withoutTypeVariable()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 testGetSupertype_chained()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 testGetSupertype_withArray()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 testGetSupertype_fromWildcard()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 testGetSupertype_fromTypeVariable()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 testGetSupertype_fromRawClass()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 testGetSupertype_notSupertype()1054 public void testGetSupertype_notSupertype() { 1055 try { 1056 new TypeToken<List<String>>() {}.getSupertype((Class) String.class); 1057 fail(); 1058 } catch (IllegalArgumentException expected) {} 1059 } 1060 testGetSupertype_fromArray()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 testGetSupertype_fullyGenericType()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 testGetSupertype_fullySpecializedType()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 testGetSupertype_partiallySpecializedType()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 testGetSubtype_withTypeVariable()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 testGetSubtype_withoutTypeVariable()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 testGetSubtype_withArray()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 testGetSubtype_fromWildcard()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 testGetSubtype_fromWildcard_lowerBoundNotSupertype()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 testGetSubtype_fromWildcard_upperBounded()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 testGetSubtype_fromTypeVariable()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 testGetSubtype_fromRawClass()1154 public void testGetSubtype_fromRawClass() { 1155 assertEquals(List.class, new TypeToken<Iterable>() {}.getSubtype(List.class).getType()); 1156 } 1157 testGetSubtype_fromArray()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() testWhere_circleRejected()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 testWhere()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 setList(List<T> list)1187 void setList(List<T> list) { 1188 this.list = list; 1189 } 1190 } 1191 testWildcardCaptured_methodParameter_upperBound()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 testWildcardCaptured_field_upperBound()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 testArrayClassPreserved()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 testMethod_getOwnerType()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 testMethod_notDeclaredByType()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 testMethod_declaredBySuperclass()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 testMethod_returnType_resolvedAgainstTypeBound()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 testMethod_parameterTypes()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 testMethod_equals()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> { lose()1273 void lose() throws E; 1274 } 1275 testMethod_exceptionTypes()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 testConstructor_getOwnerType()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 testConstructor_notDeclaredByType()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 testConstructor_declaredBySuperclass()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 testConstructor_equals()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") Container(T data)1323 public Container(T data) {} 1324 } 1325 testConstructor_parameterTypes()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") CannotConstruct()1338 public CannotConstruct() throws E {} 1339 } 1340 testConstructor_exceptionTypes()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 testRejectTypeVariable_class()1349 public void testRejectTypeVariable_class() { 1350 assertNoTypeVariable(String.class); 1351 assertNoTypeVariable(String[].class); 1352 assertNoTypeVariable(int[].class); 1353 } 1354 testRejectTypeVariable_parameterizedType()1355 public void testRejectTypeVariable_parameterizedType() { 1356 assertNoTypeVariable(new TypeCapture<Iterable<String>>() {}.capture()); 1357 } 1358 testRejectTypeVariable_wildcardType()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 testRejectTypeVariable_genericArrayType()1366 public void testRejectTypeVariable_genericArrayType() { 1367 assertNoTypeVariable( 1368 new TypeCapture<Iterable<? extends String>[]>() {}.capture()); 1369 } 1370 testRejectTypeVariable_withTypeVariable()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> { type()1384 Type type() { 1385 return new TypeToken<To<V>>(getClass()) {}.getType(); 1386 } 1387 } 1388 } 1389 testRejectTypeVariable_withOwnerType()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 assertHasTypeVariable(Type type)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 assertNoTypeVariable(Type type)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> { returningT()1423 abstract T returningT(); acceptT(T t)1424 abstract void acceptT(T t); returningX()1425 abstract <X extends T> X returningX(); acceptX(X x)1426 abstract <X> void acceptX(X x); returningT2()1427 abstract <T2 extends Enum<T2> & CharSequence> T2 returningT2(); acceptT2(T2 t2)1428 abstract <T2 extends CharSequence&Iterable<T2>> void acceptT2(T2 t2); 1429 verifyConsitentRawType()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 testRawTypes()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> { type()1449 TypeToken<T> type() { 1450 return new TypeToken<T>(getClass()) {}; 1451 } 1452 } 1453 testTypeResolution()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 testSerializable()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 testSerializable_typeVariableNotSupported()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> { go()1487 void go() { 1488 SerializableTester.reserialize(TypeToken.of(new TypeCapture<T>() {}.capture())); 1489 } 1490 } 1491 reserialize(T object)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 testTypeResolutionAfterReserialized()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 substitute(TypeToken<T> type, Class<X> arg)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 testDespiteGenericSignatureFormatError()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> { keyType()1530 TypeToken<K> keyType() { 1531 return new TypeToken<K>(getClass()) {}; 1532 } valueType()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 testEquals()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 testToString()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 mapOf(Class<K> keyType, Class<V> valueType)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 arrayOf(Class<T> componentType)1584 private static <T> TypeToken<T[]> arrayOf(Class<T> componentType) { 1585 return new TypeToken<T[]>() {} 1586 .where(new TypeParameter<T>() {}, componentType); 1587 } 1588 testNulls()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 isAssignable()1599 boolean isAssignable() { 1600 return new TypeToken<To>(getClass()) {}.isAssignableFrom(new TypeToken<From>(getClass()) {}); 1601 } 1602 of()1603 static <From, To> Assignability<From, To> of() { 1604 return new Assignability<From, To>(); 1605 } 1606 } 1607 assertAssignable(TypeToken<?> from, TypeToken<?> to)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 assertNotAssignable(TypeToken<?> from, TypeToken<?> to)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 assertHasArrayInterfaces(TypeToken<?> arrayType)1620 private static void assertHasArrayInterfaces(TypeToken<?> arrayType) { 1621 assertEquals(arrayInterfaces(), ImmutableSet.copyOf(arrayType.getGenericInterfaces())); 1622 } 1623 arrayInterfaces()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 assertIsPrimitive(TypeToken<?> type)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 assertNotPrimitive(TypeToken<?> type)1638 private static void assertNotPrimitive(TypeToken<?> type) { 1639 assertFalse(type.isPrimitive()); 1640 assertSame(type, type.wrap()); 1641 } 1642 assertIsWrapper(TypeToken<?> type)1643 private static void assertIsWrapper(TypeToken<?> type) { 1644 assertNotPrimitive(type); 1645 assertEquals(TypeToken.of(Primitives.unwrap((Class<?>) type.getType())), type.unwrap()); 1646 } 1647 assertNotWrapper(TypeToken<?> type)1648 private static void assertNotWrapper(TypeToken<?> type) { 1649 assertSame(type, type.unwrap()); 1650 } 1651 assertNotPrimitiveNorWrapper(TypeToken<?> type)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 makeUnmodifiable(Collection<?> actual)1661 private static CollectionSubject<?, Object, ?> makeUnmodifiable(Collection<?> actual) { 1662 return assertThat(Collections.<Object>unmodifiableCollection(actual)); 1663 } 1664 } 1665