Package com.alibaba.citrus.generictype

Source Code of com.alibaba.citrus.generictype.MethodTests$TestClass2

/*
* Copyright (c) 2002-2012 Alibaba Group Holding Limited.
* All rights reserved.
*
* 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 com.alibaba.citrus.generictype;

import static com.alibaba.citrus.generictype.TypeInfo.*;
import static java.lang.reflect.Modifier.*;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.GenericDeclaration;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

import com.alibaba.citrus.test.runner.Prototyped;
import com.alibaba.citrus.test.runner.Prototyped.Prototypes;
import com.alibaba.citrus.test.runner.Prototyped.TestData;
import com.alibaba.citrus.test.runner.Prototyped.TestName;
import com.alibaba.citrus.util.ClassUtil;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

/**
* 测试{@link MethodInfo}
*
* @author Michael Zhou
*/
@RunWith(Prototyped.class)
public class MethodTests extends BaseTypeTests implements Cloneable {
    private transient MethodInfo method;
    private transient boolean    isConstructor; // 是否为构造函数?
    private transient String     name; // 方法名,如果是构造函数,则为<init>
    private           Class<?>   ownerType; // 方法所在类的子类
    private           Class<?>   declaringType; // 方法所在类
    private           String     methodName; // 方法名,如果是构造函数,则为null
    private           Class<?>[] paramTypes; // 参数类型表
    private           boolean    isGeneric; // 是否包含类型参数?
    private           String     typeParams; // 类型参数toString
    private           String     signature; // 方法签名
    private           int        modifiers; // 限定符
    private           String     returnType; // 返回类型
    private           String     exceptionTypes; // 异常类型
    private           String     effectiveExceptionTypes; // 有效异常类型
    private           String     toString; // toString结果
    private           String     resolved; // resolve的结果
    private           boolean    resolveChanged; // 如果为false,代表resolve返回this
    private           String     getMethodFromClassTypeInfo; // ClassTypeInfo.getMethod的结果

    @Before
    public void init() throws Exception {
        this.declaringType = declaringType == null ? ownerType : declaringType;
        this.paramTypes = paramTypes == null ? new Class<?>[0] : paramTypes;
        this.method = (MethodInfo) factory.getGenericDeclaration(getMethodOrConstructor(ownerType, methodName,
                                                                                        paramTypes));
        this.isConstructor = methodName == null;
        this.name = isConstructor ? "<init>" : methodName;
        this.effectiveExceptionTypes = effectiveExceptionTypes == null ? exceptionTypes : effectiveExceptionTypes;
        this.resolved = resolved == null ? toString : resolved;
        this.getMethodFromClassTypeInfo = getMethodFromClassTypeInfo == null ? resolved : getMethodFromClassTypeInfo;
    }

    @TestName
    public String testName() throws Exception {
        GenericDeclaration decl = getMethodOrConstructor(ownerType, methodName, paramTypes);

        if (decl instanceof Method) {
            return String.format("%s.%s", ClassUtil.getSimpleClassName(ownerType), ((Method) decl).getName());
        } else {
            return String.format("%s[%d params]", ClassUtil.getSimpleClassName(ownerType),
                                 ((Constructor<?>) decl).getParameterTypes().length);
        }
    }

    @SuppressWarnings("unused")
    private static class TestClass<X extends Number> {
        // constructors
        public TestClass(int i) {
        }

        protected TestClass(int i, int j) throws FileNotFoundException, IOException, RuntimeException {
        }

        TestClass(int i, int j, int k) throws IOException, FileNotFoundException, RuntimeException {
        }

        private TestClass(int i, int j, int k, int l) throws Exception {
        }

        public <A, B extends Number> TestClass(A i, List<B> j, int k, int l, int m) {
        }

        // methods
        public void a(int i) {
        }

        protected String b(String i, int j) throws FileNotFoundException, IOException, RuntimeException {
            return null;
        }

        List<Integer> c(String i, int j, int k) throws IOException, FileNotFoundException, RuntimeException {
            return null;
        }

        private int d(String i, int j, int k, int l) throws Exception {
            return 0;
        }

        public final static <A, B extends Number> Map<A, ? extends B> e(A a, List<B> b) {
            return null;
        }

        public List<X> f() {
            return null;
        }
    }

    @SuppressWarnings("unused")
    private static class TestClass2<Y extends Number> extends TestClass<Y> {
        public <A, B extends Number> TestClass2(A i, List<B> j, int k, int l, int m) {
            super(i, j, k, l, m);
        }

