diff --git a/python/helpers/pycharm/nose_utils.py b/python/helpers/pycharm/nose_utils.py
index 62c77a2e1e4f..bed318a50bf0 100644
--- a/python/helpers/pycharm/nose_utils.py
+++ b/python/helpers/pycharm/nose_utils.py
@@ -107,7 +107,7 @@ class TeamcityPlugin(ErrorClassPlugin, TextTestResult, TeamcityTestResult):
location = location + ":" + str(test.test.lineno)
else:
suite = strclass(test.__class__)
- suite_location = "python_uttestid://" + suite
+ suite_location = "python_nosetestid://" + suite
try:
from nose_helper.util import func_lineno
@@ -124,8 +124,8 @@ class TeamcityPlugin(ErrorClassPlugin, TextTestResult, TeamcityTestResult):
except:
test_id = test.id()
suite_id = test_id[:test_id.rfind(".")]
- suite_location = "python_uttestid://" + str(suite_id)
- location = "python_uttestid://" + str(test_id)
+ suite_location = "python_nosetestid://" + str(suite_id)
+ location = "python_nosetestid://" + str(test_id)
return (location, suite_location)
diff --git a/python/src/META-INF/python-core.xml b/python/src/META-INF/python-core.xml
index cf37b6961b17..f11f009b3a5c 100644
--- a/python/src/META-INF/python-core.xml
+++ b/python/src/META-INF/python-core.xml
@@ -114,6 +114,7 @@
+
diff --git a/python/src/com/jetbrains/python/testing/PythonUnitTestTestIdUrlProvider.java b/python/src/com/jetbrains/python/testing/PythonUnitTestTestIdUrlProvider.java
index d0dd2c21f6f1..a53828a9eaf1 100644
--- a/python/src/com/jetbrains/python/testing/PythonUnitTestTestIdUrlProvider.java
+++ b/python/src/com/jetbrains/python/testing/PythonUnitTestTestIdUrlProvider.java
@@ -16,22 +16,12 @@
package com.jetbrains.python.testing;
import com.intellij.execution.Location;
-import com.intellij.execution.PsiLocation;
-import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.PsiFile;
import com.intellij.testIntegration.TestLocationProvider;
-import com.jetbrains.python.psi.PyClass;
-import com.jetbrains.python.psi.PyFunction;
-import com.jetbrains.python.psi.stubs.PyClassNameIndex;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -55,55 +45,20 @@ public class PythonUnitTestTestIdUrlProvider implements TestLocationProvider {
// parse path as [ns.]*fileName.className[.methodName]
if (listSize == 2) {
- return findLocations(project, list.get(0), list.get(1), null);
+ return PythonUnitTestUtil.findLocations(project, list.get(0), list.get(1), null);
}
if (listSize > 2) {
final String className = list.get(listSize - 2);
final String methodName = list.get(listSize - 1);
String fileName = list.get(listSize - 3);
- final List locations = findLocations(project, fileName, className, methodName);
+ final List locations = PythonUnitTestUtil.findLocations(project, fileName, className, methodName);
if (locations.size() > 0) {
return locations;
}
- return findLocations(project, list.get(listSize-2), list.get(listSize-1), null);
+ return PythonUnitTestUtil.findLocations(project, list.get(listSize-2), list.get(listSize-1), null);
}
return Collections.emptyList();
}
-
- private static List findLocations(Project project,
- String fileName,
- String className,
- @Nullable String methodName) {
- if (fileName.indexOf("%") >= 0) {
- fileName = fileName.substring(0, fileName.lastIndexOf("%"));
- }
-
- final List locations = new ArrayList();
- for (PyClass cls : PyClassNameIndex.find(className, project, false)) {
- ProgressManager.checkCanceled();
-
- final PsiFile containingFile = cls.getContainingFile();
- final VirtualFile virtualFile = containingFile.getVirtualFile();
- final String clsFileName = virtualFile == null? containingFile.getName() : virtualFile.getPath();
- final String clsFileNameWithoutExt = FileUtil.getNameWithoutExtension(clsFileName);
- if (!clsFileNameWithoutExt.endsWith(fileName)) {
- continue;
- }
- if (methodName == null) {
- locations.add(new PsiLocation(project, cls));
- }
- else {
- final PyFunction method = cls.findMethodByName(methodName, true);
- if (method == null) {
- continue;
- }
-
- locations.add(new PsiLocation(project, method));
- }
- }
-
- return locations;
- }
}
diff --git a/python/src/com/jetbrains/python/testing/PythonUnitTestUtil.java b/python/src/com/jetbrains/python/testing/PythonUnitTestUtil.java
index 93941439e7d7..08308973c1f1 100644
--- a/python/src/com/jetbrains/python/testing/PythonUnitTestUtil.java
+++ b/python/src/com/jetbrains/python/testing/PythonUnitTestUtil.java
@@ -17,14 +17,25 @@ package com.jetbrains.python.testing;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
+import com.intellij.execution.Location;
+import com.intellij.execution.PsiLocation;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiManager;
import com.intellij.util.containers.Stack;
import com.jetbrains.python.psi.*;
+import com.jetbrains.python.psi.stubs.PyClassNameIndex;
+import com.jetbrains.python.psi.stubs.PyFunctionNameIndex;
import com.jetbrains.python.psi.types.PyClassLikeType;
import com.jetbrains.python.psi.types.TypeEvalContext;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.regex.Pattern;
@@ -148,7 +159,9 @@ public class PythonUnitTestUtil {
return true;
}
String clsName = cls.getQualifiedName();
- String[] names = clsName.split("\\.");
+ String[] names = new String[0];
+ if (clsName != null)
+ names = clsName.split("\\.");
clsName = names[names.length - 1];
if (TEST_MATCH_PATTERN.matcher(clsName).find()) {
return true;
@@ -157,4 +170,62 @@ public class PythonUnitTestUtil {
}
return false;
}
+
+ public static List findLocations(@NotNull final Project project,
+ @NotNull String fileName,
+ @Nullable String className,
+ @Nullable String methodName) {
+ if (fileName.contains("%")) {
+ fileName = fileName.substring(0, fileName.lastIndexOf("%"));
+ }
+ final List locations = new ArrayList();
+ if (methodName == null && className == null) {
+ final VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByPath(fileName);
+ if (virtualFile == null) return locations;
+ final PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile);
+ if (psiFile != null)
+ locations.add(new PsiLocation(project, psiFile));
+ }
+
+ if (className != null) {
+ for (PyClass cls : PyClassNameIndex.find(className, project, false)) {
+ ProgressManager.checkCanceled();
+
+ final PsiFile containingFile = cls.getContainingFile();
+ final VirtualFile virtualFile = containingFile.getVirtualFile();
+ final String clsFileName = virtualFile == null? containingFile.getName() : virtualFile.getPath();
+ final String clsFileNameWithoutExt = FileUtil.getNameWithoutExtension(clsFileName);
+ if (!clsFileNameWithoutExt.endsWith(fileName)) {
+ continue;
+ }
+ if (methodName == null) {
+ locations.add(new PsiLocation(project, cls));
+ }
+ else {
+ final PyFunction method = cls.findMethodByName(methodName, true);
+ if (method == null) {
+ continue;
+ }
+
+ locations.add(new PsiLocation(project, method));
+ }
+ }
+ }
+ else if (methodName != null) {
+ for (PyFunction function : PyFunctionNameIndex.find(methodName, project)) {
+ ProgressManager.checkCanceled();
+ if (function.getContainingClass() == null) {
+ final PsiFile containingFile = function.getContainingFile();
+ final VirtualFile virtualFile = containingFile.getVirtualFile();
+ final String clsFileName = virtualFile == null? containingFile.getName() : virtualFile.getPath();
+ final String clsFileNameWithoutExt = FileUtil.getNameWithoutExtension(clsFileName);
+ if (!clsFileNameWithoutExt.endsWith(fileName)) {
+ continue;
+ }
+ locations.add(new PsiLocation(project, function));
+ }
+ }
+ }
+ return locations;
+ }
}
diff --git a/python/src/com/jetbrains/python/testing/nosetest/PythonNoseTestUrlProvider.java b/python/src/com/jetbrains/python/testing/nosetest/PythonNoseTestUrlProvider.java
new file mode 100644
index 000000000000..684a09bad563
--- /dev/null
+++ b/python/src/com/jetbrains/python/testing/nosetest/PythonNoseTestUrlProvider.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2000-2013 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 com.jetbrains.python.testing.nosetest;
+
+import com.intellij.execution.Location;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.testIntegration.TestLocationProvider;
+import com.jetbrains.python.testing.PythonUnitTestUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collections;
+import java.util.List;
+
+public class PythonNoseTestUrlProvider implements TestLocationProvider {
+ @NonNls
+ private static final String PROTOCOL_ID = "python_nosetestid";
+
+ @NotNull
+ public List getLocation(@NotNull final String protocolId, @NotNull final String path,
+ final Project project) {
+ if (!PROTOCOL_ID.equals(protocolId)) {
+ return Collections.emptyList();
+ }
+
+ final List list = StringUtil.split(path, ".");
+ if (list.isEmpty()) {
+ return Collections.emptyList();
+ }
+ final int listSize = list.size();
+
+ // parse path as [ns.]*fileName.className[.methodName]
+ if (listSize == 2) {
+ final List classes = PythonUnitTestUtil.findLocations(project, list.get(0), list.get(1), null);
+ if (classes.size() > 0)
+ return classes;
+ }
+
+ if (listSize > 2) {
+ final String className = list.get(listSize - 2);
+ final String methodName = list.get(listSize - 1);
+
+ String fileName = list.get(listSize - 3);
+ List locations = PythonUnitTestUtil.findLocations(project, fileName, className, methodName);
+ if (locations.size() > 0) {
+ return locations;
+ }
+ locations = PythonUnitTestUtil.findLocations(project, list.get(listSize - 2), list.get(listSize - 1), null);
+ if (locations.size() > 0) {
+ return locations;
+ }
+ final List functions = PythonUnitTestUtil.findLocations(project, list.get(listSize - 2), null, list.get(listSize - 1));
+ if (functions.size() > 0)
+ return functions;
+ }
+ return PythonUnitTestUtil.findLocations(project, project.getBasePath() + "/" + StringUtil.join(list, "/") + ".py", null, null);
+ }
+}