blob: 074b17b0c50f184d7d174d378a350e38e513951a [file] [log] [blame]
/*
* 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.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 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 = "";
// Whether to delegate to 'blaze test'.
private boolean runThroughBlaze;
private final BlazeAndroidRunConfigurationCommonState commonState;
public BlazeAndroidTestRunConfigurationState(String buildSystemName) {
commonState = new BlazeAndroidRunConfigurationCommonState(buildSystemName, true);
}
public BlazeAndroidRunConfigurationCommonState getCommonState() {
return commonState;
}
@Contract(pure = true)
boolean isRunThroughBlaze() {
return runThroughBlaze;
}
void setRunThroughBlaze(boolean runThroughBlaze) {
this.runThroughBlaze = runThroughBlaze;
}
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));
runThroughBlaze = Boolean.parseBoolean(element.getAttributeValue(RUN_THROUGH_BLAZE_ATTR));
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(RUN_THROUGH_BLAZE_ATTR, Boolean.toString(runThroughBlaze));
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);
}
}