141bc85288590d19c50f299372f942aa27677d77ccrazyboblee/** 241bc85288590d19c50f299372f942aa27677d77ccrazyboblee * Copyright (C) 2006 Google Inc. 341bc85288590d19c50f299372f942aa27677d77ccrazyboblee * 441bc85288590d19c50f299372f942aa27677d77ccrazyboblee * Licensed under the Apache License, Version 2.0 (the "License"); 541bc85288590d19c50f299372f942aa27677d77ccrazyboblee * you may not use this file except in compliance with the License. 641bc85288590d19c50f299372f942aa27677d77ccrazyboblee * You may obtain a copy of the License at 741bc85288590d19c50f299372f942aa27677d77ccrazyboblee * 841bc85288590d19c50f299372f942aa27677d77ccrazyboblee * http://www.apache.org/licenses/LICENSE-2.0 941bc85288590d19c50f299372f942aa27677d77ccrazyboblee * 1041bc85288590d19c50f299372f942aa27677d77ccrazyboblee * Unless required by applicable law or agreed to in writing, software 1141bc85288590d19c50f299372f942aa27677d77ccrazyboblee * distributed under the License is distributed on an "AS IS" BASIS, 1241bc85288590d19c50f299372f942aa27677d77ccrazyboblee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1341bc85288590d19c50f299372f942aa27677d77ccrazyboblee * See the License for the specific language governing permissions and 1441bc85288590d19c50f299372f942aa27677d77ccrazyboblee * limitations under the License. 1541bc85288590d19c50f299372f942aa27677d77ccrazyboblee */ 1641bc85288590d19c50f299372f942aa27677d77ccrazyboblee 1741bc85288590d19c50f299372f942aa27677d77ccrazybobleepackage com.google.inject; 1841bc85288590d19c50f299372f942aa27677d77ccrazyboblee 19eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkitimport static com.google.inject.Asserts.assertEqualsBothWays; 208c4c71cf6b0d4fcaee49ac6f95acca6ffa78536elimpbizkitimport static com.google.inject.Asserts.assertNotSerializable; 21b7a02b02d81c830d148355c90bc309bcd66fb592sberlin 22d9c913acca55023ef5d76a32c3d4a51ee6b420cbsberlinimport com.google.common.collect.ImmutableList; 233beaaaff52598e849659281fed35dc29a221fac4limpbizkitimport com.google.inject.util.Types; 24b7a02b02d81c830d148355c90bc309bcd66fb592sberlin 25b7a02b02d81c830d148355c90bc309bcd66fb592sberlinimport junit.framework.TestCase; 26b7a02b02d81c830d148355c90bc309bcd66fb592sberlin 27eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkitimport java.io.IOException; 284272aef70de48e239e9f70ab10b0becefd3030cblimpbizkitimport java.lang.reflect.Type; 294272aef70de48e239e9f70ab10b0becefd3030cblimpbizkitimport java.lang.reflect.TypeVariable; 305019270849439d3aa58bc086a4514d7471716a35limpbizkitimport java.util.List; 315019270849439d3aa58bc086a4514d7471716a35limpbizkit 3241bc85288590d19c50f299372f942aa27677d77ccrazyboblee/** 3341bc85288590d19c50f299372f942aa27677d77ccrazyboblee * @author crazybob@google.com (Bob Lee) 3441bc85288590d19c50f299372f942aa27677d77ccrazyboblee */ 350baa9fcb9ddf853e9bbf8b71c5f1167051c366e0crazybobleepublic class TypeLiteralTest extends TestCase { 3641bc85288590d19c50f299372f942aa27677d77ccrazyboblee 37eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit public void testWithParameterizedType() { 381b54d6a560517b057c66c29f3700d8b10bc7bfadcrazyboblee TypeLiteral<List<String>> a = new TypeLiteral<List<String>>() {}; 391b54d6a560517b057c66c29f3700d8b10bc7bfadcrazyboblee TypeLiteral<List<String>> b = new TypeLiteral<List<String>>( 403beaaaff52598e849659281fed35dc29a221fac4limpbizkit Types.listOf(String.class)) {}; 41eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit assertEqualsBothWays(a, b); 421b54d6a560517b057c66c29f3700d8b10bc7bfadcrazyboblee } 431b54d6a560517b057c66c29f3700d8b10bc7bfadcrazyboblee 4441bc85288590d19c50f299372f942aa27677d77ccrazyboblee public void testEquality() { 450baa9fcb9ddf853e9bbf8b71c5f1167051c366e0crazyboblee TypeLiteral<List<String>> t1 = new TypeLiteral<List<String>>() {}; 460baa9fcb9ddf853e9bbf8b71c5f1167051c366e0crazyboblee TypeLiteral<List<String>> t2 = new TypeLiteral<List<String>>() {}; 470baa9fcb9ddf853e9bbf8b71c5f1167051c366e0crazyboblee TypeLiteral<List<Integer>> t3 = new TypeLiteral<List<Integer>>() {}; 480baa9fcb9ddf853e9bbf8b71c5f1167051c366e0crazyboblee TypeLiteral<String> t4 = new TypeLiteral<String>() {}; 4941bc85288590d19c50f299372f942aa27677d77ccrazyboblee 50eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit assertEqualsBothWays(t1, t2); 5141bc85288590d19c50f299372f942aa27677d77ccrazyboblee 5241bc85288590d19c50f299372f942aa27677d77ccrazyboblee assertFalse(t2.equals(t3)); 5341bc85288590d19c50f299372f942aa27677d77ccrazyboblee assertFalse(t3.equals(t2)); 5441bc85288590d19c50f299372f942aa27677d77ccrazyboblee 5541bc85288590d19c50f299372f942aa27677d77ccrazyboblee assertFalse(t2.equals(t4)); 5641bc85288590d19c50f299372f942aa27677d77ccrazyboblee assertFalse(t4.equals(t2)); 5741bc85288590d19c50f299372f942aa27677d77ccrazyboblee 580baa9fcb9ddf853e9bbf8b71c5f1167051c366e0crazyboblee TypeLiteral<String> t5 = TypeLiteral.get(String.class); 59eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit assertEqualsBothWays(t4, t5); 6041bc85288590d19c50f299372f942aa27677d77ccrazyboblee } 6141bc85288590d19c50f299372f942aa27677d77ccrazyboblee 62cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit public List<? extends CharSequence> wildcardExtends; 63cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit 64cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit public void testWithWildcardType() throws NoSuchFieldException, IOException { 65cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit TypeLiteral<?> a = TypeLiteral.get(getClass().getField("wildcardExtends").getGenericType()); 66cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit TypeLiteral<?> b = TypeLiteral.get(Types.listOf(Types.subtypeOf(CharSequence.class))); 675d5941f9c5a882ac98a3312bd411bde00a1f425fsberlin TypeLiteral<?> c = new TypeLiteral<List<? extends CharSequence>>() {}; 68cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit assertEqualsBothWays(a, b); 695d5941f9c5a882ac98a3312bd411bde00a1f425fsberlin assertEqualsBothWays(b, c); 70cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit assertEquals("java.util.List<? extends java.lang.CharSequence>", a.toString()); 71cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit assertEquals("java.util.List<? extends java.lang.CharSequence>", b.toString()); 725d5941f9c5a882ac98a3312bd411bde00a1f425fsberlin assertEquals("java.util.List<? extends java.lang.CharSequence>", c.toString()); 738c4c71cf6b0d4fcaee49ac6f95acca6ffa78536elimpbizkit assertNotSerializable(a); 748c4c71cf6b0d4fcaee49ac6f95acca6ffa78536elimpbizkit assertNotSerializable(b); 755d5941f9c5a882ac98a3312bd411bde00a1f425fsberlin assertNotSerializable(c); 76cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit } 77cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit 7841bc85288590d19c50f299372f942aa27677d77ccrazyboblee public void testMissingTypeParameter() { 7941bc85288590d19c50f299372f942aa27677d77ccrazyboblee try { 800baa9fcb9ddf853e9bbf8b71c5f1167051c366e0crazyboblee new TypeLiteral() {}; 8141bc85288590d19c50f299372f942aa27677d77ccrazyboblee fail(); 8241bc85288590d19c50f299372f942aa27677d77ccrazyboblee } catch (RuntimeException e) { /* expected */ } 8341bc85288590d19c50f299372f942aa27677d77ccrazyboblee } 84be2a67fab538548f580477d8a6aca41297fe083ccrazyboblee 85be2a67fab538548f580477d8a6aca41297fe083ccrazyboblee public void testTypesInvolvingArraysForEquality() { 86be2a67fab538548f580477d8a6aca41297fe083ccrazyboblee TypeLiteral<String[]> stringArray = new TypeLiteral<String[]>() {}; 87be2a67fab538548f580477d8a6aca41297fe083ccrazyboblee assertEquals(stringArray, new TypeLiteral<String[]>() {}); 88be2a67fab538548f580477d8a6aca41297fe083ccrazyboblee 89be2a67fab538548f580477d8a6aca41297fe083ccrazyboblee TypeLiteral<List<String[]>> listOfStringArray 90be2a67fab538548f580477d8a6aca41297fe083ccrazyboblee = new TypeLiteral<List<String[]>>() {}; 91be2a67fab538548f580477d8a6aca41297fe083ccrazyboblee assertEquals(listOfStringArray, new TypeLiteral<List<String[]>>() {}); 92be2a67fab538548f580477d8a6aca41297fe083ccrazyboblee } 93eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit 94eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit public void testEqualityOfGenericArrayAndClassArray() { 95eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit TypeLiteral<String[]> arrayAsClass = TypeLiteral.get(String[].class); 96eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit TypeLiteral<String[]> arrayAsType = new TypeLiteral<String[]>() {}; 97f530b2542e7a93416b392f598c90b018d0f38991limpbizkit assertEquals(arrayAsClass, arrayAsType); 98eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit } 99eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit 1008ba97884d8759890f6b32b65325c1c189061c09elimpbizkit public void testEqualityOfMultidimensionalGenericArrayAndClassArray() { 1018ba97884d8759890f6b32b65325c1c189061c09elimpbizkit TypeLiteral<String[][][]> arrayAsClass = TypeLiteral.get(String[][][].class); 1028ba97884d8759890f6b32b65325c1c189061c09elimpbizkit TypeLiteral<String[][][]> arrayAsType = new TypeLiteral<String[][][]>() {}; 1038ba97884d8759890f6b32b65325c1c189061c09elimpbizkit assertEquals(arrayAsClass, arrayAsType); 1048ba97884d8759890f6b32b65325c1c189061c09elimpbizkit } 1058ba97884d8759890f6b32b65325c1c189061c09elimpbizkit 106cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit public void testTypeLiteralsMustHaveRawTypes() { 107cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit try { 108cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit TypeLiteral.get(Types.subtypeOf(Runnable.class)); 109cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit fail(); 110cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit } catch (IllegalArgumentException expected) { 111cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit Asserts.assertContains(expected.getMessage(), "Expected a Class, ParameterizedType, or " 112cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit + "GenericArrayType, but <? extends java.lang.Runnable> is of type " 113cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit + "com.google.inject.internal.MoreTypes$WildcardTypeImpl"); 114cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit } 115cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit } 116cb32cbcd87c8b511afd532fc626110ee9362fb03limpbizkit 117820d486060f4abac469437e3c4943e520036c3b3limpbizkit /** 118820d486060f4abac469437e3c4943e520036c3b3limpbizkit * Unlike Key, TypeLiteral retains full type information and differentiates 119820d486060f4abac469437e3c4943e520036c3b3limpbizkit * between {@code int.class} and {@code Integer.class}. 120820d486060f4abac469437e3c4943e520036c3b3limpbizkit */ 121820d486060f4abac469437e3c4943e520036c3b3limpbizkit public void testDifferentiationBetweenWrappersAndPrimitives() { 122820d486060f4abac469437e3c4943e520036c3b3limpbizkit Class[] primitives = new Class[] { 123820d486060f4abac469437e3c4943e520036c3b3limpbizkit boolean.class, byte.class, short.class, int.class, long.class, 124820d486060f4abac469437e3c4943e520036c3b3limpbizkit float.class, double.class, char.class, void.class 125820d486060f4abac469437e3c4943e520036c3b3limpbizkit }; 126820d486060f4abac469437e3c4943e520036c3b3limpbizkit Class[] wrappers = new Class[] { 127820d486060f4abac469437e3c4943e520036c3b3limpbizkit Boolean.class, Byte.class, Short.class, Integer.class, Long.class, 128820d486060f4abac469437e3c4943e520036c3b3limpbizkit Float.class, Double.class, Character.class, Void.class 129820d486060f4abac469437e3c4943e520036c3b3limpbizkit }; 130820d486060f4abac469437e3c4943e520036c3b3limpbizkit 131820d486060f4abac469437e3c4943e520036c3b3limpbizkit for (int t = 0; t < primitives.length; t++) { 132820d486060f4abac469437e3c4943e520036c3b3limpbizkit @SuppressWarnings("unchecked") 133820d486060f4abac469437e3c4943e520036c3b3limpbizkit TypeLiteral primitiveTl = TypeLiteral.get(primitives[t]); 134820d486060f4abac469437e3c4943e520036c3b3limpbizkit @SuppressWarnings("unchecked") 135820d486060f4abac469437e3c4943e520036c3b3limpbizkit TypeLiteral wrapperTl = TypeLiteral.get(wrappers[t]); 136820d486060f4abac469437e3c4943e520036c3b3limpbizkit 137820d486060f4abac469437e3c4943e520036c3b3limpbizkit assertFalse(primitiveTl.equals(wrapperTl)); 138820d486060f4abac469437e3c4943e520036c3b3limpbizkit assertEquals(primitives[t], primitiveTl.getType()); 139820d486060f4abac469437e3c4943e520036c3b3limpbizkit assertEquals(wrappers[t], wrapperTl.getType()); 140820d486060f4abac469437e3c4943e520036c3b3limpbizkit assertEquals(primitives[t], primitiveTl.getRawType()); 141820d486060f4abac469437e3c4943e520036c3b3limpbizkit assertEquals(wrappers[t], wrapperTl.getRawType()); 142820d486060f4abac469437e3c4943e520036c3b3limpbizkit } 143820d486060f4abac469437e3c4943e520036c3b3limpbizkit } 144820d486060f4abac469437e3c4943e520036c3b3limpbizkit 145eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit public void testSerialization() throws IOException { 1468c4c71cf6b0d4fcaee49ac6f95acca6ffa78536elimpbizkit assertNotSerializable(new TypeLiteral<List<String>>() {}); 147eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit } 1484272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit 1494272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit public void testTypeVariableWithNoBound() { 1504272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit TypeVariable<Class<HasTypeParameters>>[] typeVariables 1514272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit = HasTypeParameters.class.getTypeParameters(); 1524272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit 1534272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit TypeLiteral<?> aTl = TypeLiteral.get(typeVariables[0]); 1544272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit assertEquals(Object.class, aTl.getRawType()); 1554272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit assertEquals("A", aTl.toString()); 1564272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit TypeVariable<?> aTv = (TypeVariable) aTl.getType(); 1574272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit assertEquals(HasTypeParameters.class, aTv.getGenericDeclaration()); 1584272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit assertEquals("A", aTv.getName()); 159de4cc320c98b800f81703b8a186e08c478fab74cguice.mirrorbot@gmail.com assertEquals(ImmutableList.<Type>of(Object.class), ImmutableList.copyOf(aTv.getBounds())); 1604272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit assertEquals("A", aTv.toString()); 1614272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit assertEqualsBothWays(aTl, TypeLiteral.get(HasTypeParameters.class.getTypeParameters()[0])); 1624272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit } 1634272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit 1644272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit public void testTypeVariablesWithSingleBound() { 1654272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit TypeVariable<Class<HasTypeParameters>>[] typeVariables 1664272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit = HasTypeParameters.class.getTypeParameters(); 1674272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit 1684272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit TypeLiteral<?> cTl = TypeLiteral.get(typeVariables[2]); 1694272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit assertEquals(Object.class, cTl.getRawType()); 1704272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit assertEquals("C", cTl.toString()); 1714272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit TypeVariable<?> cTv = (TypeVariable) cTl.getType(); 1724272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit assertEquals(HasTypeParameters.class, cTv.getGenericDeclaration()); 1734272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit assertEquals("C", cTv.getName()); 174de4cc320c98b800f81703b8a186e08c478fab74cguice.mirrorbot@gmail.com assertEquals(ImmutableList.<Type>of(Runnable.class), ImmutableList.copyOf(cTv.getBounds())); 1754272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit assertEquals("C", cTv.toString()); 1764272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit assertEqualsBothWays(cTl, TypeLiteral.get(HasTypeParameters.class.getTypeParameters()[2])); 1774272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit } 1784272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit 1794272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit public void testTypeVariableWithMultipleBounds() { 1804272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit TypeVariable<Class<HasTypeParameters>>[] typeVariables 1814272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit = HasTypeParameters.class.getTypeParameters(); 1824272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit 1834272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit TypeLiteral<?> bTl = TypeLiteral.get(typeVariables[1]); 1844272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit assertEquals(Object.class, bTl.getRawType()); 1854272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit assertEquals("B", bTl.toString()); 1864272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit TypeVariable<?> bTv = (TypeVariable) bTl.getType(); 1874272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit assertEquals(HasTypeParameters.class, bTv.getGenericDeclaration()); 1884272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit assertEquals("B", bTv.getName()); 1894272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit assertEquals(ImmutableList.<Type>of(Types.listOf(typeVariables[0]), Runnable.class), 190de4cc320c98b800f81703b8a186e08c478fab74cguice.mirrorbot@gmail.com ImmutableList.copyOf(bTv.getBounds())); 1914272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit assertEquals("B", bTv.toString()); 1924272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit assertEqualsBothWays(bTl, TypeLiteral.get(HasTypeParameters.class.getTypeParameters()[1])); 1934272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit } 1944272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit 1954272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit class HasTypeParameters<A, B extends List<A> & Runnable, C extends Runnable> { 1964272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit A a; B b; C c; 1974272aef70de48e239e9f70ab10b0becefd3030cblimpbizkit } 19841bc85288590d19c50f299372f942aa27677d77ccrazyboblee} 199