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 */ 48 @Override 49 public boolean test(Object receiver, String property, Object[] args, Object expectedValue) { 50 if (!(receiver instanceof IAdaptable)) { 51 final String elementName = (receiver == null ? "null" : //$NON-NLS-1$ 52 receiver.getClass().getName()); 53 throw new IllegalArgumentException( 54 String.format("Element must be of type IAdaptable, is %s", //$NON-NLS-1$ 55 elementName)); 56 } 57 58 IJavaElement element; 59 if (receiver instanceof IJavaElement) { 60 element = (IJavaElement) receiver; 61 } else if (receiver instanceof IResource) { 62 element = JavaCore.create((IResource) receiver); 63 if (element == null) { 64 return false; 65 } 66 } else { // is IAdaptable 67 element= (IJavaElement) ((IAdaptable) receiver).getAdapter(IJavaElement.class); 68 if (element == null) { 69 IResource resource = (IResource) ((IAdaptable) receiver).getAdapter( 70 IResource.class); 71 element = JavaCore.create(resource); 72 if (element == null) { 73 return false; 74 } 75 } 76 } 77 if (PROPERTY_IS_TEST.equals(property)) { 78 return isJUnitTest(element); 79 } else if (PROPERTY_CAN_LAUNCH_AS_JUNIT_TEST.equals(property)) { 80 return canLaunchAsJUnitTest(element); 81 } 82 throw new IllegalArgumentException( 83 String.format("Unknown test property '%s'", property)); //$NON-NLS-1$ 84 } 85 86 private boolean canLaunchAsJUnitTest(IJavaElement element) { 87 try { 88 switch (element.getElementType()) { 89 case IJavaElement.JAVA_PROJECT: 90 return true; // can run, let JDT detect if there are tests 91 case IJavaElement.PACKAGE_FRAGMENT_ROOT: 92 return false; // not supported by Android test runner 93 case IJavaElement.PACKAGE_FRAGMENT: 94 return ((IPackageFragment) element).hasChildren(); 95 case IJavaElement.COMPILATION_UNIT: 96 case IJavaElement.CLASS_FILE: 97 case IJavaElement.TYPE: 98 case IJavaElement.METHOD: 99 return isJUnitTest(element); 100 default: 101 return false; 102 } 103 } catch (JavaModelException e) { 104 return false; 105 } 106 } 107 108 /** 109 * Return whether the target resource is a JUnit test. 110 */ 111 private boolean isJUnitTest(IJavaElement element) { 112 try { 113 IType testType = null; 114 if (element instanceof ICompilationUnit) { 115 testType = (((ICompilationUnit) element)).findPrimaryType(); 116 } else if (element instanceof IClassFile) { 117 testType = (((IClassFile) element)).getType(); 118 } else if (element instanceof IType) { 119 testType = (IType) element; 120 } else if (element instanceof IMember) { 121 testType = ((IMember) element).getDeclaringType(); 122 } 123 if (testType != null && testType.exists()) { 124 return TestSearchEngine.isTestOrTestSuite(testType); 125 } 126 } catch (CoreException e) { 127 // ignore, return false 128 } 129 return false; 130 } 131 } 132