19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.test.suitebuilder; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.test.ClassPathPackageInfo; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.test.ClassPathPackageInfoSource; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.test.PackageInfoSources; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.util.Predicate; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport junit.framework.TestCase; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.Serializable; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.lang.reflect.Constructor; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.lang.reflect.Method; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.lang.reflect.Modifier; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Arrays; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Collection; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Comparator; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.List; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Set; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.SortedSet; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.TreeSet; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Represents a collection of test classes present on the classpath. You can add individual classes 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or entire packages. By default sub-packages are included recursively, but methods are 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * provided to allow for arbitrary inclusion or exclusion of sub-packages. Typically a 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link TestGrouping} will have only one root package, but this is not a requirement. 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} Not needed for 1.0 SDK. 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class TestGrouping { 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 49bb469fe3da7e6d17e851a95026a9eea905c52daaBrett Chabot private static final String LOG_TAG = "TestGrouping"; 50bb469fe3da7e6d17e851a95026a9eea905c52daaBrett Chabot 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SortedSet<Class<? extends TestCase>> testCaseClasses; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final Comparator<Class<? extends TestCase>> SORT_BY_SIMPLE_NAME 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = new SortBySimpleName(); 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final Comparator<Class<? extends TestCase>> SORT_BY_FULLY_QUALIFIED_NAME 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = new SortByFullyQualifiedName(); 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected String firstIncludedPackage = null; 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ClassLoader classLoader; 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public TestGrouping(Comparator<Class<? extends TestCase>> comparator) { 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project testCaseClasses = new TreeSet<Class<? extends TestCase>>(comparator); 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return A list of all tests in the package, including small, medium, large, 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * flaky, and suppressed tests. Includes sub-packages recursively. 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public List<TestMethod> getTests() { 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project List<TestMethod> testMethods = new ArrayList<TestMethod>(); 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Class<? extends TestCase> testCase : testCaseClasses) { 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Method testMethod : getTestMethods(testCase)) { 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project testMethods.add(new TestMethod(testMethod, testCase)); 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return testMethods; 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected List<Method> getTestMethods(Class<? extends TestCase> testCaseClass) { 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project List<Method> methods = Arrays.asList(testCaseClass.getMethods()); 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return select(methods, new TestMethodPredicate()); 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SortedSet<Class<? extends TestCase>> getTestCaseClasses() { 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return testCaseClasses; 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean equals(Object o) { 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (this == o) { 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (o == null || getClass() != o.getClass()) { 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TestGrouping other = (TestGrouping) o; 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!this.testCaseClasses.equals(other.testCaseClasses)) { 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return this.testCaseClasses.comparator().equals(other.testCaseClasses.comparator()); 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int hashCode() { 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return testCaseClasses.hashCode(); 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Include all tests in the given packages and all their sub-packages, unless otherwise 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * specified. Each of the given packages must contain at least one test class, either directly 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or in a sub-package. 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param packageNames Names of packages to add. 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The {@link TestGrouping} for method chaining. 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public TestGrouping addPackagesRecursive(String... packageNames) { 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (String packageName : packageNames) { 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project List<Class<? extends TestCase>> addedClasses = testCaseClassesInPackage(packageName); 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (addedClasses.isEmpty()) { 119bb469fe3da7e6d17e851a95026a9eea905c52daaBrett Chabot Log.w(LOG_TAG, "Invalid Package: '" + packageName 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + "' could not be found or has no tests"); 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project testCaseClasses.addAll(addedClasses); 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (firstIncludedPackage == null) { 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project firstIncludedPackage = packageName; 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return this; 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Exclude all tests in the given packages and all their sub-packages, unless otherwise 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * specified. 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param packageNames Names of packages to remove. 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The {@link TestGrouping} for method chaining. 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public TestGrouping removePackagesRecursive(String... packageNames) { 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (String packageName : packageNames) { 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project testCaseClasses.removeAll(testCaseClassesInPackage(packageName)); 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return this; 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The first package name passed to {@link #addPackagesRecursive(String[])}, or null 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * if that method was never called. 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String getFirstIncludedPackage() { 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return firstIncludedPackage; 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private List<Class<? extends TestCase>> testCaseClassesInPackage(String packageName) { 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ClassPathPackageInfoSource source = PackageInfoSources.forClassPath(classLoader); 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ClassPathPackageInfo packageInfo = source.getPackageInfo(packageName); 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return selectTestClasses(packageInfo.getTopLevelClassesRecursive()); 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("unchecked") 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private List<Class<? extends TestCase>> selectTestClasses(Set<Class<?>> allClasses) { 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project List<Class<? extends TestCase>> testClasses = new ArrayList<Class<? extends TestCase>>(); 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Class<?> testClass : select(allClasses, 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new TestCasePredicate())) { 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project testClasses.add((Class<? extends TestCase>) testClass); 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return testClasses; 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private <T> List<T> select(Collection<T> items, Predicate<T> predicate) { 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<T> selectedItems = new ArrayList<T>(); 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (T item : items) { 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (predicate.apply(item)) { 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project selectedItems.add(item); 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return selectedItems; 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setClassLoader(ClassLoader classLoader) { 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.classLoader = classLoader; 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sort classes by their simple names (i.e. without the package prefix), using 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * their packages to sort classes with the same name. 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static class SortBySimpleName 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project implements Comparator<Class<? extends TestCase>>, Serializable { 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int compare(Class<? extends TestCase> class1, 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Class<? extends TestCase> class2) { 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int result = class1.getSimpleName().compareTo(class2.getSimpleName()); 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result != 0) { 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return class1.getName().compareTo(class2.getName()); 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sort classes by their fully qualified names (i.e. with the package 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * prefix). 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static class SortByFullyQualifiedName 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project implements Comparator<Class<? extends TestCase>>, Serializable { 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int compare(Class<? extends TestCase> class1, 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Class<? extends TestCase> class2) { 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return class1.getName().compareTo(class2.getName()); 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static class TestCasePredicate implements Predicate<Class<?>> { 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean apply(Class aClass) { 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int modifiers = ((Class<?>) aClass).getModifiers(); 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return TestCase.class.isAssignableFrom((Class<?>) aClass) 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && Modifier.isPublic(modifiers) 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && !Modifier.isAbstract(modifiers) 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && hasValidConstructor((Class<?>) aClass); 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("unchecked") 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean hasValidConstructor(java.lang.Class<?> aClass) { 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // The cast below is not necessary with the Java 5 compiler, but necessary with the Java 6 compiler, 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // where the return type of Class.getDeclaredConstructors() was changed 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // from Constructor<T>[] to Constructor<?>[] 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Constructor<? extends TestCase>[] constructors 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = (Constructor<? extends TestCase>[]) aClass.getConstructors(); 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Constructor<? extends TestCase> constructor : constructors) { 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Modifier.isPublic(constructor.getModifiers())) { 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project java.lang.Class[] parameterTypes = constructor.getParameterTypes(); 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (parameterTypes.length == 0 || 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (parameterTypes.length == 1 && parameterTypes[0] == String.class)) { 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 239bb469fe3da7e6d17e851a95026a9eea905c52daaBrett Chabot Log.i(LOG_TAG, String.format( 240bb469fe3da7e6d17e851a95026a9eea905c52daaBrett Chabot "TestCase class %s is missing a public constructor with no parameters " + 241bb469fe3da7e6d17e851a95026a9eea905c52daaBrett Chabot "or a single String parameter - skipping", 242bb469fe3da7e6d17e851a95026a9eea905c52daaBrett Chabot aClass.getName())); 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static class TestMethodPredicate implements Predicate<Method> { 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean apply(Method method) { 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ((method.getParameterTypes().length == 0) && 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (method.getName().startsWith("test")) && 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (method.getReturnType().getSimpleName().equals("void"))); 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 256