PY-60568 Resolving for reserved fixtures from pytest is not working

GitOrigin-RevId: 2b013f95e337695c220e75cdbe18b866aa165b6f
This commit is contained in:
Egor.Eliseev
2023-05-19 16:34:51 +00:00
committed by intellij-monorepo-bot
parent 2705b92a97
commit 8ff01dc5f6
43 changed files with 382 additions and 15 deletions
@@ -21,9 +21,6 @@ import com.jetbrains.python.testing.TestRunnerService
import com.jetbrains.python.testing.autoDetectTests.PyAutoDetectionConfigurationFactory
import com.jetbrains.python.testing.isTestElement
private const val CONFTEST_PY = "conftest.py"
private const val REQUEST_FIXTURE = "request"
private val decoratorNames = arrayOf("pytest.fixture", "fixture")
private val PyFunction.asFixture: PyTestFixture?
@@ -122,6 +119,19 @@ private fun findRightFixture(fixtureCandidates: List<PyTestFixture>,
}
}
// search reserved fixture in "_pytest" dir
if (!fixtureCandidates.isEmpty()) {
fixtureCandidates.find { fixtureCandidate ->
fixtureCandidate.function?.containingFile?.containingDirectory?.name == _PYTEST_DIR && fixtureNamedParameter.name in reservedFixturesSet
}?.let { return NamedFixtureParameterLink(it, null) }
}
// search reserved fixture class in "_pytest" dir
if (fixtureNamedParameter.name in reservedFixtureClassSet) {
fixtureNamedParameter.name?.let {
return NamedFixtureParameterLink(PyTestFixture(null, null, it), null)
}
}
return null
}
@@ -0,0 +1,31 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.jetbrains.python.testing.pyTestFixtures
const val CONFTEST_PY = "conftest.py"
const val REQUEST_FIXTURE = "request"
const val _PYTEST_DIR = "_pytest"
val reservedFixturesSet = setOf(
"capfd",
"capfdbinary",
"caplog",
"capsys",
"capsysbinary",
"cache",
"doctest_namespace",
"monkeypatch",
"pytestconfig",
"pytester",
"record_property",
"record_testsuite_property",
"recwarn",
"tmp_path",
"tmp_path_factory"
)
val reservedFixtureClassSet = setOf(
"testdir",
"tmpdir",
"tmpdir_factory"
)
@@ -0,0 +1,73 @@
@fixture
def cache():
pass
@fixture
def capfd():
pass
@fixture
def capfdbinary():
pass
@fixture
def caplog():
pass
@fixture
def capsys():
pass
@fixture
def capsysbinary():
pass
@fixture
def doctest_namespace():
pass
@fixture
def monkeypatch():
pass
@fixture
def pytestconfig():
pass
@fixture
def pytester():
pass
@fixture
def record_property():
pass
@fixture
def record_testsuite_property():
pass
@fixture
def recwarn():
pass
@fixture
def tmp_path():
pass
@fixture
def tmp_path_factory():
pass
@@ -0,0 +1,4 @@
import pytest
def test_(cac<caret>he):
pass
@@ -0,0 +1,4 @@
import pytest
def test_(cap<caret>fd):
pass
@@ -0,0 +1,4 @@
import pytest
def test_(capfdbinar<caret>y):
pass
@@ -0,0 +1,4 @@
import pytest
def test_(cap<caret>log):
pass
@@ -0,0 +1,4 @@
import pytest
def test_(cap<caret>sys):
pass
@@ -0,0 +1,4 @@
import pytest
def test_(cap<caret>sysbinary):
pass
@@ -0,0 +1,4 @@
import pytest
def test_(doctest<caret>_namespace):
pass
@@ -0,0 +1,4 @@
import pytest
def test_(monkey<caret>patch):
pass
@@ -0,0 +1,8 @@
import pytest
@pytest.fixture
def cache():
return 1
def test_(cac<caret>he):
pass
@@ -0,0 +1,8 @@
import pytest
@pytest.fixture
def capfd():
return 1
def test_(cap<caret>fd):
pass
@@ -0,0 +1,8 @@
import pytest
@pytest.fixture
def capfdbinary():
return 1
def test_(cap<caret>fdbinary):
pass
@@ -0,0 +1,8 @@
import pytest
@pytest.fixture
def caplog():
return 1
def test_(cap<caret>log):
pass
@@ -0,0 +1,8 @@
import pytest
@pytest.fixture
def capsys():
return 1
def test_(cap<caret>sys):
pass
@@ -0,0 +1,8 @@
import pytest
@pytest.fixture
def capsysbinary():
return 1
def test_(capsys<caret>binary):
pass
@@ -0,0 +1,8 @@
import pytest
@pytest.fixture
def doctest_namespace():
return 1
def test_(doctest_<caret>namespace):
pass
@@ -0,0 +1,8 @@
import pytest
@pytest.fixture
def monkeypatch():
return 1
def test_(monkey<caret>patch):
pass
@@ -0,0 +1,8 @@
import pytest
@pytest.fixture
def pytestconfig():
return 1
def test_(pytest<caret>config):
pass
@@ -0,0 +1,8 @@
import pytest
@pytest.fixture
def pytester():
return 1
def test_(pytest<caret>er):
pass
@@ -0,0 +1,8 @@
import pytest
@pytest.fixture
def record_property():
return 1
def test_(record_<caret>property):
pass
@@ -0,0 +1,8 @@
import pytest
@pytest.fixture
def record_testsuite_property():
return 1
def test_(record_testsuite_<caret>property):
pass
@@ -0,0 +1,8 @@
import pytest
@pytest.fixture
def recwarn():
return 1
def test_(rec<caret>warn):
pass
@@ -0,0 +1,8 @@
import pytest
@pytest.fixture
def testdir():
return 1
def test_(test<caret>dir):
pass
@@ -0,0 +1,8 @@
import pytest
@pytest.fixture
def tmp_path_factory():
return 1
def test_(tmp_path_<caret>factory):
pass
@@ -0,0 +1,8 @@
import pytest
@pytest.fixture
def tmp_path():
return 1
def test_(tmp_<caret>path):
pass
@@ -0,0 +1,8 @@
import pytest
@pytest.fixture
def tmpdir_factory():
return 1
def test_(tmpdir_<caret>factory):
pass
@@ -0,0 +1,8 @@
import pytest
@pytest.fixture
def tmpdir():
return 1
def test_(tmp<caret>dir):
pass
@@ -0,0 +1,4 @@
import pytest
def test_(pytest<caret>config):
pass
@@ -0,0 +1,4 @@
import pytest
def test_(pytest<caret>er):
pass
@@ -0,0 +1,4 @@
import pytest
def test_(record_<caret>property):
pass
@@ -0,0 +1,4 @@
import pytest
def test_(record_testsuite_<caret>property):
pass
@@ -0,0 +1,4 @@
import pytest
def test_(rec<caret>warn):
pass
@@ -0,0 +1,4 @@
import pytest
def test_(test<caret>dir):
pass
@@ -0,0 +1,4 @@
import pytest
def test_(tmp_path_<caret>factory):
pass
@@ -0,0 +1,4 @@
import pytest
def test_(tmp_<caret>path):
pass
@@ -0,0 +1,4 @@
import pytest
def test_(tmpdir_<caret>factory):
pass
@@ -0,0 +1,4 @@
import pytest
def test_(tmp<caret>dir):
pass
@@ -5,14 +5,13 @@ import com.intellij.psi.*
import com.jetbrains.python.fixture.PythonCommonTestCase
import com.jetbrains.python.fixtures.PyTestCase
import com.jetbrains.python.psi.resolve.ImportedResolveResult
import com.jetbrains.python.testing.pyTestFixtures.PyTestFixtureReference
import com.jetbrains.python.testing.pyTestFixtures.*
import junit.framework.TestCase
class PyTestFixtureOverridingTest : PyTestCase() {
companion object {
const val TESTS_SUBDIR = "/testPytestFixtureOverriding"
const val CONFTEST_FILE = "conftest.py"
const val SIMPLE_TEST_DIR = "/testSimple"
const val SIMPLE_TEST_CONFTEST_FIXTURE = "/test_conftest_fixture.py"
@@ -40,11 +39,12 @@ class PyTestFixtureOverridingTest : PyTestCase() {
const val COMPLEX_STRUCTURE_TEST_NEW_CONFTEST = "/$COMPLEX_STRUCTURE_TEST_DIR_WITH_CONFTEST_NAME/test_new_conftest.py"
const val COMPLEX_STRUCTURE_TEST_ROOT_CONFTEST = "/dir_without_conftest/test_root_conftest.py"
const val REQUEST_TEST_DIR = "/testRequest"
const val REQUEST_FIXTURE = "request"
const val RESERVED_FIXTURES_TEST_DIR = "/testReservedFixtures"
const val RESERVED_FIXTURES_TEST_FILE = "reserved_fixtures.py"
const val REQUEST_TEST_IN_FIXTURE = "/test_request_in_fixture.py"
const val REQUEST_TEST_IN_TEST = "/test_request_in_test.py"
const val REQUEST_USAGES_TEST = "${REQUEST_TEST_DIR}/test_request_usages.py"
const val REQUEST_USAGES_TEST = "${RESERVED_FIXTURES_TEST_DIR}/test_request_usages.py"
}
override fun getTestDataPath() = super.getTestDataPath() + TESTS_SUBDIR
@@ -53,10 +53,10 @@ class PyTestFixtureOverridingTest : PyTestCase() {
super.setUp()
TestRunnerService.getInstance(myFixture.module).selectedFactory =
PythonTestConfigurationType.getInstance().pyTestFactory
myFixture.copyDirectoryToProject("", "")
}
private fun getCaretReference(dirName: String, fileName: String): PsiReference? {
myFixture.copyDirectoryToProject("", "")
val psiFile = myFixture.configureByFile(dirName + fileName)
return psiFile?.findReferenceAt(myFixture.caretOffset)
}
@@ -94,8 +94,24 @@ class PyTestFixtureOverridingTest : PyTestCase() {
TestCase.assertTrue(hasImportedFixtureStatement)
}
private fun getReservedFixturesFiles(fixturesSet: Set<String>): Set<String> {
val result = mutableSetOf<String>()
for (fixture in fixturesSet) {
result.add("/test_${fixture}_fixture.py")
}
return result
}
private fun getReservedOverrideFixturesFiles(fixturesSet: Set<String>): Set<String> {
val result = mutableSetOf<String>()
for (fixture in fixturesSet) {
result.add("test_override_${fixture}_fixture.py")
}
return result
}
fun testSimpleFixtureFromConftest() {
assertCorrectFile(SIMPLE_TEST_DIR, SIMPLE_TEST_CONFTEST_FIXTURE, CONFTEST_FILE)
assertCorrectFile(SIMPLE_TEST_DIR, SIMPLE_TEST_CONFTEST_FIXTURE, CONFTEST_PY)
}
fun testSimpleNotResolve() {
@@ -115,7 +131,7 @@ class PyTestFixtureOverridingTest : PyTestCase() {
}
fun testClassConftestFixture() {
assertCorrectFile(CLASS_TEST_DIR, CLASS_TEST_SUBDIR, CONFTEST_FILE)
assertCorrectFile(CLASS_TEST_DIR, CLASS_TEST_SUBDIR, CONFTEST_PY)
}
fun testImportFixture() {
@@ -131,21 +147,21 @@ class PyTestFixtureOverridingTest : PyTestCase() {
}
fun testComplexStructureNewConftest() {
assertCorrectFile(COMPLEX_STRUCTURE_TEST_DIR, COMPLEX_STRUCTURE_TEST_NEW_CONFTEST, CONFTEST_FILE, COMPLEX_STRUCTURE_TEST_DIR_WITH_CONFTEST_NAME)
assertCorrectFile(COMPLEX_STRUCTURE_TEST_DIR, COMPLEX_STRUCTURE_TEST_NEW_CONFTEST, CONFTEST_PY, COMPLEX_STRUCTURE_TEST_DIR_WITH_CONFTEST_NAME)
}
fun testComplexStructureRootConftest() {
assertCorrectFile(COMPLEX_STRUCTURE_TEST_DIR, COMPLEX_STRUCTURE_TEST_ROOT_CONFTEST, CONFTEST_FILE, COMPLEX_STRUCTURE_TEST_DIR_NAME)
assertCorrectFile(COMPLEX_STRUCTURE_TEST_DIR, COMPLEX_STRUCTURE_TEST_ROOT_CONFTEST, CONFTEST_PY, COMPLEX_STRUCTURE_TEST_DIR_NAME)
}
fun testRequestInFixture() {
val fixtureReference = getCaretReference(REQUEST_TEST_DIR, REQUEST_TEST_IN_FIXTURE) as? PyTestFixtureReference
val fixtureReference = getCaretReference(RESERVED_FIXTURES_TEST_DIR, REQUEST_TEST_IN_FIXTURE) as? PyTestFixtureReference
TestCase.assertNotNull(fixtureReference)
assertEquals(REQUEST_FIXTURE, fixtureReference?.element?.text)
}
fun testRequestInTest() {
val fixtureReference = getCaretReference(REQUEST_TEST_DIR, REQUEST_TEST_IN_TEST) as? PyTestFixtureReference
val fixtureReference = getCaretReference(RESERVED_FIXTURES_TEST_DIR, REQUEST_TEST_IN_TEST) as? PyTestFixtureReference
TestCase.assertNull(fixtureReference)
}
@@ -153,4 +169,25 @@ class PyTestFixtureOverridingTest : PyTestCase() {
val usages = myFixture.testFindUsages(REQUEST_USAGES_TEST)
assertEquals(0, usages.size)
}
fun testReservedFixtures() {
for (file in getReservedFixturesFiles(reservedFixturesSet)) {
assertCorrectFile(RESERVED_FIXTURES_TEST_DIR, "/${file}", RESERVED_FIXTURES_TEST_FILE, _PYTEST_DIR)
}
}
fun testReservedOverrideFixtures() {
val expectedDirName = RESERVED_FIXTURES_TEST_DIR.substring(1)
for (file in getReservedOverrideFixturesFiles(reservedFixturesSet + reservedFixtureClassSet)) {
assertCorrectFile(RESERVED_FIXTURES_TEST_DIR, "/${file}", file, expectedDirName)
}
}
fun testReservedFixtureClasses() {
for (fixture in reservedFixtureClassSet) {
val fixtureReference = getCaretReference(RESERVED_FIXTURES_TEST_DIR, "/test_${fixture}_fixture.py") as? PyTestFixtureReference
TestCase.assertNotNull(fixtureReference)
assertEquals(fixture, fixtureReference?.element?.text)
}
}
}