Home | History | Annotate | Download | only in junit
      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