| /* |
| * 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.tests; |
| |
| import org.eclipse.core.runtime.Plugin; |
| |
| import java.lang.reflect.Modifier; |
| import java.net.URL; |
| import java.util.Enumeration; |
| |
| import junit.framework.TestCase; |
| import junit.framework.TestSuite; |
| |
| /** |
| * Class for collecting all test cases in an eclipse plugin |
| * |
| */ |
| public class EclipseTestCollector { |
| |
| /** |
| * Constructor |
| */ |
| public EclipseTestCollector() { |
| |
| } |
| |
| /** |
| * Searches through given plugin, adding all TestCase classes to given suite |
| * @param suite - TestSuite to add to |
| * @param plugin - Plugin to search for tests |
| * @param expectedPackage - expected package for tests. Only test classes |
| * that start with this package name will be added to suite |
| */ |
| @SuppressWarnings({"cast", "unchecked"}) |
| public void addTestCases(TestSuite suite, Plugin plugin, String expectedPackage) { |
| if (plugin != null) { |
| Enumeration<?> entries = plugin.getBundle().findEntries("/", "*.class", true); |
| |
| while (entries.hasMoreElements()) { |
| URL entry = (URL)entries.nextElement(); |
| String filePath = entry.getPath().replace(".class", ""); |
| try { |
| Class<?> testClass = getClass(filePath, expectedPackage); |
| if (isTestClass(testClass)) { |
| // In Eclipse 3.6 RCP Windows-x64, the signature has changed from |
| // addTestSuite(Class) |
| // to: |
| // addTestSuite(Class<? extends TestCase>) |
| // which is enough to create an error. To solve it, we cast into the |
| // generics expected by the JUnit framework used by 3.6 and suppress the |
| // warnings generated by the compiler under 3.5 |
| suite.addTestSuite((Class<? extends TestCase>)testClass); |
| } |
| } |
| catch (ClassNotFoundException e) { |
| // ignore, this is not the class we're looking for |
| //sLogger.log(Level.INFO, "Could not load class " + filePath); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Returns true if given class should be added to suite |
| */ |
| protected boolean isTestClass(Class<?> testClass) { |
| return TestCase.class.isAssignableFrom(testClass) && |
| Modifier.isPublic(testClass.getModifiers()) && |
| hasPublicConstructor(testClass); |
| } |
| |
| /** |
| * Returns true if given class has a public constructor |
| */ |
| @SuppressWarnings({"unchecked", "cast"}) |
| protected boolean hasPublicConstructor(Class<?> testClass) { |
| try { |
| // In Eclipse 3.6 RCP Windows-x64, the signature has changed from |
| // getTestConstructor(Class) |
| // to: |
| // getTestConstructor(Class<? extends TestCase>) |
| // which is enough to create an error. To solve it, we cast into the |
| // generics expected by the JUnit framework used by 3.6 and suppress the |
| // warnings generated by the compiler under 3.5 |
| TestSuite.getTestConstructor((Class<? extends TestCase>) testClass); |
| } catch(NoSuchMethodException e) { |
| return false; |
| } |
| return true; |
| } |
| |
| /** |
| * Load the class given by the plugin aka bundle file path |
| * @param filePath - path of class in bundle |
| * @param expectedPackage - expected package of class |
| * @throws ClassNotFoundException |
| */ |
| protected Class<?> getClass(String filePath, String expectedPackage) throws ClassNotFoundException { |
| String dotPath = filePath.replace('/', '.'); |
| // remove the output folders, by finding where package name starts |
| int index = dotPath.indexOf(expectedPackage); |
| if (index == -1) { |
| throw new ClassNotFoundException(); |
| } |
| String packagePath = dotPath.substring(index); |
| return Class.forName(packagePath); |
| } |
| } |