• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
test(Object receiver, String property, Object[] args, Object expectedValue)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 
canLaunchAsJUnitTest(IJavaElement element)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      */
isJUnitTest(IJavaElement element)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