Add a test to make sure the replaced classes in layoutlib are correct.

Change-Id: I9641635153c12e2c0a23583f7d094767533fc683
This commit is contained in:
Xavier Ducrohet
2009-10-06 09:58:08 -07:00
parent 92b5caa4e2
commit 0a9d46b7e7
2 changed files with 146 additions and 6 deletions

View File

@ -7,20 +7,21 @@ import java.net.URL;
import junit.framework.TestCase;
public class NinePatchTest extends TestCase {
private NinePatch mPatch;
@Override
protected void setUp() throws Exception {
URL url = this.getClass().getClassLoader().getResource("button.9.png");
URL url = this.getClass().getClassLoader().getResource(
"/com/android/layoutlib/testdata/button.9.png");
mPatch = NinePatch.load(url, false /* convert */);
}
public void test9PatchLoad() throws Exception {
assertNotNull(mPatch);
}
public void test9PatchMinSize() {
int[] padding = new int[4];
mPatch.getPadding(padding);
@ -28,8 +29,8 @@ public class NinePatchTest extends TestCase {
assertEquals(3, padding[1]);
assertEquals(13, padding[2]);
assertEquals(4, padding[3]);
assertEquals(38, mPatch.getWidth());
assertEquals(27, mPatch.getHeight());
assertEquals(36, mPatch.getWidth());
assertEquals(25, mPatch.getHeight());
}
}

View File

@ -0,0 +1,139 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* 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.android.layoutlib.bridge;
import java.lang.reflect.Method;
import junit.framework.TestCase;
public class TestClassReplacement extends TestCase {
public void testClassReplacements() {
// TODO: we want to test all the classes. For now only Paint passes the tests.
// final String[] classes = CreateInfo.RENAMED_CLASSES;
final String[] classes = new String[] {
"android.graphics.Paint", "android.graphics._Original_Paint"
};
final int count = classes.length;
for (int i = 0 ; i < count ; i += 2) {
loadAndCompareClasses(classes[i], classes[i+1]);
}
}
private void loadAndCompareClasses(String newClassName, String oldClassName) {
// load the classes
try {
Class<?> newClass = TestClassReplacement.class.getClassLoader().loadClass(newClassName);
Class<?> oldClass = TestClassReplacement.class.getClassLoader().loadClass(oldClassName);
compare(newClass, oldClass);
} catch (ClassNotFoundException e) {
fail("Failed to load class: " + e.getMessage());
}
}
private void compare(Class<?> newClass, Class<?> oldClass) {
// first compare the methods.
Method[] newClassMethods = newClass.getDeclaredMethods();
Method[] oldClassMethods = oldClass.getDeclaredMethods();
for (Method oldMethod : oldClassMethods) {
// we ignore anything that starts with native
if (oldMethod.getName().startsWith("native")) {
continue;
}
boolean found = false;
for (Method newMethod : newClassMethods) {
if (compareMethods(newClass, newMethod, oldClass, oldMethod)) {
found = true;
break;
}
}
if (found == false) {
fail(String.format("Unable to find %1$s", oldMethod.toGenericString()));
}
}
// TODO: check (somehow?) that the methods that were removed from the original class
// have been put back in the new class!
// For this we need the original unmodified class (ie renamed, but w/o the methods removed)
}
private boolean compareMethods(Class<?> newClass, Method newMethod,
Class<?> oldClass, Method oldMethod) {
// first check the name of the method
if (newMethod.getName().equals(oldMethod.getName()) == false) {
return false;
}
// check the return value
Class<?> oldReturnType = oldMethod.getReturnType();
// if it's the old class, or if it's a inner class of the oldclass, we need to change this.
oldReturnType = adapt(oldReturnType, newClass, oldClass);
// compare the return types
Class<?> newReturnType = newMethod.getReturnType();
if (newReturnType.equals(oldReturnType) == false) {
return false;
}
// now check the parameters type.
Class<?>[] oldParameters = oldMethod.getParameterTypes();
Class<?>[] newParemeters = newMethod.getParameterTypes();
if (oldParameters.length != newParemeters.length) {
return false;
}
for (int i = 0 ; i < oldParameters.length ; i++) {
if (newParemeters[i].equals(adapt(oldParameters[i], newClass, oldClass)) == false) {
return false;
}
}
return true;
}
/**
* Adapts a class to deal with renamed classes.
* <p/>For instance if old class is <code>android.graphics._Original_Paint</code> and the
* new class is <code>android.graphics.Paint</code> and the class to adapt is
* <code>android.graphics._Original_Paint$Cap</code>, then the method will return a
* {@link Class} object representing <code>android.graphics.Paint$Cap</code>.
* <p/>
* This method will also ensure that all renamed classes contains all the proper inner classes
* that they should be declaring.
* @param theClass the class to adapt
* @param newClass the new class object
* @param oldClass the old class object
* @return the adapted class.
* @throws ClassNotFoundException
*/
private Class<?> adapt(Class<?> theClass, Class<?> newClass, Class<?> oldClass) {
// only look for a new class if it's not primitive as Class.forName() would fail otherwise.
if (theClass.isPrimitive() == false) {
String n = theClass.getName().replace(oldClass.getName(), newClass.getName());
try {
return Class.forName(n);
} catch (ClassNotFoundException e) {
fail("Missing class: " + n);
}
}
return theClass;
}
}