/* * Copyright 2000-2010 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.android.run.testing; import com.intellij.execution.JavaExecutionUtil; import com.intellij.execution.Location; import com.intellij.execution.actions.ConfigurationContext; import com.intellij.execution.junit.JUnitUtil; import com.intellij.execution.junit.JavaRunConfigurationProducerBase; import com.intellij.execution.junit.JavaRuntimeConfigurationProducerBase; import com.intellij.openapi.module.Module; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Ref; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiPackage; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.android.run.AndroidRunConfigurationType; import org.jetbrains.android.run.TargetSelectionMode; import org.jetbrains.android.util.AndroidUtils; /** * @author Eugene.Kudelevsky */ public class AndroidTestConfigurationProducer extends JavaRunConfigurationProducerBase<AndroidTestRunConfiguration> { public AndroidTestConfigurationProducer() { super(AndroidTestRunConfigurationType.getInstance()); } private boolean setupAllInPackageConfiguration(AndroidTestRunConfiguration configuration, PsiElement element, ConfigurationContext context, Ref<PsiElement> sourceElement) { final PsiPackage p = JavaRuntimeConfigurationProducerBase.checkPackage(element); if (p == null) { return false; } final String packageName = p.getQualifiedName(); setupConfiguration(configuration, p, context, sourceElement); configuration.TESTING_TYPE = packageName.length() > 0 ? AndroidTestRunConfiguration.TEST_ALL_IN_PACKAGE : AndroidTestRunConfiguration.TEST_ALL_IN_MODULE; configuration.PACKAGE_NAME = packageName; configuration.setGeneratedName(); return true; } private boolean setupClassConfiguration(AndroidTestRunConfiguration configuration, PsiElement element, ConfigurationContext context, Ref<PsiElement> sourceElement) { PsiClass elementClass = PsiTreeUtil.getParentOfType(element, PsiClass.class, false); while (elementClass != null) { if (JUnitUtil.isTestClass(elementClass)) { setupConfiguration(configuration, elementClass, context, sourceElement); configuration.TESTING_TYPE = AndroidTestRunConfiguration.TEST_CLASS; configuration.CLASS_NAME = elementClass.getQualifiedName(); configuration.setGeneratedName(); return true; } elementClass = PsiTreeUtil.getParentOfType(elementClass, PsiClass.class); } return false; } private boolean setupMethodConfiguration(AndroidTestRunConfiguration configuration, PsiElement element, ConfigurationContext context, Ref<PsiElement> sourceElement) { PsiMethod elementMethod = PsiTreeUtil.getParentOfType(element, PsiMethod.class, false); while (elementMethod != null) { if (isTestMethod(elementMethod)) { PsiClass c = elementMethod.getContainingClass(); setupConfiguration(configuration, elementMethod, context, sourceElement); assert c != null; configuration.TESTING_TYPE = AndroidTestRunConfiguration.TEST_METHOD; configuration.CLASS_NAME = c.getQualifiedName(); configuration.METHOD_NAME = elementMethod.getName(); configuration.setGeneratedName(); return true; } elementMethod = PsiTreeUtil.getParentOfType(elementMethod, PsiMethod.class); } return false; } private boolean setupConfiguration(AndroidTestRunConfiguration configuration, PsiElement element, ConfigurationContext context, Ref<PsiElement> sourceElement) { final Module module = AndroidUtils.getAndroidModule(context); if (module == null) { return false; } sourceElement.set(element); setupConfigurationModule(context, configuration); final TargetSelectionMode targetSelectionMode = AndroidUtils .getDefaultTargetSelectionMode(module, AndroidTestRunConfigurationType.getInstance(), AndroidRunConfigurationType.getInstance()); if (targetSelectionMode != null) { configuration.setTargetSelectionMode(targetSelectionMode); } return true; } private static boolean isTestMethod(PsiMethod method) { PsiClass testClass = method.getContainingClass(); if (testClass != null && JUnitUtil.isTestClass(testClass)) { return new JUnitUtil.TestMethodFilter(testClass).value(method); } return false; } @Override protected boolean setupConfigurationFromContext(AndroidTestRunConfiguration configuration, ConfigurationContext context, Ref<PsiElement> sourceElement) { if (AndroidUtils.getAndroidModule(context) == null) { return false; } Location location = context.getLocation(); if (location == null) { return false; } location = JavaExecutionUtil.stepIntoSingleClass(location); if (location == null) { return false; } final PsiElement element = location.getPsiElement(); if (setupAllInPackageConfiguration(configuration, element, context, sourceElement)) { return true; } if (setupMethodConfiguration(configuration, element, context, sourceElement)) { return true; } return setupClassConfiguration(configuration, element, context, sourceElement); } @Override public boolean isConfigurationFromContext(AndroidTestRunConfiguration configuration, ConfigurationContext context) { Location location = context.getLocation(); final Module contextModule = AndroidUtils.getAndroidModule(context); if (contextModule == null || location == null) { return false; } location = JavaExecutionUtil.stepIntoSingleClass(location); if (location == null) { return false; } final PsiElement element = location.getPsiElement(); final PsiPackage psiPackage = JavaRuntimeConfigurationProducerBase.checkPackage(element); final String packageName = psiPackage == null ? null : psiPackage.getQualifiedName(); final PsiClass elementClass = PsiTreeUtil.getParentOfType(element, PsiClass.class, false); final String className = elementClass == null ? null : elementClass.getQualifiedName(); final PsiMethod elementMethod = PsiTreeUtil.getParentOfType(element, PsiMethod.class, false); final String methodName = elementMethod == null ? null : elementMethod.getName(); final Module moduleInConfig = configuration.getConfigurationModule().getModule(); if (!Comparing.equal(contextModule, moduleInConfig)) { return false; } switch (configuration.TESTING_TYPE) { case AndroidTestRunConfiguration.TEST_ALL_IN_MODULE: return psiPackage != null && packageName.isEmpty(); case AndroidTestRunConfiguration.TEST_ALL_IN_PACKAGE: return packageName != null && packageName.equals(configuration.PACKAGE_NAME); case AndroidTestRunConfiguration.TEST_CLASS: return elementMethod == null && className != null && className.equals(configuration.CLASS_NAME); case AndroidTestRunConfiguration.TEST_METHOD: return methodName != null && methodName.equals(configuration.METHOD_NAME) && className != null && className.equals(configuration.CLASS_NAME); } return false; } }