blob: 339a1b8c7784ae14b41dbb8cddfb4605bb699c80 [file] [log] [blame]
/*
* Copyright 2017 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.python.run.smrunner;
import com.google.common.base.Joiner;
import com.google.idea.blaze.base.command.BlazeFlags;
import com.google.idea.blaze.base.model.primitives.Kind;
import com.google.idea.blaze.base.run.smrunner.BlazeTestEventsHandler;
import com.intellij.execution.Location;
import com.intellij.execution.testframework.sm.runner.SMTestLocator;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.jetbrains.python.psi.PyClass;
import com.jetbrains.python.psi.PyFunction;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import javax.annotation.Nullable;
/** Provides python-specific methods needed by the SM-runner test UI. */
public class BlazePythonTestEventsHandler implements BlazeTestEventsHandler {
@Override
public boolean handlesKind(@Nullable Kind kind) {
return kind == Kind.PY_TEST;
}
@Override
public SMTestLocator getTestLocator() {
return BlazePythonTestLocator.INSTANCE;
}
@Override
public String testDisplayName(@Nullable Kind kind, String rawName) {
int lastDotIndex = rawName.lastIndexOf('.');
return lastDotIndex != -1 ? rawName.substring(lastDotIndex + 1) : rawName;
}
@Nullable
@Override
public String getTestFilter(Project project, List<Location<?>> testLocations) {
// python test runner parses filters of the form "class1.method1 class2.method2 ..."
// parameterized test cases can cause the same class.method combination to be present
// multiple times, so we use a set
Set<String> filters = new LinkedHashSet<>();
for (Location<?> location : testLocations) {
String filter = getFilter(location.getPsiElement());
if (filter != null) {
filters.add(filter);
}
}
if (filters.isEmpty()) {
return null;
}
return String.format("%s=%s", BlazeFlags.TEST_FILTER, Joiner.on(' ').join(filters));
}
@Nullable
private static String getFilter(PsiElement psiElement) {
if (psiElement instanceof PyClass) {
return ((PyClass) psiElement).getName();
}
if (!(psiElement instanceof PyFunction)) {
return null;
}
PyClass pyClass = ((PyFunction) psiElement).getContainingClass();
if (pyClass == null) {
return null;
}
String methodName = ((PyFunction) psiElement).getName();
String className = pyClass.getName();
return methodName != null && className != null ? className + "." + methodName : null;
}
}