        public void g(List<Y> list) {
        }
    }

    @Prototypes
    public static TestData<MethodTests> data() {
        TestData<MethodTests> data = TestData.getInstance(MethodTests.class);
        MethodTests prototype;

        // =========================
        // constructor
        // -----------------
        prototype = data.newPrototype();
        prototype.ownerType = TestClass.class;
        prototype.methodName = null;
        prototype.paramTypes = new Class<?>[] { int.class };
        prototype.isGeneric = false;
        prototype.typeParams = "[]";
        prototype.signature = "<init>(I)V";
        prototype.modifiers = PUBLIC;
        prototype.returnType = "void";
        prototype.exceptionTypes = "[]";
        prototype.effectiveExceptionTypes = "[]";
        prototype.toString = "public MethodTests$TestClass(int)";
        prototype.resolved = null;

        // -----------------
        prototype = data.newPrototype();
        prototype.ownerType = TestClass.class;
        prototype.methodName = null;
        prototype.paramTypes = new Class<?>[] { int.class, int.class };
        prototype.isGeneric = false;
        prototype.typeParams = "[]";
        prototype.signature = "<init>(II)V";
        prototype.modifiers = PROTECTED;
        prototype.returnType = "void";
        prototype.exceptionTypes = "[FileNotFoundException, IOException, RuntimeException]";
        prototype.effectiveExceptionTypes = "[IOException]";
        prototype.toString = "protected MethodTests$TestClass(int, int) throws IOException";
        prototype.resolved = null;

        // -----------------
        prototype = data.newPrototype();
        prototype.ownerType = TestClass.class;
        prototype.methodName = null;
        prototype.paramTypes = new Class<?>[] { int.class, int.class, int.class };
        prototype.isGeneric = false;
        prototype.typeParams = "[]";
        prototype.signature = "<init>(III)V";
        prototype.modifiers = 0;
        prototype.returnType = "void";
        prototype.exceptionTypes = "[IOException, FileNotFoundException, RuntimeException]";
        prototype.effectiveExceptionTypes = "[IOException]";
        prototype.toString = "MethodTests$TestClass(int, int, int) throws IOException";
        prototype.resolved = null;

        // -----------------
        prototype = data.newPrototype();
        prototype.ownerType = TestClass.class;
        prototype.methodName = null;
        prototype.paramTypes = new Class<?>[] { int.class, int.class, int.class, int.class };
        prototype.isGeneric = false;
        prototype.typeParams = "[]";
        prototype.signature = "<init>(IIII)V";
        prototype.modifiers = PRIVATE;
        prototype.returnType = "void";
        prototype.exceptionTypes = "[Exception]";
        prototype.effectiveExceptionTypes = "[Exception]";
        prototype.toString = "private MethodTests$TestClass(int, int, int, int) throws Exception";
        prototype.resolved = null;

        // -----------------
        prototype = data.newPrototype();
        prototype.ownerType = TestClass.class;
        prototype.methodName = null;
        prototype.paramTypes = new Class<?>[] { Object.class, List.class, int.class, int.class, int.class };
        prototype.isGeneric = true;
        prototype.typeParams = "[A, B]";
        prototype.signature = "<init>(Ljava/lang/Object;Ljava/util/List;III)V";
        prototype.modifiers = PUBLIC;
        prototype.returnType = "void";
        prototype.exceptionTypes = "[]";
        prototype.effectiveExceptionTypes = "[]";
        prototype.toString = "public <A, B> MethodTests$TestClass(A, List<E=B>, int, int, int)";
        prototype.resolved = "public <A, B> MethodTests$TestClass(Object, List<E=Number>, int, int, int)";
        prototype.resolveChanged = true;
        prototype.getMethodFromClassTypeInfo = "public <A, B> MethodTests$TestClass(A, List<E=B>, int, int, int)";

        // =========================
        // method
        // -----------------
        prototype = data.newPrototype();
        prototype.ownerType = TestClass.class;
        prototype.methodName = "a";
        prototype.paramTypes = new Class<?>[] { int.class };
        prototype.isGeneric = false;
        prototype.typeParams = "[]";
        prototype.signature = "a(I)V";
        prototype.modifiers = PUBLIC;
        prototype.returnType = "void";
        prototype.exceptionTypes = "[]";
        prototype.effectiveExceptionTypes = "[]";
        prototype.toString = "public void MethodTests$TestClass.a(int)";
        prototype.resolved = null;

        // -----------------
        prototype = data.newPrototype();
        prototype.ownerType = TestClass.class;
        prototype.methodName = "b";
        prototype.paramTypes = new Class<?>[] { String.class, int.class };
        prototype.isGeneric = false;
        prototype.typeParams = "[]";
        prototype.signature = "b(Ljava/lang/String;I)Ljava/lang/String;";
        prototype.modifiers = PROTECTED;
        prototype.returnType = "String";
        prototype.exceptionTypes = "[FileNotFoundException, IOException, RuntimeException]";
        prototype.effectiveExceptionTypes = "[IOException]";
        prototype.toString = "protected String MethodTests$TestClass.b(String, int) throws IOException";
        prototype.resolved = null;

        // -----------------
        prototype = data.newPrototype();
        prototype.ownerType = TestClass.class;
        prototype.methodName = "c";
        prototype.paramTypes = new Class<?>[] { String.class, int.class, int.class };
        prototype.isGeneric = false;
        prototype.typeParams = "[]";
        prototype.signature = "c(Ljava/lang/String;II)Ljava/util/List;";
        prototype.modifiers = 0;
        prototype.returnType = "List<E=Integer>";
        prototype.exceptionTypes = "[IOException, FileNotFoundException, RuntimeException]";
        prototype.effectiveExceptionTypes = "[IOException]";
        prototype.toString = "List<E=Integer> MethodTests$TestClass.c(String, int, int) throws IOException";
        prototype.resolved = null;

        // -----------------
        prototype = data.newPrototype();
        prototype.ownerType = TestClass.class;
        prototype.methodName = "d";
        prototype.paramTypes = new Class<?>[] { String.class, int.class, int.class, int.class };
        prototype.isGeneric = false;
        prototype.typeParams = "[]";
        prototype.signature = "d(Ljava/lang/String;III)I";
        prototype.modifiers = PRIVATE;
        prototype.returnType = "int";
        prototype.exceptionTypes = "[Exception]";
        prototype.effectiveExceptionTypes = "[Exception]";
        prototype.toString = "private int MethodTests$TestClass.d(String, int, int, int) throws Exception";
        prototype.resolved = null;

        // -----------------
        prototype = data.newPrototype();
        prototype.ownerType = TestClass.class;
        prototype.methodName = "e";
        prototype.paramTypes = new Class<?>[] { Object.class, List.class };
        prototype.isGeneric = true;
        prototype.typeParams = "[A, B]";
        prototype.signature = "e(Ljava/lang/Object;Ljava/util/List;)Ljava/util/Map;";
        prototype.modifiers = PUBLIC | STATIC;
        prototype.returnType = "Map<K=A, V=? extends B>";
        prototype.exceptionTypes = "[]";
        prototype.effectiveExceptionTypes = "[]";
        prototype.toString = "public static <A, B> Map<K=A, V=? extends B> MethodTests$TestClass.e(A, List<E=B>)";
        prototype.resolved = "public static <A, B> Map<K=Object, V=Number> MethodTests$TestClass.e(Object, List<E=Number>)";
        prototype.resolveChanged = true;
        prototype.getMethodFromClassTypeInfo = "public static <A, B> Map<K=A, V=B> MethodTests$TestClass.e(A, List<E=B>)";

        // -----------------
        prototype = data.newPrototype();
        prototype.ownerType = TestClass2.class;
        prototype.declaringType = TestClass.class;
        prototype.methodName = "f";
        prototype.paramTypes = new Class<?>[] { };
        prototype.isGeneric = false;
        prototype.typeParams = "[]";
        prototype.signature = "f()Ljava/util/List;";
        prototype.modifiers = PUBLIC;
        prototype.returnType = "List<E=X>";
        prototype.exceptionTypes = "[]";
        prototype.effectiveExceptionTypes = "[]";
        prototype.toString = "public List<E=X> MethodTests$TestClass.f()";
        prototype.resolved = "public List<E=Number> MethodTests$TestClass.f()";
        prototype.resolveChanged = true;
        prototype.getMethodFromClassTypeInfo = "public List<E=Y> MethodTests$TestClass.f()";

        // -----------------
        prototype = data.newPrototype();
        prototype.ownerType = TestClass2.class;
        prototype.declaringType = TestClass2.class;
        prototype.methodName = "g";
        prototype.paramTypes = new Class<?>[] { List.class };
        prototype.isGeneric = false;
        prototype.typeParams = "[]";
        prototype.signature = "g(Ljava/util/List;)V";
        prototype.modifiers = PUBLIC;
        prototype.returnType = "void";
        prototype.exceptionTypes = "[]";
        prototype.effectiveExceptionTypes = "[]";
        prototype.toString = "public void MethodTests$TestClass2.g(List<E=Y>)";
        prototype.resolved = "public void MethodTests$TestClass2.g(List<E=Number>)";
        prototype.resolveChanged = true;
        prototype.getMethodFromClassTypeInfo = "public void MethodTests$TestClass2.g(List<E=Y>)";

        return data;
    }

