PY-66043: Resolve module references in PYTEST_PLUGINS

close #2814


Merge-request: IJ-MR-140174
Merged-by: Egor Eliseev <Egor.Eliseev@jetbrains.com>

GitOrigin-RevId: 4a7d46178ceedc283345980f118fbe607d84e685
This commit is contained in:
chbndrhnns
2024-07-17 15:38:34 +00:00
committed by intellij-monorepo-bot
parent ecedd0df00
commit c274285cae
6 changed files with 46 additions and 2 deletions

View File

@@ -270,8 +270,9 @@ private fun getFixtureFromPytestPlugins(targetFile: PyFile, fixtureCandidates: L
val fixtures: List<PyExpression> = when (assignedValue) {
is PyListLiteralExpression -> assignedValue.elements.toList()
is PyStringLiteralExpression -> listOf(assignedValue)
is PyQualifiedExpression -> listOf(getFixtureNameFromQualifiedName(assignedValue))
is PyParenthesizedExpression -> assignedValue.children.find { it is PyTupleExpression }?.let { tuple ->
(tuple as PyTupleExpression).elements.filterIsInstance<PyStringLiteralExpression>()
(tuple as PyTupleExpression).elements.mapNotNull { resolve(it) }
} ?: emptyList()
else -> emptyList()
}
@@ -292,6 +293,12 @@ private fun getFixtureFromPytestPlugins(targetFile: PyFile, fixtureCandidates: L
return NamedFixtureLink(candidate, null)
}
private fun getFixtureNameFromQualifiedName(assignedValue: PyQualifiedExpression): PyStringLiteralExpression {
val factory = PyElementGenerator.getInstance(assignedValue.project)
val qualifiedName = assignedValue.asQualifiedName().toString().substringBeforeLast(".__name__", "")
return factory.createStringLiteralFromString(qualifiedName)
}
/**
* @return Boolean If named parameter has fixture or not
*/
@@ -321,6 +328,15 @@ fun findDecoratorsByName(module: Module, names: Iterable<String>): Iterable<PyDe
}
internal fun resolve(expr: PyExpression): PyExpression? {
when (expr) {
is PyStringLiteralExpression -> return expr
is PyQualifiedExpression -> return getFixtureNameFromQualifiedName(expr)
}
return null
}
private fun createFixture(decorator: PyDecorator): PyTestFixture? {
val target = decorator.target ?: return null
return (decorator.getTestFixtureName() ?: target.name)?.let { name ->

View File

@@ -0,0 +1,5 @@
# Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
from .fixtures import first
pytest_plugins = first.__name__

View File

@@ -0,0 +1,7 @@
# Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
import pytest
@pytest.fixture
def first():
return 1

View File

@@ -0,0 +1,7 @@
# Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
import pytest
def test_first(fi<caret>rst):
assert first == 1

View File

@@ -1 +1,3 @@
pytest_plugins = ("fixtures.first", "fixtures.second")
from .fixtures import second
pytest_plugins = ("fixtures.first", fixtures.second)

View File

@@ -68,6 +68,7 @@ class PyTestFixtureResolvingTest : PyTestCase() {
const val PYTEST_PLUGINS_FIXTURES_AS_LIST_DIR = "/pytest_plugins_as_list"
const val PYTEST_PLUGINS_FIXTURES_AS_STR_DIR = "/pytest_plugins_as_str"
const val PYTEST_PLUGINS_FIXTURES_AS_TUPLE_DIR = "/pytest_plugins_as_tuple"
const val PYTEST_PLUGINS_FIXTURES_AS_REF_DIR = "/pytest_plugins_as_ref"
const val PYTEST_PLUGINS_FIXTURES = "fixtures"
const val PYTEST_PLUGINS_FIXTURES_FIRST = "first.py"
const val PYTEST_PLUGINS_FIXTURES_SECOND = "second.py"
@@ -76,6 +77,7 @@ class PyTestFixtureResolvingTest : PyTestCase() {
const val PYTEST_PLUGINS_FIXTURES_AS_TUPLE_FIRST_TEST = "/test_pytest_plugins_as_tuple_first.py"
const val PYTEST_PLUGINS_FIXTURES_AS_TUPLE_SECOND_TEST = "/test_pytest_plugins_as_tuple_second.py"
const val PYTEST_PLUGINS_FIXTURES_AS_STR_TEST = "/test_pytest_plugins_as_str.py"
const val PYTEST_PLUGINS_FIXTURES_AS_REF_TEST = "/test_pytest_plugins_as_ref.py"
const val IMPORT_WITH_WILDCARD_DIR_NAME = "testImportWithWildcard"
const val IMPORT_WITH_WILDCARD_DIR = "/$IMPORT_WITH_WILDCARD_DIR_NAME"
@@ -293,6 +295,11 @@ class PyTestFixtureResolvingTest : PyTestCase() {
assertCorrectFile(testDir, PYTEST_PLUGINS_FIXTURES_AS_STR_TEST, PYTEST_PLUGINS_FIXTURES_FIRST, PYTEST_PLUGINS_FIXTURES)
}
fun testPytestPluginsFixtureAsReferences() {
val testDir = PYTEST_PLUGINS_FIXTURES_DIR + PYTEST_PLUGINS_FIXTURES_AS_REF_DIR
assertCorrectFile(testDir, PYTEST_PLUGINS_FIXTURES_AS_REF_TEST, PYTEST_PLUGINS_FIXTURES_FIRST, PYTEST_PLUGINS_FIXTURES)
}
fun testImportWithWildCardFromInit() {
val testDir = IMPORT_WITH_WILDCARD_DIR + IMPORT_WITH_WILDCARD_FROM_INIT_DIR
assertCorrectFile(testDir, IMPORT_WITH_WILDCARD_TEST_FILE, IMPORT_WITH_WILDCARD_FIXTURES_FILE, IMPORT_WITH_WILDCARD_FIXTURES_DIR)