DATACMNS-88 - Map value types are now resolve correctly for generic types extending Map.

Extracted base ParentTypeAwareTypeInformation class as base class for TypeInformations that need to consider the parent's type variable map.
This commit is contained in:
Oliver Gierke
2011-10-14 10:25:32 +02:00
parent 498f40b69f
commit b3c8cb5620
7 changed files with 197 additions and 88 deletions

View File

@@ -55,33 +55,40 @@ public class ClassTypeInformationUnitTests {
TypeInformation<?> content = wrapper.getProperty("content");
assertEquals(String.class, content.getType());
assertEquals(String.class, discoverer.getProperty("wrapped").getProperty("content").getType());
assertEquals(String.class, discoverer.getProperty("wrapped.content").getType());
assertEquals(String.class,
discoverer.getProperty("wrapped").getProperty("content").getType());
assertEquals(String.class, discoverer.getProperty("wrapped.content")
.getType());
}
@Test
@SuppressWarnings("rawtypes")
public void discoversBoundType() {
TypeInformation<GenericTypeWithBound> information = ClassTypeInformation.from(GenericTypeWithBound.class);
TypeInformation<GenericTypeWithBound> information = ClassTypeInformation.from(
GenericTypeWithBound.class);
assertEquals(Person.class, information.getProperty("person").getType());
}
@Test
public void discoversBoundTypeForSpecialization() {
TypeInformation<SpecialGenericTypeWithBound> information = ClassTypeInformation
.from(SpecialGenericTypeWithBound.class);
assertEquals(SpecialPerson.class, information.getProperty("person").getType());
TypeInformation<SpecialGenericTypeWithBound> information = ClassTypeInformation.from(
SpecialGenericTypeWithBound.class);
assertEquals(SpecialPerson.class, information.getProperty("person")
.getType());
}
@Test
@SuppressWarnings("rawtypes")
public void discoversBoundTypeForNested() {
TypeInformation<AnotherGenericType> information = ClassTypeInformation.from(AnotherGenericType.class);
assertEquals(GenericTypeWithBound.class, information.getProperty("nested").getType());
assertEquals(Person.class, information.getProperty("nested.person").getType());
TypeInformation<AnotherGenericType> information = ClassTypeInformation.from(
AnotherGenericType.class);
assertEquals(GenericTypeWithBound.class, information.getProperty("nested")
.getType());
assertEquals(Person.class, information.getProperty("nested.person")
.getType());
}
@Test
@@ -118,25 +125,25 @@ public class ClassTypeInformationUnitTests {
assertEquals(Map.class, map.getType());
assertEquals(Calendar.class, map.getMapValueType().getType());
}
@Test
public void typeInfoDoesNotEqualForGenericTypesWithDifferentParent() {
TypeInformation<ConcreteWrapper> first = ClassTypeInformation.from(ConcreteWrapper.class);
TypeInformation<AnotherConcreteWrapper> second = ClassTypeInformation.from(AnotherConcreteWrapper.class);
assertFalse(first.getProperty("wrapped").equals(second.getProperty("wrapped")));
}
@Test
public void handlesPropertyFieldMismatchCorrectly() {
TypeInformation<PropertyGetter> from = ClassTypeInformation.from(PropertyGetter.class);
TypeInformation<?> property = from.getProperty("_name");
assertThat(property, is(notNullValue()));
assertThat(property.getType(), is(typeCompatibleWith(String.class)));
property = from.getProperty("name");
assertThat(property, is(notNullValue()));
assertThat(property.getType(), is(typeCompatibleWith(byte[].class)));
@@ -203,7 +210,8 @@ public class ClassTypeInformationUnitTests {
S nested;
}
static class SpecialGenericTypeWithBound extends GenericTypeWithBound<SpecialPerson> {
static class SpecialGenericTypeWithBound extends
GenericTypeWithBound<SpecialPerson> {
}
@@ -231,14 +239,14 @@ public class ClassTypeInformationUnitTests {
static class ConcreteWrapper extends GenericWrapper<String> {
}
static class AnotherConcreteWrapper extends GenericWrapper<Long> {
}
static class PropertyGetter {
private String _name;
public byte[] getName() {
return _name.getBytes();
}

View File

@@ -15,25 +15,36 @@
*/
package org.springframework.data.util;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import java.lang.reflect.ParameterizedType;
import java.util.HashMap;
import java.util.Locale;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
/**
* Unit tests for {@link ParameterizedTypeInformation}.
*
* @author Oliver Gierke
*/
@RunWith(MockitoJUnitRunner.class)
public class ParameterizedTypeUnitTests {
@Mock ParameterizedType one, two;
@Test
public void considersTypeInformationsWithDifferingParentsNotEqual() {
TypeDiscoverer<String> stringParent = new TypeDiscoverer<String>(String.class, null);
TypeDiscoverer<Object> objectParent = new TypeDiscoverer<Object>(Object.class, null);
ParameterizedTypeInformation<Object> first = new ParameterizedTypeInformation<Object>(Object.class, stringParent);
ParameterizedTypeInformation<Object> second = new ParameterizedTypeInformation<Object>(Object.class, objectParent);
ParameterizedTypeInformation<Object> first = new ParameterizedTypeInformation<Object>(one, stringParent);
ParameterizedTypeInformation<Object> second = new ParameterizedTypeInformation<Object>(one, objectParent);
assertFalse(first.equals(second));
}
@@ -43,9 +54,40 @@ public class ParameterizedTypeUnitTests {
TypeDiscoverer<String> stringParent = new TypeDiscoverer<String>(String.class, null);
ParameterizedTypeInformation<Object> first = new ParameterizedTypeInformation<Object>(Object.class, stringParent);
ParameterizedTypeInformation<Object> second = new ParameterizedTypeInformation<Object>(Object.class, stringParent);
ParameterizedTypeInformation<Object> first = new ParameterizedTypeInformation<Object>(one, stringParent);
ParameterizedTypeInformation<Object> second = new ParameterizedTypeInformation<Object>(one, stringParent);
assertTrue(first.equals(second));
}
/**
* @see DATACMNS-88
*/
@Test
public void resolvesMapValueTypeCorrectly() {
TypeInformation<Foo> type = ClassTypeInformation.from(Foo.class);
TypeInformation<?> propertyType = type.getProperty("param");
assertThat(propertyType.getProperty("value").getType(), is(typeCompatibleWith(String.class)));
assertThat(propertyType.getMapValueType().getType(), is(typeCompatibleWith(String.class)));
propertyType = type.getProperty("param2");
assertThat(propertyType.getProperty("value").getType(), is(typeCompatibleWith(String.class)));
assertThat(propertyType.getMapValueType().getType(), is(typeCompatibleWith(Locale.class)));
}
@SuppressWarnings("serial")
class Localized<S> extends HashMap<Locale, S> {
S value;
}
@SuppressWarnings("serial")
class Localized2<S> extends HashMap<S, Locale> {
S value;
}
class Foo {
Localized<String> param;
Localized2<String> param2;
}
}