/* * 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.jdbi.v3.core.generic; import static java.util.Optional.empty; import static org.assertj.core.api.Assertions.assertThat; import java.lang.reflect.Type; import java.util.Optional; import org.jdbi.v3.core.generic.GenericTypes; import org.junit.Test; public class GenericTypesTest { class Foo<T> { } @SuppressWarnings("rawtypes") Foo raw() { return null; } @Test public void getErasedTypeOfRaw() throws Exception { assertThat(GenericTypes.getErasedType(methodReturnType("raw"))).isEqualTo(Foo.class); } @Test public void findGenericParameterOfRaw() throws Exception { assertThat(GenericTypes.findGenericParameter(methodReturnType("raw"), Foo.class)).isEqualTo(empty()); } Foo<String> generic() { return null; } @Test public void getErasedTypeOfGeneric() throws Exception { assertThat(GenericTypes.getErasedType(methodReturnType("generic"))).isEqualTo(Foo.class); } @Test public void findGenericParameterOfGeneric() throws Exception { assertThat(GenericTypes.findGenericParameter(methodReturnType("generic"), Foo.class)) .contains(String.class); } Foo<Foo<String>> nestedGeneric() { return null; } @Test public void getErasedTypeOfNestedGeneric() throws Exception { assertThat(GenericTypes.getErasedType(methodReturnType("nestedGeneric"))).isEqualTo(Foo.class); } @Test public void findGenericParameterOfNestedGeneric() throws Exception { assertThat(GenericTypes.findGenericParameter(methodReturnType("nestedGeneric"), Foo.class)) .contains(methodReturnType("generic")); } class Bar<T> extends Foo<T> { } Bar<Integer> subTypeGeneric() { return null; } @Test public void findGenericParameterOfSuperClass() throws Exception { assertThat(GenericTypes.findGenericParameter(methodReturnType("subTypeGeneric"), Foo.class)) .isEqualTo(Optional.of(Integer.class)); } class Baz<T> extends Bar<T> { } Baz<String> descendentTypeGeneric() { return null; } @Test public void findGenericParameterOfAncestorClass() throws Exception { assertThat(GenericTypes.findGenericParameter(methodReturnType("descendentTypeGeneric"), Foo.class)) .contains(String.class); } private Type methodReturnType(String methodName) throws NoSuchMethodException { return getClass().getDeclaredMethod(methodName).getGenericReturnType(); } @Test public void resolveType() throws Exception { abstract class A<T> { abstract T a(); } abstract class B extends A<String> { } assertThat(GenericTypes.resolveType(A.class.getDeclaredMethod("a").getGenericReturnType(), B.class)) .isEqualTo(String.class); } @Test public void resolveTypeUnrelatedContext() throws Exception { abstract class A1<T> { abstract T a(); } abstract class A2<T> { abstract T a(); } abstract class B extends A2<String> { } Type t = A1.class.getDeclaredMethod("a").getGenericReturnType(); assertThat(GenericTypes.resolveType(t, B.class)).isEqualTo(t); } }