/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.core.convert;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.*;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import junit.framework.TestCase;
import org.springframework.core.MethodParameter;
/**
* @author Keith Donald
* @author Andy Clement
* @author Phillip Webb
*/
@SuppressWarnings("rawtypes")
public class TypeDescriptorTests extends TestCase {
public List<String> listOfString;
public List<List<String>> listOfListOfString = new ArrayList<List<String>>();
public List<List> listOfListOfUnknown = new ArrayList<List>();
public int[] intArray;
public List<String>[] arrayOfListOfString;
public List<Integer> listField = new ArrayList<Integer>();
public Map<String, Integer> mapField = new HashMap<String, Integer>();
public Map<String, List<Integer>> nestedMapField = new HashMap<String, List<Integer>>();
public void testParameterPrimitive() throws Exception {
TypeDescriptor desc = new TypeDescriptor(new MethodParameter(getClass().getMethod("testParameterPrimitive", int.class), 0));
assertEquals(int.class, desc.getType());
assertEquals(Integer.class, desc.getObjectType());
assertEquals("int", desc.getName());
assertEquals("int", desc.toString());
assertTrue(desc.isPrimitive());
assertEquals(0, desc.getAnnotations().length);
assertFalse(desc.isCollection());
assertFalse(desc.isMap());
}
public void testParameterPrimitive(int primitive) {
}
public void testParameterScalar() throws Exception {
TypeDescriptor desc = new TypeDescriptor(new MethodParameter(getClass().getMethod("testParameterScalar", String.class), 0));
assertEquals(String.class, desc.getType());
assertEquals(String.class, desc.getObjectType());
assertEquals("java.lang.String", desc.getName());
assertEquals("java.lang.String", desc.toString());
assertTrue(!desc.isPrimitive());
assertEquals(0, desc.getAnnotations().length);
assertFalse(desc.isCollection());
assertFalse(desc.isArray());
assertFalse(desc.isMap());
}
public void testParameterScalar(String value) {
}
public void testParameterList() throws Exception {
MethodParameter methodParameter = new MethodParameter(getClass().getMethod("testParameterList", List.class), 0);
TypeDescriptor desc = new TypeDescriptor(methodParameter);
assertEquals(List.class, desc.getType());
assertEquals(List.class, desc.getObjectType());
assertEquals("java.util.List", desc.getName());
assertEquals("java.util.List<java.util.List<java.util.Map<java.lang.Integer, java.lang.Enum>>>", desc.toString());
assertTrue(!desc.isPrimitive());
assertEquals(0, desc.getAnnotations().length);
assertTrue(desc.isCollection());
assertFalse(desc.isArray());
assertEquals(List.class, desc.getElementTypeDescriptor().getType());
assertEquals(TypeDescriptor.nested(methodParameter, 1), desc.getElementTypeDescriptor());
assertEquals(TypeDescriptor.nested(methodParameter, 2), desc.getElementTypeDescriptor().getElementTypeDescriptor());
assertEquals(TypeDescriptor.nested(methodParameter, 3), desc.getElementTypeDescriptor().getElementTypeDescriptor().getMapValueTypeDescriptor());
assertEquals(Integer.class, desc.getElementTypeDescriptor().getElementTypeDescriptor().getMapKeyTypeDescriptor().getType());
assertEquals(Enum.class, desc.getElementTypeDescriptor().getElementTypeDescriptor().getMapValueTypeDescriptor().getType());
assertFalse(desc.isMap());
}
public void testParameterList(List<List<Map<Integer, Enum<?>>>> list) {
}
public void testParameterListNoParamTypes() throws Exception {
MethodParameter methodParameter = new MethodParameter(getClass().getMethod("testParameterListNoParamTypes", List.class), 0);
TypeDescriptor desc = new TypeDescriptor(methodParameter);
assertEquals(List.class, desc.getType());
assertEquals(List.class, desc.getObjectType());
assertEquals("java.util.List", desc.getName());
assertEquals("java.util.List<?>", desc.toString());
assertTrue(!desc.isPrimitive());
assertEquals(0, desc.getAnnotations().length);
assertTrue(desc.isCollection());
assertFalse(desc.isArray());
assertNull(desc.getElementTypeDescriptor());
assertFalse(desc.isMap());
}
public void testParameterListNoParamTypes(List list) {
}
public void testParameterArray() throws Exception {
MethodParameter methodParameter = new MethodParameter(getClass().getMethod("testParameterArray", Integer[].class), 0);
TypeDescriptor desc = new TypeDescriptor(methodParameter);
assertEquals(Integer[].class, desc.getType());
assertEquals(Integer[].class, desc.getObjectType());
assertEquals("java.lang.Integer[]", desc.getName());
assertEquals("java.lang.Integer[]", desc.toString());
assertTrue(!desc.isPrimitive());
assertEquals(0, desc.getAnnotations().length);
assertFalse(desc.isCollection());
assertTrue(desc.isArray());
assertEquals(Integer.class, desc.getElementTypeDescriptor().getType());
assertEquals(TypeDescriptor.valueOf(Integer.class), desc.getElementTypeDescriptor());
assertFalse(desc.isMap());
}
public void testParameterArray(Integer[] array) {
}
public void testParameterMap() throws Exception {
MethodParameter methodParameter = new MethodParameter(getClass().getMethod("testParameterMap", Map.class), 0);
TypeDescriptor desc = new TypeDescriptor(methodParameter);
assertEquals(Map.class, desc.getType());
assertEquals(Map.class, desc.getObjectType());
assertEquals("java.util.Map", desc.getName());
assertEquals("java.util.Map<java.lang.Integer, java.util.List<java.lang.String>>", desc.toString());
assertTrue(!desc.isPrimitive());
assertEquals(0, desc.getAnnotations().length);
assertFalse(desc.isCollection());
assertFalse(desc.isArray());
assertTrue(desc.isMap());
assertEquals(TypeDescriptor.nested(methodParameter, 1), desc.getMapValueTypeDescriptor());
assertEquals(TypeDescriptor.nested(methodParameter, 2), desc.getMapValueTypeDescriptor().getElementTypeDescriptor());
assertEquals(Integer.class, desc.getMapKeyTypeDescriptor().getType());
assertEquals(List.class, desc.getMapValueTypeDescriptor().getType());
assertEquals(String.class, desc.getMapValueTypeDescriptor().getElementTypeDescriptor().getType());
}
public void testParameterMap(Map<Integer, List<String>> map) {
}
public void testParameterAnnotated() throws Exception {
TypeDescriptor t1 = new TypeDescriptor(new MethodParameter(getClass().getMethod("testAnnotatedMethod", String.class), 0));
assertEquals(String.class, t1.getType());
assertEquals(1, t1.getAnnotations().length);
assertNotNull(t1.getAnnotation(ParameterAnnotation.class));
assertTrue(t1.hasAnnotation(ParameterAnnotation.class));
assertEquals(123, t1.getAnnotation(ParameterAnnotation.class).value());
}
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface ParameterAnnotation {
int value();
}
public void testAnnotatedMethod(@ParameterAnnotation(123) String parameter) {
}
public void testPropertyComplex() throws Exception {
Property property = new Property(getClass(), getClass().getMethod("getComplexProperty"), getClass().getMethod("setComplexProperty", Map.class));
TypeDescriptor desc = new TypeDescriptor(property);
assertEquals(String.class, desc.getMapKeyTypeDescriptor().getType());
assertEquals(Integer.class, desc.getMapValueTypeDescriptor().getElementTypeDescriptor().getElementTypeDescriptor().getType());
}
public Map<String, List<List<Integer>>> getComplexProperty() {
return null;
}
public void setComplexProperty(Map<String, List<List<Integer>>> complexProperty) {
}
public void testPropertyGenericType() throws Exception {
GenericType<Integer> genericBean = new IntegerType();
Property property = new Property(getClass(), genericBean.getClass().getMethod("getProperty"), genericBean.getClass().getMethod("setProperty", Integer.class));
TypeDescriptor desc = new TypeDescriptor(property);
assertEquals(Integer.class, desc.getType());
}
public void testPropertyTypeCovariance() throws Exception {
GenericType<Number> genericBean = new NumberType();
Property property = new Property(getClass(), genericBean.getClass().getMethod("getProperty"), genericBean.getClass().getMethod("setProperty", Number.class));
TypeDescriptor desc = new TypeDescriptor(property);
assertEquals(Integer.class, desc.getType());
}
public void testPropertyGenericTypeList() throws Exception {
GenericType<Integer> genericBean = new IntegerType();
Property property = new Property(getClass(), genericBean.getClass().getMethod("getListProperty"), genericBean.getClass().getMethod("setListProperty", List.class));
TypeDescriptor desc = new TypeDescriptor(property);
assertEquals(List.class, desc.getType());
assertEquals(Integer.class, desc.getElementTypeDescriptor().getType());
}
public interface GenericType<T> {
T getProperty();
void setProperty(T t);
List<T> getListProperty();
void setListProperty(List<T> t);
}
public class IntegerType implements GenericType<Integer> {
@Override
public Integer getProperty() {
return null;
}
@Override
public void setProperty(Integer t) {
}
@Override
public List<Integer> getListProperty() {
return null;
}
@Override
public void setListProperty(List<Integer> t) {
}
}
public class NumberType implements GenericType<Number> {
@Override
public Integer getProperty() {
return null;
}
@Override
public void setProperty(Number t) {
}
@Override
public List<Number> getListProperty() {
return null;
}
@Override
public void setListProperty(List<Number> t) {
}
}
public void testPropertyGenericClassList() throws Exception {
IntegerClass genericBean = new IntegerClass();
Property property = new Property(genericBean.getClass(), genericBean.getClass().getMethod("getListProperty"), genericBean.getClass().getMethod("setListProperty", List.class));
TypeDescriptor desc = new TypeDescriptor(property);
assertEquals(List.class, desc.getType());
assertEquals(Integer.class, desc.getElementTypeDescriptor().getType());
assertNotNull(desc.getAnnotation(MethodAnnotation1.class));
assertTrue(desc.hasAnnotation(MethodAnnotation1.class));
}
public static class GenericClass<T> {
public T getProperty() {
return null;
}
public void setProperty(T t) {
}
@MethodAnnotation1
public List<T> getListProperty() {
return null;
}
public void setListProperty(List<T> t) {
}
}
public static class IntegerClass extends GenericClass<Integer> {
}
public void testProperty() throws Exception {
Property property = new Property(getClass(), getClass().getMethod("getProperty"), getClass().getMethod("setProperty", Map.class));
TypeDescriptor desc = new TypeDescriptor(property);
assertEquals(Map.class, desc.getType());
assertEquals(Integer.class, desc.getMapKeyTypeDescriptor().getElementTypeDescriptor().getType());
assertEquals(Long.class, desc.getMapValueTypeDescriptor().getElementTypeDescriptor().getType());
assertNotNull(desc.getAnnotation(MethodAnnotation1.class));
assertNotNull(desc.getAnnotation(MethodAnnotation2.class));
assertNotNull(desc.getAnnotation(MethodAnnotation3.class));
}
@MethodAnnotation1
public Map<List<Integer>, List<Long>> getProperty() {
return property;
}
@MethodAnnotation2
public void setProperty(Map<List<Integer>, List<Long>> property) {
this.property = property;
}
@MethodAnnotation3
private Map<List<Integer>, List<Long>> property;
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodAnnotation1 {
}
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodAnnotation2 {
}
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodAnnotation3 {
}
public void testFieldScalar() throws Exception {
TypeDescriptor typeDescriptor = new TypeDescriptor(getClass().getField("fieldScalar"));
assertFalse(typeDescriptor.isPrimitive());
assertFalse(typeDescriptor.isArray());
assertFalse(typeDescriptor.isCollection());
assertFalse(typeDescriptor.isMap());
assertEquals(Integer.class, typeDescriptor.getType());
assertEquals(Integer.class, typeDescriptor.getObjectType());
}
public Integer fieldScalar;
public void testFieldList() throws Exception {
TypeDescriptor typeDescriptor = new TypeDescriptor(TypeDescriptorTests.class.getDeclaredField("listOfString"));
assertFalse(typeDescriptor.isArray());
assertEquals(List.class, typeDescriptor.getType());
assertEquals(String.class, typeDescriptor.getElementTypeDescriptor().getType());
assertEquals("java.util.List<java.lang.String>", typeDescriptor.toString());
}
public void testFieldListOfListOfString() throws Exception {
TypeDescriptor typeDescriptor = new TypeDescriptor(TypeDescriptorTests.class.getDeclaredField("listOfListOfString"));
assertFalse(typeDescriptor.isArray());
assertEquals(List.class, typeDescriptor.getType());
assertEquals(List.class, typeDescriptor.getElementTypeDescriptor().getType());
assertEquals(String.class, typeDescriptor.getElementTypeDescriptor().getElementTypeDescriptor().getType());
assertEquals("java.util.List<java.util.List<java.lang.String>>", typeDescriptor.toString());
}
public void testFieldListOfListUnknown() throws Exception {
TypeDescriptor typeDescriptor = new TypeDescriptor(TypeDescriptorTests.class.getDeclaredField("listOfListOfUnknown"));
assertFalse(typeDescriptor.isArray());
assertEquals(List.class, typeDescriptor.getType());
assertEquals(List.class, typeDescriptor.getElementTypeDescriptor().getType());
assertNull(typeDescriptor.getElementTypeDescriptor().getElementTypeDescriptor());
assertEquals("java.util.List<java.util.List<?>>", typeDescriptor.toString());
}
public void testFieldArray() throws Exception {
TypeDescriptor typeDescriptor = new TypeDescriptor(TypeDescriptorTests.class.getDeclaredField("intArray"));
assertTrue(typeDescriptor.isArray());
assertEquals(Integer.TYPE,typeDescriptor.getElementTypeDescriptor().getType());
assertEquals("int[]",typeDescriptor.toString());
}
public void testFieldComplexTypeDescriptor() throws Exception {
TypeDescriptor typeDescriptor = new TypeDescriptor(TypeDescriptorTests.class.getDeclaredField("arrayOfListOfString"));
assertTrue(typeDescriptor.isArray());
assertEquals(List.class,typeDescriptor.getElementTypeDescriptor().getType());
assertEquals(String.class, typeDescriptor.getElementTypeDescriptor().getElementTypeDescriptor().getType());
assertEquals("java.util.List[]",typeDescriptor.toString());
}
public void testFieldComplexTypeDescriptor2() throws Exception {
TypeDescriptor typeDescriptor = new TypeDescriptor(TypeDescriptorTests.class.getDeclaredField("nestedMapField"));
assertTrue(typeDescriptor.isMap());
assertEquals(String.class,typeDescriptor.getMapKeyTypeDescriptor().getType());
assertEquals(List.class, typeDescriptor.getMapValueTypeDescriptor().getType());
assertEquals(Integer.class, typeDescriptor.getMapValueTypeDescriptor().getElementTypeDescriptor().getType());
assertEquals("java.util.Map<java.lang.String, java.util.List<java.lang.Integer>>", typeDescriptor.toString());
}
public void testFieldMap() throws Exception {
TypeDescriptor desc = new TypeDescriptor(TypeDescriptorTests.class.getField("fieldMap"));
assertTrue(desc.isMap());
assertEquals(Integer.class, desc.getMapKeyTypeDescriptor().getElementTypeDescriptor().getType());
assertEquals(Long.class, desc.getMapValueTypeDescriptor().getElementTypeDescriptor().getType());
}
public Map<List<Integer>, List<Long>> fieldMap;
public void testFieldAnnotated() throws Exception {
TypeDescriptor typeDescriptor = new TypeDescriptor(getClass().getField("fieldAnnotated"));
assertEquals(1, typeDescriptor.getAnnotations().length);
assertNotNull(typeDescriptor.getAnnotation(FieldAnnotation.class));
}
@FieldAnnotation
public List<String> fieldAnnotated;
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldAnnotation {
}
public void testValueOfScalar() {
TypeDescriptor typeDescriptor = TypeDescriptor.valueOf(Integer.class);
assertFalse(typeDescriptor.isPrimitive());
assertFalse(typeDescriptor.isArray());
assertFalse(typeDescriptor.isCollection());
assertFalse(typeDescriptor.isMap());
assertEquals(Integer.class, typeDescriptor.getType());
assertEquals(Integer.class, typeDescriptor.getObjectType());
}
public void testValueOfPrimitive() {
TypeDescriptor typeDescriptor = TypeDescriptor.valueOf(int.class);
assertTrue(typeDescriptor.isPrimitive());
assertFalse(typeDescriptor.isArray());
assertFalse(typeDescriptor.isCollection());
assertFalse(typeDescriptor.isMap());
assertEquals(Integer.TYPE, typeDescriptor.getType());
assertEquals(Integer.class, typeDescriptor.getObjectType());
}
public void testValueOfArray() throws Exception {
TypeDescriptor typeDescriptor = TypeDescriptor.valueOf(int[].class);
assertTrue(typeDescriptor.isArray());
assertFalse(typeDescriptor.isCollection());
assertFalse(typeDescriptor.isMap());
assertEquals(Integer.TYPE, typeDescriptor.getElementTypeDescriptor().getType());
}
public void testValueOfCollection() throws Exception {
TypeDescriptor typeDescriptor = TypeDescriptor.valueOf(Collection.class);
assertTrue(typeDescriptor.isCollection());
assertFalse(typeDescriptor.isArray());
assertFalse(typeDescriptor.isMap());
assertNull(typeDescriptor.getElementTypeDescriptor());
}
public void testForObject() {
TypeDescriptor desc = TypeDescriptor.forObject("3");
assertEquals(String.class, desc.getType());
}
public void testForObjectNullTypeDescriptor() {
TypeDescriptor desc = TypeDescriptor.forObject(null);
assertNull(desc);
}
public void testNestedMethodParameterType2Levels() throws Exception {
TypeDescriptor t1 = TypeDescriptor.nested(new MethodParameter(getClass().getMethod("test2", List.class), 0), 2);
assertEquals(String.class, t1.getType());
}
public void testNestedMethodParameterTypeMap() throws Exception {
TypeDescriptor t1 = TypeDescriptor.nested(new MethodParameter(getClass().getMethod("test3", Map.class), 0), 1);
assertEquals(String.class, t1.getType());
}
public void testNestedMethodParameterTypeMapTwoLevels() throws Exception {
TypeDescriptor t1 = TypeDescriptor.nested(new MethodParameter(getClass().getMethod("test4", List.class), 0), 2);
assertEquals(String.class, t1.getType());
}
public void testNestedMethodParameterNot1NestedLevel() throws Exception {
try {
TypeDescriptor.nested(new MethodParameter(getClass().getMethod("test4", List.class), 0, 2), 2);
fail("expected IllegalArgumentException");
}
catch (IllegalArgumentException e){
}
}
public void testNestedTooManyLevels() throws Exception {
try {
TypeDescriptor t1 = TypeDescriptor.nested(new MethodParameter(getClass().getMethod("test4", List.class), 0), 3);
assertEquals(String.class, t1.getType());
fail("expected IllegalStateException");
}
catch (IllegalStateException e) {
}
}
public void testNestedMethodParameterTypeNotNestable() throws Exception {
try {
TypeDescriptor.nested(new MethodParameter(getClass().getMethod("test5", String.class), 0), 2);
fail("expected IllegalStateException");
}
catch (IllegalStateException e) {
}
}
public void testNestedMethodParameterTypeInvalidNestingLevel() throws Exception {
try {
TypeDescriptor.nested(new MethodParameter(getClass().getMethod("test5", String.class), 0, 2), 2);
fail("expected IllegalArgumentException");
}
catch (IllegalArgumentException e) {
}
}
public void test1(List<String> param1) {
}
public void test2(List<List<String>> param1) {
}
public void test3(Map<Integer, String> param1) {
}
public void test4(List<Map<Integer, String>> param1) {
}
public void test5(String param1) {
}
public void testNestedNotParameterized() throws Exception {
TypeDescriptor t1 = TypeDescriptor.nested(new MethodParameter(getClass().getMethod("test6", List.class), 0), 1);
assertEquals(List.class,t1.getType());
assertEquals("java.util.List<?>", t1.toString());
TypeDescriptor t2 = TypeDescriptor.nested(new MethodParameter(getClass().getMethod("test6", List.class), 0), 2);
assertNull(t2);
}
public void test6(List<List> param1) {
}
public void testNestedFieldTypeMapTwoLevels() throws Exception {
TypeDescriptor t1 = TypeDescriptor.nested(getClass().getField("test4"), 2);
assertEquals(String.class, t1.getType());
}
public List<Map<Integer, String>> test4;
public void testNestedPropertyTypeMapTwoLevels() throws Exception {
Property property = new Property(getClass(), getClass().getMethod("getTest4"), getClass().getMethod("setTest4", List.class));
TypeDescriptor t1 = TypeDescriptor.nested(property, 2);
assertEquals(String.class, t1.getType());
}
public List<Map<Integer, String>> getTest4() {
return null;
}
public void setTest4(List<Map<Integer, String>> test4) {
}
public void testCollection() {
TypeDescriptor desc = TypeDescriptor.collection(List.class, TypeDescriptor.valueOf(Integer.class));
assertEquals(List.class, desc.getType());
assertEquals(List.class, desc.getObjectType());
assertEquals("java.util.List", desc.getName());
assertEquals("java.util.List<java.lang.Integer>", desc.toString());
assertTrue(!desc.isPrimitive());
assertEquals(0, desc.getAnnotations().length);
assertTrue(desc.isCollection());
assertFalse(desc.isArray());
assertEquals(Integer.class, desc.getElementTypeDescriptor().getType());
assertEquals(TypeDescriptor.valueOf(Integer.class), desc.getElementTypeDescriptor());
assertFalse(desc.isMap());
}
public void testCollectionNested() {
TypeDescriptor desc = TypeDescriptor.collection(List.class, TypeDescriptor.collection(List.class, TypeDescriptor.valueOf(Integer.class)));
assertEquals(List.class, desc.getType());
assertEquals(List.class, desc.getObjectType());
assertEquals("java.util.List", desc.getName());
assertEquals("java.util.List<java.util.List<java.lang.Integer>>", desc.toString());
assertTrue(!desc.isPrimitive());
assertEquals(0, desc.getAnnotations().length);
assertTrue(desc.isCollection());
assertFalse(desc.isArray());
assertEquals(List.class, desc.getElementTypeDescriptor().getType());
assertEquals(TypeDescriptor.valueOf(Integer.class), desc.getElementTypeDescriptor().getElementTypeDescriptor());
assertFalse(desc.isMap());
}
public void testMap() {
TypeDescriptor desc = TypeDescriptor.map(Map.class, TypeDescriptor.valueOf(String.class), TypeDescriptor.valueOf(Integer.class));
assertEquals(Map.class, desc.getType());
assertEquals(Map.class, desc.getObjectType());
assertEquals("java.util.Map", desc.getName());
assertEquals("java.util.Map<java.lang.String, java.lang.Integer>", desc.toString());
assertTrue(!desc.isPrimitive());
assertEquals(0, desc.getAnnotations().length);
assertFalse(desc.isCollection());
assertFalse(desc.isArray());
assertTrue(desc.isMap());
assertEquals(String.class, desc.getMapKeyTypeDescriptor().getType());
assertEquals(Integer.class, desc.getMapValueTypeDescriptor().getType());
}
public void testMapNested() {
TypeDescriptor desc = TypeDescriptor.map(Map.class, TypeDescriptor.valueOf(String.class),
TypeDescriptor.map(Map.class, TypeDescriptor.valueOf(String.class), TypeDescriptor.valueOf(Integer.class)));
assertEquals(Map.class, desc.getType());
assertEquals(Map.class, desc.getObjectType());
assertEquals("java.util.Map", desc.getName());
assertEquals("java.util.Map<java.lang.String, java.util.Map<java.lang.String, java.lang.Integer>>", desc.toString());
assertTrue(!desc.isPrimitive());
assertEquals(0, desc.getAnnotations().length);
assertFalse(desc.isCollection());
assertFalse(desc.isArray());
assertTrue(desc.isMap());
assertEquals(String.class, desc.getMapKeyTypeDescriptor().getType());
assertEquals(String.class, desc.getMapValueTypeDescriptor().getMapKeyTypeDescriptor().getType());
assertEquals(Integer.class, desc.getMapValueTypeDescriptor().getMapValueTypeDescriptor().getType());
}
public void testNarrow() {
TypeDescriptor desc = TypeDescriptor.valueOf(Number.class);
Integer value = new Integer(3);
desc = desc.narrow(value);
assertEquals(Integer.class, desc.getType());
}
public void testElementType() {
TypeDescriptor desc = TypeDescriptor.valueOf(List.class);
Integer value = new Integer(3);
desc = desc.elementTypeDescriptor(value);
assertEquals(Integer.class, desc.getType());
}
public void testElementTypePreserveContext() throws Exception {
TypeDescriptor desc = new TypeDescriptor(getClass().getField("listPreserveContext"));
assertEquals(Integer.class, desc.getElementTypeDescriptor().getElementTypeDescriptor().getType());
List<Integer> value = new ArrayList<Integer>(3);
desc = desc.elementTypeDescriptor(value);
assertEquals(Integer.class, desc.getElementTypeDescriptor().getType());
assertNotNull(desc.getAnnotation(FieldAnnotation.class));
}
@FieldAnnotation
public List<List<Integer>> listPreserveContext;
public void testMapKeyType() {
TypeDescriptor desc = TypeDescriptor.valueOf(Map.class);
Integer value = new Integer(3);
desc = desc.getMapKeyTypeDescriptor(value);
assertEquals(Integer.class, desc.getType());
}
public void testMapKeyTypePreserveContext() throws Exception {
TypeDescriptor desc = new TypeDescriptor(getClass().getField("mapPreserveContext"));
assertEquals(Integer.class, desc.getMapKeyTypeDescriptor().getElementTypeDescriptor().getType());
List<Integer> value = new ArrayList<Integer>(3);
desc = desc.getMapKeyTypeDescriptor(value);
assertEquals(Integer.class, desc.getElementTypeDescriptor().getType());
assertNotNull(desc.getAnnotation(FieldAnnotation.class));
}
@FieldAnnotation
public Map<List<Integer>, List<Integer>> mapPreserveContext;
public void testMapValueType() {
TypeDescriptor desc = TypeDescriptor.valueOf(Map.class);
Integer value = new Integer(3);
desc = desc.getMapValueTypeDescriptor(value);
assertEquals(Integer.class, desc.getType());
}
public void testMapValueTypePreserveContext() throws Exception {
TypeDescriptor desc = new TypeDescriptor(getClass().getField("mapPreserveContext"));
assertEquals(Integer.class, desc.getMapValueTypeDescriptor().getElementTypeDescriptor().getType());
List<Integer> value = new ArrayList<Integer>(3);
desc = desc.getMapValueTypeDescriptor(value);
assertEquals(Integer.class, desc.getElementTypeDescriptor().getType());
assertNotNull(desc.getAnnotation(FieldAnnotation.class));
}
public void testEquals() throws Exception {
TypeDescriptor t1 = TypeDescriptor.valueOf(String.class);
TypeDescriptor t2 = TypeDescriptor.valueOf(String.class);
TypeDescriptor t3 = TypeDescriptor.valueOf(Date.class);
TypeDescriptor t4 = TypeDescriptor.valueOf(Date.class);
TypeDescriptor t5 = TypeDescriptor.valueOf(List.class);
TypeDescriptor t6 = TypeDescriptor.valueOf(List.class);
TypeDescriptor t7 = TypeDescriptor.valueOf(Map.class);
TypeDescriptor t8 = TypeDescriptor.valueOf(Map.class);
assertEquals(t1, t2);
assertEquals(t3, t4);
assertEquals(t5, t6);
assertEquals(t7, t8);
TypeDescriptor t9 = new TypeDescriptor(getClass().getField("listField"));
TypeDescriptor t10 = new TypeDescriptor(getClass().getField("listField"));
assertEquals(t9, t10);
TypeDescriptor t11 = new TypeDescriptor(getClass().getField("mapField"));
TypeDescriptor t12 = new TypeDescriptor(getClass().getField("mapField"));
assertEquals(t11, t12);
}
public void testIsAssignableTypes() {
assertTrue(TypeDescriptor.valueOf(Integer.class).isAssignableTo(TypeDescriptor.valueOf(Number.class)));
assertFalse(TypeDescriptor.valueOf(Number.class).isAssignableTo(TypeDescriptor.valueOf(Integer.class)));
assertFalse(TypeDescriptor.valueOf(String.class).isAssignableTo(TypeDescriptor.valueOf(String[].class)));
}
public void testIsAssignableElementTypes() throws Exception {
assertTrue(new TypeDescriptor(getClass().getField("listField")).isAssignableTo(new TypeDescriptor(getClass().getField("listField"))));
assertTrue(new TypeDescriptor(getClass().getField("notGenericList")).isAssignableTo(new TypeDescriptor(getClass().getField("listField"))));
assertTrue(new TypeDescriptor(getClass().getField("listField")).isAssignableTo(new TypeDescriptor(getClass().getField("notGenericList"))));
assertFalse(new TypeDescriptor(getClass().getField("isAssignableElementTypes")).isAssignableTo(new TypeDescriptor(getClass().getField("listField"))));
assertTrue(TypeDescriptor.valueOf(List.class).isAssignableTo(new TypeDescriptor(getClass().getField("listField"))));
}
public List notGenericList;
public List<Number> isAssignableElementTypes;
public void testIsAssignableMapKeyValueTypes() throws Exception {
assertTrue(new TypeDescriptor(getClass().getField("mapField")).isAssignableTo(new TypeDescriptor(getClass().getField("mapField"))));
assertTrue(new TypeDescriptor(getClass().getField("notGenericMap")).isAssignableTo(new TypeDescriptor(getClass().getField("mapField"))));
assertTrue(new TypeDescriptor(getClass().getField("mapField")).isAssignableTo(new TypeDescriptor(getClass().getField("notGenericMap"))));
assertFalse(new TypeDescriptor(getClass().getField("isAssignableMapKeyValueTypes")).isAssignableTo(new TypeDescriptor(getClass().getField("mapField"))));
assertTrue(TypeDescriptor.valueOf(Map.class).isAssignableTo(new TypeDescriptor(getClass().getField("mapField"))));
}
public Map notGenericMap;
public Map<CharSequence, Number> isAssignableMapKeyValueTypes;
public void testUpCast() throws Exception {
Property property = new Property(getClass(), getClass().getMethod("getProperty"),
getClass().getMethod("setProperty", Map.class));
TypeDescriptor typeDescriptor = new TypeDescriptor(property);
TypeDescriptor upCast = typeDescriptor.upcast(Object.class);
assertTrue(upCast.getAnnotation(MethodAnnotation1.class) != null);
}
public void testUpCastNotSuper() throws Exception {
Property property = new Property(getClass(), getClass().getMethod("getProperty"),
getClass().getMethod("setProperty", Map.class));
TypeDescriptor typeDescriptor = new TypeDescriptor(property);
try {
typeDescriptor.upcast(Collection.class);
fail("Did not throw");
} catch(IllegalArgumentException e) {
assertEquals("interface java.util.Map is not assignable to interface java.util.Collection", e.getMessage());
}
}
public void testElementTypeForCollectionSubclass() throws Exception {
@SuppressWarnings("serial")
class CustomSet extends HashSet<String> {
}
assertEquals(TypeDescriptor.valueOf(CustomSet.class).getElementTypeDescriptor(), TypeDescriptor.valueOf(String.class));
assertEquals(TypeDescriptor.forObject(new CustomSet()).getElementTypeDescriptor(), TypeDescriptor.valueOf(String.class));
}
public void testElementTypeForMapSubclass() throws Exception {
@SuppressWarnings("serial")
class CustomMap extends HashMap<String, Integer> {
}
assertEquals(TypeDescriptor.valueOf(CustomMap.class).getMapKeyTypeDescriptor(), TypeDescriptor.valueOf(String.class));
assertEquals(TypeDescriptor.valueOf(CustomMap.class).getMapValueTypeDescriptor(), TypeDescriptor.valueOf(Integer.class));
assertEquals(TypeDescriptor.forObject(new CustomMap()).getMapKeyTypeDescriptor(), TypeDescriptor.valueOf(String.class));
assertEquals(TypeDescriptor.forObject(new CustomMap()).getMapValueTypeDescriptor(), TypeDescriptor.valueOf(Integer.class));
}
public void testCreateMapArray() throws Exception {
TypeDescriptor mapType = TypeDescriptor.map(LinkedHashMap.class, TypeDescriptor.valueOf(String.class), TypeDescriptor.valueOf(Integer.class));
TypeDescriptor arrayType = TypeDescriptor.array(mapType);
assertEquals(arrayType.getType(), LinkedHashMap[].class);
assertEquals(arrayType.getElementTypeDescriptor(), mapType);
}
public void testCreateStringArray() throws Exception {
TypeDescriptor arrayType = TypeDescriptor.array(TypeDescriptor.valueOf(String.class));
assertEquals(arrayType, TypeDescriptor.valueOf(String[].class));
}
public void testCreateNullArray() throws Exception {
assertNull(TypeDescriptor.array(null));
}
public void testSerializable() throws Exception {
TypeDescriptor typeDescriptor = TypeDescriptor.forObject("");
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream outputStream = new ObjectOutputStream(out);
outputStream.writeObject(typeDescriptor);
ObjectInputStream inputStream = new ObjectInputStream(new ByteArrayInputStream(
out.toByteArray()));
TypeDescriptor readObject = (TypeDescriptor) inputStream.readObject();
assertThat(readObject, equalTo(typeDescriptor));
}
}