diff options
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/sdk')
2 files changed, 348 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/sdk/AndroidJarLoaderTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/sdk/AndroidJarLoaderTest.java new file mode 100644 index 000000000..5f7de429b --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/sdk/AndroidJarLoaderTest.java @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php + * + * 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.android.ide.eclipse.adt.internal.sdk; + +import com.android.ide.eclipse.adt.internal.sdk.AndroidJarLoader; +import com.android.ide.eclipse.adt.internal.sdk.IAndroidClassLoader.IClassDescriptor; +import com.android.ide.eclipse.tests.AdtTestData; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; + +import junit.framework.TestCase; + +/** + * Unit Test for {@link AndroidJarLoader}. + * + * Uses the classes jar.example.Class1/Class2 stored in tests/data/jar_example.jar. + */ +public class AndroidJarLoaderTest extends TestCase { + + private AndroidJarLoader mFrameworkClassLoader; + + /** Creates an instance of {@link AndroidJarLoader} on our test data JAR */ + @Override + public void setUp() throws Exception { + String jarfilePath = AdtTestData.getInstance().getTestFilePath( + "com/android/ide/eclipse/testdata/jar_example.jar"); //$NON-NLS-1$ + mFrameworkClassLoader = new AndroidJarLoader(jarfilePath); + } + + @Override + public void tearDown() throws Exception { + mFrameworkClassLoader = null; + System.gc(); + } + + /** Preloads classes. They should load just fine. */ + public final void testPreLoadClasses() throws Exception { + mFrameworkClassLoader.preLoadClasses("jar.example.", null, null); //$NON-NLS-1$ + HashMap<String, Class<?>> map = getPrivateClassCache(); + assertEquals(0, map.size()); + HashMap<String,byte[]> data = getPrivateEntryCache(); + assertTrue(data.containsKey("jar.example.Class1")); //$NON-NLS-1$ + assertTrue(data.containsKey("jar.example.Class2")); //$NON-NLS-1$ + assertTrue(data.containsKey("jar.example.Class1$InnerStaticClass1")); //$NON-NLS-1$ + assertTrue(data.containsKey("jar.example.Class1$InnerClass2")); //$NON-NLS-1$ + assertEquals(4, data.size()); + } + + /** Preloads a class not in the JAR. Preloading does nothing in this case. */ + public final void testPreLoadClasses_classNotFound() throws Exception { + mFrameworkClassLoader.preLoadClasses("not.a.package.", null, null); //$NON-NLS-1$ + HashMap<String, Class<?>> map = getPrivateClassCache(); + assertEquals(0, map.size()); + HashMap<String,byte[]> data = getPrivateEntryCache(); + assertEquals(0, data.size()); + } + + /** Finds a class we just preloaded. It should work. */ + public final void testFindClass_classFound() throws Exception { + Class<?> c = _findClass(mFrameworkClassLoader, "jar.example.Class2"); //$NON-NLS-1$ + assertEquals("jar.example.Class2", c.getName()); //$NON-NLS-1$ + HashMap<String, Class<?>> map = getPrivateClassCache(); + assertTrue(map.containsKey("jar.example.Class1")); //$NON-NLS-1$ + assertTrue(map.containsKey("jar.example.Class2")); //$NON-NLS-1$ + assertEquals(2, map.size()); + } + + /** call the protected method findClass */ + private Class<?> _findClass(AndroidJarLoader jarLoader, String name) throws Exception { + Method findClassMethod = AndroidJarLoader.class.getDeclaredMethod( + "findClass", String.class); //$NON-NLS-1$ + findClassMethod.setAccessible(true); + try { + return (Class<?>)findClassMethod.invoke(jarLoader, name); + } + catch (InvocationTargetException e) { + throw (Exception)e.getCause(); + } + } + + /** Trying to find a class that we fail to preload should throw a CNFE. */ + public final void testFindClass_classNotFound() throws Exception { + try { + // Will throw ClassNotFoundException + _findClass(mFrameworkClassLoader, "not.a.valid.ClassName"); //$NON-NLS-1$ + } catch (ClassNotFoundException e) { + // check the message in the CNFE + assertEquals("not.a.valid.ClassName", e.getMessage()); //$NON-NLS-1$ + return; + } + // Exception not thrown - this is a failure + fail("Expected ClassNotFoundException not thrown"); + } + + public final void testFindClassesDerivingFrom() throws Exception { + HashMap<String, ArrayList<IClassDescriptor>> found = + mFrameworkClassLoader.findClassesDerivingFrom("jar.example.", new String[] { //$NON-NLS-1$ + "jar.example.Class1", //$NON-NLS-1$ + "jar.example.Class2" }); //$NON-NLS-1$ + + assertTrue(found.containsKey("jar.example.Class1")); //$NON-NLS-1$ + assertTrue(found.containsKey("jar.example.Class2")); //$NON-NLS-1$ + assertEquals(2, found.size()); + // Only Class2 derives from Class1.. + // Class1 and Class1$InnerStaticClass1 derive from Object and are thus ignored. + // Class1$InnerClass2 should never be seen either. + assertEquals("jar.example.Class2", //$NON-NLS-1$ + found.get("jar.example.Class1").get(0).getFullClassName()); //$NON-NLS-1$ + assertEquals(1, found.get("jar.example.Class1").size()); //$NON-NLS-1$ + assertEquals(0, found.get("jar.example.Class2").size()); //$NON-NLS-1$ + } + + // --- Utilities --- + + /** + * Retrieves the private mFrameworkClassLoader.mClassCache field using reflection. + * + * @throws NoSuchFieldException + * @throws SecurityException + * @throws IllegalAccessException + * @throws IllegalArgumentException + */ + @SuppressWarnings("unchecked") + private HashMap<String, Class<?> > getPrivateClassCache() + throws SecurityException, NoSuchFieldException, + IllegalArgumentException, IllegalAccessException { + Field field = AndroidJarLoader.class.getDeclaredField("mClassCache"); //$NON-NLS-1$ + field.setAccessible(true); + return (HashMap<String, Class<?>>) field.get(mFrameworkClassLoader); + } + + /** + * Retrieves the private mFrameworkClassLoader.mEntryCache field using reflection. + * + * @throws NoSuchFieldException + * @throws SecurityException + * @throws IllegalAccessException + * @throws IllegalArgumentException + */ + @SuppressWarnings("unchecked") + private HashMap<String,byte[]> getPrivateEntryCache() + throws SecurityException, NoSuchFieldException, + IllegalArgumentException, IllegalAccessException { + Field field = AndroidJarLoader.class.getDeclaredField("mEntryCache"); //$NON-NLS-1$ + field.setAccessible(true); + return (HashMap<String, byte[]>) field.get(mFrameworkClassLoader); + } +} diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/sdk/LayoutParamsParserTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/sdk/LayoutParamsParserTest.java new file mode 100644 index 000000000..c89dd0649 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/sdk/LayoutParamsParserTest.java @@ -0,0 +1,182 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php + * + * 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.android.ide.eclipse.adt.internal.sdk; + +import com.android.ide.common.resources.platform.AttrsXmlParser; +import com.android.ide.common.resources.platform.ViewClassInfo; +import com.android.ide.common.resources.platform.ViewClassInfo.LayoutParamsInfo; +import com.android.ide.eclipse.adt.internal.sdk.AndroidJarLoader.ClassWrapper; +import com.android.ide.eclipse.adt.internal.sdk.IAndroidClassLoader.IClassDescriptor; +import com.android.ide.eclipse.mock.TestLogger; +import com.android.ide.eclipse.tests.AdtTestData; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.TreeMap; + +import junit.framework.TestCase; + +/** + * Test the inner private methods of PlatformDataParser. + * + * Convention: method names that start with an underscore are actually local wrappers + * that call private methods from {@link AndroidTargetParser} using reflection. + * This is inspired by the Python coding rule which mandates underscores prefixes for + * "private" methods. + */ +public class LayoutParamsParserTest extends TestCase { + + private static final String MOCK_DATA_PATH = + "com/android/ide/eclipse/testdata/mock_attrs.xml"; //$NON-NLS-1$ + + private static class MockFrameworkClassLoader extends AndroidJarLoader { + MockFrameworkClassLoader() { + super(null /* osFrameworkLocation */); + } + + @Override + public HashMap<String, ArrayList<IClassDescriptor>> findClassesDerivingFrom( + String rootPackage, String[] superClasses) throws ClassFormatError { + return new HashMap<String, ArrayList<IClassDescriptor>>(); + } + } + + private static class MockLayoutParamsParser extends LayoutParamsParser { + public MockLayoutParamsParser() { + super(new MockFrameworkClassLoader(), + new AttrsXmlParser( + AdtTestData.getInstance().getTestFilePath(MOCK_DATA_PATH), + new TestLogger(), 100).preload()); + + mTopViewClass = new ClassWrapper(mock_android.view.View.class); + mTopGroupClass = new ClassWrapper(mock_android.view.ViewGroup.class); + mTopLayoutParamsClass = new ClassWrapper(mock_android.view.ViewGroup.LayoutParams.class); + + mViewList = new ArrayList<IClassDescriptor>(); + mGroupList = new ArrayList<IClassDescriptor>(); + mViewMap = new TreeMap<String, ExtViewClassInfo>(); + mGroupMap = new TreeMap<String, ExtViewClassInfo>(); + mLayoutParamsMap = new HashMap<String, LayoutParamsInfo>(); + } + } + + private MockLayoutParamsParser mParser; + + @Override + public void setUp() throws Exception { + mParser = new MockLayoutParamsParser(); + } + + @Override + public void tearDown() throws Exception { + } + + public final void testFindLayoutParams() throws Exception { + assertEquals(mock_android.view.ViewGroup.LayoutParams.class, + ((ClassWrapper)_findLayoutParams(mock_android.view.ViewGroup.class)).wrappedClass()); + + assertEquals(mock_android.widget.LinearLayout.LayoutParams.class, + ((ClassWrapper)_findLayoutParams(mock_android.widget.LinearLayout.class)).wrappedClass()); + + assertEquals(mock_android.widget.TableLayout.LayoutParams.class, + ((ClassWrapper)_findLayoutParams(mock_android.widget.TableLayout.class)).wrappedClass()); + } + + public final void testGetLayoutParamsInfo() throws Exception { + LayoutParamsInfo info1 = _getLayoutParamsInfo( + mock_android.view.ViewGroup.LayoutParams.class); + assertNotNull(info1); + // ViewGroup.LayoutData has Object for superClass, which we don't map + assertNull(info1.getSuperClass()); + + LayoutParamsInfo info2 = _getLayoutParamsInfo( + mock_android.widget.LinearLayout.LayoutParams.class); + assertNotNull(info2); + // LinearLayout.LayoutData links to ViewGroup.LayoutParams + assertSame(info1, info2.getSuperClass()); + + LayoutParamsInfo info3 = _getLayoutParamsInfo( + mock_android.widget.TableLayout.LayoutParams.class); + assertNotNull(info3); + // TableLayout.LayoutData does not link to ViewGroup.LayoutParams nor + // LinearLayout.LayoutParams + assertNotSame(info1, info3.getSuperClass()); + assertNotSame(info2, info3.getSuperClass()); + // TableLayout.LayoutParams => ViewGroup.MarginLayoutParams => ViewGroup.LayoutParams + assertSame(info1, info3.getSuperClass().getSuperClass()); + } + + public final void testGetLayoutClasses() throws Exception { + // _getLayoutClasses(); + } + + //---- access to private methods + + /** Calls the private constructor of the parser */ + @SuppressWarnings("unused") + private AndroidTargetParser _Constructor(String osJarPath) throws Exception { + Constructor<AndroidTargetParser> constructor = + AndroidTargetParser.class.getDeclaredConstructor(String.class); + constructor.setAccessible(true); + return constructor.newInstance(osJarPath); + } + + /** calls the private getLayoutClasses() of the parser */ + @SuppressWarnings("unused") + private void _getLayoutClasses() throws Exception { + Method method = AndroidTargetParser.class.getDeclaredMethod("getLayoutClasses"); //$NON-NLS-1$ + method.setAccessible(true); + method.invoke(mParser); + } + + /** calls the private addGroup() of the parser */ + @SuppressWarnings("unused") + private ViewClassInfo _addGroup(Class<?> groupClass) throws Exception { + Method method = LayoutParamsParser.class.getDeclaredMethod("addGroup", //$NON-NLS-1$ + IClassDescriptor.class); + method.setAccessible(true); + return (ViewClassInfo) method.invoke(mParser, new ClassWrapper(groupClass)); + } + + /** calls the private addLayoutParams() of the parser */ + @SuppressWarnings("unused") + private LayoutParamsInfo _addLayoutParams(Class<?> groupClass) throws Exception { + Method method = LayoutParamsParser.class.getDeclaredMethod("addLayoutParams", //$NON-NLS-1$ + IClassDescriptor.class); + method.setAccessible(true); + return (LayoutParamsInfo) method.invoke(mParser, new ClassWrapper(groupClass)); + } + + /** calls the private getLayoutParamsInfo() of the parser */ + private LayoutParamsInfo _getLayoutParamsInfo(Class<?> layoutParamsClass) throws Exception { + Method method = LayoutParamsParser.class.getDeclaredMethod("getLayoutParamsInfo", //$NON-NLS-1$ + IClassDescriptor.class); + method.setAccessible(true); + return (LayoutParamsInfo) method.invoke(mParser, new ClassWrapper(layoutParamsClass)); + } + + /** calls the private findLayoutParams() of the parser */ + private IClassDescriptor _findLayoutParams(Class<?> groupClass) throws Exception { + Method method = LayoutParamsParser.class.getDeclaredMethod("findLayoutParams", //$NON-NLS-1$ + IClassDescriptor.class); + method.setAccessible(true); + return (IClassDescriptor) method.invoke(mParser, new ClassWrapper(groupClass)); + } + +} |