diff --git a/python/helpers/pycharm/_jb_runner_tools.py b/python/helpers/pycharm/_jb_runner_tools.py index 9f3c5cf798ee..2312aaf3fbe2 100644 --- a/python/helpers/pycharm/_jb_runner_tools.py +++ b/python/helpers/pycharm/_jb_runner_tools.py @@ -402,7 +402,7 @@ def jb_start_tests(): NewTeamcityServiceMessages().message('enteredTheMatrix') # Working dir should be on path, that is how runners work when launched from command line - sys.path.append(os.getcwd()) + sys.path.insert(1, os.getcwd()) return namespace.path, namespace.target, additional_args diff --git a/python/psi-api/src/com/jetbrains/python/psi/resolve/PyQualifiedNameResolveContext.java b/python/psi-api/src/com/jetbrains/python/psi/resolve/PyQualifiedNameResolveContext.java index e68a776c519b..bde854324fdb 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/resolve/PyQualifiedNameResolveContext.java +++ b/python/psi-api/src/com/jetbrains/python/psi/resolve/PyQualifiedNameResolveContext.java @@ -31,12 +31,6 @@ import org.jetbrains.annotations.Nullable; * @author vlan */ public interface PyQualifiedNameResolveContext { - /** - * For mode when context resolves element relative to this directory - * @see #copyWithRelative(PsiDirectory) - */ - @Nullable - PsiDirectory getRelativeDirectory(); @Nullable PsiElement getFoothold(); int getRelativeLevel(); @@ -77,10 +71,4 @@ public interface PyQualifiedNameResolveContext { PyQualifiedNameResolveContext copyWithRoots(); @NotNull PyQualifiedNameResolveContext copyWithoutStubs(); - - /** - * @see #getRelativeDirectory() - */ - @NotNull - PyQualifiedNameResolveContext copyWithRelative(@NotNull PsiDirectory directory); } \ No newline at end of file diff --git a/python/src/com/jetbrains/extensions/PyFileExt.kt b/python/src/com/jetbrains/extensions/PyFileExt.kt new file mode 100644 index 000000000000..d70f9f96f027 --- /dev/null +++ b/python/src/com/jetbrains/extensions/PyFileExt.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2000-2017 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.extensions + +import com.intellij.psi.util.QualifiedName +import com.jetbrains.python.psi.PyFile +import com.jetbrains.python.psi.PyPsiFacade + +/** + * @author Ilya.Kazakevich + */ + +fun PyFile.getQName():QualifiedName? { + val name = PyPsiFacade.getInstance(this.project).findShortestImportableName(this.virtualFile, this) ?: return null + return QualifiedName.fromDottedString(name) +} \ No newline at end of file diff --git a/python/src/com/jetbrains/extenstions/QualifiedNameExt.kt b/python/src/com/jetbrains/extenstions/QualifiedNameExt.kt index 35db3fe94f64..695e76b2f212 100644 --- a/python/src/com/jetbrains/extenstions/QualifiedNameExt.kt +++ b/python/src/com/jetbrains/extenstions/QualifiedNameExt.kt @@ -17,20 +17,22 @@ package com.jetbrains.extenstions import com.intellij.openapi.module.Module import com.intellij.openapi.vfs.VirtualFile +import com.intellij.psi.PsiDirectory import com.intellij.psi.PsiElement import com.intellij.psi.PsiManager import com.intellij.psi.util.QualifiedName -import com.jetbrains.extensions.getSdk import com.jetbrains.python.psi.PyClass import com.jetbrains.python.psi.resolve.fromModule +import com.jetbrains.python.psi.resolve.resolveModuleAt import com.jetbrains.python.psi.resolve.resolveQualifiedName import com.jetbrains.python.psi.types.TypeEvalContext -import com.jetbrains.python.sdk.PythonSdkType /** * Resolves qname of any symbol to appropriate PSI element. */ -fun QualifiedName.toElement(module: Module, context: TypeEvalContext, folderToStart: VirtualFile? = null): PsiElement? { +fun QualifiedName.toElement(module: Module, + context: TypeEvalContext, + folderToStart: VirtualFile? = null): PsiElement? { var currentName = QualifiedName.fromComponents(this.components) @@ -39,22 +41,20 @@ fun QualifiedName.toElement(module: Module, context: TypeEvalContext, folderToSt // Drill as deep, as we can var lastElement: String? = null - var resolveContext = fromModule(module) + var psiDirectory: PsiDirectory? = null + val resolveContext = fromModule(module).copyWithMembers() if (folderToStart != null) { - val psiDirectory = PsiManager.getInstance(module.project).findDirectory(folderToStart) - if (psiDirectory != null) { - resolveContext = resolveContext.copyWithRelative(psiDirectory) - } - } - - // check for module and set if py3k - if (PythonSdkType.getLanguageLevelForSdk(module.getSdk()).isPy3K) { - resolveContext = resolveContext.copyWithPlainDirectories() + psiDirectory = PsiManager.getInstance(module.project).findDirectory(folderToStart) } while (currentName.componentCount > 0 && element == null) { - element = resolveQualifiedName(currentName, resolveContext.copyWithMembers()).firstOrNull() + if (psiDirectory != null) { + element = resolveModuleAt(currentName, psiDirectory, resolveContext).firstOrNull() + } else { + element = resolveQualifiedName(currentName, resolveContext).firstOrNull() + } + if (element != null) { break } diff --git a/python/src/com/jetbrains/python/psi/resolve/PyQualifiedNameResolveContextImpl.kt b/python/src/com/jetbrains/python/psi/resolve/PyQualifiedNameResolveContextImpl.kt index eb41d46b23ee..e50a213cbded 100644 --- a/python/src/com/jetbrains/python/psi/resolve/PyQualifiedNameResolveContextImpl.kt +++ b/python/src/com/jetbrains/python/psi/resolve/PyQualifiedNameResolveContextImpl.kt @@ -27,7 +27,6 @@ import com.jetbrains.python.psi.PyUtil data class PyQualifiedNameResolveContextImpl(private val psiManager: PsiManager, private val module: Module?, private val foothold: PsiElement?, private val sdk: Sdk?, private val relativeLevel : Int = -1, - private val relativeDirectory: PsiDirectory? = null, private val withoutRoots : Boolean = false, private val withoutForeign: Boolean = false, private val withMembers : Boolean = false, @@ -49,8 +48,6 @@ data class PyQualifiedNameResolveContextImpl(private val psiManager: PsiManager, override fun getPsiManager() = psiManager - override fun getRelativeDirectory() = relativeDirectory - override fun getWithMembers() = withMembers override fun getWithPlainDirectories() = withPlainDirectories @@ -80,8 +77,6 @@ data class PyQualifiedNameResolveContextImpl(private val psiManager: PsiManager, return if (relativeLevel > 0) ResolveImportUtil.stepBackFrom(file, relativeLevel) else file.containingDirectory } - override fun copyWithRelative(directory: PsiDirectory) = copy(relativeDirectory = directory) - override fun getFootholdFile() = when (foothold) { is PsiDirectory -> foothold.findFile(PyNames.INIT_DOT_PY) else -> foothold?.containingFile?.originalFile diff --git a/python/src/com/jetbrains/python/psi/resolve/PyResolveImportUtil.kt b/python/src/com/jetbrains/python/psi/resolve/PyResolveImportUtil.kt index e258faa63a94..d8d3d61330bf 100644 --- a/python/src/com/jetbrains/python/psi/resolve/PyResolveImportUtil.kt +++ b/python/src/com/jetbrains/python/psi/resolve/PyResolveImportUtil.kt @@ -228,10 +228,7 @@ private fun isNamespacePackage(element: PsiElement): Boolean { return false } -private fun resolveWithRelativeLevel(name: QualifiedName, context: PyQualifiedNameResolveContext): List { - if (context.relativeDirectory != null) { - return resolveModuleAt(name, context.relativeDirectory, context) - } +private fun resolveWithRelativeLevel(name: QualifiedName, context : PyQualifiedNameResolveContext): List { val footholdFile = context.footholdFile if (context.relativeLevel >= 0 && footholdFile != null && !PyUserSkeletonsUtil.isUnderUserSkeletonsDirectory(footholdFile)) { return resolveModuleAt(name, context.containingDirectory, context) + relativeResultsForStubsFromRoots(name, context) diff --git a/python/src/com/jetbrains/python/testing/universalTests/PyTestRunnerUtils.kt b/python/src/com/jetbrains/python/testing/universalTests/PyTestRunnerUtils.kt new file mode 100644 index 000000000000..884554da99f0 --- /dev/null +++ b/python/src/com/jetbrains/python/testing/universalTests/PyTestRunnerUtils.kt @@ -0,0 +1,108 @@ +/* + * Copyright 2000-2017 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.universalTests + +import com.intellij.openapi.diagnostic.Logger +import com.intellij.openapi.module.ModuleUtil +import com.intellij.openapi.project.Project +import com.intellij.openapi.vfs.VfsUtil +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.psi.PsiFileSystemItem +import com.intellij.psi.PsiManager +import com.intellij.psi.util.QualifiedName +import com.jetbrains.extensions.getQName +import com.jetbrains.python.PyNames +import com.jetbrains.python.psi.PyFile +import com.jetbrains.python.psi.PyQualifiedNameOwner +import com.jetbrains.python.psi.PyUtil +import com.jetbrains.python.psi.resolve.fromModule +import com.jetbrains.python.psi.resolve.resolveModuleAt + +/** + * @author Ilya.Kazakevich + */ + + +/** + * For each element finds its name calculated against closest folder inside of module sources. + * Having "foo.spam.eggs" where "foo" is plain dir but "spam" and 'eggs' are packages (with init) + * will return "foo" as folder and 'spam.eggs' as name + */ +internal fun findPathWithPackagesByName(element: PyQualifiedNameOwner): Pair? { + val module = ModuleUtil.findModuleForPsiElement(element) ?: return null + val elementQNameStr = element.qualifiedName ?: return null + var elementQName = QualifiedName.fromDottedString(elementQNameStr) + var fileQName = (element.containingFile as PyFile).getQName() ?: return null + val context = fromModule(module) + + val psiManager = PsiManager.getInstance(element.project) + + val root = findPathWithPackagesByFsItem(element.containingFile)?:return null + val newFolder = psiManager.findDirectory(root) ?: return null + //var currentName = QualifiedName.fromDottedString(elementQName) + while (resolveModuleAt(fileQName, newFolder, context).isEmpty() && fileQName.componentCount > 0) { + fileQName = fileQName.removeHead(1) + elementQName = elementQName.removeHead(1) + } + if (elementQName.componentCount > 0) { + return Pair(newFolder.virtualFile, elementQName) + } + return null +} + +/** + * Same as [findPathWithPackagesByName] but uses fs item instead. + * For foo/eggs/spam.py will return 'foo' if "eggs" has init.py or "foo/eggs" if not + * + */ +internal fun findPathWithPackagesByFsItem(elementPath: PsiFileSystemItem): VirtualFile? { + var currentDir = if (elementPath.isDirectory) { + elementPath.virtualFile + } + else { + elementPath?.parent?.virtualFile ?: return null + } + + val projectDir = findVFSItemRoot(elementPath.virtualFile, elementPath.project) ?: return null + while (VfsUtil.isAncestor(projectDir, currentDir, false) && (currentDir.findChild(PyNames.INIT_DOT_PY) != null)) { + currentDir = currentDir.parent + } + return currentDir +} + +/** + * Finds root closest to some file + */ +private fun findVFSItemRoot(virtualFile: VirtualFile, project: Project): VirtualFile? { + val module = ModuleUtil.findModuleForFile(virtualFile, project) + if (module == null) { + Logger.getInstance(PyUniversalTestConfiguration::class.java).warn("No module for " + virtualFile) + return null + } + return PyUtil.getSourceRoots(module) + .map { + val path = VfsUtil.getRelativePath(virtualFile, it) ?: return null + com.intellij.openapi.util.Pair(path, it) + } + .filterNotNull() + .sortedBy { + it.first.length + } + .map(com.intellij.openapi.util.Pair::second) + .firstOrNull() ?: return null + +} + diff --git a/python/src/com/jetbrains/python/testing/universalTests/PyUniversalTests.kt b/python/src/com/jetbrains/python/testing/universalTests/PyUniversalTests.kt index 76aa3c6cc688..3a7bf25f66d2 100644 --- a/python/src/com/jetbrains/python/testing/universalTests/PyUniversalTests.kt +++ b/python/src/com/jetbrains/python/testing/universalTests/PyUniversalTests.kt @@ -38,7 +38,10 @@ import com.intellij.openapi.project.Project import com.intellij.openapi.util.JDOMExternalizerUtil import com.intellij.openapi.util.Pair import com.intellij.openapi.util.Ref -import com.intellij.openapi.vfs.* +import com.intellij.openapi.vfs.LocalFileSystem +import com.intellij.openapi.vfs.VfsUtil +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.openapi.vfs.VirtualFileSystem import com.intellij.psi.PsiDirectory import com.intellij.psi.PsiElement import com.intellij.psi.PsiFileSystemItem @@ -50,7 +53,6 @@ import com.intellij.refactoring.listeners.RefactoringElementListener import com.intellij.refactoring.listeners.UndoRefactoringElementAdapter import com.jetbrains.extenstions.toElement import com.jetbrains.python.PyBundle -import com.jetbrains.python.PyNames import com.jetbrains.python.psi.* import com.jetbrains.python.psi.types.TypeEvalContext import com.jetbrains.python.run.AbstractPythonRunConfiguration @@ -77,57 +79,6 @@ val factories: Array = arrayOf(PyUniversalUnitTe internal fun getAdditionalArgumentsPropertyName() = PyUniversalTestConfiguration::additionalArguments.name -/** - * Checks if configuration can run with provided qname against provided working dir. - * Fixes name and configuration if can't - */ -private fun configureRelative(name: QualifiedName, - configuration: PyUniversalTestConfiguration): QualifiedName { - val module = configuration.module?: return name - val fileSystem = LocalFileSystem.getInstance() - val context = TypeEvalContext.userInitiated(module.project, null) - - // Working dir points to project root for newly created configuration - var path = fileSystem.findFileByPath(configuration.workingDirectorySafe)?:return name - - // If some element can't be resolved that means one of its parts is not package. - // foo.spam.bar does not work if "foo" is not package - // convert it to "spam.bar" and set "foo" as working dir instead - - var currentName = name - while (currentName.toElement(module, context, path) !is PyElement) { - val head = currentName.firstComponent ?: return name - currentName = currentName.removeHead(1) - path = path.findFileByRelativePath(head) ?: return name - } - configuration.workingDirectory = path.canonicalPath - return currentName -} - -/** - * Checks if configuration can run with provided path against provided working dir. - * Fixes configuration workdir if it can't - */ -private fun configureRelative(path: VirtualFile, configuration: PyUniversalTestConfiguration) { - val workDir = LocalFileSystem.getInstance().findFileByPath(configuration.workingDirectorySafe)?:return - if (! VfsUtil.isAncestor(workDir, path, false)) { - return - } - - var currentPath = if(path.isDirectory) { - path - } else { - path.parent - } - - //Ensure path is __init__.py based for all between path and configuration - // no init py -- not a package - - while (currentPath.findFileByRelativePath(PyNames.INIT_DOT_PY) != null && currentPath != workDir) { - currentPath = currentPath.parent - } - configuration.workingDirectory = currentPath.path -} /** * Since runners report names of tests as qualified name, no need to convert it to PSI and back to string. @@ -178,7 +129,7 @@ private object PyUniversalTestsLocator : SMTestLocator { val qualifiedName = QualifiedName.fromDottedString(path) // Assume qname id good and resolve it directly val element = qualifiedName.toElement(scope.module, - TypeEvalContext.codeAnalysis(project, null), folder) + TypeEvalContext.codeAnalysis(project, null), folderToStart = folder) if (element != null) { // Path is qualified name of python test according to runners protocol // Parentheses are part of generators / parametrized tests @@ -595,7 +546,7 @@ object PyUniversalTestsConfigurationProducer : AbstractPythonTestConfigurationPr private fun getTargetForConfig(configuration: PyUniversalTestConfiguration, baseElement: PsiElement, fixConfiguration: Boolean = false): ConfigurationTarget? { - val setRelative = (fixConfiguration && configuration.packageOnlyIfInitPy(baseElement)) + val fixPackages = (fixConfiguration && configuration.packageOnlyIfInitPy(baseElement)) var element = baseElement // Go up until we reach top of the file @@ -604,21 +555,28 @@ object PyUniversalTestsConfigurationProducer : AbstractPythonTestConfigurationPr do { if (configuration.couldBeTestTarget(element)) { when (element) { - is PyQualifiedNameOwner -> { // Function, class, method + is PyQualifiedNameOwner -> { // Function, class, method var qualifiedName = element.qualifiedName if (qualifiedName == null) { Logger.getInstance(PyUniversalTestConfiguration::class.java).warn("$element has no qualified name") return null } - if (setRelative) { - qualifiedName = configureRelative(QualifiedName.fromDottedString(qualifiedName), configuration).toString() + if (fixPackages) { + + val pathResult = findPathWithPackagesByName(element) + if (pathResult == null) { + Logger.getInstance(PyUniversalTestConfiguration::class.java).warn("Can't resolve") + return null + } + configuration.workingDirectory = pathResult.first.path + qualifiedName = pathResult.second.toString() } return ConfigurationTarget(qualifiedName, TestTargetType.PYTHON) } - is PsiFileSystemItem -> { + is PsiFileSystemItem -> { val path = element.virtualFile - if (setRelative) { - configureRelative(path, configuration).toString() + if (fixPackages) { + configuration.workingDirectory = findPathWithPackagesByFsItem(element)?.path ?: return null } return ConfigurationTarget(path.path, TestTargetType.PATH) } diff --git a/python/src/com/jetbrains/python/testing/universalTests/PyUniversalUnitTest.kt b/python/src/com/jetbrains/python/testing/universalTests/PyUniversalUnitTest.kt index 5b5573ed2282..cf3e12095488 100644 --- a/python/src/com/jetbrains/python/testing/universalTests/PyUniversalUnitTest.kt +++ b/python/src/com/jetbrains/python/testing/universalTests/PyUniversalUnitTest.kt @@ -77,6 +77,7 @@ class PyUniversalUnitTestConfiguration(project: Project, factory: PyUniversalUni override fun isFrameworkInstalled() = true //Unittest is always available // See loader.py: is_not_importable = not os.path.isfile(os.path.join(start_dir, '__init__.py')) + // https://mail.python.org/pipermail/python-dev/2017-March/147656.html override fun packageOnlyIfInitPy(anchor: PsiElement) = true } diff --git a/python/testData/testRunner/env/createConfigurationTest/logic.py b/python/testData/testRunner/env/createConfigurationTest/logic.py new file mode 100644 index 000000000000..f29a347acf26 --- /dev/null +++ b/python/testData/testRunner/env/createConfigurationTest/logic.py @@ -0,0 +1,3 @@ +# coding=utf-8 +def smart_func(): + return 42 \ No newline at end of file diff --git a/python/testData/testRunner/env/createConfigurationTest/tests_folder/test_lonely.py b/python/testData/testRunner/env/createConfigurationTest/tests_folder/test_lonely.py new file mode 100644 index 000000000000..60dedfb2b071 --- /dev/null +++ b/python/testData/testRunner/env/createConfigurationTest/tests_folder/test_lonely.py @@ -0,0 +1,9 @@ +from unittest import TestCase + +from logic import smart_func +from tests_package.test_tools import ANSWER + + +class TestLonely(TestCase): + def test_test(self): + self.assertEqual(ANSWER, smart_func()) diff --git a/python/testData/testRunner/env/createConfigurationTest/tests_package/__init__.py b/python/testData/testRunner/env/createConfigurationTest/tests_package/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/testRunner/env/createConfigurationTest/tests_package/package_test/__init__.py b/python/testData/testRunner/env/createConfigurationTest/tests_package/package_test/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/testRunner/env/createConfigurationTest/tests_package/package_test/test_in_package.py b/python/testData/testRunner/env/createConfigurationTest/tests_package/package_test/test_in_package.py new file mode 100644 index 000000000000..30e7e7a37f70 --- /dev/null +++ b/python/testData/testRunner/env/createConfigurationTest/tests_package/package_test/test_in_package.py @@ -0,0 +1,9 @@ +from unittest import TestCase + +from logic import smart_func +from tests_package.test_tools import ANSWER + + +class TestLogic(TestCase): + def test_test(self): + self.assertEqual(ANSWER, smart_func()) \ No newline at end of file diff --git a/python/testData/testRunner/env/createConfigurationTest/tests_package/test_tools.py b/python/testData/testRunner/env/createConfigurationTest/tests_package/test_tools.py new file mode 100644 index 000000000000..42add9c908e1 --- /dev/null +++ b/python/testData/testRunner/env/createConfigurationTest/tests_package/test_tools.py @@ -0,0 +1 @@ +ANSWER = 42 \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/env/python/testing/CreateConfigurationByFileTask.java b/python/testSrc/com/jetbrains/env/python/testing/CreateConfigurationByFileTask.java new file mode 100644 index 000000000000..06fc8447be01 --- /dev/null +++ b/python/testSrc/com/jetbrains/env/python/testing/CreateConfigurationByFileTask.java @@ -0,0 +1,129 @@ +/* + * Copyright 2000-2017 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.env.python.testing; + +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiManager; +import com.intellij.psi.impl.file.PsiDirectoryFactory; +import com.jetbrains.python.testing.AbstractPythonTestRunConfiguration; +import com.jetbrains.python.testing.universalTests.PyUniversalTestConfiguration; +import org.hamcrest.Matchers; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.junit.Assert; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Creates configuration for each file provided to it + * + * @author Ilya.Kazakevich + */ +class CreateConfigurationByFileTask extends CreateConfigurationTestTask { + @NotNull + private final String[] myFileNames; + + /** + * @see CreateConfigurationTestTask#CreateConfigurationTestTask(String, Class) + */ + CreateConfigurationByFileTask(@Nullable final String testRunnerName, + @NotNull final Class expectedConfigurationType, + @NotNull final String...fileNames) { + super(testRunnerName, expectedConfigurationType); + myFileNames = fileNames.clone(); + } + + /** + * @see CreateConfigurationTestTask#CreateConfigurationTestTask(String, Class) + */ + CreateConfigurationByFileTask(@Nullable final String testRunnerName, + @NotNull final Class expectedConfigurationType) { + this(testRunnerName, expectedConfigurationType, "test_file.py", "test_class.py"); + } + + @NotNull + @Override + protected final List getPsiElementsToRightClickOn() { + return Arrays.stream(myFileNames).map(this::getElementToRightClickOnByFile).collect(Collectors.toList()); + } + + /** + * @param fileName file or folder name provided by class instantiator + * @return element to right click on to generate test + */ + @NotNull + protected PsiElement getElementToRightClickOnByFile(@NotNull final String fileName) { + final VirtualFile virtualFile = myFixture.getTempDirFixture().getFile(fileName); + assert virtualFile != null : "Can't find " + fileName; + + // Configure context by folder in case of folder, or by element if file + final PsiElement elementToRightClickOn; + if (virtualFile.isDirectory()) { + elementToRightClickOn = PsiDirectoryFactory.getInstance(getProject()).createDirectory(virtualFile); + } + else { + myFixture.configureByFile(fileName); + elementToRightClickOn = myFixture.getElementAtCaret(); + } + return elementToRightClickOn; + } + + + + + static class CreateConfigurationTestAndRenameClassTask extends CreateConfigurationByFileTask { + CreateConfigurationTestAndRenameClassTask(@NotNull final String testRunnerName, + @NotNull final Class expectedConfigurationType) { + super(testRunnerName, expectedConfigurationType, "test_class.py"); + } + + @Override + protected void checkConfiguration(@NotNull T configuration, @NotNull PsiElement elementToRightClickOn) { + super.checkConfiguration(configuration, elementToRightClickOn); + Assert.assertThat("Wrong name generated", configuration.getName(), Matchers.containsString("TheTest")); + Assert.assertThat("Bad target generated", configuration.getTarget().getTarget(), Matchers.endsWith("TheTest")); + myFixture.renameElementAtCaret("FooTest"); + Assert.assertThat("Name not renamed", configuration.getName(), Matchers.containsString("FooTest")); + } + } + + static class CreateConfigurationTestAndRenameFolderTask + extends CreateConfigurationByFileTask { + CreateConfigurationTestAndRenameFolderTask(@Nullable final String testRunnerName, + @NotNull final Class expectedConfigurationType) { + super(testRunnerName, expectedConfigurationType, "folderWithTests"); + } + + @Override + protected void checkConfiguration(@NotNull final T configuration, @NotNull PsiElement elementToRightClickOn) { + super.checkConfiguration(configuration, elementToRightClickOn); + Assert.assertThat("Wrong name generated", configuration.getName(), Matchers.containsString("folderWithTests")); + Assert.assertThat("Bad target generated", configuration.getTarget().getTarget(), Matchers.containsString("folderWithTests")); + + final VirtualFile virtualFolder = myFixture.getTempDirFixture().getFile("folderWithTests"); + assert virtualFolder != null : "Can't find folder"; + final PsiDirectory psiFolder = PsiManager.getInstance(getProject()).findDirectory(virtualFolder); + assert psiFolder != null : "No psi for folder found"; + myFixture.renameElement(psiFolder, "newFolder"); + Assert.assertThat("Name not renamed", configuration.getName(), Matchers.containsString("newFolder")); + Assert.assertThat("Target not renamed", configuration.getTarget().getTarget(), Matchers.containsString("newFolder")); + } + } +} diff --git a/python/testSrc/com/jetbrains/env/python/testing/CreateConfigurationMultipleCasesTask.java b/python/testSrc/com/jetbrains/env/python/testing/CreateConfigurationMultipleCasesTask.java new file mode 100644 index 000000000000..477294b640aa --- /dev/null +++ b/python/testSrc/com/jetbrains/env/python/testing/CreateConfigurationMultipleCasesTask.java @@ -0,0 +1,157 @@ +/* + * Copyright 2000-2017 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.env.python.testing; + +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VfsUtilCore; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.jetbrains.python.psi.PyClass; +import com.jetbrains.python.psi.PyFile; +import com.jetbrains.python.testing.universalTests.ConfigurationTarget; +import com.jetbrains.python.testing.universalTests.PyUniversalTestConfiguration; +import org.hamcrest.Matchers; +import org.jetbrains.annotations.NotNull; +import org.junit.Assert; + +import java.util.ArrayList; +import java.util.List; + +/** + * + * Creates configurations for many different cases: packages, classes, files and folders. It checks then that configuration is ok. + * @author Ilya.Kazakevich + */ +final class CreateConfigurationMultipleCasesTask extends CreateConfigurationTestTask { + + CreateConfigurationMultipleCasesTask(@NotNull final String testRunnerName, + @NotNull final Class expectedConfigurationType) { + super(testRunnerName, expectedConfigurationType); + } + + + + @NotNull + @Override + protected List getPsiElementsToRightClickOn() { + final List result = new ArrayList<>(); + + + result.add(getDir("tests_package/package_test")); + result.add(getFile("tests_package/package_test", "test_in_package.py")); + result.add(getFile("tests_package/package_test", "test_in_package.py").findTopLevelClass("TestLogic")); + + result.add(getDir("tests_folder")); + result.add(getFile("tests_folder", "test_lonely.py")); + result.add(getFile("tests_folder", "test_lonely.py").findTopLevelClass("TestLonely")); + + + return result; + } + + @Override + protected void checkConfiguration(@NotNull final T configuration, @NotNull final PsiElement element) { + // When namespace packages are supported we can run tests in for of foo.spam.Bar even if foo is plain dir + // otherwise we need to set "foo" as working dir and run spam.Bar. + + final boolean namespacePackagesSupported = ! configuration.packageOnlyIfInitPy(element); + + final LocalFileSystem fileSystem = LocalFileSystem.getInstance(); + final ConfigurationTarget target = configuration.getTarget(); + final VirtualFile workingDirectory = fileSystem.refreshAndFindFileByPath(configuration.getWorkingDirectorySafe()); + Assert.assertNotNull("Working directory hasn't been set", workingDirectory); + final VirtualFile projectRoot = myFixture.getTempDirFixture().getFile("."); + assert projectRoot != null; + + assert element instanceof PsiNamedElement : "Unknown element " + element; + final String elementName = ((PsiNamedElement)element).getName(); + assert elementName != null; + + if (element instanceof PsiDirectory && elementName.endsWith("package_test")) { + + if (!namespacePackagesSupported) { + Assert.assertEquals("Bad configuration for folder", "tests_package/package_test", + VfsUtilCore.getRelativeLocation(target.asVirtualFile(fileSystem), workingDirectory)); + } + + Assert.assertThat("Bad target", configuration.getTarget().getTarget(), Matchers.endsWith("package_test")); + + } + else if (element instanceof PyFile &&elementName.endsWith("test_in_package.py")) { + if (!namespacePackagesSupported) { + Assert.assertEquals("Bad configuration for file", "tests_package/package_test/test_in_package.py", + VfsUtilCore.getRelativeLocation(target.asVirtualFile(fileSystem), workingDirectory)); + } + + Assert.assertThat("Bad target", configuration.getTarget().getTarget(), Matchers.endsWith("test_in_package.py")); + + } + else if (element instanceof PyClass && elementName.endsWith("TestLogic")) { + + if (!namespacePackagesSupported) { + Assert.assertEquals("Bad working dir for class", projectRoot, workingDirectory); + } + + Assert.assertEquals("Bad configuration for class", "tests_package.package_test.test_in_package.TestLogic", target.getTarget()); + } + else if (element instanceof PsiDirectory && elementName.endsWith("tests_folder")) { + if (!namespacePackagesSupported) { + Assert.assertEquals("Bad configuration for no package folder", workingDirectory, target.asVirtualFile(fileSystem)); + } + + Assert.assertThat("Bad target", configuration.getTarget().getTarget(), Matchers.endsWith("tests_folder")); + } + else if (element instanceof PyFile && elementName.endsWith("test_lonely.py")) { + if (!namespacePackagesSupported) { + Assert.assertEquals("Bad configuration for no package file", "test_lonely.py", + VfsUtilCore.getRelativeLocation(target.asVirtualFile(fileSystem), workingDirectory)); + } + + Assert.assertThat("Bad target", configuration.getTarget().getTarget(), Matchers.endsWith("test_lonely.py")); + } + else if (element instanceof PyClass && elementName.endsWith("TestLonely")) { + + if (!namespacePackagesSupported) { + Assert.assertEquals("Bad configuration for no package class", workingDirectory, projectRoot.findChild("tests_folder")); + Assert.assertEquals("Bad configuration for class no package", "test_lonely.TestLonely", target.getTarget()); + } else { + Assert.assertEquals("Bad configuration for class no package", "tests_folder.test_lonely.TestLonely", target.getTarget()); + } + + + } + else { + throw new AssertionError("Unexpected configuration " + configuration); + } + } + + @NotNull + private PsiDirectory getDir(@NotNull final String dirName) { + final PsiManager psiManager = PsiManager.getInstance(myFixture.getProject()); + final VirtualFile vfsDir = myFixture.getTempDirFixture().getFile(dirName); + assert vfsDir != null : "No vfs " + dirName; + final PsiDirectory psiDirectory = psiManager.findDirectory(vfsDir); + assert psiDirectory != null : "No psi " + dirName; + return psiDirectory; + } + + @NotNull + private PyFile getFile(@NotNull final String dirName, @NotNull final String fileName) { + final PsiFile psiFile = getDir(dirName).findFile(fileName); + assert psiFile instanceof PyFile : "Bad file " + psiFile; + return (PyFile)psiFile; + } +} diff --git a/python/testSrc/com/jetbrains/env/python/testing/CreateConfigurationTestTask.java b/python/testSrc/com/jetbrains/env/python/testing/CreateConfigurationTestTask.java index c83a0e4a4b72..0a1a0d9a47cd 100644 --- a/python/testSrc/com/jetbrains/env/python/testing/CreateConfigurationTestTask.java +++ b/python/testSrc/com/jetbrains/env/python/testing/CreateConfigurationTestTask.java @@ -22,11 +22,7 @@ import com.intellij.execution.actions.ConfigurationFromContext; import com.intellij.execution.configurations.RunConfiguration; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiManager; -import com.intellij.psi.impl.file.PsiDirectoryFactory; import com.jetbrains.env.PyExecutionFixtureTestTask; import com.jetbrains.python.sdk.InvalidSdkException; import com.jetbrains.python.sdkTools.SdkCreationType; @@ -50,35 +46,21 @@ import java.util.Optional; * * @author Ilya.Kazakevich */ -class CreateConfigurationTestTask extends PyExecutionFixtureTestTask { +abstract class CreateConfigurationTestTask extends PyExecutionFixtureTestTask { @Nullable private final String myTestRunnerName; @NotNull - private final String[] myFileNames; - @NotNull private final Class myExpectedConfigurationType; /** * @param testRunnerName test runner name (to set as default to make sure producer launched) * @param expectedConfigurationType type configuration tha should be produced */ - CreateConfigurationTestTask(@NotNull final String testRunnerName, - @NotNull final Class expectedConfigurationType) { - this(testRunnerName, expectedConfigurationType, "test_file.py", "test_class.py"); - } - - /** - * @param testRunnerName test runner name (to set as default to make sure producer launched) or null if set nothing - * @param expectedConfigurationType type configuration tha should be produced - * @param fileNames python files with caret or folders to check right click on - */ CreateConfigurationTestTask(@Nullable final String testRunnerName, - @NotNull final Class expectedConfigurationType, - @NotNull final String... fileNames) { + @NotNull final Class expectedConfigurationType) { super("/testRunner/env/createConfigurationTest/"); myTestRunnerName = testRunnerName; - myFileNames = fileNames.clone(); myExpectedConfigurationType = expectedConfigurationType; } @@ -92,15 +74,12 @@ class CreateConfigurationTestTask extends PyExecutio createTempSdk(sdkHome, SdkCreationType.SDK_PACKAGES_ONLY); ApplicationManager.getApplication().invokeAndWait(() -> ApplicationManager.getApplication().runWriteAction(() -> { - for (final String fileName : myFileNames) { - - - final PsiElement elementToRightClickOn = getElementToRightClickOnByFile(fileName); + for (final PsiElement elementToRightClickOn : getPsiElementsToRightClickOn()) { final List configurationsFromContext = new ConfigurationContext(elementToRightClickOn).getConfigurationsFromContext(); - Assert.assertNotNull("Producers were not able to create any configuration in " + fileName, configurationsFromContext); + Assert.assertNotNull("Producers were not able to create any configuration in " + elementToRightClickOn, configurationsFromContext); final Optional maybeConfig = configurationsFromContext.stream() @@ -110,85 +89,31 @@ class CreateConfigurationTestTask extends PyExecutio RunnerAndConfigurationSettings runnerAndConfigurationSettings = maybeConfig.get().getConfigurationSettings(); - Assert.assertNotNull("Producers were not able to create any configuration in " + fileName, runnerAndConfigurationSettings); + Assert.assertNotNull("Producers were not able to create any configuration in " + elementToRightClickOn, runnerAndConfigurationSettings); final RunConfiguration configuration = runnerAndConfigurationSettings.getConfiguration(); Assert.assertNotNull("No real configuration created", configuration); Assert.assertThat("No name for configuration", configuration.getName(), Matchers.not(Matchers.isEmptyOrNullString())); - Assert.assertThat("Bad configuration type in " + fileName, configuration, + Assert.assertThat("Bad configuration type in " + elementToRightClickOn, configuration, Matchers.is(Matchers.instanceOf(myExpectedConfigurationType))); RunManager.getInstance(getProject()).addConfiguration(runnerAndConfigurationSettings, false); @SuppressWarnings("unchecked") // Checked one line above final T typedConfiguration = (T)configuration; - checkConfiguration(typedConfiguration); + checkConfiguration(typedConfiguration, elementToRightClickOn); } }), ModalityState.NON_MODAL); } - /** - * @param fileName file or folder name provided by class instantiator - * @return element to right click on to generate test - */ @NotNull - protected PsiElement getElementToRightClickOnByFile(@NotNull final String fileName) { - final VirtualFile virtualFile = myFixture.getTempDirFixture().getFile(fileName); - assert virtualFile != null : "Can't find " + fileName; + protected abstract List getPsiElementsToRightClickOn(); - // Configure context by folder in case of folder, or by element if file - final PsiElement elementToRightClickOn; - if (virtualFile.isDirectory()) { - elementToRightClickOn = PsiDirectoryFactory.getInstance(getProject()).createDirectory(virtualFile); - } - else { - myFixture.configureByFile(fileName); - elementToRightClickOn = myFixture.getElementAtCaret(); - } - return elementToRightClickOn; + + + protected void checkConfiguration(@NotNull final T configuration, @NotNull final PsiElement elementToRightClickOn) { + // Configuration already checked when created, but you can do specific checks here } - protected void checkConfiguration(@NotNull final T configuration) { - - } - - static class CreateConfigurationTestAndRenameClassTask extends CreateConfigurationTestTask { - CreateConfigurationTestAndRenameClassTask(@NotNull final String testRunnerName, - @NotNull final Class expectedConfigurationType) { - super(testRunnerName, expectedConfigurationType, "test_class.py"); - } - - @Override - protected void checkConfiguration(@NotNull PyUniversalTestConfiguration configuration) { - super.checkConfiguration(configuration); - Assert.assertThat("Wrong name generated", configuration.getName(), Matchers.containsString("TheTest")); - Assert.assertThat("Bad target generated", configuration.getTarget().getTarget(), Matchers.endsWith("TheTest")); - myFixture.renameElementAtCaret("FooTest"); - Assert.assertThat("Name not renamed", configuration.getName(), Matchers.containsString("FooTest")); - } - } - - static class CreateConfigurationTestAndRenameFolderTask - extends CreateConfigurationTestTask { - CreateConfigurationTestAndRenameFolderTask(@Nullable final String testRunnerName, - @NotNull final Class expectedConfigurationType) { - super(testRunnerName, expectedConfigurationType, "folderWithTests"); - } - - @Override - protected void checkConfiguration(@NotNull final PyUniversalTestConfiguration configuration) { - super.checkConfiguration(configuration); - Assert.assertThat("Wrong name generated", configuration.getName(), Matchers.containsString("folderWithTests")); - Assert.assertThat("Bad target generated", configuration.getTarget().getTarget(), Matchers.containsString("folderWithTests")); - - final VirtualFile virtualFolder = myFixture.getTempDirFixture().getFile("folderWithTests"); - assert virtualFolder != null : "Can't find folder"; - final PsiDirectory psiFolder = PsiManager.getInstance(getProject()).findDirectory(virtualFolder); - assert psiFolder != null : "No psi for folder found"; - myFixture.renameElement(psiFolder, "newFolder"); - Assert.assertThat("Name not renamed", configuration.getName(), Matchers.containsString("newFolder")); - Assert.assertThat("Target not renamed", configuration.getTarget().getTarget(), Matchers.containsString("newFolder")); - } - } /** * Task to create configuration diff --git a/python/testSrc/com/jetbrains/env/python/testing/PythonDocTestingTest.java b/python/testSrc/com/jetbrains/env/python/testing/PythonDocTestingTest.java index 551707888753..bd4945ed68a7 100644 --- a/python/testSrc/com/jetbrains/env/python/testing/PythonDocTestingTest.java +++ b/python/testSrc/com/jetbrains/env/python/testing/PythonDocTestingTest.java @@ -21,7 +21,7 @@ public final class PythonDocTestingTest extends PyEnvTestCase { @Test public void testConfigurationProducer() throws Exception { runPythonTest( - new CreateConfigurationTestTask<>(null, PythonDocTestRunConfiguration.class, "doctest_test.py")); + new CreateConfigurationByFileTask<>(null, PythonDocTestRunConfiguration.class, "doctest_test.py")); } @Test diff --git a/python/testSrc/com/jetbrains/env/python/testing/PythonNoseTestingTest.java b/python/testSrc/com/jetbrains/env/python/testing/PythonNoseTestingTest.java index 3e90a697828b..abd1870f47b0 100644 --- a/python/testSrc/com/jetbrains/env/python/testing/PythonNoseTestingTest.java +++ b/python/testSrc/com/jetbrains/env/python/testing/PythonNoseTestingTest.java @@ -23,6 +23,11 @@ import static org.junit.Assert.assertEquals; @EnvTestTagsRequired(tags = "nose") public final class PythonNoseTestingTest extends PyEnvTestCase { + @Test + public void testMultipleCases() throws Exception { + runPythonTest( + new CreateConfigurationMultipleCasesTask<>(PythonTestConfigurationsModel.PYTHONS_NOSETEST_NAME, PyUniversalNoseTestConfiguration.class)); + } /** * Checks tests are resolved when launched from subfolder @@ -85,20 +90,20 @@ public final class PythonNoseTestingTest extends PyEnvTestCase { @Test public void testConfigurationProducer() throws Exception { runPythonTest( - new CreateConfigurationTestTask<>(PythonTestConfigurationsModel.PYTHONS_NOSETEST_NAME, PyUniversalNoseTestConfiguration.class)); + new CreateConfigurationByFileTask<>(PythonTestConfigurationsModel.PYTHONS_NOSETEST_NAME, PyUniversalNoseTestConfiguration.class)); } @Test public void testConfigurationProducerOnDirectory() throws Exception { runPythonTest( - new CreateConfigurationTestTask.CreateConfigurationTestAndRenameFolderTask(PythonTestConfigurationsModel.PYTHONS_NOSETEST_NAME, + new CreateConfigurationByFileTask.CreateConfigurationTestAndRenameFolderTask<>(PythonTestConfigurationsModel.PYTHONS_NOSETEST_NAME, PyUniversalNoseTestConfiguration.class)); } @Test public void testRenameClass() throws Exception { runPythonTest( - new CreateConfigurationTestTask.CreateConfigurationTestAndRenameClassTask( + new CreateConfigurationByFileTask.CreateConfigurationTestAndRenameClassTask<>( PythonTestConfigurationsModel.PYTHONS_NOSETEST_NAME, PyUniversalNoseTestConfiguration.class)); } diff --git a/python/testSrc/com/jetbrains/env/python/testing/PythonPyTestingTest.java b/python/testSrc/com/jetbrains/env/python/testing/PythonPyTestingTest.java index cd54c18eecd5..afc0870db292 100644 --- a/python/testSrc/com/jetbrains/env/python/testing/PythonPyTestingTest.java +++ b/python/testSrc/com/jetbrains/env/python/testing/PythonPyTestingTest.java @@ -34,7 +34,13 @@ public final class PythonPyTestingTest extends PyEnvTestCase { @Test public void testConfigurationProducer() throws Exception { runPythonTest( - new CreateConfigurationTestTask<>(PythonTestConfigurationsModel.PY_TEST_NAME, PyUniversalPyTestConfiguration.class)); + new CreateConfigurationByFileTask<>(PythonTestConfigurationsModel.PY_TEST_NAME, PyUniversalPyTestConfiguration.class)); + } + + @Test + public void testMultipleCases() throws Exception { + runPythonTest( + new CreateConfigurationMultipleCasesTask<>(PythonTestConfigurationsModel.PY_TEST_NAME, PyUniversalPyTestConfiguration.class)); } /** @@ -97,14 +103,14 @@ public final class PythonPyTestingTest extends PyEnvTestCase { @Test public void testConfigurationProducerOnDirectory() throws Exception { runPythonTest( - new CreateConfigurationTestTask.CreateConfigurationTestAndRenameFolderTask(PythonTestConfigurationsModel.PY_TEST_NAME, - PyUniversalPyTestConfiguration.class)); + new CreateConfigurationByFileTask.CreateConfigurationTestAndRenameFolderTask<>(PythonTestConfigurationsModel.PY_TEST_NAME, + PyUniversalPyTestConfiguration.class)); } @Test public void testProduceConfigurationOnFile() throws Exception { runPythonTest( - new CreateConfigurationTestTask(PythonTestConfigurationsModel.PY_TEST_NAME, PyUniversalPyTestConfiguration.class, "spam.py") { + new CreateConfigurationByFileTask(PythonTestConfigurationsModel.PY_TEST_NAME, PyUniversalPyTestConfiguration.class, "spam.py") { @NotNull @Override protected PsiElement getElementToRightClickOnByFile(@NotNull final String fileName) { @@ -116,7 +122,7 @@ public final class PythonPyTestingTest extends PyEnvTestCase { @Test public void testRenameClass() throws Exception { runPythonTest( - new CreateConfigurationTestTask.CreateConfigurationTestAndRenameClassTask( + new CreateConfigurationByFileTask.CreateConfigurationTestAndRenameClassTask<>( PythonTestConfigurationsModel.PY_TEST_NAME, PyUniversalPyTestConfiguration.class)); } diff --git a/python/testSrc/com/jetbrains/env/python/testing/PythonUnitTestingTest.java b/python/testSrc/com/jetbrains/env/python/testing/PythonUnitTestingTest.java index 86d490bd4b87..a44a3d77797a 100644 --- a/python/testSrc/com/jetbrains/env/python/testing/PythonUnitTestingTest.java +++ b/python/testSrc/com/jetbrains/env/python/testing/PythonUnitTestingTest.java @@ -29,6 +29,7 @@ import com.jetbrains.env.ut.PyUnitTestProcessRunner; import com.jetbrains.python.PyBundle; import com.jetbrains.python.psi.LanguageLevel; import com.jetbrains.python.testing.PythonTestConfigurationsModel; +import com.jetbrains.python.testing.universalTests.PyUniversalNoseTestConfiguration; import com.jetbrains.python.testing.universalTests.PyUniversalUnitTestConfiguration; import com.jetbrains.python.testing.universalTests.PyUniversalUnitTestFactory; import com.jetbrains.python.testing.universalTests.TestTargetType; @@ -47,9 +48,15 @@ import static org.junit.Assert.assertEquals; */ public final class PythonUnitTestingTest extends PyEnvTestCase { + @Test + public void testMultipleCases() throws Exception { + runPythonTest( + new CreateConfigurationMultipleCasesTask<>(PythonTestConfigurationsModel.PYTHONS_UNITTEST_NAME, PyUniversalUnitTestConfiguration.class)); + } + @Test public void testConfigurationProducer() throws Exception { - new CreateConfigurationTestTask<>(PythonTestConfigurationsModel.PYTHONS_UNITTEST_NAME, PyUniversalUnitTestConfiguration.class); + new CreateConfigurationByFileTask<>(PythonTestConfigurationsModel.PYTHONS_UNITTEST_NAME, PyUniversalUnitTestConfiguration.class); } /** @@ -118,14 +125,14 @@ public final class PythonUnitTestingTest extends PyEnvTestCase { @Test public void testConfigurationProducerOnDirectory() throws Exception { runPythonTest( - new CreateConfigurationTestTask.CreateConfigurationTestAndRenameFolderTask(PythonTestConfigurationsModel.PYTHONS_UNITTEST_NAME, + new CreateConfigurationByFileTask.CreateConfigurationTestAndRenameFolderTask<>(PythonTestConfigurationsModel.PYTHONS_UNITTEST_NAME, PyUniversalUnitTestConfiguration.class)); } @Test public void testRenameClass() throws Exception { runPythonTest( - new CreateConfigurationTestTask.CreateConfigurationTestAndRenameClassTask( + new CreateConfigurationByFileTask.CreateConfigurationTestAndRenameClassTask<>( PythonTestConfigurationsModel.PYTHONS_UNITTEST_NAME, PyUniversalUnitTestConfiguration.class)); }