1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Eclipse Public License, Version 1.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.eclipse.org/org/documents/epl-v10.php 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.ide.eclipse.adt.internal.launch.junit; 17 18 import org.eclipse.core.expressions.PropertyTester; 19 import org.eclipse.core.resources.IResource; 20 import org.eclipse.core.runtime.CoreException; 21 import org.eclipse.core.runtime.IAdaptable; 22 import org.eclipse.jdt.core.IClassFile; 23 import org.eclipse.jdt.core.ICompilationUnit; 24 import org.eclipse.jdt.core.IJavaElement; 25 import org.eclipse.jdt.core.IMember; 26 import org.eclipse.jdt.core.IPackageFragment; 27 import org.eclipse.jdt.core.IType; 28 import org.eclipse.jdt.core.JavaCore; 29 import org.eclipse.jdt.core.JavaModelException; 30 import org.eclipse.jdt.internal.junit.util.TestSearchEngine; 31 32 /** 33 * A {@link PropertyTester} that checks if selected elements can be run as Android 34 * JUnit tests. 35 * <p/> 36 * Based on org.eclipse.jdt.internal.junit.JUnitPropertyTester. The only substantial difference in 37 * this implementation is source folders cannot be run as Android JUnit. 38 */ 39 @SuppressWarnings("restriction") 40 public class AndroidJUnitPropertyTester extends PropertyTester { 41 private static final String PROPERTY_IS_TEST = "isTest"; //$NON-NLS-1$ 42 43 private static final String PROPERTY_CAN_LAUNCH_AS_JUNIT_TEST = "canLaunchAsJUnit"; //$NON-NLS-1$ 44 45 /* (non-Javadoc) 46 * @see org.eclipse.jdt.internal.corext.refactoring.participants.properties.IPropertyEvaluator#test(java.lang.Object, java.lang.String, java.lang.String) 47 */ test(Object receiver, String property, Object[] args, Object expectedValue)48 public boolean test(Object receiver, String property, Object[] args, Object expectedValue) { 49 if (!(receiver instanceof IAdaptable)) { 50 final String elementName = (receiver == null ? "null" : //$NON-NLS-1$ 51 receiver.getClass().getName()); 52 throw new IllegalArgumentException( 53 String.format("Element must be of type IAdaptable, is %s", //$NON-NLS-1$ 54 elementName)); 55 } 56 57 IJavaElement element; 58 if (receiver instanceof IJavaElement) { 59 element = (IJavaElement) receiver; 60 } else if (receiver instanceof IResource) { 61 element = JavaCore.create((IResource) receiver); 62 if (element == null) { 63 return false; 64 } 65 } else { // is IAdaptable 66 element= (IJavaElement) ((IAdaptable) receiver).getAdapter(IJavaElement.class); 67 if (element == null) { 68 IResource resource = (IResource) ((IAdaptable) receiver).getAdapter( 69 IResource.class); 70 element = JavaCore.create(resource); 71 if (element == null) { 72 return false; 73 } 74 } 75 } 76 if (PROPERTY_IS_TEST.equals(property)) { 77 return isJUnitTest(element); 78 } else if (PROPERTY_CAN_LAUNCH_AS_JUNIT_TEST.equals(property)) { 79 return canLaunchAsJUnitTest(element); 80 } 81 throw new IllegalArgumentException( 82 String.format("Unknown test property '%s'", property)); //$NON-NLS-1$ 83 } 84 canLaunchAsJUnitTest(IJavaElement element)85 private boolean canLaunchAsJUnitTest(IJavaElement element) { 86 try { 87 switch (element.getElementType()) { 88 case IJavaElement.JAVA_PROJECT: 89 return true; // can run, let JDT detect if there are tests 90 case IJavaElement.PACKAGE_FRAGMENT_ROOT: 91 return false; // not supported by Android test runner 92 case IJavaElement.PACKAGE_FRAGMENT: 93 return ((IPackageFragment) element).hasChildren(); 94 case IJavaElement.COMPILATION_UNIT: 95 case IJavaElement.CLASS_FILE: 96 case IJavaElement.TYPE: 97 case IJavaElement.METHOD: 98 return isJUnitTest(element); 99 default: 100 return false; 101 } 102 } catch (JavaModelException e) { 103 return false; 104 } 105 } 106 107 /** 108 * Return whether the target resource is a JUnit test. 109 */ isJUnitTest(IJavaElement element)110 private boolean isJUnitTest(IJavaElement element) { 111 try { 112 IType testType = null; 113 if (element instanceof ICompilationUnit) { 114 testType = (((ICompilationUnit) element)).findPrimaryType(); 115 } else if (element instanceof IClassFile) { 116 testType = (((IClassFile) element)).getType(); 117 } else if (element instanceof IType) { 118 testType = (IType) element; 119 } else if (element instanceof IMember) { 120 testType = ((IMember) element).getDeclaringType(); 121 } 122 if (testType != null && testType.exists()) { 123 return TestSearchEngine.isTestOrTestSuite(testType); 124 } 125 } catch (CoreException e) { 126 // ignore, return false 127 } 128 return false; 129 } 130 } 131