    @Test
    public void isGeneric() {
        assertEquals(isGeneric, method.isGeneric());
    }

    @Test
    public void getTypeParameters() {
        assertEquals(typeParams, method.getTypeParameters().toString());
    }

    @Test
    public void isConstructor() {
        assertEquals(isConstructor, method.isConstructor());
    }

    @Test
    public void getConstructorOrMethod() {
        if (isConstructor) {
            assertNotNull(method.getConstructor());
            assertNull(method.getMethod());
        } else {
            assertNull(method.getConstructor());
            assertNotNull(method.getMethod());
        }
    }

    @Test
    public void getDeclaringType() {
        assertSame(factory.getType(declaringType), method.getDeclaringType());
    }

    @Test
    public void getSignature() {
        assertEquals(signature, method.getSignature().toString());
    }

    @Test
    public void getModifiers() {
        assertEquals(modifiers, method.getModifiers());
    }

    @Test
    public void getReturnType() {
        assertEquals(returnType, method.getReturnType().toString());
    }

    @Test
    public void getName() {
        assertEquals(name, method.getName());
    }

    @Test
    public void getParamTypes() {
        List<TypeInfo> types = method.getParameterTypes();

        assertEquals(paramTypes.length, types.size());

        int i = 0;
        for (TypeInfo type : types) {
            assertEquals(paramTypes[i++], type.getRawType());
        }
    }

