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:
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user