| /* |
| * Copyright 2016 The Bazel Authors. All rights reserved. |
| * |
| * 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 com.google.idea.blaze.android.run.test; |
| |
| import com.android.tools.idea.run.ValidationError; |
| import com.google.common.base.Strings; |
| import com.google.common.collect.Maps; |
| import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationCommonState; |
| import com.google.idea.blaze.android.run.test.BlazeAndroidTestLaunchMethodsProvider.AndroidTestLaunchMethod; |
| import com.google.idea.blaze.base.run.state.RunConfigurationState; |
| import com.google.idea.blaze.base.run.state.RunConfigurationStateEditor; |
| import com.intellij.openapi.project.Project; |
| import com.intellij.openapi.util.InvalidDataException; |
| import com.intellij.openapi.util.WriteExternalException; |
| import java.util.List; |
| import java.util.Map; |
| import javax.annotation.Nullable; |
| import org.jdom.Element; |
| import org.jetbrains.android.facet.AndroidFacet; |
| import org.jetbrains.annotations.Contract; |
| |
| /** State specific for the android test configuration. */ |
| final class BlazeAndroidTestRunConfigurationState implements RunConfigurationState { |
| |
| private static final String LAUNCH_METHOD_ATTR = "launch-method"; |
| @Deprecated private static final String RUN_THROUGH_BLAZE_ATTR = "blaze-run-through-blaze"; |
| |
| public static final int TEST_ALL_IN_MODULE = 0; |
| public static final int TEST_ALL_IN_PACKAGE = 1; |
| public static final int TEST_CLASS = 2; |
| public static final int TEST_METHOD = 3; |
| |
| // We reinterpret Android Studio's test mode for running "all tests in a module" |
| // (all the tests in the installed test APK) as running all |
| // the tests in a rule. |
| public static final int TEST_ALL_IN_TARGET = TEST_ALL_IN_MODULE; |
| |
| private static final String TESTING_TYPE = "TESTING_TYPE"; |
| private static final String INSTRUMENTATION_RUNNER_CLASS = "INSTRUMENTATION_RUNNER_CLASS"; |
| private static final String METHOD_NAME = "METHOD_NAME"; |
| private static final String CLASS_NAME = "CLASS_NAME"; |
| private static final String PACKAGE_NAME = "PACKAGE_NAME"; |
| private static final String EXTRA_OPTIONS = "EXTRA_OPTIONS"; |
| |
| private int testingType = TEST_ALL_IN_MODULE; |
| private String instrumentationRunnerClass = ""; |
| private String methodName = ""; |
| private String className = ""; |
| private String packageName = ""; |
| private String extraOptions = ""; |
| |
| private AndroidTestLaunchMethod launchMethod = AndroidTestLaunchMethod.NON_BLAZE; |
| |
| private final BlazeAndroidRunConfigurationCommonState commonState; |
| |
| public BlazeAndroidTestRunConfigurationState(String buildSystemName) { |
| commonState = new BlazeAndroidRunConfigurationCommonState(buildSystemName, true); |
| } |
| |
| public BlazeAndroidRunConfigurationCommonState getCommonState() { |
| return commonState; |
| } |
| |
| @Contract(pure = true) |
| AndroidTestLaunchMethod getLaunchMethod() { |
| return launchMethod; |
| } |
| |
| void setLaunchMethod(AndroidTestLaunchMethod launchMethod) { |
| this.launchMethod = launchMethod; |
| } |
| |
| public int getTestingType() { |
| return testingType; |
| } |
| |
| public void setTestingType(int testingType) { |
| this.testingType = testingType; |
| } |
| |
| public String getInstrumentationRunnerClass() { |
| return instrumentationRunnerClass; |
| } |
| |
| public void setInstrumentationRunnerClass(String instrumentationRunnerClass) { |
| this.instrumentationRunnerClass = instrumentationRunnerClass; |
| } |
| |
| public String getMethodName() { |
| return methodName; |
| } |
| |
| public void setMethodName(String methodName) { |
| this.methodName = methodName; |
| } |
| |
| public String getClassName() { |
| return className; |
| } |
| |
| public void setClassName(String className) { |
| this.className = className; |
| } |
| |
| public String getPackageName() { |
| return packageName; |
| } |
| |
| public void setPackageName(String packageName) { |
| this.packageName = packageName; |
| } |
| |
| public String getExtraOptions() { |
| return extraOptions; |
| } |
| |
| public void setExtraOptions(String extraOptions) { |
| this.extraOptions = extraOptions; |
| } |
| |
| /** |
| * We collect errors rather than throwing to avoid missing fatal errors by exiting early for a |
| * warning. |
| */ |
| public List<ValidationError> validate(@Nullable AndroidFacet facet) { |
| return commonState.validate(facet); |
| } |
| |
| @Override |
| public void readExternal(Element element) throws InvalidDataException { |
| commonState.readExternal(element); |
| |
| String testingTypeAttribute = element.getAttributeValue(TESTING_TYPE); |
| if (!Strings.isNullOrEmpty(testingTypeAttribute)) { |
| testingType = Integer.parseInt(testingTypeAttribute); |
| } |
| instrumentationRunnerClass = |
| Strings.nullToEmpty(element.getAttributeValue(INSTRUMENTATION_RUNNER_CLASS)); |
| methodName = Strings.nullToEmpty(element.getAttributeValue(METHOD_NAME)); |
| className = Strings.nullToEmpty(element.getAttributeValue(CLASS_NAME)); |
| packageName = Strings.nullToEmpty(element.getAttributeValue(PACKAGE_NAME)); |
| extraOptions = Strings.nullToEmpty(element.getAttributeValue(EXTRA_OPTIONS)); |
| |
| String launchMethodAttribute = element.getAttributeValue(LAUNCH_METHOD_ATTR); |
| if (launchMethodAttribute != null) { |
| launchMethod = AndroidTestLaunchMethod.valueOf(launchMethodAttribute); |
| } else { |
| if (Boolean.parseBoolean(element.getAttributeValue(RUN_THROUGH_BLAZE_ATTR))) { |
| launchMethod = AndroidTestLaunchMethod.BLAZE_TEST; |
| } else { |
| launchMethod = AndroidTestLaunchMethod.NON_BLAZE; |
| } |
| } |
| |
| for (Map.Entry<String, String> entry : getLegacyValues(element).entrySet()) { |
| String value = entry.getValue(); |
| switch (entry.getKey()) { |
| case TESTING_TYPE: |
| if (!Strings.isNullOrEmpty(value)) { |
| testingType = Integer.parseInt(value); |
| } |
| break; |
| case INSTRUMENTATION_RUNNER_CLASS: |
| instrumentationRunnerClass = Strings.nullToEmpty(value); |
| break; |
| case METHOD_NAME: |
| methodName = Strings.nullToEmpty(value); |
| break; |
| case CLASS_NAME: |
| className = Strings.nullToEmpty(value); |
| break; |
| case PACKAGE_NAME: |
| packageName = Strings.nullToEmpty(value); |
| break; |
| case EXTRA_OPTIONS: |
| extraOptions = Strings.nullToEmpty(value); |
| break; |
| default: |
| break; |
| } |
| } |
| } |
| |
| @Override |
| public void writeExternal(Element element) throws WriteExternalException { |
| commonState.writeExternal(element); |
| |
| element.setAttribute(LAUNCH_METHOD_ATTR, launchMethod.name()); |
| element.setAttribute(TESTING_TYPE, Integer.toString(testingType)); |
| element.setAttribute(INSTRUMENTATION_RUNNER_CLASS, instrumentationRunnerClass); |
| element.setAttribute(METHOD_NAME, methodName); |
| element.setAttribute(CLASS_NAME, className); |
| element.setAttribute(PACKAGE_NAME, packageName); |
| element.setAttribute(EXTRA_OPTIONS, extraOptions); |
| } |
| |
| /** Imports legacy values in the old reflective JDOM externalizer manner. Can be removed ~2.0+. */ |
| private static Map<String, String> getLegacyValues(Element element) { |
| Map<String, String> result = Maps.newHashMap(); |
| for (Element option : element.getChildren("option")) { |
| String name = option.getAttributeValue("name"); |
| String value = option.getAttributeValue("value"); |
| result.put(name, value); |
| } |
| return result; |
| } |
| |
| @Override |
| public RunConfigurationStateEditor getEditor(Project project) { |
| return new BlazeAndroidTestRunConfigurationStateEditor(commonState.getEditor(project), project); |
| } |
| } |