mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
PY-62419 Pytest fixtures from pytest_plugins are not resolved
Add fixtures searching in `pytest_plugins` statement from `conftest.py` Add tests Merge-request: IJ-MR-121756 Merged-by: Egor Eliseev <Egor.Eliseev@jetbrains.com> GitOrigin-RevId: 673ad9a614dba84ffdf87398f908a54af02be81f
This commit is contained in:
committed by
intellij-monorepo-bot
parent
d31e9ef795
commit
0aecae551e
@@ -8,6 +8,7 @@ import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.stubs.StubIndex
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import com.intellij.util.PathUtil
|
||||
import com.intellij.util.Processor
|
||||
import com.intellij.util.ThreeState
|
||||
import com.jetbrains.extensions.getSdk
|
||||
@@ -164,9 +165,10 @@ private fun findRightFixture(fixtureCandidates: List<PyTestFixture>,
|
||||
*/
|
||||
private fun searchInConftest(fixtureCandidates: List<PyTestFixture>, currentDirectory: PsiDirectory, elementName: String, func: PyFunction?): NamedFixtureLink? {
|
||||
fixtureCandidates.find { it.isInConftestInDir(currentDirectory) }?.let { return NamedFixtureLink(it, null) }
|
||||
// search in imports in "conftest.py" file
|
||||
// search in imports and 'pytest_plugins' in "conftest.py" file
|
||||
(currentDirectory.findFile(CONFTEST_PY) as? PyFile)?.let { pyFile ->
|
||||
getFixtureFromImports(pyFile, elementName, func, fixtureCandidates)?.let { return it }
|
||||
getFixtureFromPytestPlugins(pyFile, fixtureCandidates)?.let { return it }
|
||||
}
|
||||
return null
|
||||
}
|
||||
@@ -192,6 +194,40 @@ private fun getFixtureFromImports(targetFile: PyFile, elementName: String, func:
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Return fixture from pytest_plugins
|
||||
*/
|
||||
private fun getFixtureFromPytestPlugins(targetFile: PyFile, fixtureCandidates: List<PyTestFixture>): NamedFixtureLink? {
|
||||
|
||||
val pyTestPluginsStatement = targetFile.statements.findLast { it is PyAssignmentStatement && it.isAssignmentTo("pytest_plugins") }
|
||||
as? PyAssignmentStatement ?: return null
|
||||
val assignedValue = pyTestPluginsStatement.assignedValue ?: return null // str or Sequence[str]
|
||||
|
||||
val fixtures: List<PyExpression> = when (assignedValue) {
|
||||
is PyListLiteralExpression -> assignedValue.elements.toList()
|
||||
is PyStringLiteralExpression -> listOf(assignedValue)
|
||||
is PyParenthesizedExpression -> assignedValue.children.find { it is PyTupleExpression }?.let { tuple ->
|
||||
(tuple as PyTupleExpression).elements.filterIsInstance<PyStringLiteralExpression>()
|
||||
} ?: emptyList()
|
||||
else -> emptyList()
|
||||
}
|
||||
|
||||
if (fixtures.isEmpty()) return null
|
||||
|
||||
val fixturesPaths = fixtures.map {
|
||||
val text = it.text
|
||||
text.subSequence(1, text.length - 1).toString().replace('.', '/')
|
||||
}
|
||||
|
||||
val candidate = fixtureCandidates.find { fixtureCandidate ->
|
||||
var fixtureFilePath = fixtureCandidate.function?.containingFile?.virtualFile?.path ?: return@find false
|
||||
fixtureFilePath = PathUtil.toSystemIndependentName(fixtureFilePath).let { it.subSequence(0, it.length - 3).toString() }
|
||||
fixturesPaths.any { fixtureFilePath.endsWith(it) }
|
||||
} ?: return null
|
||||
|
||||
return NamedFixtureLink(candidate, null)
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Boolean If named parameter has fixture or not
|
||||
*/
|
||||
@@ -221,7 +257,6 @@ fun findDecoratorsByName(module: Module, vararg names: String): Iterable<PyDecor
|
||||
}
|
||||
|
||||
|
||||
|
||||
private fun createFixture(decorator: PyDecorator): PyTestFixture? {
|
||||
val target = decorator.target ?: return null
|
||||
return (decorator.getNamedArgument("name") ?: target.name)?.let { name ->
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
pytest_plugins = ["fixtures.first", "fixtures.second"]
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
import pytest
|
||||
|
||||
@pytest.fixture
|
||||
def first():
|
||||
return 1
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
import pytest
|
||||
|
||||
@pytest.fixture
|
||||
def second():
|
||||
return 2
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
import pytest
|
||||
|
||||
|
||||
def test_first(fi<caret>rst):
|
||||
assert first == 1
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
import pytest
|
||||
|
||||
|
||||
def test_second(sec<caret>ond):
|
||||
assert second == 2
|
||||
+1
@@ -0,0 +1 @@
|
||||
pytest_plugins = "fixtures.first"
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
import pytest
|
||||
|
||||
@pytest.fixture
|
||||
def first():
|
||||
return 1
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
import pytest
|
||||
|
||||
def test_first(fi<caret>rst):
|
||||
assert first == 1
|
||||
+1
@@ -0,0 +1 @@
|
||||
pytest_plugins = ("fixtures.first", "fixtures.second")
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
import pytest
|
||||
|
||||
@pytest.fixture
|
||||
def first():
|
||||
return 1
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
import pytest
|
||||
|
||||
@pytest.fixture
|
||||
def second():
|
||||
return 2
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
import pytest
|
||||
|
||||
|
||||
def test_first(fi<caret>rst):
|
||||
assert first == 1
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
import pytest
|
||||
|
||||
|
||||
def test_second(sec<caret>ond):
|
||||
assert second == 2
|
||||
@@ -58,6 +58,20 @@ class PyTestFixtureResolvingTest : PyTestCase() {
|
||||
const val TEST_IMPORTED_FIXTURE_IN_CONFTEST = "/test_imported_fixtures_in_conftest.py"
|
||||
const val IMPORTED_FIXTURE_IN_CONFTEST_FOO_FIXTURES_DIR_NAME = "fixtures"
|
||||
const val IMPORTED_FIXTURE_IN_CONFTEST_FOO_FIXTURES = "foo_fixtures.py"
|
||||
|
||||
const val PYTEST_PLUGINS_FIXTURES_DIR_NAME = "testPytestPluginsFixtures"
|
||||
const val PYTEST_PLUGINS_FIXTURES_DIR = "/$PYTEST_PLUGINS_FIXTURES_DIR_NAME"
|
||||
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 = "fixtures"
|
||||
const val PYTEST_PLUGINS_FIXTURES_FIRST = "first.py"
|
||||
const val PYTEST_PLUGINS_FIXTURES_SECOND = "second.py"
|
||||
const val PYTEST_PLUGINS_FIXTURES_AS_LIST_FIRST_TEST = "/test_pytest_plugins_as_list_first.py"
|
||||
const val PYTEST_PLUGINS_FIXTURES_AS_LIST_SECOND_TEST = "/test_pytest_plugins_as_list_second.py"
|
||||
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"
|
||||
}
|
||||
|
||||
override fun getTestDataPath() = super.getTestDataPath() + TESTS_SUBDIR
|
||||
@@ -223,4 +237,21 @@ class PyTestFixtureResolvingTest : PyTestCase() {
|
||||
fun testImportedFixtureInConftest() {
|
||||
assertCorrectFile(IMPORTED_FIXTURE_IN_CONFTEST_DIR, TEST_IMPORTED_FIXTURE_IN_CONFTEST, IMPORTED_FIXTURE_IN_CONFTEST_FOO_FIXTURES, IMPORTED_FIXTURE_IN_CONFTEST_FOO_FIXTURES_DIR_NAME)
|
||||
}
|
||||
|
||||
fun testPytestPluginsFixtureAsList() {
|
||||
val testDir = PYTEST_PLUGINS_FIXTURES_DIR + PYTEST_PLUGINS_FIXTURES_AS_LIST_DIR
|
||||
assertCorrectFile(testDir, PYTEST_PLUGINS_FIXTURES_AS_LIST_FIRST_TEST, PYTEST_PLUGINS_FIXTURES_FIRST, PYTEST_PLUGINS_FIXTURES)
|
||||
assertCorrectFile(testDir, PYTEST_PLUGINS_FIXTURES_AS_LIST_SECOND_TEST, PYTEST_PLUGINS_FIXTURES_SECOND, PYTEST_PLUGINS_FIXTURES)
|
||||
}
|
||||
|
||||
fun testPytestPluginsFixtureAsTuple() {
|
||||
val testDir = PYTEST_PLUGINS_FIXTURES_DIR + PYTEST_PLUGINS_FIXTURES_AS_TUPLE_DIR
|
||||
assertCorrectFile(testDir, PYTEST_PLUGINS_FIXTURES_AS_TUPLE_FIRST_TEST, PYTEST_PLUGINS_FIXTURES_FIRST, PYTEST_PLUGINS_FIXTURES)
|
||||
assertCorrectFile(testDir, PYTEST_PLUGINS_FIXTURES_AS_TUPLE_SECOND_TEST, PYTEST_PLUGINS_FIXTURES_SECOND, PYTEST_PLUGINS_FIXTURES)
|
||||
}
|
||||
|
||||
fun testPytestPluginsFixtureAsStr() {
|
||||
val testDir = PYTEST_PLUGINS_FIXTURES_DIR + PYTEST_PLUGINS_FIXTURES_AS_STR_DIR
|
||||
assertCorrectFile(testDir, PYTEST_PLUGINS_FIXTURES_AS_STR_TEST, PYTEST_PLUGINS_FIXTURES_FIRST, PYTEST_PLUGINS_FIXTURES)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user