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 com.android.SdkConstants;
     19 import com.android.annotations.NonNull;
     20 import com.android.annotations.Nullable;
     21 import com.android.ide.common.xml.ManifestData;
     22 import com.android.ide.common.xml.ManifestData.Instrumentation;
     23 import com.android.ide.common.xml.ManifestData.UsesLibrary;
     24 import com.android.ide.eclipse.adt.AdtConstants;
     25 import com.android.ide.eclipse.adt.internal.launch.LaunchMessages;
     26 import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper;
     27 import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
     28 
     29 import org.eclipse.core.resources.IProject;
     30 import org.eclipse.core.runtime.CoreException;
     31 import org.eclipse.jdt.core.IJavaProject;
     32 
     33 /**
     34  * Provides validation for Android instrumentation test runner
     35  */
     36 class InstrumentationRunnerValidator {
     37     private final IJavaProject mJavaProject;
     38     private String[] mInstrumentationNames = null;
     39     private boolean mHasRunnerLibrary = false;
     40 
     41     static final String INSTRUMENTATION_OK = null;
     42 
     43     /**
     44      * Initializes the InstrumentationRunnerValidator.
     45      *
     46      * @param javaProject the {@link IJavaProject} for the Android project to validate
     47      */
     48     InstrumentationRunnerValidator(IJavaProject javaProject) {
     49         mJavaProject = javaProject;
     50         ManifestData manifestData = AndroidManifestHelper.parseForData(javaProject.getProject());
     51         init(manifestData);
     52     }
     53 
     54     /**
     55      * Initializes the InstrumentationRunnerValidator.
     56      *
     57      * @param project the {@link IProject} for the Android project to validate
     58      * @throws CoreException if a fatal error occurred in initialization
     59      */
     60     InstrumentationRunnerValidator(IProject project) throws CoreException {
     61         this(BaseProjectHelper.getJavaProject(project));
     62     }
     63 
     64     /**
     65      * Initializes the InstrumentationRunnerValidator with an existing {@link AndroidManifestHelper}
     66      *
     67      * @param javaProject the {@link IJavaProject} for the Android project to validate
     68      * @param manifestData the {@link ManifestData} for the Android project
     69      */
     70     InstrumentationRunnerValidator(IJavaProject javaProject, ManifestData manifestData) {
     71         mJavaProject = javaProject;
     72         init(manifestData);
     73     }
     74 
     75     private void init(ManifestData manifestData) {
     76         if (manifestData == null) {
     77             mInstrumentationNames = new String[0];
     78             mHasRunnerLibrary = false;
     79             return;
     80         }
     81 
     82         Instrumentation[] instrumentations = manifestData.getInstrumentations();
     83         mInstrumentationNames = new String[instrumentations.length];
     84         for (int i = 0; i < instrumentations.length; i++) {
     85             mInstrumentationNames[i] = instrumentations[i].getName();
     86         }
     87         mHasRunnerLibrary = hasTestRunnerLibrary(manifestData);
     88     }
     89 
     90     /**
     91      * Helper method to determine if given manifest has a <code>SdkConstants.LIBRARY_TEST_RUNNER
     92      * </code> library reference
     93      *
     94      * @param manifestParser the {@link ManifestData} to search
     95      * @return true if test runner library found, false otherwise
     96      */
     97     private boolean hasTestRunnerLibrary(ManifestData manifestData) {
     98        for (UsesLibrary lib : manifestData.getUsesLibraries()) {
     99            if (AdtConstants.LIBRARY_TEST_RUNNER.equals(lib.getName())) {
    100                return true;
    101            }
    102        }
    103        return false;
    104     }
    105 
    106     /**
    107      * Return the set of instrumentation names for the Android project.
    108      *
    109      * @return array of instrumentation class names, possibly empty
    110      */
    111     @NonNull
    112     String[] getInstrumentationNames() {
    113         return mInstrumentationNames;
    114     }
    115 
    116     /**
    117      * Helper method to get the first instrumentation that can be used as a test runner.
    118      *
    119      * @return fully qualified instrumentation class name. <code>null</code> if no valid
    120      * instrumentation can be found.
    121      */
    122     @Nullable
    123     String getValidInstrumentationTestRunner() {
    124         for (String instrumentation : getInstrumentationNames()) {
    125             if (validateInstrumentationRunner(instrumentation) == INSTRUMENTATION_OK) {
    126                 return instrumentation;
    127             }
    128         }
    129         return null;
    130     }
    131 
    132     /**
    133      * Helper method to determine if specified instrumentation can be used as a test runner
    134      *
    135      * @param instrumentation the instrumentation class name to validate. Assumes this
    136      *   instrumentation is one of {@link #getInstrumentationNames()}
    137      * @return <code>INSTRUMENTATION_OK</code> if valid, otherwise returns error message
    138      */
    139     String validateInstrumentationRunner(String instrumentation) {
    140         if (!mHasRunnerLibrary) {
    141             return String.format(LaunchMessages.InstrValidator_NoTestLibMsg_s,
    142                     AdtConstants.LIBRARY_TEST_RUNNER);
    143         }
    144         // check if this instrumentation is the standard test runner
    145         if (!instrumentation.equals(SdkConstants.CLASS_INSTRUMENTATION_RUNNER)) {
    146             // Ideally, we'd check if the class extends instrumentation test runner.
    147             // However, the Google Instrumentation Test Runner extends Google Instrumentation, and not a test runner,
    148             // so we just check that the super class is Instrumentation.
    149             String result = BaseProjectHelper.testClassForManifest(mJavaProject,
    150                     instrumentation, SdkConstants.CLASS_INSTRUMENTATION, true);
    151              if (result != BaseProjectHelper.TEST_CLASS_OK) {
    152                 return String.format(
    153                         LaunchMessages.InstrValidator_WrongRunnerTypeMsg_s,
    154                         SdkConstants.CLASS_INSTRUMENTATION);
    155              }
    156         }
    157         return INSTRUMENTATION_OK;
    158     }
    159 }
    160