Add a test to make sure the replaced classes in layoutlib are correct.
Change-Id: I9641635153c12e2c0a23583f7d094767533fc683
This commit is contained in:
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user