/* * Copyright (C) 2011 Red Hat, Inc. and/or its affiliates. * * 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.jboss.errai.codegen.test.meta; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; import org.jboss.errai.codegen.meta.MetaClass; import org.jboss.errai.codegen.meta.MetaConstructor; import org.jboss.errai.codegen.meta.MetaField; import org.jboss.errai.codegen.meta.MetaMethod; import org.jboss.errai.codegen.meta.MetaParameterizedType; import org.jboss.errai.codegen.meta.MetaType; import org.jboss.errai.codegen.meta.MetaTypeVariable; import org.jboss.errai.codegen.meta.MetaWildcardType; import org.jboss.errai.codegen.test.model.ClassWithArrayGenerics; import org.jboss.errai.codegen.test.model.ClassWithGenericCollections; import org.jboss.errai.codegen.test.model.ClassWithGenericMethods; import org.jboss.errai.codegen.test.model.HasManyConstructors; import org.jboss.errai.codegen.test.model.ObjectWithNested; import org.jboss.errai.codegen.test.model.ParameterizedClass; import org.jboss.errai.codegen.test.model.TestInterface; import org.jboss.errai.codegen.test.model.tree.Child; import org.jboss.errai.codegen.test.model.tree.Grandparent; import org.jboss.errai.codegen.test.model.tree.GrandparentInterface; import org.jboss.errai.codegen.test.model.tree.GrandparentSuperInterface; import org.jboss.errai.codegen.test.model.tree.IsolatedInterface; import org.jboss.errai.codegen.test.model.tree.Parent; import org.jboss.errai.codegen.test.model.tree.ParentInterface; import org.jboss.errai.codegen.test.model.tree.ParentSuperInterface1; import org.jboss.errai.codegen.test.model.tree.ParentSuperInterface2; import org.jboss.errai.codegen.util.GenUtil; import org.junit.Test; import org.mvel2.util.NullType; import com.google.common.collect.Lists; import com.google.gwt.core.ext.typeinfo.NotFoundException; /** * Subclassable container for the test cases that guarantee an implementation of * MetaClass conforms to the general contract. Each implementation of MetaClass * should have a corresponding subclass of this test. This way, every * implementation of MetaClass will be subjected to the same set of tests. * * @author Christian Sadilek <csadilek@redhat.com> * @author Jonathan Fuerth <jfuerth@redhat.com> * @author Mike Brock <cbrock@redhat.com> */ public abstract class AbstractMetaClassTest { /** * Requests the MetaClass impl from the subclass and checks that it's the * expected subtype of MetaClass before returning it. * * @param javaClass * @return */ private MetaClass getMetaClass(final Class<?> javaClass) { final MetaClass impl = getMetaClassImpl(javaClass); assertEquals(getTypeOfMetaClassBeingTested(), impl.getClass()); return impl; } /** * Returns a MetaClass object--of the type being tested--that represents {@code javaClass}. * * @param javaClass The Java class type being requested. * @return an instance of the subtype of MetaClass that's being tested. */ protected abstract MetaClass getMetaClassImpl(Class<?> javaClass); /** * Returns the type of MetaClass that will be returned from {@link #getMetaClassImpl(Class)}. */ protected abstract Class<? extends MetaClass> getTypeOfMetaClassBeingTested(); @Test public void testInternalNameForOneDimensionalPrimitiveArray() { final String internalName = getMetaClass(char[].class).getInternalName(); assertEquals("Wrong internal name generated for one-dimensional primitive array", "[C", internalName); } @Test public void testInternalNameForOneDimensionalObjectArray() { final String internalName = getMetaClass(String[].class).getInternalName(); assertEquals("Wrong internal name generated for one-dimensional object array", "[Ljava/lang/String;", internalName); } @Test public void testInternalNameForMultiDimensionalPrimitiveArray() { final String internalName = getMetaClass(char[][].class).getInternalName(); assertEquals("Wrong internal name generated for multidimensional primitive array", "[[C", internalName); } @Test public void testInternalNameForMultiDimensionalObjectArray() { final String internalName = getMetaClass(String[][].class).getInternalName(); assertEquals("Wrong internal name generated for multidimensional object array", "[[Ljava/lang/String;", internalName); } @Test public void testObjectIsAssignableFromNull() throws Exception { // This test checks the valid case: // Object example = null; final MetaClass metaObject = getMetaClass(Object.class); final MetaClass metaNull = getMetaClass(NullType.class); assertTrue(metaObject.isAssignableFrom(metaNull)); } @Test public void testChildIsAssignableFromNull() throws Exception { // This test checks the valid case: // Child example = null; final MetaClass metaChild = getMetaClass(Child.class); final MetaClass metaNull = getMetaClass(NullType.class); assertTrue(metaChild.isAssignableFrom(metaNull)); } @Test public void testNullIsAssignableToChild() throws Exception { // This test checks the valid case: // Child example = null; final MetaClass metaChild = getMetaClass(Child.class); final MetaClass metaNull = getMetaClass(NullType.class); assertTrue(metaNull.isAssignableTo(metaChild)); } @Test public void testIsAssignableFromComparisonForNested() { final MetaClass interfaceClass = getMetaClass(TestInterface.class); final MetaClass metaHolderClass = getMetaClass(ObjectWithNested.class); // dig out the nested interface from the holder class and ensure it's what we were looking for final MetaClass nestedInterface = metaHolderClass.getDeclaredClasses()[0]; assertEquals("MyNestedInterface", nestedInterface.getName()); assertEquals(getTypeOfMetaClassBeingTested(), nestedInterface.getClass()); assertTrue("MyNestedInterface should be assignable from TestInterface", interfaceClass.isAssignableFrom(nestedInterface)); } @Test public void testChildIsAssignableFromChild() { // This test checks the valid case: // Child example = new Child(); final MetaClass metaChild = getMetaClass(Child.class); assertTrue(metaChild.isAssignableFrom(metaChild)); } @Test public void testChildIsAssignableToChild() { // This test checks the valid case: // Child example = new Child(); final MetaClass metaChild = getMetaClass(Child.class); assertTrue(metaChild.isAssignableTo(metaChild)); } @Test public void testParentIsAssignableFromChild() { // This test checks the valid case: // Parent example = new Child(); final MetaClass metaChild = getMetaClass(Child.class); final MetaClass metaParent = getMetaClass(Parent.class); assertTrue(metaParent.isAssignableFrom(metaChild)); } @Test public void testChildIsNotAssignableFromParent() { // This test checks the disallowed case: // Child child = new Parent(); final MetaClass metaChild = getMetaClass(Child.class); final MetaClass metaParent = getMetaClass(Parent.class); assertFalse(metaChild.isAssignableFrom(metaParent)); } @Test public void testGrandParentIsAssignableFromChild() { // This test checks the valid case: // Grandparent example = new Child(); final MetaClass metaChild = getMetaClass(Child.class); final MetaClass metaGrandparent = getMetaClass(Grandparent.class); assertTrue(metaGrandparent.isAssignableFrom(metaChild)); } @Test public void testChildIsNotAssignableFromGrandParent() { // This test checks the disallowed case: // Child child = new Grandparent(); final MetaClass metaChild = getMetaClass(Child.class); final MetaClass metaGrandparent = getMetaClass(Grandparent.class); assertFalse(metaChild.isAssignableFrom(metaGrandparent)); } /** * This is a regression test for ERRAI-238. */ @Test public void testUncleIsAssignableFromChild() { // This test checks the valid case: // ParentInterface example = new Child(); final MetaClass metaChild = getMetaClass(Child.class); final MetaClass metaUncle = getMetaClass(ParentInterface.class); assertTrue(metaUncle.isAssignableFrom(metaChild)); } @Test public void testChildIsNotAssignableFromUncle() { // This test checks the disallowed case: // Child child = new ParentInterface() {}; final MetaClass metaChild = getMetaClass(Child.class); final MetaClass metaUncle = getMetaClass(ParentInterface.class); assertFalse(metaChild.isAssignableFrom(metaUncle)); } /** * This is a regression test for ERRAI-238. */ @Test public void testUncleInLawIsAssignableFromChild() { // This test checks the valid case: // ParentSuperInterface1 example = new Child(); final MetaClass metaChild = getMetaClass(Child.class); final MetaClass metaUncleInLaw = getMetaClass(ParentSuperInterface1.class); assertTrue(metaUncleInLaw.isAssignableFrom(metaChild)); } @Test public void testChildIsNotAssignableFromUncleInLaw() { // This test checks the disallowed case: // Child child = new ParentSuperInterface1() {}; final MetaClass metaChild = getMetaClass(Child.class); final MetaClass metaUncleInLaw = getMetaClass(ParentSuperInterface1.class); assertFalse(metaChild.isAssignableFrom(metaUncleInLaw)); } /** * This is a regression test for ERRAI-238. */ @Test public void testUncleInLaw2IsAssignableFromChild() { // This test checks the valid case: // ParentSuperInterface2 example = new Child(); final MetaClass metaChild = getMetaClass(Child.class); final MetaClass metaUncleInLaw = getMetaClass(ParentSuperInterface2.class); assertTrue(metaUncleInLaw.isAssignableFrom(metaChild)); } @Test public void testChildIsNotAssignableFromUncleInLaw2() { // This test checks the disallowed case: // Child child = new ParentSuperInterface2() {}; final MetaClass metaChild = getMetaClass(Child.class); final MetaClass metaUncleInLaw = getMetaClass(ParentSuperInterface2.class); assertFalse(metaChild.isAssignableFrom(metaUncleInLaw)); } /** * This is a regression test for ERRAI-238. */ @Test public void testGreatUncleIsAssignableFromChild() { // This test checks the valid case: // GrandparentInterface example = new Child(); final MetaClass metaChild = getMetaClass(Child.class); final MetaClass metaGreatUncle = getMetaClass(GrandparentInterface.class); assertTrue(metaGreatUncle.isAssignableFrom(metaChild)); } @Test public void testChildIsNotAssignableFromGreatUncle() { // This test checks the disallowed case: // Child child = new GrandparentInterface() {}; final MetaClass metaChild = getMetaClass(Child.class); final MetaClass metaGreatUncle = getMetaClass(GrandparentInterface.class); assertFalse(metaChild.isAssignableFrom(metaGreatUncle)); } /** * This is a regression test for ERRAI-238. */ @Test public void testGreatUncleInLawIsAssignableFromChild() { // This test checks the valid case: //GrandparentSuperInterface example = new Child(); final MetaClass metaChild = getMetaClass(Child.class); final MetaClass metaGreatUncleInLaw = getMetaClass(GrandparentSuperInterface.class); assertTrue(metaGreatUncleInLaw.isAssignableFrom(metaChild)); } @Test public void testChildIsNotAssignableFromGreatUncleInLaw() { // This test checks the disallowed case: // Child child = new GrandparentSuperInterface() {}; final MetaClass metaChild = getMetaClass(Child.class); final MetaClass metaGreatUncleInLaw = getMetaClass(GrandparentSuperInterface.class); assertFalse(metaChild.isAssignableFrom(metaGreatUncleInLaw)); } @Test public void testObjectIsAssignableFromChild() { // This test checks the valid case: //Object example = new Child(); final MetaClass metaChild = getMetaClass(Child.class); final MetaClass metaObject = getMetaClass(Object.class); assertTrue(metaObject.isAssignableFrom(metaChild)); } @Test public void testChildIsNotAssignableFromObject() { // This test checks the disallowed case: // Child child = new Object(); final MetaClass metaChild = getMetaClass(Child.class); final MetaClass metaObject = getMetaClass(Object.class); assertFalse(metaChild.isAssignableFrom(metaObject)); } @Test public void testObjectIsAssignableFromIsolatedInterface() { // This test checks the valid case: // Object example = new IsolatedInterface() {}; final MetaClass metaInterface = getMetaClass(IsolatedInterface.class); final MetaClass metaObject = getMetaClass(Object.class); assertTrue(metaObject.isAssignableFrom(metaInterface)); } @Test public void testIsolatedInterfaceIsNotAssignableFromObject() { // This test checks the disallowed case: // IsolatedInterface ii = new Object(); final MetaClass metaInterface = getMetaClass(IsolatedInterface.class); final MetaClass metaObject = getMetaClass(Object.class); assertFalse(metaInterface.isAssignableFrom(metaObject)); } @Test public void testUncleIsAssignableToChild() { // This test checks the allowed case: // ParentInterface pi = new Child(); final MetaClass metaChild = getMetaClass(Child.class); final MetaClass metaUncle = getMetaClass(ParentInterface.class); assertTrue(metaChild.isAssignableTo(metaUncle)); } @Test public void testNoDuplicateMethodsInClassHierarchy() throws NotFoundException { final MetaClass child = getMetaClass(Child.class); final List<MetaMethod> foundMethods = new ArrayList<>(); for (final MetaMethod m : child.getMethods()) { if (m.getName().equals("interfaceMethodOverriddenMultipleTimes")) { foundMethods.add(m); } } assertEquals("Only one copy of the method should have been found", 1, foundMethods.size()); } @Test public void testSuperClass() throws Exception { final MetaClass child = getMetaClass(Child.class); final MetaClass parent = child.getSuperClass(); assertEquals(getMetaClass(Parent.class), parent); } @Test public void testNamingMethods() throws Exception { final MetaClass child = getMetaClass(Child.class); assertEquals(Child.class.getSimpleName(), child.getName()); assertEquals(Child.class.getName(), child.getFullyQualifiedName()); assertEquals(Child.class.getName(), child.getCanonicalName()); assertEquals("L" + Child.class.getName().replace('.', '/') + ";", child.getInternalName()); } @Test public void testAccessModifiersForPublicTopLevelClass() throws Exception { final MetaClass child = getMetaClass(Child.class); assertTrue(child.isPublic()); assertFalse(child.isProtected()); assertFalse(child.isPrivate()); assertTrue(child.isDefaultInstantiable()); } // TODO: add private, pkg private, protected methods to Child, Parent, Grandparent, and test getDeclaredMethods() // System.out.println("--gwt methods--"); // for (MetaMethod method : Child.class.getName().getDeclaredMethods()) { // System.out.println(method.toString()); // } // assertEquals(new HashSet<MetaMethod>(Arrays.asList(Child.class.getName().getDeclaredMethods())), // new HashSet<MetaMethod>(Arrays.asList(javaMC.getDeclaredMethods()))); @Test public void testGetInterfaces() throws Exception { final MetaClass grandparent = getMetaClass(Grandparent.class); assertEquals(1, grandparent.getInterfaces().length); assertEquals( Arrays.asList(getMetaClass(GrandparentInterface.class)), Arrays.asList(grandparent.getInterfaces())); } @Test public void testFieldWithStringTypeParam() throws Exception { final MetaClass metaClass = getMetaClass(ClassWithGenericCollections.class); final MetaField field = metaClass.getDeclaredField("hasStringParam"); assertNotNull(field); assertEquals("Collection", field.getType().getName()); assertEquals("java.util.Collection", field.getType().getFullyQualifiedName()); assertEquals("<java.lang.String>", field.getType().getParameterizedType().toString()); assertEquals("java.util.Collection<java.lang.String>", field.getType().getFullyQualifiedNameWithTypeParms()); assertEquals("java.util.Collection", field.getType().getErased().getFullyQualifiedNameWithTypeParms()); assertEquals( Arrays.asList(getMetaClass(String.class)), Arrays.asList(field.getType().getParameterizedType().getTypeParameters())); } @Test public void testFieldWithStringBoundedWildcardTypeParam() throws Exception { final MetaClass metaClass = getMetaClass(ClassWithGenericCollections.class); final MetaField field = metaClass.getDeclaredField("hasWildcardExtendsStringParam"); assertNotNull(field); assertEquals("Collection", field.getType().getName()); assertEquals("java.util.Collection", field.getType().getFullyQualifiedName()); assertEquals("<? extends java.lang.String>", field.getType().getParameterizedType().toString()); assertEquals("java.util.Collection<? extends java.lang.String>", field.getType().getFullyQualifiedNameWithTypeParms()); assertEquals("java.util.Collection", field.getType().getErased().getFullyQualifiedNameWithTypeParms()); assertEquals(1, field.getType().getParameterizedType().getTypeParameters().length); final MetaWildcardType typeParam = (MetaWildcardType) field.getType().getParameterizedType().getTypeParameters()[0]; assertEquals("Should have no lower bound", Arrays.asList(), Arrays.asList(typeParam.getLowerBounds())); assertEquals("Upper bound should be java.lang.String", Arrays.asList(getMetaClass(String.class)), Arrays.asList(typeParam.getUpperBounds())); } @Test public void testFieldWithUnboundedTypeVarParam() throws Exception { final MetaClass metaClass = getMetaClass(ClassWithGenericCollections.class); final MetaField field = metaClass.getDeclaredField("hasUnboundedTypeVarFromClass"); assertNotNull(field); assertEquals("Collection", field.getType().getName()); assertEquals("java.util.Collection", field.getType().getFullyQualifiedName()); assertEquals("java.util.Collection<T>", field.getType().getParameterizedType().getName()); assertEquals("java.util.Collection<T>", field.getType().getFullyQualifiedNameWithTypeParms()); assertEquals("java.util.Collection", field.getType().getErased().getFullyQualifiedNameWithTypeParms()); assertEquals(1, field.getType().getParameterizedType().getTypeParameters().length); final MetaTypeVariable typeVar = (MetaTypeVariable) field.getType().getParameterizedType().getTypeParameters()[0]; assertEquals("T", typeVar.getName()); assertEquals("Should have no upper bound", Arrays.asList(getMetaClass(Object.class)), Arrays.asList(typeVar.getBounds())); } @Test public void testFieldWithSingleUpperBoundedTypeVarParam() throws Exception { final MetaClass metaClass = getMetaClass(ClassWithGenericCollections.class); final MetaMethod field = metaClass.getDeclaredMethod("hasSingleBoundedTypeVarFromSelf", new Class[] {}); assertNotNull(field); final MetaTypeVariable returnType = (MetaTypeVariable) field.getGenericReturnType(); assertEquals("B", returnType.getName()); assertEquals("Should have a single upper bound", Arrays.asList(getMetaClass(Serializable.class)), Arrays.asList(returnType.getBounds())); } @Test public void testFieldWithTwoUpperBoundedTypeVarParam() throws Exception { final MetaClass metaClass = getMetaClass(ClassWithGenericCollections.class); final MetaMethod field = metaClass.getDeclaredMethod("hasDoubleBoundedTypeVarFromSelf", new Class[] {}); assertNotNull(field); final MetaTypeVariable returnType = (MetaTypeVariable) field.getGenericReturnType(); assertEquals("B", returnType.getName()); assertEquals("Should have two upper bounds", Arrays.asList(getMetaClass(Collection.class), getMetaClass(Serializable.class)), Arrays.asList(returnType.getBounds())); } @Test public void testEraseNonGenericType() throws Exception { final MetaClass child = getMetaClass(Child.class); assertSame(child, child.getErased()); } @Test public void testEraseParameterizedTopLevelType() throws Exception { final MetaClass parameterized = getMetaClass(ParameterizedClass.class); assertEquals("ParameterizedClass", parameterized.getName()); assertEquals("org.jboss.errai.codegen.test.model.ParameterizedClass", parameterized.getFullyQualifiedName()); assertNull(parameterized.getParameterizedType()); // I think this would be correct, but right now we get the raw type name //assertEquals("org.jboss.errai.codegen.test.model.ParameterizedClass<T>", parameterized.getFullyQualifiedNameWithTypeParms()); assertEquals("org.jboss.errai.codegen.test.model.ParameterizedClass", parameterized.getErased().getFullyQualifiedNameWithTypeParms()); } @Test public void testMethodObjectReturnType() { final MetaClass c = getMetaClass(ClassWithGenericMethods.class); final MetaMethod method = c.getMethod("methodReturningObject", new Class[] {}); assertEquals("java.lang.Object", method.getReturnType().getFullyQualifiedNameWithTypeParms()); assertEquals(getTypeOfMetaClassBeingTested(), method.getReturnType().getClass()); // the generic return type should be the same: plain old Object assertEquals(getMetaClass(Object.class), method.getGenericReturnType()); } @Test public void testMethodReturnTypeWithWildcardParameter() { final MetaClass c = getMetaClass(ClassWithGenericMethods.class); final MetaMethod method = c.getMethod("methodReturningUnboundedWildcardCollection", new Class[] {}); // TODO (ERRAI-459) decide whether it's correct to have the type param present or not // then adjust this assertion to strict equality rather than startsWith() assertTrue(method.getReturnType().getFullyQualifiedNameWithTypeParms().startsWith("java.util.Collection")); final MetaType genericReturnType = method.getGenericReturnType(); assertNotNull(genericReturnType); assertTrue("Got unexpected return type type " + genericReturnType.getClass(), genericReturnType instanceof MetaParameterizedType); final MetaParameterizedType mpReturnType = (MetaParameterizedType) genericReturnType; assertEquals(1, mpReturnType.getTypeParameters().length); // Sole type parameter should be <?> assertTrue(mpReturnType.getTypeParameters()[0] instanceof MetaWildcardType); final MetaWildcardType typeParam = (MetaWildcardType) mpReturnType.getTypeParameters()[0]; assertArrayEquals(new MetaType[] {}, typeParam.getLowerBounds()); assertArrayEquals(new MetaType[] { getMetaClass(Object.class) }, typeParam.getUpperBounds()); } @Test public void testMethodReturnTypeWithUpperBoundedWildcardParameter() { final MetaClass c = getMetaClass(ClassWithGenericMethods.class); final MetaMethod method = c.getMethod("methodReturningUpperBoundedWildcardCollection", new Class[] {}); // TODO (ERRAI-459) decide whether it's correct to have the type param present or not // then adjust this assertion to strict equality rather than startsWith() assertTrue(method.getReturnType().getFullyQualifiedNameWithTypeParms().startsWith("java.util.Collection")); final MetaType genericReturnType = method.getGenericReturnType(); assertNotNull(genericReturnType); assertTrue("Got unexpected return type type " + genericReturnType.getClass(), genericReturnType instanceof MetaParameterizedType); final MetaParameterizedType mpReturnType = (MetaParameterizedType) genericReturnType; assertEquals(1, mpReturnType.getTypeParameters().length); // Sole type parameter should be <? extends String> assertTrue(mpReturnType.getTypeParameters()[0] instanceof MetaWildcardType); final MetaWildcardType typeParam = (MetaWildcardType) mpReturnType.getTypeParameters()[0]; assertArrayEquals(new MetaType[] {}, typeParam.getLowerBounds()); assertArrayEquals(new MetaType[] { getMetaClass(String.class) }, typeParam.getUpperBounds()); } @Test public void testMethodReturnTypeWithLowerBoundedWildcardParameter() { final MetaClass c = getMetaClass(ClassWithGenericMethods.class); final MetaMethod method = c.getMethod("methodReturningLowerBoundedWildcardCollection", new Class[] {}); // TODO (ERRAI-459) decide whether it's correct to have the type param present or not // then adjust this assertion to strict equality rather than startsWith() assertTrue(method.getReturnType().getFullyQualifiedNameWithTypeParms().startsWith("java.util.Collection")); final MetaType genericReturnType = method.getGenericReturnType(); assertNotNull(genericReturnType); assertTrue("Got unexpected return type type " + genericReturnType.getClass(), genericReturnType instanceof MetaParameterizedType); final MetaParameterizedType mpReturnType = (MetaParameterizedType) genericReturnType; assertEquals(1, mpReturnType.getTypeParameters().length); // Sole type parameter should be <? extends String> assertTrue(mpReturnType.getTypeParameters()[0] instanceof MetaWildcardType); final MetaWildcardType typeParam = (MetaWildcardType) mpReturnType.getTypeParameters()[0]; assertArrayEquals(new MetaType[] { getMetaClass(String.class) }, typeParam.getLowerBounds()); assertArrayEquals(new MetaType[] { getMetaClass(Object.class)}, typeParam.getUpperBounds()); } @Test public void testGetMethods() { final MetaClass c = getMetaClass(Child.class); final MetaMethod[] methods = c.getMethods(); assertNotNull(methods); final List<String> methodSignatures = new ArrayList<>(); for(final MetaMethod m : methods) { methodSignatures.add(GenUtil.getMethodString(m)); } final List<String> expectedMethods = new ArrayList<>(); expectedMethods.add("protectedMethod([])"); expectedMethods.add("interfaceMethodOverriddenMultipleTimes([])"); expectedMethods.add("packagePrivateMethod([])"); expectedMethods.add("finalize([])"); expectedMethods.add("equals([java.lang.Object])"); expectedMethods.add("toString([])"); expectedMethods.add("notify([])"); expectedMethods.add("wait([])"); expectedMethods.add("clone([])"); expectedMethods.add("notifyAll([])"); expectedMethods.add("getClass([])"); expectedMethods.add("wait([long])"); expectedMethods.add("hashCode([])"); expectedMethods.add("wait([long, int])"); Collections.sort(expectedMethods); Collections.sort(methodSignatures); assertEquals(expectedMethods.toString(), methodSignatures.toString()); } @Test public void testGetFields() { final List<String> expectedFields = Lists.newLinkedList(); expectedFields.add(Child.class.getCanonicalName() + "." + "childPublic"); expectedFields.add(Parent.class.getCanonicalName() + "." + "parentPublic"); final ArrayList<String> actualFields = new ArrayList<>(); for (final MetaField field : getMetaClass(Child.class).getFields()) { actualFields.add(field.getDeclaringClass().getCanonicalName() + "." + field.getName()); } Collections.sort(expectedFields); Collections.sort(actualFields); assertEquals(expectedFields.toString(), actualFields.toString()); } @Test public void testGetDeclaredFields() { final List<String> expectedFields = Lists.newLinkedList(); expectedFields.add(Child.class.getCanonicalName() + "." + "childPrivate"); expectedFields.add(Child.class.getCanonicalName() + "." + "childPackage"); expectedFields.add(Child.class.getCanonicalName() + "." + "childProtected"); expectedFields.add(Child.class.getCanonicalName() + "." + "childPublic"); final ArrayList<String> actualFields = new ArrayList<>(); for (final MetaField field : getMetaClass(Child.class).getDeclaredFields()) { actualFields.add(field.getDeclaringClass().getCanonicalName() + "." + field.getName()); } Collections.sort(expectedFields); Collections.sort(actualFields); assertEquals(expectedFields.toString(), actualFields.toString()); } @Test public void testGetConstructors() throws Exception { final MetaClass mc = getMetaClass(HasManyConstructors.class); final MetaConstructor[] ctors = mc.getConstructors(); assertEquals("Expected only a single visible constructor to be returned.", 1, ctors.length); } @Test public void testGetConstructorOnlyFindsPublicConstructor() throws Exception { final MetaClass mc = getMetaClass(HasManyConstructors.class); assertNotNull(mc.getConstructor(new Class[0])); assertNull(mc.getConstructor(new Class[] {int.class})); assertNull(mc.getConstructor(new Class[] {String.class})); assertNull(mc.getConstructor(new Class[] {double.class})); } @Test public void testGetDeclaredConstructors() throws Exception { final MetaClass mc = getMetaClass(HasManyConstructors.class); final MetaConstructor[] ctors = mc.getDeclaredConstructors(); assertEquals("Not all constructors were returned.", 4, ctors.length); } @Test public void testGetDeclaredConstructorFindsAllConstructors() throws Exception { final MetaClass mc = getMetaClass(HasManyConstructors.class); assertNotNull(mc.getDeclaredConstructor(new Class[0])); assertNotNull(mc.getDeclaredConstructor(new Class[] {int.class})); assertNotNull(mc.getDeclaredConstructor(new Class[] {String.class})); assertNotNull(mc.getDeclaredConstructor(new Class[] {double.class})); } @Test public void testHashCodeErrorWithGenericHavingArrayUpperBound() throws Exception { final MetaClass mc = getMetaClass(ClassWithArrayGenerics.class).getField("field").getType(); // Precondition assertNotNull("Failed to find field with type under test.", mc); assertNotNull("Type should be parameterized", mc.getParameterizedType()); final MetaClass superClassWithProblematicBound = mc.getSuperClass(); try { superClassWithProblematicBound.hashCode(); } catch (final Throwable t) { throw new AssertionError("An error occurred.", t); } } }