package nl.ipo.cds.attributemapping; import static nl.ipo.cds.attributemapping.AttributeMapperUtils.areTypesAssignable; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.List; import org.junit.Test; public class TestAttributeMapperUtils { @Test public void testAssignablePrimitiveTypes () { assertTrue (areTypesAssignable (Byte.TYPE, Byte.TYPE)); assertTrue (areTypesAssignable (Character.TYPE, Character.TYPE)); assertTrue (areTypesAssignable (Short.TYPE, Short.TYPE)); assertTrue (areTypesAssignable (Integer.TYPE, Integer.TYPE)); assertTrue (areTypesAssignable (Long.TYPE, Long.TYPE)); assertTrue (areTypesAssignable (Float.TYPE, Float.TYPE)); assertTrue (areTypesAssignable (Double.TYPE, Double.TYPE)); assertTrue (areTypesAssignable (Boolean.TYPE, Boolean.TYPE)); } @Test public void testAssignableBoxing () throws Exception { final int value = 1; final Method method = getClass ().getMethod ("testBoxing", Integer.class); method.invoke (this, value); assertTrue (areTypesAssignable (Byte.TYPE, Byte.class)); assertTrue (areTypesAssignable (Character.TYPE, Character.class)); assertTrue (areTypesAssignable (Short.TYPE, Short.class)); assertTrue (areTypesAssignable (Integer.TYPE, Integer.class)); assertTrue (areTypesAssignable (Long.TYPE, Long.class)); assertTrue (areTypesAssignable (Float.TYPE, Float.class)); assertTrue (areTypesAssignable (Double.TYPE, Double.class)); assertTrue (areTypesAssignable (Boolean.TYPE, Boolean.class)); } @Test public void testAssignableUnboxing () throws Exception { final Integer value = 1; final Method method = getClass ().getMethod ("testUnboxing", Integer.TYPE); method.invoke (this, value); assertTrue (areTypesAssignable (Byte.class, Byte.TYPE)); assertTrue (areTypesAssignable (Character.class, Character.TYPE)); assertTrue (areTypesAssignable (Short.class, Short.TYPE)); assertTrue (areTypesAssignable (Integer.class, Integer.TYPE)); assertTrue (areTypesAssignable (Long.class, Long.TYPE)); assertTrue (areTypesAssignable (Float.class, Float.TYPE)); assertTrue (areTypesAssignable (Double.class, Double.TYPE)); assertTrue (areTypesAssignable (Boolean.class, Boolean.TYPE)); } @Test public void testAssignableUpcasting () throws Exception { final int value = 1; final Method method = getClass ().getMethod ("testUpcasting", Long.TYPE); method.invoke (this, value); assertTrue (areTypesAssignable (Byte.TYPE, Short.TYPE)); assertTrue (areTypesAssignable (Byte.TYPE, Character.TYPE)); assertTrue (areTypesAssignable (Byte.TYPE, Integer.TYPE)); assertTrue (areTypesAssignable (Byte.TYPE, Long.TYPE)); assertFalse (areTypesAssignable (Byte.TYPE, Float.TYPE)); assertFalse (areTypesAssignable (Byte.TYPE, Double.TYPE)); assertFalse (areTypesAssignable (Character.TYPE, Byte.TYPE)); assertTrue (areTypesAssignable (Character.TYPE, Short.TYPE)); assertTrue (areTypesAssignable (Character.TYPE, Integer.TYPE)); assertTrue (areTypesAssignable (Character.TYPE, Long.TYPE)); assertFalse (areTypesAssignable (Character.TYPE, Float.TYPE)); assertFalse (areTypesAssignable (Character.TYPE, Double.TYPE)); assertFalse (areTypesAssignable (Short.TYPE, Byte.TYPE)); assertTrue (areTypesAssignable (Short.TYPE, Character.TYPE)); assertTrue (areTypesAssignable (Short.TYPE, Integer.TYPE)); assertTrue (areTypesAssignable (Short.TYPE, Long.TYPE)); assertFalse (areTypesAssignable (Short.TYPE, Float.TYPE)); assertFalse (areTypesAssignable (Short.TYPE, Double.TYPE)); assertFalse (areTypesAssignable (Integer.TYPE, Byte.TYPE)); assertFalse (areTypesAssignable (Integer.TYPE, Character.TYPE)); assertFalse (areTypesAssignable (Integer.TYPE, Short.TYPE)); assertTrue (areTypesAssignable (Integer.TYPE, Long.TYPE)); assertFalse (areTypesAssignable (Integer.TYPE, Float.TYPE)); assertFalse (areTypesAssignable (Integer.TYPE, Double.TYPE)); assertFalse (areTypesAssignable (Long.TYPE, Byte.TYPE)); assertFalse (areTypesAssignable (Long.TYPE, Character.TYPE)); assertFalse (areTypesAssignable (Long.TYPE, Short.TYPE)); assertFalse (areTypesAssignable (Long.TYPE, Integer.TYPE)); assertFalse (areTypesAssignable (Long.TYPE, Float.TYPE)); assertFalse (areTypesAssignable (Long.TYPE, Double.TYPE)); assertFalse (areTypesAssignable (Float.TYPE, Byte.TYPE)); assertFalse (areTypesAssignable (Float.TYPE, Character.TYPE)); assertFalse (areTypesAssignable (Float.TYPE, Short.TYPE)); assertFalse (areTypesAssignable (Float.TYPE, Integer.TYPE)); assertFalse (areTypesAssignable (Float.TYPE, Long.TYPE)); assertTrue (areTypesAssignable (Float.TYPE, Double.TYPE)); assertFalse (areTypesAssignable (Double.TYPE, Byte.TYPE)); assertFalse (areTypesAssignable (Double.TYPE, Character.TYPE)); assertFalse (areTypesAssignable (Double.TYPE, Short.TYPE)); assertFalse (areTypesAssignable (Double.TYPE, Integer.TYPE)); assertFalse (areTypesAssignable (Double.TYPE, Long.TYPE)); assertFalse (areTypesAssignable (Double.TYPE, Float.TYPE)); // Test whether boxed types are converted during upcast-check: assertTrue (areTypesAssignable (Byte.class, Long.TYPE)); assertTrue (areTypesAssignable (Short.class, Long.TYPE)); assertTrue (areTypesAssignable (Character.class, Long.TYPE)); assertTrue (areTypesAssignable (Integer.class, Long.TYPE)); assertTrue (areTypesAssignable (Float.class, Double.TYPE)); } @Test public void testAssignableSubclasses () { assertTrue (areTypesAssignable (Horse.class, Animal.class)); assertFalse (areTypesAssignable (Animal.class, Horse.class)); } @Test public void testAssignableArrays () { assertTrue (areTypesAssignable (String[].class, String[].class)); assertFalse (areTypesAssignable (String.class, String[].class)); assertFalse (areTypesAssignable (String[].class, String.class)); assertTrue (areTypesAssignable (String[].class, Object.class)); assertFalse (areTypesAssignable (Object.class, String[].class)); assertFalse (areTypesAssignable (Object[].class, String[].class)); assertTrue (areTypesAssignable (String[].class, Object[].class)); assertFalse (areTypesAssignable (String[][].class, String[].class)); assertFalse (areTypesAssignable (String[].class, String[][].class)); } @Test public void testAssignableGenericParameters () throws Exception { // Generic types without parameters are never assignable because this may cause class-cast exceptions // at runtime: assertFalse (areTypesAssignable (List.class, List.class)); assertFalse (areTypesAssignable (ArrayList.class, List.class)); assertFalse (areTypesAssignable (StringList.class, ArrayList.class)); assertFalse (areTypesAssignable (IntegerList.class, ArrayList.class)); assertFalse (areTypesAssignable (IntegerList.class, StringList.class)); assertFalse (areTypesAssignable (List[].class, List[].class)); assertFalse (areTypesAssignable (List[][].class, List[][].class)); // Generic types can be assigned to compatibel superclasses that are not generic: assertTrue (areTypesAssignable (List.class, Object.class)); assertTrue (areTypesAssignable (ParameterizedStringList.class, StringList.class)); final Method method = getClass ().getMethod ( "testGenericTypes", List.class, // List<String> List.class, // List<String> ArrayList.class, // ArrayList<String> ArrayList.class, // ArrayList<String> List.class, // List<Integer> ArrayList.class, // ArrayList<Integer> List[].class, // List<String>[] List[].class, // List<String>[] List[].class, // List<Integer>[] ArrayList[].class, // ArrayList<String>[] String.class); final Type[] types = method.getGenericParameterTypes (); assertTrue (types[0] instanceof ParameterizedType); assertTrue (types[10] instanceof Class<?>); assertTrue (areTypesAssignable (types[0], types[1])); // List<String> -> List<String> assertTrue (areTypesAssignable (types[2], types[3])); // ArrayList<String> -> ArrayList<String> assertTrue (areTypesAssignable (types[2], types[0])); // ArrayList<String> -> List<String> assertFalse (areTypesAssignable (types[0], types[2])); // List<String> -> ArrayList<String> assertFalse (areTypesAssignable (types[0], types[4])); // List<String> -> List<Integer> assertFalse (areTypesAssignable (StringList.class, types[4])); // StringList -> List<Integer> assertFalse (areTypesAssignable (types[4], types[0])); // List<Integer> -> List<String> assertFalse (areTypesAssignable (types[5], types[0])); // ArrayList<Integer> -> List<String> assertTrue (areTypesAssignable (types[6], types[7])); // List<String>[] -> List<String>[] assertTrue (areTypesAssignable (types[9], types[6])); // ArrayList<String>[] -> List<String>[] assertFalse (areTypesAssignable (types[8], types[6])); // List<Integer>[] -> List<String>[] assertFalse (areTypesAssignable (StringList[].class, types[8])); // StringList[] -> List<Integer>[] } @Test public void testAssignablePrimitivesToObject () throws Exception { assertTrue (areTypesAssignable (Byte.TYPE, Object.class)); assertTrue (areTypesAssignable (Character.TYPE, Object.class)); assertTrue (areTypesAssignable (Short.TYPE, Object.class)); assertTrue (areTypesAssignable (Integer.TYPE, Object.class)); assertTrue (areTypesAssignable (Long.TYPE, Object.class)); assertTrue (areTypesAssignable (Float.TYPE, Object.class)); assertTrue (areTypesAssignable (Double.TYPE, Object.class)); assertTrue (areTypesAssignable (Boolean.TYPE, Object.class)); } @Test public void testAssignableInterfaceToObject () throws Exception { assertTrue (Object.class.isAssignableFrom (TestInterface.class)); assertTrue (areTypesAssignable (TestInterface.class, Object.class)); } @Test public void testAssignableNullToObject () throws Exception { assertTrue (areTypesAssignable (NullReference.class, Animal.class)); } public void testBoxing (Integer i) { assertNotNull (i); } public void testUnboxing (int i) { assertNotNull (i); } public void testUpcasting (long l) { assertEquals (1, l); } public void testUpcastingBoxed (Long l) { assertEquals (1, l.longValue ()); } public void testGenericTypes ( final List<String> a, final List<String> b, final ArrayList<String> c, final ArrayList<String> d, final List<Integer> e, final ArrayList<Integer> f, final List<String>[] g, final List<String>[] h, final List<Integer>[] i, final ArrayList<String>[] j, final String k) { } public static class TestInterface { } public static class Animal { } public static class Horse extends Animal { } public static class StringList extends ArrayList<String> { private static final long serialVersionUID = 4715459014586031508L; } public static class ParameterizedStringList<T> extends StringList { private static final long serialVersionUID = 1734710538263249942L; } public static class IntegerList extends ArrayList<Integer> { private static final long serialVersionUID = -7203056260491531646L; } }