mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-03-22 15:19:59 +07:00
PY-48996: mark folders as test
PoC GitOrigin-RevId: d63c9b180bbdc96e6fc08ec8f63452ca187210ea
This commit is contained in:
committed by
intellij-monorepo-bot
parent
43c8fde108
commit
a9530c1efa
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.jetbrains.python;
|
||||
|
||||
import com.intellij.ide.util.projectWizard.EmptyModuleBuilder;
|
||||
@@ -21,6 +21,6 @@ public class PlatformPythonModuleType extends PythonModuleTypeBase<EmptyModuleBu
|
||||
|
||||
@Override
|
||||
public boolean isSupportedRootType(JpsModuleSourceRootType<?> type) {
|
||||
return type == JavaSourceRootType.SOURCE;
|
||||
return type == JavaSourceRootType.SOURCE || type == JavaSourceRootType.TEST_SOURCE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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.
|
||||
*/
|
||||
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.jetbrains.python.configuration;
|
||||
|
||||
import com.intellij.facet.impl.DefaultFacetsProvider;
|
||||
@@ -91,7 +77,7 @@ public class PyContentEntriesModuleConfigurable extends SearchableConfigurable.P
|
||||
}
|
||||
|
||||
protected PyContentEntriesEditor createEditor(@NotNull Module module, @NotNull ModuleConfigurationStateImpl state) {
|
||||
return new PyContentEntriesEditor(module, state, true, JavaSourceRootType.SOURCE);
|
||||
return new PyContentEntriesEditor(module, state, true, JavaSourceRootType.SOURCE, JavaSourceRootType.TEST_SOURCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
<action id="MarkSourceRoot" class="com.intellij.ide.projectView.actions.MarkJavaSourceRootAction"/>
|
||||
<action id="MarkExcludeRoot" class="com.intellij.ide.projectView.actions.MarkExcludeRootAction"/>
|
||||
<action id="MarkAsContentRoot" class="com.intellij.ide.projectView.actions.MarkAsContentRootAction"/>
|
||||
<action id="MarkTestSourceRoot" class="com.intellij.ide.projectView.actions.MarkTestSourceRootAction"/>
|
||||
<action id="UnmarkRoot" class="com.intellij.ide.projectView.actions.UnmarkRootAction"/>
|
||||
<add-to-group group-id="MarkRootGroup"/>
|
||||
</group>
|
||||
|
||||
@@ -12,10 +12,12 @@ import com.intellij.execution.testframework.sm.runner.SMTRunnerConsoleProperties
|
||||
import com.intellij.execution.testframework.sm.runner.SMTestLocator
|
||||
import com.intellij.openapi.application.runReadAction
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.module.ModuleUtil
|
||||
import com.intellij.openapi.module.impl.scopes.ModuleWithDependenciesScope
|
||||
import com.intellij.openapi.options.SettingsEditor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.openapi.roots.ModuleRootManager
|
||||
import com.intellij.openapi.util.JDOMExternalizerUtil.readField
|
||||
import com.intellij.openapi.util.JDOMExternalizerUtil.writeField
|
||||
import com.intellij.openapi.util.Pair
|
||||
@@ -26,6 +28,7 @@ import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.PsiDirectory
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFileSystemItem
|
||||
import com.intellij.psi.PsiManager
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.util.QualifiedName
|
||||
import com.intellij.refactoring.listeners.RefactoringElementListener
|
||||
@@ -53,6 +56,7 @@ import jetbrains.buildServer.messages.serviceMessages.ServiceMessage
|
||||
import jetbrains.buildServer.messages.serviceMessages.TestStdErr
|
||||
import jetbrains.buildServer.messages.serviceMessages.TestStdOut
|
||||
import org.jetbrains.annotations.PropertyKey
|
||||
import org.jetbrains.jps.model.java.JavaSourceRootType
|
||||
import java.util.regex.Matcher
|
||||
|
||||
/**
|
||||
@@ -94,9 +98,7 @@ internal fun getAdditionalArgumentsProperty() = PyAbstractTestConfiguration::add
|
||||
*/
|
||||
fun isTestElement(element: PsiElement, testCaseClassRequired: ThreeState, typeEvalContext: TypeEvalContext): Boolean = when (element) {
|
||||
is PyFile -> PythonUnitTestDetectorsBasedOnSettings.isTestFile(element, testCaseClassRequired, typeEvalContext)
|
||||
is com.intellij.psi.PsiDirectory -> element.name.contains("test", true) || element.children.any {
|
||||
it is PyFile && PythonUnitTestDetectorsBasedOnSettings.isTestFile(it, testCaseClassRequired, typeEvalContext)
|
||||
}
|
||||
is PsiDirectory -> isTestFolder(element, testCaseClassRequired, typeEvalContext)
|
||||
is PyFunction -> PythonUnitTestDetectorsBasedOnSettings.isTestFunction(element,
|
||||
testCaseClassRequired, typeEvalContext)
|
||||
is com.jetbrains.python.psi.PyClass -> {
|
||||
@@ -105,6 +107,25 @@ fun isTestElement(element: PsiElement, testCaseClassRequired: ThreeState, typeEv
|
||||
else -> false
|
||||
}
|
||||
|
||||
/**
|
||||
* If element is a subelement of the folder excplicitly marked as test root -- use it
|
||||
*/
|
||||
private fun getExplicitlyConfiguredTestRoot(element: PsiFileSystemItem): VirtualFile? {
|
||||
val vfDirectory = element.virtualFile
|
||||
val module = ModuleUtil.findModuleForPsiElement(element) ?: return null
|
||||
return ModuleRootManager.getInstance(module).getSourceRoots(JavaSourceRootType.TEST_SOURCE).firstOrNull {
|
||||
VfsUtil.isAncestor(it, vfDirectory, false)
|
||||
}
|
||||
}
|
||||
|
||||
private fun isTestFolder(element: PsiDirectory,
|
||||
testCaseClassRequired: ThreeState,
|
||||
typeEvalContext: TypeEvalContext): Boolean {
|
||||
return (getExplicitlyConfiguredTestRoot(element) != null) || element.name.contains("test", true) || element.children.any {
|
||||
it is PyFile && PythonUnitTestDetectorsBasedOnSettings.isTestFile(it, testCaseClassRequired, typeEvalContext)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Since runners report names of tests as qualified name, no need to convert it to PSI and back to string.
|
||||
@@ -734,9 +755,14 @@ internal class PyTestsConfigurationProducer : AbstractPythonTestConfigurationPro
|
||||
}
|
||||
|
||||
/**
|
||||
* Inspects file relative imports, finds farthest and returns folder with imported file
|
||||
* Returns test root for this file. Either it is specified explicitly or calculated using following strategy:
|
||||
* Inspect file relative imports, find farthest and return folder with imported file
|
||||
*/
|
||||
private fun getDirectoryForFileToBeImportedFrom(file: PyFile): PsiDirectory? {
|
||||
getExplicitlyConfiguredTestRoot(file)?.let {
|
||||
return PsiManager.getInstance(file.project).findDirectory(it)
|
||||
}
|
||||
|
||||
val maxRelativeLevel = file.fromImports.map { it.relativeLevel }.maxOrNull() ?: 0
|
||||
var elementFolder = file.parent ?: return null
|
||||
for (i in 1..maxRelativeLevel) {
|
||||
@@ -794,8 +820,7 @@ internal class PyTestsConfigurationProducer : AbstractPythonTestConfigurationPro
|
||||
location.metainfo?.let { configuration.setMetaInfo(it) }
|
||||
}
|
||||
else {
|
||||
val targetForConfig = PyTestsConfigurationProducer.getTargetForConfig(configuration,
|
||||
element) ?: return false
|
||||
val targetForConfig = getTargetForConfig(configuration, element) ?: return false
|
||||
targetForConfig.configurationTarget.copyTo(configuration.target)
|
||||
// Directory may be set in Default configuration. In that case no need to rewrite it.
|
||||
if (configuration.workingDirectory.isNullOrEmpty()) {
|
||||
|
||||
Reference in New Issue
Block a user