    @Test
    public void getExceptionTypes() {
        assertEquals(exceptionTypes, method.getExceptionTypes().toString());
    }

    @Test
    public void getEffectiveExceptionTypes() {
        assertEquals(effectiveExceptionTypes, method.getEffectiveExceptionTypes().toString());
    }

    @Test
    public void getActualTypeParameters() {
        List<TypeVariableInfo> vars = method.getTypeParameters();
        List<TypeInfo> actualArgs = method.getActualTypeArguments();

        for (int i = 0; i < vars.size(); i++) {
            assertEquals(vars.get(i).getBaseType(), actualArgs.get(i));
            assertEquals(vars.get(i).getBaseType(), vars.get(i).resolve(method));
            assertEquals(vars.get(i).getBaseType(), vars.get(i).resolve(factory.getGenericDeclaration(List.class)));
        }
    }

    @Test
    public void resolve() {
        assertEquals(resolved, method.resolve(null).toString());
        assertEquals(resolved, method.resolve(null, true).toString());
        assertEquals(resolveChanged, method != method.resolve(null));
    }

    @Test
    public void getMethod_from_ClassTypeInfo() {
        ClassTypeInfo ownerType = TypeInfo.factory.getClassType(this.ownerType);

        if (isConstructor) {
            assertEquals(getMethodFromClassTypeInfo, ownerType.getConstructor(paramTypes).toString());
        } else {
            assertEquals(getMethodFromClassTypeInfo, ownerType.getMethod(methodName, paramTypes).toString());
        }
    }

    @Test
    public void equalsHashCode() throws Exception {
        MethodInfo newMethod = (MethodInfo) factory.getGenericDeclaration(getMethodOrConstructor(ownerType, methodName,
                                                                                                 paramTypes));

        assertEquals(newMethod, method);
        assertNotSame(newMethod, method);
        assertEquals(newMethod.hashCode(), method.hashCode());

        newMethod = (MethodInfo) factory.getGenericDeclaration(getMethodOrConstructor(String.class, null,
                                                                                      new Class<?>[] { String.class }));

        assertThat(method, not(equalTo(newMethod)));
        assertNotSame(newMethod, method);
        assertThat(method.hashCode(), not(equalTo(newMethod.hashCode())));
    }

    @Test
    public void toString_() {
        assertEquals(toString, method.toString());
    }
}
TOP

Related Classes of com.alibaba.citrus.generictype.MethodTests$TestClass2

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.