• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 package org.apache.commons.lang3.reflect;
18 
19 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
20 import static org.junit.jupiter.api.Assertions.assertEquals;
21 import static org.junit.jupiter.api.Assertions.assertFalse;
22 import static org.junit.jupiter.api.Assertions.assertNull;
23 import static org.junit.jupiter.api.Assertions.assertThrows;
24 import static org.junit.jupiter.api.Assertions.assertTrue;
25 
26 import java.awt.Insets;
27 import java.io.Serializable;
28 import java.lang.reflect.Constructor;
29 import java.lang.reflect.Field;
30 import java.lang.reflect.GenericArrayType;
31 import java.lang.reflect.Method;
32 import java.lang.reflect.ParameterizedType;
33 import java.lang.reflect.Type;
34 import java.lang.reflect.TypeVariable;
35 import java.lang.reflect.WildcardType;
36 import java.net.URI;
37 import java.util.ArrayList;
38 import java.util.Collection;
39 import java.util.Collections;
40 import java.util.HashMap;
41 import java.util.List;
42 import java.util.Map;
43 import java.util.Properties;
44 import java.util.TreeSet;
45 
46 import org.apache.commons.lang3.AbstractLangTest;
47 import org.apache.commons.lang3.reflect.testbed.Foo;
48 import org.apache.commons.lang3.reflect.testbed.GenericParent;
49 import org.apache.commons.lang3.reflect.testbed.GenericTypeHolder;
50 import org.apache.commons.lang3.reflect.testbed.StringParameterizedChild;
51 import org.junit.jupiter.api.Disabled;
52 import org.junit.jupiter.api.Test;
53 
54 class AAAClass extends AAClass<String> {
55     public class BBBClass extends BBClass<String> {
56         // empty
57     }
58 }
59 
60 @SuppressWarnings("unused") // Unused type parameter for test
61 class AAClass<T> {
62 
63     public class BBClass<S> {
64         // empty
65     }
66 }
67 
68 @SuppressWarnings("rawtypes")
69 //raw types, where used, are used purposely
70 class AClass extends AAClass<String>.BBClass<Number> {
71 
72     @SuppressWarnings("unused") // Unused type parameter for test
73     public interface AInterface<T> {
74         // empty
75     }
76 
77     @SuppressWarnings("unused") // Unused type parameter for test
78     public class BClass<T> {
79         // empty
80     }
81 
82     @SuppressWarnings("unused") // Unused type parameter for test
83     public class CClass<T> extends BClass {
84         // empty
85     }
86 
87     @SuppressWarnings("unused") // Unused type parameter for test
88     public class DClass<T> extends CClass<T> {
89         // empty
90     }
91 
92     @SuppressWarnings("unused") // Unused type parameter for test
93     public class EClass<T> extends DClass {
94         // empty
95     }
96 
97     public class FClass extends EClass<String> {
98         // empty
99     }
100 
101     public class GClass<T extends BClass<? extends T> & AInterface<AInterface<? super T>>> {
102         // empty
103     }
104 
105     public BClass<Number> bClass;
106 
107     public CClass<? extends String> cClass;
108 
109     public DClass<String> dClass;
110 
111     public EClass<String> eClass;
112 
113     public FClass fClass;
114 
115     public GClass gClass;
116 
AClass(final AAClass<String> enclosingInstance)117     AClass(final AAClass<String> enclosingInstance) {
118         enclosingInstance.super();
119     }
120 }
121 @SuppressWarnings("rawtypes")
122 abstract class Test1<G> {
m0()123     public abstract Object m0();
m1()124     public abstract String[] m1();
m2()125     public abstract <E> E[] m2();
m3()126     public abstract <E> List<? extends E> m3();
m4()127     public abstract <E extends Enum<E>> List<? extends Enum<E>> m4();
m5()128     public abstract List<? extends Enum<?>> m5();
m6()129     public abstract List<? super Enum<?>> m6();
m7()130     public abstract List<?> m7();
m8()131     public abstract Map<? extends Enum<?>, ? super Enum<?>> m8();
m9()132     public abstract <K, V> Map<? extends K, ? super V[]> m9();
m10()133     public abstract <K, V> Map<? extends K, V[]> m10();
m11()134     public abstract <K, V> Map<? extends K, List<V[]>> m11();
m12()135     public abstract List m12();
m13()136     public abstract Map m13();
m14()137     public abstract Properties m14();
m15()138     public abstract G m15();
m16()139     public abstract List<G> m16();
m17()140     public abstract Enum m17();
141 }
142 
143 /**
144  * Test TypeUtils
145  */
146 @SuppressWarnings({ "unchecked", "unused", "rawtypes" })
147 //raw types, where used, are used purposely
148 public class TypeUtilsTest<B> extends AbstractLangTest {
149 
150     public interface And<K, V> extends This<Number, Number> {
151     }
152 
153     public static class ClassWithSuperClassWithGenericType extends ArrayList<Object> {
154         private static final long serialVersionUID = 1L;
155 
methodWithGenericReturnType()156         public static <U> Iterable<U> methodWithGenericReturnType() {
157             return null;
158         }
159     }
160 
161     public class Other<T> implements This<String, T> {
162     }
163 
164     public class Tester implements This<String, B> {
165     }
166 
167     public class That<K, V> implements This<K, V> {
168     }
169 
170     public class The<K, V> extends That<Number, Number> implements And<String, String> {
171     }
172 
173     public class Thing<Q> extends Other<B> {
174     }
175 
176     public interface This<K, V> {
177     }
178 
179     public static Comparable<String> stringComparable;
180 
181     public static Comparable<URI> uriComparable;
182 
183     public static Comparable<Integer> intComparable;
184 
185     public static Comparable<Long> longComparable;
186 
187     public static Comparable<?> wildcardComparable;
188 
189     public static URI uri;
190 
191     public static List<String>[] stringListArray;
192 
stub()193     public static <G extends Comparable<G>> G stub() {
194         return null;
195     }
196 
stub2()197     public static <G extends Comparable<? super G>> G stub2() {
198         return null;
199     }
200 
stub3()201     public static <T extends Comparable<? extends T>> T stub3() {
202         return null;
203     }
204 
205     public This<String, String> dis;
206 
207     public That<String, String> dat;
208 
209     public The<String, String> da;
210 
211     public Other<String> uhder;
212 
213     public Thing ding;
214 
215     public TypeUtilsTest<String>.Tester tester;
216 
217     public Tester tester2;
218 
219     public TypeUtilsTest<String>.That<String, String> dat2;
220 
221     public TypeUtilsTest<Number>.That<String, String> dat3;
222 
223     public Comparable<? extends Integer>[] intWildcardComparable;
224 
225     public Iterable<? extends Map<Integer, ? extends Collection<?>>> iterable;
226 
delegateBooleanAssertion(final Type[] types, final int i2, final int i1, final boolean expected)227     public void delegateBooleanAssertion(final Type[] types, final int i2, final int i1, final boolean expected) {
228         final Type type1 = types[i1];
229         final Type type2 = types[i2];
230         final boolean isAssignable = TypeUtils.isAssignable(type2, type1);
231 
232         if (expected) {
233             assertTrue(isAssignable,
234                     "[" + i1 + ", " + i2 + "]: From "
235                                 + String.valueOf(type2) + " to "
236                                 + String.valueOf(type1));
237         } else {
238             assertFalse(isAssignable,
239                     "[" + i1 + ", " + i2 + "]: From "
240                                 + String.valueOf(type2) + " to "
241                                 + String.valueOf(type1));
242         }
243     }
244 
dummyMethod(final List list0, final List<Object> list1, final List<?> list2, final List<? super Object> list3, final List<String> list4, final List<? extends String> list5, final List<? super String> list6, final List[] list7, final List<Object>[] list8, final List<?>[] list9, final List<? super Object>[] list10, final List<String>[] list11, final List<? extends String>[] list12, final List<? super String>[] list13)245     public void dummyMethod(final List list0, final List<Object> list1, final List<?> list2,
246             final List<? super Object> list3, final List<String> list4, final List<? extends String> list5,
247             final List<? super String> list6, final List[] list7, final List<Object>[] list8, final List<?>[] list9,
248             final List<? super Object>[] list10, final List<String>[] list11, final List<? extends String>[] list12,
249             final List<? super String>[] list13) {
250     }
251 
252     @Test
testContainsTypeVariables()253     public void testContainsTypeVariables() throws Exception {
254         assertFalse(TypeUtils.containsTypeVariables(Test1.class.getMethod("m0").getGenericReturnType()));
255         assertFalse(TypeUtils.containsTypeVariables(Test1.class.getMethod("m1").getGenericReturnType()));
256         assertTrue(TypeUtils.containsTypeVariables(Test1.class.getMethod("m2").getGenericReturnType()));
257         assertTrue(TypeUtils.containsTypeVariables(Test1.class.getMethod("m3").getGenericReturnType()));
258         assertTrue(TypeUtils.containsTypeVariables(Test1.class.getMethod("m4").getGenericReturnType()));
259         assertFalse(TypeUtils.containsTypeVariables(Test1.class.getMethod("m5").getGenericReturnType()));
260         assertFalse(TypeUtils.containsTypeVariables(Test1.class.getMethod("m6").getGenericReturnType()));
261         assertFalse(TypeUtils.containsTypeVariables(Test1.class.getMethod("m7").getGenericReturnType()));
262         assertFalse(TypeUtils.containsTypeVariables(Test1.class.getMethod("m8").getGenericReturnType()));
263         assertTrue(TypeUtils.containsTypeVariables(Test1.class.getMethod("m9").getGenericReturnType()));
264         assertTrue(TypeUtils.containsTypeVariables(Test1.class.getMethod("m10").getGenericReturnType()));
265         assertTrue(TypeUtils.containsTypeVariables(Test1.class.getMethod("m11").getGenericReturnType()));
266         assertTrue(TypeUtils.containsTypeVariables(Test1.class.getMethod("m12").getGenericReturnType()));
267         assertTrue(TypeUtils.containsTypeVariables(Test1.class.getMethod("m13").getGenericReturnType()));
268         assertFalse(TypeUtils.containsTypeVariables(Test1.class.getMethod("m14").getGenericReturnType()));
269         assertTrue(TypeUtils.containsTypeVariables(Test1.class.getMethod("m15").getGenericReturnType()));
270         assertTrue(TypeUtils.containsTypeVariables(Test1.class.getMethod("m16").getGenericReturnType()));
271         assertTrue(TypeUtils.containsTypeVariables(Test1.class.getMethod("m17").getGenericReturnType()));
272     }
273 
274     @Test
testDetermineTypeVariableAssignments()275     public void testDetermineTypeVariableAssignments() throws SecurityException,
276             NoSuchFieldException {
277         final ParameterizedType iterableType = (ParameterizedType) getClass().getField("iterable")
278                 .getGenericType();
279         final Map<TypeVariable<?>, Type> typeVarAssigns = TypeUtils.determineTypeArguments(TreeSet.class,
280                 iterableType);
281         final TypeVariable<?> treeSetTypeVar = TreeSet.class.getTypeParameters()[0];
282         assertTrue(typeVarAssigns.containsKey(treeSetTypeVar));
283         assertEquals(iterableType.getActualTypeArguments()[0], typeVarAssigns
284                 .get(treeSetTypeVar));
285     }
286 
287     @Test
testGenericArrayType()288     public void testGenericArrayType() throws Exception {
289         final Type expected = getClass().getField("intWildcardComparable").getGenericType();
290         final GenericArrayType actual =
291             TypeUtils.genericArrayType(TypeUtils.parameterize(Comparable.class, TypeUtils.wildcardType()
292                 .withUpperBounds(Integer.class).build()));
293         assertTrue(TypeUtils.equals(expected, actual));
294         assertEquals("java.lang.Comparable<? extends java.lang.Integer>[]", actual.toString());
295     }
296 
297     @Test
testGetArrayComponentType()298     public void testGetArrayComponentType() throws Exception {
299         final Method method = getClass().getMethod("dummyMethod", List.class, List.class, List.class,
300                 List.class, List.class, List.class, List.class, List[].class, List[].class,
301                 List[].class, List[].class, List[].class, List[].class, List[].class);
302 
303         final Type[] types = method.getGenericParameterTypes();
304 
305         assertNull(TypeUtils.getArrayComponentType(types[0]));
306         assertNull(TypeUtils.getArrayComponentType(types[1]));
307         assertNull(TypeUtils.getArrayComponentType(types[2]));
308         assertNull(TypeUtils.getArrayComponentType(types[3]));
309         assertNull(TypeUtils.getArrayComponentType(types[4]));
310         assertNull(TypeUtils.getArrayComponentType(types[5]));
311         assertNull(TypeUtils.getArrayComponentType(types[6]));
312         assertEquals(types[0], TypeUtils.getArrayComponentType(types[7]));
313         assertEquals(types[1], TypeUtils.getArrayComponentType(types[8]));
314         assertEquals(types[2], TypeUtils.getArrayComponentType(types[9]));
315         assertEquals(types[3], TypeUtils.getArrayComponentType(types[10]));
316         assertEquals(types[4], TypeUtils.getArrayComponentType(types[11]));
317         assertEquals(types[5], TypeUtils.getArrayComponentType(types[12]));
318         assertEquals(types[6], TypeUtils.getArrayComponentType(types[13]));
319     }
320 
321     @Test
testGetPrimitiveArrayComponentType()322     public void testGetPrimitiveArrayComponentType() {
323         assertEquals(boolean.class, TypeUtils.getArrayComponentType(boolean[].class));
324         assertEquals(byte.class, TypeUtils.getArrayComponentType(byte[].class));
325         assertEquals(short.class, TypeUtils.getArrayComponentType(short[].class));
326         assertEquals(int.class, TypeUtils.getArrayComponentType(int[].class));
327         assertEquals(char.class, TypeUtils.getArrayComponentType(char[].class));
328         assertEquals(long.class, TypeUtils.getArrayComponentType(long[].class));
329         assertEquals(float.class, TypeUtils.getArrayComponentType(float[].class));
330         assertEquals(double.class, TypeUtils.getArrayComponentType(double[].class));
331 
332         assertNull(TypeUtils.getArrayComponentType(boolean.class));
333         assertNull(TypeUtils.getArrayComponentType(byte.class));
334         assertNull(TypeUtils.getArrayComponentType(short.class));
335         assertNull(TypeUtils.getArrayComponentType(int.class));
336         assertNull(TypeUtils.getArrayComponentType(char.class));
337         assertNull(TypeUtils.getArrayComponentType(long.class));
338         assertNull(TypeUtils.getArrayComponentType(float.class));
339         assertNull(TypeUtils.getArrayComponentType(double.class));
340     }
341 
342     @Test
testGetRawType()343     public void testGetRawType() throws SecurityException, NoSuchFieldException {
344         final Type stringParentFieldType = GenericTypeHolder.class.getDeclaredField("stringParent")
345                 .getGenericType();
346         final Type integerParentFieldType = GenericTypeHolder.class.getDeclaredField("integerParent")
347                 .getGenericType();
348         final Type foosFieldType = GenericTypeHolder.class.getDeclaredField("foos").getGenericType();
349         final Type genericParentT = GenericParent.class.getTypeParameters()[0];
350         assertEquals(GenericParent.class, TypeUtils.getRawType(stringParentFieldType, null));
351         assertEquals(GenericParent.class, TypeUtils.getRawType(integerParentFieldType,
352                         null));
353         assertEquals(List.class, TypeUtils.getRawType(foosFieldType, null));
354         assertEquals(String.class, TypeUtils.getRawType(genericParentT,
355                 StringParameterizedChild.class));
356         assertEquals(String.class, TypeUtils.getRawType(genericParentT,
357                 stringParentFieldType));
358         assertEquals(Foo.class, TypeUtils.getRawType(Iterable.class.getTypeParameters()[0],
359                 foosFieldType));
360         assertEquals(Foo.class, TypeUtils.getRawType(List.class.getTypeParameters()[0],
361                 foosFieldType));
362         assertNull(TypeUtils.getRawType(genericParentT, GenericParent.class));
363         assertEquals(GenericParent[].class, TypeUtils.getRawType(GenericTypeHolder.class
364                 .getDeclaredField("barParents").getGenericType(), null));
365     }
366 
367     @Test
testGetTypeArguments()368     public void testGetTypeArguments() {
369         Map<TypeVariable<?>, Type> typeVarAssigns;
370         TypeVariable<?> treeSetTypeVar;
371         Type typeArg;
372 
373         typeVarAssigns = TypeUtils.getTypeArguments(Integer.class, Comparable.class);
374         treeSetTypeVar = Comparable.class.getTypeParameters()[0];
375         assertTrue(typeVarAssigns.containsKey(treeSetTypeVar),
376                 "Type var assigns for Comparable from Integer: " + typeVarAssigns);
377         typeArg = typeVarAssigns.get(treeSetTypeVar);
378         assertEquals(Integer.class, typeVarAssigns.get(treeSetTypeVar),
379                 "Type argument of Comparable from Integer: " + typeArg);
380 
381         typeVarAssigns = TypeUtils.getTypeArguments(int.class, Comparable.class);
382         treeSetTypeVar = Comparable.class.getTypeParameters()[0];
383         assertTrue(typeVarAssigns.containsKey(treeSetTypeVar),
384                 "Type var assigns for Comparable from int: " + typeVarAssigns);
385         typeArg = typeVarAssigns.get(treeSetTypeVar);
386         assertEquals(Integer.class, typeVarAssigns.get(treeSetTypeVar),
387                 "Type argument of Comparable from int: " + typeArg);
388 
389         final Collection<Integer> col = Collections.emptyList();
390         typeVarAssigns = TypeUtils.getTypeArguments(List.class, Collection.class);
391         treeSetTypeVar = Comparable.class.getTypeParameters()[0];
392         assertFalse(typeVarAssigns.containsKey(treeSetTypeVar),
393                 "Type var assigns for Collection from List: " + typeVarAssigns);
394 
395         typeVarAssigns = TypeUtils.getTypeArguments(AAAClass.BBBClass.class, AAClass.BBClass.class);
396         assertEquals(2, typeVarAssigns.size());
397         assertEquals(String.class, typeVarAssigns.get(AAClass.class.getTypeParameters()[0]));
398         assertEquals(String.class, typeVarAssigns.get(AAClass.BBClass.class.getTypeParameters()[0]));
399 
400         typeVarAssigns = TypeUtils.getTypeArguments(Other.class, This.class);
401         assertEquals(2, typeVarAssigns.size());
402         assertEquals(String.class, typeVarAssigns.get(This.class.getTypeParameters()[0]));
403         assertEquals(Other.class.getTypeParameters()[0], typeVarAssigns.get(This.class.getTypeParameters()[1]));
404 
405         typeVarAssigns = TypeUtils.getTypeArguments(And.class, This.class);
406         assertEquals(2, typeVarAssigns.size());
407         assertEquals(Number.class, typeVarAssigns.get(This.class.getTypeParameters()[0]));
408         assertEquals(Number.class, typeVarAssigns.get(This.class.getTypeParameters()[1]));
409 
410         typeVarAssigns = TypeUtils.getTypeArguments(Thing.class, Other.class);
411         assertEquals(2, typeVarAssigns.size());
412         assertEquals(getClass().getTypeParameters()[0], typeVarAssigns.get(getClass().getTypeParameters()[0]));
413         assertEquals(getClass().getTypeParameters()[0], typeVarAssigns.get(Other.class.getTypeParameters()[0]));
414     }
415 
416     @Test
testIsArrayGenericTypes()417     public void testIsArrayGenericTypes() throws Exception {
418         final Method method = getClass().getMethod("dummyMethod", List.class, List.class, List.class,
419                 List.class, List.class, List.class, List.class, List[].class, List[].class,
420                 List[].class, List[].class, List[].class, List[].class, List[].class);
421 
422         final Type[] types = method.getGenericParameterTypes();
423 
424         assertFalse(TypeUtils.isArrayType(types[0]));
425         assertFalse(TypeUtils.isArrayType(types[1]));
426         assertFalse(TypeUtils.isArrayType(types[2]));
427         assertFalse(TypeUtils.isArrayType(types[3]));
428         assertFalse(TypeUtils.isArrayType(types[4]));
429         assertFalse(TypeUtils.isArrayType(types[5]));
430         assertFalse(TypeUtils.isArrayType(types[6]));
431         assertTrue(TypeUtils.isArrayType(types[7]));
432         assertTrue(TypeUtils.isArrayType(types[8]));
433         assertTrue(TypeUtils.isArrayType(types[9]));
434         assertTrue(TypeUtils.isArrayType(types[10]));
435         assertTrue(TypeUtils.isArrayType(types[11]));
436         assertTrue(TypeUtils.isArrayType(types[12]));
437         assertTrue(TypeUtils.isArrayType(types[13]));
438     }
439 
440     @Test
testIsArrayTypeClasses()441     public void testIsArrayTypeClasses() {
442         assertTrue(TypeUtils.isArrayType(boolean[].class));
443         assertTrue(TypeUtils.isArrayType(byte[].class));
444         assertTrue(TypeUtils.isArrayType(short[].class));
445         assertTrue(TypeUtils.isArrayType(int[].class));
446         assertTrue(TypeUtils.isArrayType(char[].class));
447         assertTrue(TypeUtils.isArrayType(long[].class));
448         assertTrue(TypeUtils.isArrayType(float[].class));
449         assertTrue(TypeUtils.isArrayType(double[].class));
450         assertTrue(TypeUtils.isArrayType(Object[].class));
451         assertTrue(TypeUtils.isArrayType(String[].class));
452 
453         assertFalse(TypeUtils.isArrayType(boolean.class));
454         assertFalse(TypeUtils.isArrayType(byte.class));
455         assertFalse(TypeUtils.isArrayType(short.class));
456         assertFalse(TypeUtils.isArrayType(int.class));
457         assertFalse(TypeUtils.isArrayType(char.class));
458         assertFalse(TypeUtils.isArrayType(long.class));
459         assertFalse(TypeUtils.isArrayType(float.class));
460         assertFalse(TypeUtils.isArrayType(double.class));
461         assertFalse(TypeUtils.isArrayType(Object.class));
462         assertFalse(TypeUtils.isArrayType(String.class));
463     }
464 
465     @SuppressWarnings("boxing") // deliberately used here
466     @Test
testIsAssignable()467     public void testIsAssignable() throws SecurityException, NoSuchMethodException,
468             NoSuchFieldException {
469         List list0 = null;
470         List<Object> list1;
471         List<?> list2;
472         List<? super Object> list3;
473         List<String> list4;
474         List<? extends String> list5;
475         List<? super String> list6;
476         List[] list7 = null;
477         List<Object>[] list8;
478         List<?>[] list9;
479         List<? super Object>[] list10;
480         List<String>[] list11;
481         List<? extends String>[] list12;
482         List<? super String>[] list13;
483         final Class<?> clazz = getClass();
484         final Method method = clazz.getMethod("dummyMethod", List.class, List.class, List.class,
485                 List.class, List.class, List.class, List.class, List[].class, List[].class,
486                 List[].class, List[].class, List[].class, List[].class, List[].class);
487         final Type[] types = method.getGenericParameterTypes();
488 //        list0 = list0;
489         delegateBooleanAssertion(types, 0, 0, true);
490         list1 = list0;
491         delegateBooleanAssertion(types, 0, 1, true);
492         list0 = list1;
493         delegateBooleanAssertion(types, 1, 0, true);
494         list2 = list0;
495         delegateBooleanAssertion(types, 0, 2, true);
496         list0 = list2;
497         delegateBooleanAssertion(types, 2, 0, true);
498         list3 = list0;
499         delegateBooleanAssertion(types, 0, 3, true);
500         list0 = list3;
501         delegateBooleanAssertion(types, 3, 0, true);
502         list4 = list0;
503         delegateBooleanAssertion(types, 0, 4, true);
504         list0 = list4;
505         delegateBooleanAssertion(types, 4, 0, true);
506         list5 = list0;
507         delegateBooleanAssertion(types, 0, 5, true);
508         list0 = list5;
509         delegateBooleanAssertion(types, 5, 0, true);
510         list6 = list0;
511         delegateBooleanAssertion(types, 0, 6, true);
512         list0 = list6;
513         delegateBooleanAssertion(types, 6, 0, true);
514 //        list1 = list1;
515         delegateBooleanAssertion(types, 1, 1, true);
516         list2 = list1;
517         delegateBooleanAssertion(types, 1, 2, true);
518         list1 = (List<Object>) list2;
519         delegateBooleanAssertion(types, 2, 1, false);
520         list3 = list1;
521         delegateBooleanAssertion(types, 1, 3, true);
522         list1 = (List<Object>) list3;
523         delegateBooleanAssertion(types, 3, 1, false);
524         // list4 = list1;
525         delegateBooleanAssertion(types, 1, 4, false);
526         // list1 = list4;
527         delegateBooleanAssertion(types, 4, 1, false);
528         // list5 = list1;
529         delegateBooleanAssertion(types, 1, 5, false);
530         // list1 = list5;
531         delegateBooleanAssertion(types, 5, 1, false);
532         list6 = list1;
533         delegateBooleanAssertion(types, 1, 6, true);
534         list1 = (List<Object>) list6;
535         delegateBooleanAssertion(types, 6, 1, false);
536 //        list2 = list2;
537         delegateBooleanAssertion(types, 2, 2, true);
538         list2 = list3;
539         delegateBooleanAssertion(types, 2, 3, false);
540         list2 = list4;
541         delegateBooleanAssertion(types, 3, 2, true);
542         list3 = (List<? super Object>) list2;
543         delegateBooleanAssertion(types, 2, 4, false);
544         list2 = list5;
545         delegateBooleanAssertion(types, 4, 2, true);
546         list4 = (List<String>) list2;
547         delegateBooleanAssertion(types, 2, 5, false);
548         list2 = list6;
549         delegateBooleanAssertion(types, 5, 2, true);
550         list5 = (List<? extends String>) list2;
551         delegateBooleanAssertion(types, 2, 6, false);
552 //        list3 = list3;
553         delegateBooleanAssertion(types, 6, 2, true);
554         list6 = (List<? super String>) list2;
555         delegateBooleanAssertion(types, 3, 3, true);
556         // list4 = list3;
557         delegateBooleanAssertion(types, 3, 4, false);
558         // list3 = list4;
559         delegateBooleanAssertion(types, 4, 3, false);
560         // list5 = list3;
561         delegateBooleanAssertion(types, 3, 5, false);
562         // list3 = list5;
563         delegateBooleanAssertion(types, 5, 3, false);
564         list6 = list3;
565         delegateBooleanAssertion(types, 3, 6, true);
566         list3 = (List<? super Object>) list6;
567         delegateBooleanAssertion(types, 6, 3, false);
568 //        list4 = list4;
569         delegateBooleanAssertion(types, 4, 4, true);
570         list5 = list4;
571         delegateBooleanAssertion(types, 4, 5, true);
572         list4 = (List<String>) list5;
573         delegateBooleanAssertion(types, 5, 4, false);
574         list6 = list4;
575         delegateBooleanAssertion(types, 4, 6, true);
576         list4 = (List<String>) list6;
577         delegateBooleanAssertion(types, 6, 4, false);
578 //        list5 = list5;
579         delegateBooleanAssertion(types, 5, 5, true);
580         list6 = (List<? super String>) list5;
581         delegateBooleanAssertion(types, 5, 6, false);
582         list5 = (List<? extends String>) list6;
583         delegateBooleanAssertion(types, 6, 5, false);
584 //        list6 = list6;
585         delegateBooleanAssertion(types, 6, 6, true);
586 
587 //        list7 = list7;
588         delegateBooleanAssertion(types, 7, 7, true);
589         list8 = list7;
590         delegateBooleanAssertion(types, 7, 8, true);
591         list7 = list8;
592         delegateBooleanAssertion(types, 8, 7, true);
593         list9 = list7;
594         delegateBooleanAssertion(types, 7, 9, true);
595         list7 = list9;
596         delegateBooleanAssertion(types, 9, 7, true);
597         list10 = list7;
598         delegateBooleanAssertion(types, 7, 10, true);
599         list7 = list10;
600         delegateBooleanAssertion(types, 10, 7, true);
601         list11 = list7;
602         delegateBooleanAssertion(types, 7, 11, true);
603         list7 = list11;
604         delegateBooleanAssertion(types, 11, 7, true);
605         list12 = list7;
606         delegateBooleanAssertion(types, 7, 12, true);
607         list7 = list12;
608         delegateBooleanAssertion(types, 12, 7, true);
609         list13 = list7;
610         delegateBooleanAssertion(types, 7, 13, true);
611         list7 = list13;
612         delegateBooleanAssertion(types, 13, 7, true);
613 //        list8 = list8;
614         delegateBooleanAssertion(types, 8, 8, true);
615         list9 = list8;
616         delegateBooleanAssertion(types, 8, 9, true);
617         list8 = (List<Object>[]) list9;
618         delegateBooleanAssertion(types, 9, 8, false);
619         list10 = list8;
620         delegateBooleanAssertion(types, 8, 10, true);
621         list8 = (List<Object>[]) list10; // NOTE cast is required by Sun Java, but not by Eclipse
622         delegateBooleanAssertion(types, 10, 8, false);
623         // list11 = list8;
624         delegateBooleanAssertion(types, 8, 11, false);
625         // list8 = list11;
626         delegateBooleanAssertion(types, 11, 8, false);
627         // list12 = list8;
628         delegateBooleanAssertion(types, 8, 12, false);
629         // list8 = list12;
630         delegateBooleanAssertion(types, 12, 8, false);
631         list13 = list8;
632         delegateBooleanAssertion(types, 8, 13, true);
633         list8 = (List<Object>[]) list13;
634         delegateBooleanAssertion(types, 13, 8, false);
635 //        list9 = list9;
636         delegateBooleanAssertion(types, 9, 9, true);
637         list10 = (List<? super Object>[]) list9;
638         delegateBooleanAssertion(types, 9, 10, false);
639         list9 = list10;
640         delegateBooleanAssertion(types, 10, 9, true);
641         list11 = (List<String>[]) list9;
642         delegateBooleanAssertion(types, 9, 11, false);
643         list9 = list11;
644         delegateBooleanAssertion(types, 11, 9, true);
645         list12 = (List<? extends String>[]) list9;
646         delegateBooleanAssertion(types, 9, 12, false);
647         list9 = list12;
648         delegateBooleanAssertion(types, 12, 9, true);
649         list13 = (List<? super String>[]) list9;
650         delegateBooleanAssertion(types, 9, 13, false);
651         list9 = list13;
652         delegateBooleanAssertion(types, 13, 9, true);
653 //        list10 = list10;
654         delegateBooleanAssertion(types, 10, 10, true);
655         // list11 = list10;
656         delegateBooleanAssertion(types, 10, 11, false);
657         // list10 = list11;
658         delegateBooleanAssertion(types, 11, 10, false);
659         // list12 = list10;
660         delegateBooleanAssertion(types, 10, 12, false);
661         // list10 = list12;
662         delegateBooleanAssertion(types, 12, 10, false);
663         list13 = list10;
664         delegateBooleanAssertion(types, 10, 13, true);
665         list10 = (List<? super Object>[]) list13;
666         delegateBooleanAssertion(types, 13, 10, false);
667 //        list11 = list11;
668         delegateBooleanAssertion(types, 11, 11, true);
669         list12 = list11;
670         delegateBooleanAssertion(types, 11, 12, true);
671         list11 = (List<String>[]) list12;
672         delegateBooleanAssertion(types, 12, 11, false);
673         list13 = list11;
674         delegateBooleanAssertion(types, 11, 13, true);
675         list11 = (List<String>[]) list13;
676         delegateBooleanAssertion(types, 13, 11, false);
677 //        list12 = list12;
678         delegateBooleanAssertion(types, 12, 12, true);
679         list13 = (List<? super String>[]) list12;
680         delegateBooleanAssertion(types, 12, 13, false);
681         list12 = (List<? extends String>[]) list13;
682         delegateBooleanAssertion(types, 13, 12, false);
683 //        list13 = list13;
684         delegateBooleanAssertion(types, 13, 13, true);
685         final Type disType = getClass().getField("dis").getGenericType();
686         // Reporter.log( ( ( ParameterizedType ) disType
687         // ).getOwnerType().getClass().toString() );
688         final Type datType = getClass().getField("dat").getGenericType();
689         final Type daType = getClass().getField("da").getGenericType();
690         final Type uhderType = getClass().getField("uhder").getGenericType();
691         final Type dingType = getClass().getField("ding").getGenericType();
692         final Type testerType = getClass().getField("tester").getGenericType();
693         final Type tester2Type = getClass().getField("tester2").getGenericType();
694         final Type dat2Type = getClass().getField("dat2").getGenericType();
695         final Type dat3Type = getClass().getField("dat3").getGenericType();
696         dis = dat;
697         assertTrue(TypeUtils.isAssignable(datType, disType));
698         // dis = da;
699         assertFalse(TypeUtils.isAssignable(daType, disType));
700         dis = uhder;
701         assertTrue(TypeUtils.isAssignable(uhderType, disType));
702         dis = ding;
703         assertFalse(TypeUtils.isAssignable(dingType, disType),
704                 String.format("type %s not assignable to %s!", dingType, disType));
705         dis = tester;
706         assertTrue(TypeUtils.isAssignable(testerType, disType));
707         // dis = tester2;
708         assertFalse(TypeUtils.isAssignable(tester2Type, disType));
709         // dat = dat2;
710         assertFalse(TypeUtils.isAssignable(dat2Type, datType));
711         // dat2 = dat;
712         assertFalse(TypeUtils.isAssignable(datType, dat2Type));
713         // dat = dat3;
714         assertFalse(TypeUtils.isAssignable(dat3Type, datType));
715         final char ch = 0;
716         final boolean bo = false;
717         final byte by = 0;
718         final short sh = 0;
719         int in = 0;
720         long lo = 0;
721         final float fl = 0;
722         double du;
723         du = ch;
724         assertTrue(TypeUtils.isAssignable(char.class, double.class));
725         du = by;
726         assertTrue(TypeUtils.isAssignable(byte.class, double.class));
727         du = sh;
728         assertTrue(TypeUtils.isAssignable(short.class, double.class));
729         du = in;
730         assertTrue(TypeUtils.isAssignable(int.class, double.class));
731         du = lo;
732         assertTrue(TypeUtils.isAssignable(long.class, double.class));
733         du = fl;
734         assertTrue(TypeUtils.isAssignable(float.class, double.class));
735         lo = in;
736         assertTrue(TypeUtils.isAssignable(int.class, long.class));
737         lo = Integer.valueOf(0);
738         assertTrue(TypeUtils.isAssignable(Integer.class, long.class));
739         // Long lngW = 1;
740         assertFalse(TypeUtils.isAssignable(int.class, Long.class));
741         // lngW = Integer.valueOf( 0 );
742         assertFalse(TypeUtils.isAssignable(Integer.class, Long.class));
743         in = Integer.valueOf(0);
744         assertTrue(TypeUtils.isAssignable(Integer.class, int.class));
745         final Integer inte = in;
746         assertTrue(TypeUtils.isAssignable(int.class, Integer.class));
747         assertTrue(TypeUtils.isAssignable(int.class, Number.class));
748         assertTrue(TypeUtils.isAssignable(int.class, Object.class));
749         final Type intComparableType = getClass().getField("intComparable").getGenericType();
750         intComparable = 1;
751         assertTrue(TypeUtils.isAssignable(int.class, intComparableType));
752         assertTrue(TypeUtils.isAssignable(int.class, Comparable.class));
753         final Serializable ser = 1;
754         assertTrue(TypeUtils.isAssignable(int.class, Serializable.class));
755         final Type longComparableType = getClass().getField("longComparable").getGenericType();
756         // longComparable = 1;
757         assertFalse(TypeUtils.isAssignable(int.class, longComparableType));
758         // longComparable = Integer.valueOf( 0 );
759         assertFalse(TypeUtils.isAssignable(Integer.class, longComparableType));
760         // int[] ia;
761         // long[] la = ia;
762         assertFalse(TypeUtils.isAssignable(int[].class, long[].class));
763         final Integer[] ia = null;
764         final Type caType = getClass().getField("intWildcardComparable").getGenericType();
765         intWildcardComparable = ia;
766         assertTrue(TypeUtils.isAssignable(Integer[].class, caType));
767         // int[] ina = ia;
768         assertFalse(TypeUtils.isAssignable(Integer[].class, int[].class));
769         final int[] ina = null;
770         final Object[] oa;
771         // oa = ina;
772         assertFalse(TypeUtils.isAssignable(int[].class, Object[].class));
773         oa = new Integer[0];
774         assertTrue(TypeUtils.isAssignable(Integer[].class, Object[].class));
775         final Type bClassType = AClass.class.getField("bClass").getGenericType();
776         final Type cClassType = AClass.class.getField("cClass").getGenericType();
777         final Type dClassType = AClass.class.getField("dClass").getGenericType();
778         final Type eClassType = AClass.class.getField("eClass").getGenericType();
779         final Type fClassType = AClass.class.getField("fClass").getGenericType();
780         final AClass aClass = new AClass(new AAClass<>());
781         aClass.bClass = aClass.cClass;
782         assertTrue(TypeUtils.isAssignable(cClassType, bClassType));
783         aClass.bClass = aClass.dClass;
784         assertTrue(TypeUtils.isAssignable(dClassType, bClassType));
785         aClass.bClass = aClass.eClass;
786         assertTrue(TypeUtils.isAssignable(eClassType, bClassType));
787         aClass.bClass = aClass.fClass;
788         assertTrue(TypeUtils.isAssignable(fClassType, bClassType));
789         aClass.cClass = aClass.dClass;
790         assertTrue(TypeUtils.isAssignable(dClassType, cClassType));
791         aClass.cClass = aClass.eClass;
792         assertTrue(TypeUtils.isAssignable(eClassType, cClassType));
793         aClass.cClass = aClass.fClass;
794         assertTrue(TypeUtils.isAssignable(fClassType, cClassType));
795         aClass.dClass = aClass.eClass;
796         assertTrue(TypeUtils.isAssignable(eClassType, dClassType));
797         aClass.dClass = aClass.fClass;
798         assertTrue(TypeUtils.isAssignable(fClassType, dClassType));
799         aClass.eClass = aClass.fClass;
800         assertTrue(TypeUtils.isAssignable(fClassType, eClassType));
801     }
802 
testIsAssignable(final Class testUnassignableClass)803     private void testIsAssignable(final Class testUnassignableClass) {
804         final Class<Constructor> rawClass = Constructor.class;
805         final Class<Insets> typeArgClass = Insets.class;
806         // Builds a ParameterizedType for Constructor<Insets>
807         final ParameterizedType paramType = TypeUtils.parameterize(rawClass, typeArgClass);
808         assertEquals(rawClass, paramType.getRawType());
809         assertEquals(typeArgClass, paramType.getActualTypeArguments()[0]);
810 
811         assertFalse(testUnassignableClass.isAssignableFrom(paramType.getClass()));
812         assertFalse(paramType.getClass().isAssignableFrom(testUnassignableClass));
813 
814         final GenericArrayType arrayType = TypeUtils.genericArrayType(paramType);
815         assertFalse(TypeUtils.isAssignable(arrayType, paramType),
816                 () -> String.format("TypeUtils.isAssignable(%s, %s)", arrayType, paramType));
817         assertFalse(TypeUtils.isAssignable(paramType, arrayType),
818                 () -> String.format("TypeUtils.isAssignable(%s, %s)", paramType, arrayType));
819     }
820 
821     @Test
testIsAssignableGenericArrayTypeToParameterizedType()822     public void testIsAssignableGenericArrayTypeToParameterizedType() {
823         final Class<Constructor> rawClass = Constructor.class;
824         final Class<Insets> typeArgClass = Insets.class;
825         // Builds a ParameterizedType for Constructor<Insets>
826         final ParameterizedType paramType = TypeUtils.parameterize(rawClass, typeArgClass);
827         assertEquals(rawClass, paramType.getRawType());
828         assertEquals(typeArgClass, paramType.getActualTypeArguments()[0]);
829 
830         assertFalse(GenericArrayType.class.isAssignableFrom(paramType.getClass()));
831         assertFalse(paramType.getClass().isAssignableFrom(GenericArrayType.class));
832 
833         final GenericArrayType testType = TypeUtils.genericArrayType(paramType);
834         assertFalse(TypeUtils.isAssignable(paramType, testType),
835                 () -> String.format("TypeUtils.isAssignable(%s, %s)", paramType, testType));
836         assertFalse(TypeUtils.isAssignable(testType, paramType),
837                 () -> String.format("TypeUtils.isAssignable(%s, %s)", testType, paramType));
838     }
839 
840     @Test
841     @Disabled("TODO")
testIsAssignableGenericArrayTypeToWildercardType()842     public void testIsAssignableGenericArrayTypeToWildercardType() {
843         final Class<Constructor> rawClass = Constructor.class;
844         final Class<Insets> typeArgClass = Insets.class;
845         // Builds a ParameterizedType for Constructor<Insets>
846         final ParameterizedType paramType = TypeUtils.parameterize(rawClass, typeArgClass);
847         assertEquals(rawClass, paramType.getRawType());
848         assertEquals(typeArgClass, paramType.getActualTypeArguments()[0]);
849 
850         assertFalse(WildcardType.class.isAssignableFrom(paramType.getClass()));
851         assertFalse(paramType.getClass().isAssignableFrom(WildcardType.class));
852 
853         final WildcardType testType = TypeUtils.WILDCARD_ALL;
854         // TODO This test returns true unlike the test above.
855         // Is this a bug in this test or in the main code?
856         assertFalse(TypeUtils.isAssignable(paramType, testType),
857                 () -> String.format("TypeUtils.isAssignable(%s, %s)", paramType, testType));
858         assertFalse(TypeUtils.isAssignable(testType, paramType),
859                 () -> String.format("TypeUtils.isAssignable(%s, %s)", testType, paramType));
860     }
861 
862     @Test
testIsAssignableGenericArrayTypeToObject()863     public void testIsAssignableGenericArrayTypeToObject() {
864         final Class<Constructor> rawClass = Constructor.class;
865         final Class<Insets> typeArgClass = Insets.class;
866         // Builds a ParameterizedType for Constructor<Insets>
867         final ParameterizedType paramType = TypeUtils.parameterize(rawClass, typeArgClass);
868         assertEquals(rawClass, paramType.getRawType());
869         assertEquals(typeArgClass, paramType.getActualTypeArguments()[0]);
870 
871         assertTrue(Object.class.isAssignableFrom(paramType.getClass()));
872         assertFalse(paramType.getClass().isAssignableFrom(Object.class));
873 
874         final Type testType = Object.class;
875         assertTrue(TypeUtils.isAssignable(paramType, testType),
876                 () -> String.format("TypeUtils.isAssignable(%s, %s)", paramType, testType));
877         assertFalse(TypeUtils.isAssignable(testType, paramType),
878                 () -> String.format("TypeUtils.isAssignable(%s, %s)", testType, paramType));
879     }
880 
881     @SuppressWarnings("boxing") // boxing is deliberate here
882     @Test
testIsInstance()883     public void testIsInstance() throws SecurityException, NoSuchFieldException {
884         final Type intComparableType = getClass().getField("intComparable").getGenericType();
885         final Type uriComparableType = getClass().getField("uriComparable").getGenericType();
886         intComparable = 1;
887         assertTrue(TypeUtils.isInstance(1, intComparableType));
888         // uriComparable = 1;
889         assertFalse(TypeUtils.isInstance(1, uriComparableType));
890     }
891 
892     @Test
testLang1114()893     public void testLang1114() throws Exception {
894         final Type nonWildcardType = getClass().getDeclaredField("wildcardComparable").getGenericType();
895         final Type wildcardType = ((ParameterizedType) nonWildcardType).getActualTypeArguments()[0];
896 
897         assertFalse(TypeUtils.equals(wildcardType, nonWildcardType));
898         assertFalse(TypeUtils.equals(nonWildcardType, wildcardType));
899     }
900 
901     @Test
testLANG1190()902     public void testLANG1190() throws Exception {
903         final Type fromType = ClassWithSuperClassWithGenericType.class.getDeclaredMethod("methodWithGenericReturnType").getGenericReturnType();
904         final Type failingToType = TypeUtils.wildcardType().withLowerBounds(ClassWithSuperClassWithGenericType.class).build();
905 
906         assertTrue(TypeUtils.isAssignable(fromType, failingToType));
907     }
908 
909     @Test
testLANG1348()910     public void testLANG1348() throws Exception {
911         final Method method = Enum.class.getMethod("valueOf", Class.class, String.class);
912         assertEquals("T extends java.lang.Enum<T>", TypeUtils.toString(method.getGenericReturnType()));
913     }
914 
915     @Test
testLang820()916     public void testLang820() {
917         final Type[] typeArray = {String.class, String.class};
918         final Type[] expectedArray = {String.class};
919         assertArrayEquals(expectedArray, TypeUtils.normalizeUpperBounds(typeArray));
920     }
921 
922     @Test
testLowerBoundedWildcardType()923     public void testLowerBoundedWildcardType() {
924        final WildcardType lowerBounded = TypeUtils.wildcardType().withLowerBounds(java.sql.Date.class).build();
925        assertEquals(String.format("? super %s", java.sql.Date.class.getName()), TypeUtils.toString(lowerBounded));
926        assertEquals(String.format("? super %s", java.sql.Date.class.getName()), lowerBounded.toString());
927 
928        final TypeVariable<Class<Iterable>> iterableT0 = Iterable.class.getTypeParameters()[0];
929        final WildcardType lowerTypeVariable = TypeUtils.wildcardType().withLowerBounds(iterableT0).build();
930        assertEquals(String.format("? super %s", iterableT0.getName()), TypeUtils.toString(lowerTypeVariable));
931        assertEquals(String.format("? super %s", iterableT0.getName()), lowerTypeVariable.toString());
932     }
933 
934     @Test
testParameterize()935     public void testParameterize() throws Exception {
936         final ParameterizedType stringComparableType = TypeUtils.parameterize(Comparable.class, String.class);
937         assertTrue(TypeUtils.equals(getClass().getField("stringComparable").getGenericType(),
938             stringComparableType));
939         assertEquals("java.lang.Comparable<java.lang.String>", stringComparableType.toString());
940     }
941 
942     @Test
testParameterizeNarrowerTypeArray()943     public void testParameterizeNarrowerTypeArray() {
944         final TypeVariable<?>[] variables = ArrayList.class.getTypeParameters();
945         final ParameterizedType parameterizedType = TypeUtils.parameterize(ArrayList.class, variables);
946         final Map<TypeVariable<?>, Type> mapping = Collections.<TypeVariable<?>, Type>singletonMap(variables[0], String.class);
947         final Type unrolled = TypeUtils.unrollVariables(mapping, parameterizedType);
948         assertEquals(TypeUtils.parameterize(ArrayList.class, String.class), unrolled);
949     }
950 
951     @Test
testParameterizeNullPointerException()952     public void testParameterizeNullPointerException() {
953         assertThrows(NullPointerException.class, () -> TypeUtils.parameterize(null, Collections.emptyMap()));
954         final Map<TypeVariable<?>, Type> nullTypeVariableMap = null;
955         assertThrows(NullPointerException.class, () -> TypeUtils.parameterize(String.class, nullTypeVariableMap));
956     }
957 
958     @Test
testParameterizeVarArgsNullPointerException()959     public void testParameterizeVarArgsNullPointerException() {
960         assertThrows(NullPointerException.class, () -> TypeUtils.parameterize(null));
961     }
962 
963     @Test
testParameterizeWithOwner()964     public void testParameterizeWithOwner() throws Exception {
965         final Type owner = TypeUtils.parameterize(TypeUtilsTest.class, String.class);
966         final ParameterizedType dat2Type = TypeUtils.parameterizeWithOwner(owner, That.class, String.class, String.class);
967         assertTrue(TypeUtils.equals(getClass().getField("dat2").getGenericType(), dat2Type));
968     }
969 
970     @Test
testParameterizeWithOwner3ArgsNullPointerException()971     public void testParameterizeWithOwner3ArgsNullPointerException() {
972         final Type owner = TypeUtils.parameterize(TypeUtilsTest.class, String.class);
973         assertThrows(NullPointerException.class, () -> TypeUtils.parameterizeWithOwner(owner, null, String.class));
974         final Map<TypeVariable<?>, Type> nullTypeVariableMap = null;
975         assertThrows(NullPointerException.class, () -> TypeUtils.parameterizeWithOwner(owner, That.class, nullTypeVariableMap));
976     }
977 
978     @Test
testParameterizeWithOwnerVarArgsNullPointerException()979     public void testParameterizeWithOwnerVarArgsNullPointerException() {
980         final Type owner = TypeUtils.parameterize(TypeUtilsTest.class, String.class);
981         assertThrows(NullPointerException.class, () -> TypeUtils.parameterizeWithOwner(owner, null));
982     }
983 
984     @Test
testToLongString()985     public void testToLongString() {
986         assertEquals(getClass().getName() + ":B", TypeUtils.toLongString(getClass().getTypeParameters()[0]));
987     }
988 
989     @Test
testToStringLang1311()990     public void testToStringLang1311() {
991         assertEquals("int[]", TypeUtils.toString(int[].class));
992         assertEquals("java.lang.Integer[]", TypeUtils.toString(Integer[].class));
993         final Field stringListField = FieldUtils.getDeclaredField(getClass(), "stringListArray");
994         assertEquals("java.util.List<java.lang.String>[]", TypeUtils.toString(stringListField.getGenericType()));
995     }
996 
997     @Test
testTypesSatisfyVariables()998     public void testTypesSatisfyVariables() throws SecurityException,
999             NoSuchMethodException {
1000         final Map<TypeVariable<?>, Type> typeVarAssigns = new HashMap<>();
1001         final Integer max = TypeUtilsTest.<Integer>stub();
1002         typeVarAssigns.put(getClass().getMethod("stub").getTypeParameters()[0], Integer.class);
1003         assertTrue(TypeUtils.typesSatisfyVariables(typeVarAssigns));
1004         typeVarAssigns.clear();
1005         typeVarAssigns.put(getClass().getMethod("stub2").getTypeParameters()[0], Integer.class);
1006         assertTrue(TypeUtils.typesSatisfyVariables(typeVarAssigns));
1007         typeVarAssigns.clear();
1008         typeVarAssigns.put(getClass().getMethod("stub3").getTypeParameters()[0], Integer.class);
1009         assertTrue(TypeUtils.typesSatisfyVariables(typeVarAssigns));
1010     }
1011 
1012     @Test
testUnboundedWildcardType()1013     public void testUnboundedWildcardType() {
1014         final WildcardType unbounded = TypeUtils.wildcardType().withLowerBounds((Type) null).withUpperBounds().build();
1015         assertTrue(TypeUtils.equals(TypeUtils.WILDCARD_ALL, unbounded));
1016         assertArrayEquals(new Type[] { Object.class }, TypeUtils.getImplicitUpperBounds(unbounded));
1017         assertArrayEquals(new Type[] { null }, TypeUtils.getImplicitLowerBounds(unbounded));
1018         assertEquals("?", TypeUtils.toString(unbounded));
1019         assertEquals("?", unbounded.toString());
1020     }
1021 
1022     @Test
testWildcardType()1023     public void testWildcardType() throws Exception {
1024         final WildcardType simpleWildcard = TypeUtils.wildcardType().withUpperBounds(String.class).build();
1025         final Field cClass = AClass.class.getField("cClass");
1026         assertTrue(TypeUtils.equals(((ParameterizedType) cClass.getGenericType()).getActualTypeArguments()[0],
1027             simpleWildcard));
1028         assertEquals(String.format("? extends %s", String.class.getName()), TypeUtils.toString(simpleWildcard));
1029         assertEquals(String.format("? extends %s", String.class.getName()), simpleWildcard.toString());
1030     }
1031 
1032     @Test
testWrap()1033     public void testWrap() {
1034         final Type t = getClass().getTypeParameters()[0];
1035         assertTrue(TypeUtils.equals(t, TypeUtils.wrap(t).getType()));
1036 
1037         assertEquals(String.class, TypeUtils.wrap(String.class).getType());
1038     }
1039 }
1040