mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[python] PY-59322 Don't add gutter icon to pytest fixtures with test_* prefix
Merge-request: IJ-MR-181128 Merged-by: Egor Eliseev <Egor.Eliseev@jetbrains.com> GitOrigin-RevId: 3f1d486d3bab13647f498ce3f146b43c3638f2ea
This commit is contained in:
committed by
intellij-monorepo-bot
parent
57dc355ada
commit
a5a215495f
@@ -9,18 +9,35 @@ import com.jetbrains.python.psi.PyClass
|
||||
import com.jetbrains.python.psi.PyFile
|
||||
import com.jetbrains.python.psi.PyFunction
|
||||
import com.jetbrains.python.psi.types.TypeEvalContext
|
||||
import com.jetbrains.python.testing.pyTestFixtures.TEST_FIXTURE_DECORATOR_NAMES
|
||||
|
||||
/**
|
||||
* Any "test_" function could be used as test by pytest.
|
||||
* Pytest could use any "test_" function as a test.
|
||||
* See `PythonUnitTestDetectorsBasedOnSettings.isTestFunction`.
|
||||
*/
|
||||
fun isTestFunction(function: PyFunction) = function.name?.startsWith("test") == true
|
||||
fun isTestFunction(function: PyFunction): Boolean {
|
||||
// Check if the function name starts with "test"
|
||||
val isTestNamed = function.name?.startsWith("test") == true
|
||||
if (!isTestNamed) return false
|
||||
|
||||
// Get the list of decorators, if any, otherwise consider this a test function
|
||||
val decoratorList = function.decoratorList?.decorators ?: return true
|
||||
|
||||
// Determine if any decorator matches known pytest fixture names
|
||||
val isPytestFixture = decoratorList.any { decorator ->
|
||||
val decoratorName = decorator.callee?.text
|
||||
decoratorName in TEST_FIXTURE_DECORATOR_NAMES
|
||||
}
|
||||
|
||||
// A test function must not be a pytest fixture
|
||||
return !isPytestFixture
|
||||
}
|
||||
|
||||
/**
|
||||
* Inheritor of TestCase class is always test for unittest and could also be launched with pytest.
|
||||
* See `PythonUnitTestDetectorsBasedOnSettings.isTestFunction`.
|
||||
*/
|
||||
fun isUnitTestCaseClass(clazz: PyClass, context: TypeEvalContext) = clazz.inherits(context, "unittest.TestCase", "unittest.case.TestCase")
|
||||
fun isUnitTestCaseClass(clazz: PyClass, context: TypeEvalContext): Boolean = clazz.inherits(context, "unittest.TestCase", "unittest.case.TestCase")
|
||||
|
||||
/**
|
||||
* Checks if class [isUnitTestCaseClass] or both conditions are true: it's name starts/ends with "Test" and it has at least one
|
||||
@@ -55,13 +72,13 @@ fun isTestClass(clazz: PyClass, context: TypeEvalContext): Boolean {
|
||||
|
||||
fun isTestFile(file: PyFile,
|
||||
context: TypeEvalContext): Boolean {
|
||||
return if (file.topLevelClasses.stream().anyMatch { o: PyClass ->
|
||||
return if (file.topLevelClasses.any { o: PyClass ->
|
||||
isTestClass(o, context)
|
||||
}) {
|
||||
true
|
||||
}
|
||||
else file.name.startsWith("test_") ||
|
||||
file.topLevelFunctions.stream().anyMatch { o: PyFunction ->
|
||||
file.topLevelFunctions.any { o: PyFunction ->
|
||||
isTestFunction(o)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
import pytest
|
||||
|
||||
@pytest.fixture
|
||||
def test_fixture():
|
||||
return 42
|
||||
|
||||
def test_actual():
|
||||
assert True
|
||||
@@ -6,12 +6,12 @@ import com.intellij.execution.lineMarker.RunLineMarkerContributor.Info
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.jetbrains.python.fixtures.PyTestCase
|
||||
import junit.framework.TestCase
|
||||
|
||||
open class PyTestRunLineMarkerTest : PyTestCase() {
|
||||
companion object {
|
||||
const val TESTS_DIR = "/pyTestLineMarker/"
|
||||
const val PYTHON_FILE = "pythonFile.py"
|
||||
const val FIXTURE_FILE = "fixtureTest.py"
|
||||
}
|
||||
|
||||
override fun getTestDataPath(): String = super.getTestDataPath() + TESTS_DIR
|
||||
@@ -25,9 +25,9 @@ open class PyTestRunLineMarkerTest : PyTestCase() {
|
||||
|
||||
protected fun getCaretElement(fileName: String): PsiElement? {
|
||||
val psiFile = configureByFile(fileName)
|
||||
TestCase.assertNotNull("Can't find test file", psiFile)
|
||||
assertNotNull("Can't find test file", psiFile)
|
||||
val element = psiFile?.findElementAt(myFixture.caretOffset)
|
||||
TestCase.assertNotNull("Can't find caret element", element)
|
||||
assertNotNull("Can't find caret element", element)
|
||||
return element
|
||||
}
|
||||
|
||||
@@ -37,14 +37,14 @@ open class PyTestRunLineMarkerTest : PyTestCase() {
|
||||
|
||||
protected fun assertInfoFound(element: PsiElement, lineMarkerContributor: RunLineMarkerContributor) {
|
||||
val info = getInfo(element, lineMarkerContributor)
|
||||
TestCase.assertNotNull("Info is not found", info)
|
||||
assertNotNull("Info is not found", info)
|
||||
if (info != null) {
|
||||
TestCase.assertNotNull("Run icon is not found", info.icon)
|
||||
assertNotNull("Run icon is not found", info.icon)
|
||||
}
|
||||
}
|
||||
|
||||
protected fun assertInfoNotFound(element: PsiElement, lineMarkerContributor: RunLineMarkerContributor) {
|
||||
TestCase.assertNull("Info is found", getInfo(element, lineMarkerContributor))
|
||||
assertNull("Info is found", getInfo(element, lineMarkerContributor))
|
||||
}
|
||||
|
||||
fun testPythonFile() {
|
||||
@@ -54,4 +54,23 @@ open class PyTestRunLineMarkerTest : PyTestCase() {
|
||||
assertInfoFound(element, lineMarkerContributor)
|
||||
}
|
||||
}
|
||||
|
||||
fun testFixtureWithTestPrefix() {
|
||||
val lineMarkerContributor = PyTestLineMarkerContributor()
|
||||
|
||||
myFixture.configureByText(FIXTURE_FILE, """
|
||||
import pytest
|
||||
|
||||
@pytest.fixture
|
||||
def <caret>test_fixture():
|
||||
return 42
|
||||
|
||||
def test_actual():
|
||||
assert True
|
||||
""".trimIndent())
|
||||
|
||||
val fixtureElement = myFixture.file.findElementAt(myFixture.caretOffset)
|
||||
assertNotNull(fixtureElement)
|
||||
assertInfoNotFound(fixtureElement!!, lineMarkerContributor)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user