package org.simpleflatmapper.util.test; import org.junit.Assert; import org.junit.Test; import org.simpleflatmapper.test.beans.DbObject; import org.simpleflatmapper.util.TypeHelper; import org.simpleflatmapper.util.TypeReference; import java.lang.reflect.GenericArrayType; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.math.BigDecimal; import java.util.*; import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentMap; import static org.junit.Assert.*; public class TypeHelperTest { @Test public void testToClass() { Assert.assertEquals(Map.class, TypeHelper.toClass(new TypeReference<Map<String, String>>() {}.getType())); ParameterizedType type = (ParameterizedType) new TypeReference<Map<? extends Number, String>>() { }.getType(); assertEquals(Number.class, TypeHelper.toClass(type.getActualTypeArguments()[0])); assertEquals(Date.class, TypeHelper.toClass(MyComparable.class.getTypeParameters()[0])); assertEquals(Date.class, TypeHelper.toClass(Date.class)); try { TypeHelper.toClass(new Type() { public String getTypeName() { return null; } }); fail(); } catch (UnsupportedOperationException e) { } assertEquals(String[].class, TypeHelper.toClass(new GenericArrayType() { @Override public Type getGenericComponentType() { return String.class; } })); } @Test public void testIs() { assertTrue(TypeHelper.isJavaLang(Long.class)); assertFalse(TypeHelper.isJavaLang(Date.class)); assertTrue(TypeHelper.isPrimitive(long.class)); assertFalse(TypeHelper.isPrimitive(Long.class)); assertTrue(TypeHelper.isArray(new Object[0].getClass())); assertFalse(TypeHelper.isArray(new Object().getClass())); assertTrue(TypeHelper.isNumber(Long.class)); assertTrue(TypeHelper.isNumber(BigDecimal.class)); assertFalse(TypeHelper.isNumber(Date.class)); assertTrue(TypeHelper.isEnum(E.class)); assertFalse(TypeHelper.isEnum(BigDecimal.class)); } @Test public void testIsAssignable() { assertTrue(TypeHelper.isAssignable((Type)int.class, (Type)Integer.class)); assertTrue(TypeHelper.isAssignable((Type)Number.class, (Type)Integer.class)); assertFalse(TypeHelper.isAssignable((Type)Integer.class, (Type)Number.class)); } @Test public void testGetTypeMaps() { Type type = new TypeReference<Map<String, Number>>() { }.getType(); Map<TypeVariable<?>, Type> typesMap = TypeHelper.getTypesMap(type); assertEquals(2, typesMap.size()); assertEquals(String.class, typesMap.get(Map.class.getTypeParameters()[0])); assertEquals(Number.class, typesMap.get(Map.class.getTypeParameters()[1])); } enum E {A, B} static class MyComparable<T extends Date> implements Comparable<T> { @Override public int compareTo(T o) { return 0; } } @Test public void testIsNumber() { assertTrue(TypeHelper.isNumber(byte.class)); assertTrue(TypeHelper.isNumber(Byte.class)); assertTrue(TypeHelper.isNumber(BigDecimal.class)); assertFalse(TypeHelper.isNumber(char.class)); assertFalse(TypeHelper.isNumber(String.class)); } @Test public void testAreCompatible() { assertTrue(TypeHelper.areCompatible(Integer.class, int.class)); assertTrue(TypeHelper.areCompatible(Integer.class, Integer.class)); assertTrue(TypeHelper.areCompatible(Number.class, int.class)); assertTrue(TypeHelper.areCompatible(Number.class, Integer.class)); assertTrue(TypeHelper.areCompatible(Object.class, int.class)); assertTrue(TypeHelper.areCompatible(Object.class, Integer.class)); assertFalse(TypeHelper.areCompatible(Double.class, Integer.class)); } @Test public void testWrap() { assertEquals(Character.class, TypeHelper.wrap(char.class)); } @Test public void testGetComponentTypeOfArray() { assertEquals(String.class, TypeHelper.getComponentTypeOfListOrArray(String[].class)); } @Test public void testGetComponentTypeOfList() { assertEquals(String.class, TypeHelper.getComponentTypeOfListOrArray(new TypeReference<List<String>>(){}.getType())); assertEquals(Object.class, TypeHelper.getComponentTypeOfListOrArray(List.class)); } @Test public void testGetComponentTypeOfStringList() { assertEquals(String.class, TypeHelper.getComponentTypeOfListOrArray(StringList.class)); } @Test public void testGetKeyValueTypeOfMapOnGenericInterface() { TypeHelper.MapEntryTypes typeOfMap = TypeHelper.getKeyValueTypeOfMap(new TypeReference<Map<String, Integer>>() { }.getType()); assertEquals(new TypeHelper.MapEntryTypes(String.class, Integer.class), typeOfMap); assertEquals(String.class, typeOfMap.getKeyType()); assertEquals(Integer.class, typeOfMap.getValueType()); assertEquals(new TypeHelper.MapEntryTypes(Object.class, Object.class), TypeHelper.getKeyValueTypeOfMap(Map.class)); } @Test public void testGetKeyValueTypeOfMapOnSpecifiedClass() { assertEquals(new TypeHelper.MapEntryTypes(String.class, Integer.class), TypeHelper.getKeyValueTypeOfMap(StringIntegerMap.class)); } @Test public void testGetKeyValueTypeOfMapOnConcurrentMap() { assertEquals(new TypeHelper.MapEntryTypes(String.class, Integer.class), TypeHelper.getKeyValueTypeOfMap(new TypeReference<ConcurrentMap<String, Integer>>(){}.getType())); } @Test public void testMapperEntryTypes() { assertEquals(new TypeHelper.MapEntryTypes(String.class, Integer.class), new TypeHelper.MapEntryTypes(String.class, Integer.class)); assertNotEquals(new TypeHelper.MapEntryTypes(Number.class, Integer.class), new TypeHelper.MapEntryTypes(String.class, Integer.class)); assertEquals(new TypeHelper.MapEntryTypes(String.class, Integer.class).hashCode(), new TypeHelper.MapEntryTypes(String.class, Integer.class).hashCode()); assertNotEquals(new TypeHelper.MapEntryTypes(Number.class, Integer.class).hashCode(), new TypeHelper.MapEntryTypes(String.class, Integer.class).hashCode()); new TypeHelper.MapEntryTypes(String.class, Integer.class).toString(); } @Test public void testGetGenericParametersForInterface() { Type type = new TypeReference<MyClass<DbObject, Integer>>() { }.getType(); assertArrayEquals(new Type[] {String.class, Integer.class}, TypeHelper.getGenericParameterForClass(type, Map.class)); assertArrayEquals(new Type[]{DbObject.class}, TypeHelper.getGenericParameterForClass(type, Callable.class)); } @Test public void testGetGenericParametersForInterfaceNotImplement() { Type type = new TypeReference<MyClass<DbObject, String>>() { }.getType(); try { TypeHelper.getGenericParameterForClass(type, Collection.class); fail("expect exception"); } catch(IllegalArgumentException e) { //expected } } public static class MyClass<T, K> implements Map<String, K>, Callable<T> { @Override public T call() throws Exception { return null; } @Override public int size() { return 0; } @Override public boolean isEmpty() { return false; } @Override public boolean containsKey(Object key) { return false; } @Override public boolean containsValue(Object value) { return false; } @Override public K get(Object key) { return null; } @Override public K put(String key, K value) { return null; } @Override public K remove(Object key) { return null; } @Override public void putAll(Map<? extends String, ? extends K> m) { } @Override public void clear() { } @Override public Set<String> keySet() { return null; } @Override public Collection<K> values() { return null; } @Override public Set<Entry<String, K>> entrySet() { return null; } } public static class StringList extends MyList<String> { } public static class MyList<P> extends ArrayList<P> { } public static class StringIntegerMap extends HashMap<String, Integer> { } }