From 6febe1e8a21b99c6e31259b3cbcacc76094631bd Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Mon, 27 Mar 2017 18:02:21 +0200 Subject: [PATCH] Convert RenameTest to light fixture test case Extract multi-module rename test to a separate class. --- .../kotlin/generators/tests/GenerateTests.kt | 5 + ...thJdkAndRuntimeLightProjectDescriptor.java | 2 +- .../rename/renameEquals/equals.test | 3 +- .../after/RenameKotlinPropertyWithJvmField.kt | 2 +- .../after/A/A.iml | 0 .../after/A/notSrc/test2.kt | 0 .../after/A/src/foo/test.kt | 0 .../before/A/A.iml | 0 .../before/A/notSrc/test.kt | 0 .../before/A/src/foo/test.kt | 0 ...SourceRootWithNamesakeUnderSourceRoot.test | 0 .../rename/AbstractMultiModuleRenameTest.kt | 61 +++++ .../refactoring/rename/AbstractRenameTest.kt | 227 +++++++++--------- .../MultiModuleRenameTestGenerated.java | 44 ++++ .../rename/RenameTestGenerated.java | 6 - .../tests/rename/AbstractSpringRenameTest.kt | 2 +- 16 files changed, 233 insertions(+), 119 deletions(-) rename idea/testData/refactoring/{rename => renameMultiModule}/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/after/A/A.iml (100%) rename idea/testData/refactoring/{rename => renameMultiModule}/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/after/A/notSrc/test2.kt (100%) rename idea/testData/refactoring/{rename => renameMultiModule}/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/after/A/src/foo/test.kt (100%) rename idea/testData/refactoring/{rename => renameMultiModule}/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/before/A/A.iml (100%) rename idea/testData/refactoring/{rename => renameMultiModule}/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/before/A/notSrc/test.kt (100%) rename idea/testData/refactoring/{rename => renameMultiModule}/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/before/A/src/foo/test.kt (100%) rename idea/testData/refactoring/{rename => renameMultiModule}/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/fileNotUnderSourceRootWithNamesakeUnderSourceRoot.test (100%) create mode 100644 idea/tests/org/jetbrains/kotlin/idea/refactoring/rename/AbstractMultiModuleRenameTest.kt create mode 100644 idea/tests/org/jetbrains/kotlin/idea/refactoring/rename/MultiModuleRenameTestGenerated.java diff --git a/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt b/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt index 706d0dca4b0..d66df71f881 100755 --- a/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt +++ b/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt @@ -114,6 +114,7 @@ import org.jetbrains.kotlin.idea.refactoring.introduce.AbstractExtractionTest import org.jetbrains.kotlin.idea.refactoring.move.AbstractMoveTest import org.jetbrains.kotlin.idea.refactoring.pullUp.AbstractPullUpTest import org.jetbrains.kotlin.idea.refactoring.pushDown.AbstractPushDownTest +import org.jetbrains.kotlin.idea.refactoring.rename.AbstractMultiModuleRenameTest import org.jetbrains.kotlin.idea.refactoring.rename.AbstractRenameTest import org.jetbrains.kotlin.idea.refactoring.safeDelete.AbstractSafeDeleteTest import org.jetbrains.kotlin.idea.repl.AbstractIdeReplCompletionTest @@ -742,6 +743,10 @@ fun main(args: Array) { model("refactoring/rename", extension = "test", singleClass = true) } + testClass { + model("refactoring/renameMultiModule", extension = "test", singleClass = true) + } + testClass { model("codeInsight/outOfBlock") } diff --git a/idea/idea-test-framework/src/org/jetbrains/kotlin/idea/test/KotlinWithJdkAndRuntimeLightProjectDescriptor.java b/idea/idea-test-framework/src/org/jetbrains/kotlin/idea/test/KotlinWithJdkAndRuntimeLightProjectDescriptor.java index 4e33a30ebf7..12bcbbdfa3b 100644 --- a/idea/idea-test-framework/src/org/jetbrains/kotlin/idea/test/KotlinWithJdkAndRuntimeLightProjectDescriptor.java +++ b/idea/idea-test-framework/src/org/jetbrains/kotlin/idea/test/KotlinWithJdkAndRuntimeLightProjectDescriptor.java @@ -30,7 +30,7 @@ public class KotlinWithJdkAndRuntimeLightProjectDescriptor extends KotlinJdkAndL super(ForTestCompileRuntime.runtimeJarForTests()); } - protected KotlinWithJdkAndRuntimeLightProjectDescriptor(@NotNull List libraryFiles) { + public KotlinWithJdkAndRuntimeLightProjectDescriptor(@NotNull List libraryFiles) { super(libraryFiles); } diff --git a/idea/testData/refactoring/rename/renameEquals/equals.test b/idea/testData/refactoring/rename/renameEquals/equals.test index 8db83e8f0b4..92675488d44 100644 --- a/idea/testData/refactoring/rename/renameEquals/equals.test +++ b/idea/testData/refactoring/rename/renameEquals/equals.test @@ -3,5 +3,6 @@ "classId": "/A", "oldName": "equals", "newName": "foo", - "mainFile": "equals.kt" + "mainFile": "equals.kt", + "skipSubstitute": true } \ No newline at end of file diff --git a/idea/testData/refactoring/rename/renameKotlinPropertyWithJvmField/after/RenameKotlinPropertyWithJvmField.kt b/idea/testData/refactoring/rename/renameKotlinPropertyWithJvmField/after/RenameKotlinPropertyWithJvmField.kt index 58abb6feeff..bbfba25613d 100644 --- a/idea/testData/refactoring/rename/renameKotlinPropertyWithJvmField/after/RenameKotlinPropertyWithJvmField.kt +++ b/idea/testData/refactoring/rename/renameKotlinPropertyWithJvmField/after/RenameKotlinPropertyWithJvmField.kt @@ -1,5 +1,5 @@ package testing.rename public open class C { - @JvmStatic var second = 1 + @JvmStatic var second = 1 } \ No newline at end of file diff --git a/idea/testData/refactoring/rename/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/after/A/A.iml b/idea/testData/refactoring/renameMultiModule/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/after/A/A.iml similarity index 100% rename from idea/testData/refactoring/rename/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/after/A/A.iml rename to idea/testData/refactoring/renameMultiModule/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/after/A/A.iml diff --git a/idea/testData/refactoring/rename/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/after/A/notSrc/test2.kt b/idea/testData/refactoring/renameMultiModule/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/after/A/notSrc/test2.kt similarity index 100% rename from idea/testData/refactoring/rename/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/after/A/notSrc/test2.kt rename to idea/testData/refactoring/renameMultiModule/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/after/A/notSrc/test2.kt diff --git a/idea/testData/refactoring/rename/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/after/A/src/foo/test.kt b/idea/testData/refactoring/renameMultiModule/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/after/A/src/foo/test.kt similarity index 100% rename from idea/testData/refactoring/rename/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/after/A/src/foo/test.kt rename to idea/testData/refactoring/renameMultiModule/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/after/A/src/foo/test.kt diff --git a/idea/testData/refactoring/rename/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/before/A/A.iml b/idea/testData/refactoring/renameMultiModule/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/before/A/A.iml similarity index 100% rename from idea/testData/refactoring/rename/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/before/A/A.iml rename to idea/testData/refactoring/renameMultiModule/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/before/A/A.iml diff --git a/idea/testData/refactoring/rename/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/before/A/notSrc/test.kt b/idea/testData/refactoring/renameMultiModule/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/before/A/notSrc/test.kt similarity index 100% rename from idea/testData/refactoring/rename/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/before/A/notSrc/test.kt rename to idea/testData/refactoring/renameMultiModule/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/before/A/notSrc/test.kt diff --git a/idea/testData/refactoring/rename/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/before/A/src/foo/test.kt b/idea/testData/refactoring/renameMultiModule/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/before/A/src/foo/test.kt similarity index 100% rename from idea/testData/refactoring/rename/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/before/A/src/foo/test.kt rename to idea/testData/refactoring/renameMultiModule/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/before/A/src/foo/test.kt diff --git a/idea/testData/refactoring/rename/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/fileNotUnderSourceRootWithNamesakeUnderSourceRoot.test b/idea/testData/refactoring/renameMultiModule/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/fileNotUnderSourceRootWithNamesakeUnderSourceRoot.test similarity index 100% rename from idea/testData/refactoring/rename/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/fileNotUnderSourceRootWithNamesakeUnderSourceRoot.test rename to idea/testData/refactoring/renameMultiModule/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/fileNotUnderSourceRootWithNamesakeUnderSourceRoot.test diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/rename/AbstractMultiModuleRenameTest.kt b/idea/tests/org/jetbrains/kotlin/idea/refactoring/rename/AbstractMultiModuleRenameTest.kt new file mode 100644 index 00000000000..a64cd0915b9 --- /dev/null +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/rename/AbstractMultiModuleRenameTest.kt @@ -0,0 +1,61 @@ +/* + * Copyright 2010-2017 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. + */ + +package org.jetbrains.kotlin.idea.refactoring.rename + +import com.intellij.openapi.fileEditor.FileDocumentManager +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.psi.PsiDocumentManager +import com.intellij.psi.PsiManager +import org.jetbrains.kotlin.idea.jsonUtils.getString +import org.jetbrains.kotlin.idea.test.KotlinMultiFileTestCase +import org.jetbrains.kotlin.idea.test.PluginTestCaseBase +import java.io.File + +abstract class AbstractMultiModuleRenameTest : KotlinMultiFileTestCase() { + override fun getTestRoot(): String = "/refactoring/renameMultiModule/" + override fun getTestDataPath(): String = PluginTestCaseBase.getTestDataPathBase() + + fun doTest(path: String) { + val renameParamsObject = loadTestConfiguration(File(path)) + + val file = renameParamsObject.getString("file") + val newName = renameParamsObject.getString("newName") + + isMultiModule = true + + doTestCommittingDocuments { rootDir, _ -> + val mainFile = rootDir.findFileByRelativePath(file)!! + val psiFile = PsiManager.getInstance(project).findFile(mainFile) + + runRenameProcessor(project, newName, psiFile, renameParamsObject, true, true) + } + } + + protected fun doTestCommittingDocuments(action : (VirtualFile, VirtualFile?) -> Unit) { + super.doTest({ rootDir, rootAfter -> + action(rootDir, rootAfter) + + PsiDocumentManager.getInstance(project!!).commitAllDocuments() + FileDocumentManager.getInstance().saveAllDocuments() + }, getTestDirName(true)) + } + + protected fun getTestDirName(lowercaseFirstLetter : Boolean) : String { + val testName = getTestName(lowercaseFirstLetter) + return testName.substring(0, testName.indexOf('_')) + } +} diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/rename/AbstractRenameTest.kt b/idea/tests/org/jetbrains/kotlin/idea/refactoring/rename/AbstractRenameTest.kt index d4d88bf1593..0260cdf38c8 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/rename/AbstractRenameTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/rename/AbstractRenameTest.kt @@ -23,8 +23,6 @@ import com.intellij.lang.properties.psi.PropertiesFile import com.intellij.lang.properties.psi.Property import com.intellij.openapi.actionSystem.CommonDataKeys import com.intellij.openapi.actionSystem.DataContext -import com.intellij.openapi.editor.Editor -import com.intellij.openapi.editor.EditorFactory import com.intellij.openapi.extensions.Extensions import com.intellij.openapi.fileEditor.FileDocumentManager import com.intellij.openapi.module.Module @@ -32,6 +30,7 @@ import com.intellij.openapi.project.Project import com.intellij.openapi.roots.ModuleRootManager import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.util.text.StringUtil +import com.intellij.openapi.vfs.LocalFileSystem import com.intellij.openapi.vfs.VfsUtilCore import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFileVisitor @@ -39,20 +38,21 @@ import com.intellij.psi.* import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil import com.intellij.psi.search.GlobalSearchScope import com.intellij.refactoring.BaseRefactoringProcessor.ConflictsInTestsException -import com.intellij.refactoring.MultiFileTestCase import com.intellij.refactoring.rename.PsiElementRenameHandler import com.intellij.refactoring.rename.RenameHandlerRegistry import com.intellij.refactoring.rename.RenameProcessor import com.intellij.refactoring.rename.RenamePsiElementProcessor import com.intellij.refactoring.rename.naming.AutomaticRenamerFactory import com.intellij.refactoring.util.CommonRefactoringUtil.RefactoringErrorHintException +import com.intellij.testFramework.LightProjectDescriptor import com.intellij.testFramework.PlatformTestUtil +import com.intellij.testFramework.UsefulTestCase +import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.idea.caches.resolve.analyzeFullyAndGetResult import org.jetbrains.kotlin.idea.jsonUtils.getNullableString import org.jetbrains.kotlin.idea.jsonUtils.getString -import org.jetbrains.kotlin.idea.refactoring.toPsiFile import org.jetbrains.kotlin.idea.references.mainReference import org.jetbrains.kotlin.idea.search.allScope import org.jetbrains.kotlin.idea.test.* @@ -63,6 +63,7 @@ import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.serialization.deserialization.findClassAcrossModuleDependencies +import org.jetbrains.kotlin.test.KotlinTestUtils import org.junit.Assert import java.io.File @@ -79,38 +80,47 @@ private enum class RenameType { AUTO_DETECT } -abstract class AbstractRenameTest : KotlinMultiFileTestCase() { +abstract class AbstractRenameTest : KotlinLightCodeInsightFixtureTestCase() { inner class TestContext( - val project: Project = getProject()!!, - val javaFacade: JavaPsiFacade = getJavaFacade()!!, - val module: Module = getModule()!!) + val testFile: File, + val project: Project = getProject(), + val javaFacade: JavaPsiFacade = myFixture.javaFacade, + val module: Module = myFixture.module) - open fun doTest(path : String) { - val fileText = FileUtil.loadFile(File(path), true) + override fun getProjectDescriptor(): LightProjectDescriptor { + if (KotlinTestUtils.isAllFilesPresentTest(getTestName(false))) return super.getProjectDescriptor() - val jsonParser = JsonParser() - val renameObject = jsonParser.parse(fileText) as JsonObject + val testConfigurationFile = File(testDataPath, fileName()) + val renameObject = loadTestConfiguration(testConfigurationFile) + val withRuntime = renameObject.getNullableString("withRuntime") + val libraryInfos = renameObject.getAsJsonArray("libraries")?.map { it.asString!! } + if (libraryInfos != null) { + val jarPaths = listOf(ForTestCompileRuntime.runtimeJarForTests()) + libraryInfos.map { + File(PlatformTestUtil.getCommunityPath(), it.substringAfter("@")) + } + return KotlinWithJdkAndRuntimeLightProjectDescriptor(jarPaths) + } + + if (withRuntime != null) { + return KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE + } + return KotlinLightProjectDescriptor.INSTANCE + } + + open fun doTest(path: String) { + val testFile = File(path) + val renameObject = loadTestConfiguration(testFile) val renameTypeStr = renameObject.getString("type") val hintDirective = renameObject.getNullableString("hint") - val withRuntime = renameObject.getNullableString("withRuntime") - if (withRuntime != null) { - ConfigLibraryUtil.configureKotlinRuntimeAndSdk(myModule, PluginTestCaseBase.mockJdk()) - } - - isMultiModule = renameObject["isMultiModule"]?.asBoolean ?: false - - val libraryInfos = renameObject.getAsJsonArray("libraries")?.map { it.asString!! } ?: emptyList() - ConfigLibraryUtil.configureLibraries(myModule, PlatformTestUtil.getCommunityPath(), libraryInfos) - val fixtureClasses = renameObject.getAsJsonArray("fixtureClasses")?.map { it.asString } ?: emptyList() try { fixtureClasses.forEach { TestFixtureExtension.loadFixture(it, module) } - val context = TestContext() + val context = TestContext(testFile) when (RenameType.valueOf(renameTypeStr)) { RenameType.JAVA_CLASS -> renameJavaClassTest(renameObject, context) @@ -122,7 +132,7 @@ abstract class AbstractRenameTest : KotlinMultiFileTestCase() { RenameType.MARKED_ELEMENT -> renameMarkedElement(renameObject, context) RenameType.FILE -> renameFile(renameObject, context) RenameType.BUNDLE_PROPERTY -> renameBundleProperty(renameObject, context) - RenameType.AUTO_DETECT -> renameWithAutoDetection(renameObject) + RenameType.AUTO_DETECT -> renameWithAutoDetection(renameObject, context) } if (hintDirective != null) { @@ -130,7 +140,7 @@ abstract class AbstractRenameTest : KotlinMultiFileTestCase() { } if (renameObject["checkErrorsAfter"]?.asBoolean ?: false) { - val psiManager = PsiManager.getInstance(myProject) + val psiManager = myFixture.psiManager val visitor = object : VirtualFileVisitor() { override fun visitFile(file: VirtualFile): Boolean { (psiManager.findFile(file) as? KtFile)?.let { DirectiveBasedActionUtils.checkForUnexpectedErrors(it) } @@ -156,7 +166,6 @@ abstract class AbstractRenameTest : KotlinMultiFileTestCase() { } finally { fixtureClasses.forEach { TestFixtureExtension.unloadFixture(it) } - ConfigLibraryUtil.unconfigureLibrariesByInfo(myModule, libraryInfos) } } @@ -168,11 +177,10 @@ abstract class AbstractRenameTest : KotlinMultiFileTestCase() { val mainFilePath = renameParamsObject.getString("mainFile") val newName = renameParamsObject.getString("newName") - doTestCommittingDocuments { rootDir, _ -> + doTestCommittingDocuments(context) { rootDir -> configExtra(rootDir, renameParamsObject) - val mainFile = rootDir.findFileByRelativePath(mainFilePath)!! - val psiFile = PsiManager.getInstance(context.project).findFile(mainFile)!! + val psiFile = myFixture.configureFromTempProjectFile(mainFilePath) val doc = PsiDocumentManager.getInstance(project).getDocument(psiFile)!! val marker = doc.extractMarkerOffset(project, "/*rename*/") @@ -180,14 +188,13 @@ abstract class AbstractRenameTest : KotlinMultiFileTestCase() { val isByRef = renameParamsObject["byRef"]?.asBoolean ?: false val isInjected = renameParamsObject["injected"]?.asBoolean ?: false - var currentEditor: Editor? = null + var currentEditor = myFixture.editor var currentFile: PsiFile = psiFile if (isByRef || isInjected) { - currentEditor = createEditor(mainFile) currentEditor.caretModel.moveToOffset(marker) if (isInjected) { currentFile = InjectedLanguageUtil.findInjectedPsiNoCommit(psiFile, marker)!! - currentEditor = InjectedLanguageUtil.getInjectedEditorForInjectedFile(currentEditor, currentFile) + currentEditor = InjectedLanguageUtil.getInjectedEditorForInjectedFile(myFixture.editor, currentFile) } } val toRename = if (isByRef) { @@ -201,7 +208,7 @@ abstract class AbstractRenameTest : KotlinMultiFileTestCase() { val searchInComments = renameParamsObject["searchInComments"]?.asBoolean ?: true val searchInTextOccurrences = renameParamsObject["searchInTextOccurrences"]?.asBoolean ?: true - runRenameProcessor(context, newName, substitution, renameParamsObject, searchInComments, searchInTextOccurrences) + runRenameProcessor(context.project, newName, substitution, renameParamsObject, searchInComments, searchInTextOccurrences) } } @@ -209,11 +216,11 @@ abstract class AbstractRenameTest : KotlinMultiFileTestCase() { val classFQN = renameParamsObject.getString("classId").toClassId().asSingleFqName().asString() val newName = renameParamsObject.getString("newName") - doTestCommittingDocuments { _, _ -> + doTestCommittingDocuments(context) { _ -> val aClass = context.javaFacade.findClass(classFQN, context.project.allScope())!! val substitution = RenamePsiElementProcessor.forElement(aClass).substituteElementToRename(aClass, null) - runRenameProcessor(context, newName, substitution, renameParamsObject, true, true) + runRenameProcessor(context.project, newName, substitution, renameParamsObject, true, true) } } @@ -222,7 +229,7 @@ abstract class AbstractRenameTest : KotlinMultiFileTestCase() { val methodSignature = renameParamsObject.getString("methodSignature") val newName = renameParamsObject.getString("newName") - doTestCommittingDocuments { _, _ -> + doTestCommittingDocuments(context) { val aClass = context.javaFacade.findClass(classFQN, GlobalSearchScope.moduleScope(context.module))!! val methodText = context.javaFacade.elementFactory.createMethodFromText(methodSignature + "{}", null) @@ -231,7 +238,7 @@ abstract class AbstractRenameTest : KotlinMultiFileTestCase() { if (method == null) throw IllegalStateException("Method with signature '$methodSignature' wasn't found in class $classFQN") val substitution = RenamePsiElementProcessor.forElement(method).substituteElementToRename(method, null) - runRenameProcessor(context, newName, substitution, renameParamsObject, false, false) + runRenameProcessor(context.project, newName, substitution, renameParamsObject, false, false) } } @@ -260,21 +267,19 @@ abstract class AbstractRenameTest : KotlinMultiFileTestCase() { val newName = renameParamsObject.getString("newName") val mainFilePath = renameParamsObject.getNullableString("mainFile") ?: "${getTestDirName(false)}.kt" - doTestCommittingDocuments { rootDir, _ -> - val mainFile = rootDir.findChild(mainFilePath)!! - val document = FileDocumentManager.getInstance().getDocument(mainFile)!! - val jetFile = PsiDocumentManager.getInstance(context.project).getPsiFile(document) as KtFile + doTestCommittingDocuments(context) { + val mainFile = myFixture.configureFromTempProjectFile(mainFilePath) as KtFile - val fileFqn = jetFile.packageFqName + val fileFqn = mainFile.packageFqName Assert.assertTrue("File '${mainFilePath}' should have package containing ${fqn}", fileFqn.isSubpackageOf(fqn)) - val packageSegment = jetFile.packageDirective!!.packageNames[fqn.pathSegments().size - 1] + val packageSegment = mainFile.packageDirective!!.packageNames[fqn.pathSegments().size - 1] val segmentReference = packageSegment.mainReference val psiElement = segmentReference.resolve()!! val substitution = RenamePsiElementProcessor.forElement(psiElement).substituteElementToRename(psiElement, null) - runRenameProcessor(context, newName, substitution, renameParamsObject, true, true) + runRenameProcessor(context.project, newName, substitution, renameParamsObject, true, true) } } @@ -282,11 +287,10 @@ abstract class AbstractRenameTest : KotlinMultiFileTestCase() { val file = renameParamsObject.getString("file") val newName = renameParamsObject.getString("newName") - doTestCommittingDocuments { rootDir, _ -> - val mainFile = rootDir.findFileByRelativePath(file)!! - val psiFile = PsiManager.getInstance(context.project).findFile(mainFile) + doTestCommittingDocuments(context) { + val psiFile = myFixture.configureFromTempProjectFile(file) - runRenameProcessor(context, newName, psiFile, renameParamsObject, true, true) + runRenameProcessor(context.project, newName, psiFile, renameParamsObject, true, true) } } @@ -295,12 +299,11 @@ abstract class AbstractRenameTest : KotlinMultiFileTestCase() { val oldName = renameParamsObject.getString("oldName") val newName = renameParamsObject.getString("newName") - doTestCommittingDocuments { rootDir, _ -> - val mainFile = rootDir.findChild(file)!! - val psiFile = PsiManager.getInstance(context.project).findFile(mainFile) as PropertiesFile - val property = psiFile.findPropertyByKey(oldName) as Property + doTestCommittingDocuments(context) { + val mainFile = myFixture.configureFromTempProjectFile(file) as PropertiesFile + val property = mainFile.findPropertyByKey(oldName) as Property - runRenameProcessor(context, newName, property, renameParamsObject, true, true) + runRenameProcessor(context.project, newName, property, renameParamsObject, true, true) } } @@ -319,12 +322,10 @@ abstract class AbstractRenameTest : KotlinMultiFileTestCase() { val newName = renameParamsObject.getString("newName") val mainFilePath = renameParamsObject.getNullableString("mainFile") ?: "${getTestDirName(false)}.kt" - doTestCommittingDocuments { rootDir, _ -> - val mainFile = rootDir.findChild(mainFilePath)!! - val document = FileDocumentManager.getInstance().getDocument(mainFile)!! - val jetFile = PsiDocumentManager.getInstance(context.project).getPsiFile(document) as KtFile + doTestCommittingDocuments(context) { + val ktFile = myFixture.configureFromTempProjectFile(mainFilePath) as KtFile - val module = jetFile.analyzeFullyAndGetResult().moduleDescriptor + val module = ktFile.analyzeFullyAndGetResult().moduleDescriptor val (declaration, scopeToSearch) = if (classIdStr != null) { module.findClassAcrossModuleDependencies(classIdStr.toClassId())!!.let { it to it.defaultType.memberScope } @@ -334,91 +335,99 @@ abstract class AbstractRenameTest : KotlinMultiFileTestCase() { val psiElement = DescriptorToSourceUtils.descriptorToDeclaration(findDescriptorToRename(declaration, scopeToSearch))!! - val substitution = RenamePsiElementProcessor.forElement(psiElement).substituteElementToRename(psiElement, null) + // The Java processor always chooses renaming the base element when running in unit test mode, + // so if we want to rename only the inherited element, we need to skip the substitutor. + val skipSubstitute = renameParamsObject["skipSubstitute"]?.asBoolean ?: false + val substitution = if (skipSubstitute) + psiElement + else + RenamePsiElementProcessor.forElement(psiElement).substituteElementToRename(psiElement, null) - runRenameProcessor(context, newName, substitution, renameParamsObject, true, true) + runRenameProcessor(context.project, newName, substitution, renameParamsObject, true, true) } } - private fun renameWithAutoDetection(renameParamsObject: JsonObject) { + private fun renameWithAutoDetection(renameParamsObject: JsonObject, context: TestContext) { val mainFilePath = renameParamsObject.getString("mainFile") val newName = renameParamsObject.getString("newName") - doTestCommittingDocuments { rootDir, _ -> + doTestCommittingDocuments(context) { rootDir -> configExtra(rootDir, renameParamsObject) - val psiFile = rootDir.findFileByRelativePath(mainFilePath)!!.toPsiFile(project)!! + val psiFile = myFixture.configureFromTempProjectFile(mainFilePath) val doc = PsiDocumentManager.getInstance(project).getDocument(psiFile)!! val marker = doc.extractMarkerOffset(project, "/*rename*/") assert(marker != -1) - val editor = EditorFactory.getInstance().createEditor(doc) editor.caretModel.moveToOffset(marker) - try { - val dataContext = DataContext { dataId -> - when (dataId) { - CommonDataKeys.EDITOR.name -> editor - CommonDataKeys.CARET.name -> editor.caretModel.currentCaret - CommonDataKeys.PSI_FILE.name -> psiFile - PsiElementRenameHandler.DEFAULT_NAME.name -> newName - else -> null - } + val dataContext = DataContext { dataId -> + when (dataId) { + CommonDataKeys.EDITOR.name -> editor + CommonDataKeys.CARET.name -> editor.caretModel.currentCaret + CommonDataKeys.PSI_FILE.name -> psiFile + PsiElementRenameHandler.DEFAULT_NAME.name -> newName + else -> null } - val handler = RenameHandlerRegistry.getInstance().getRenameHandler(dataContext)!! - Assert.assertTrue(handler.isAvailableOnDataContext(dataContext)) - handler.invoke(project, editor, psiFile, dataContext) - } - finally { - EditorFactory.getInstance().releaseEditor(editor) } + val handler = RenameHandlerRegistry.getInstance().getRenameHandler(dataContext)!! + Assert.assertTrue(handler.isAvailableOnDataContext(dataContext)) + handler.invoke(project, editor, psiFile, dataContext) } } - private fun runRenameProcessor( - context: TestContext, - newName: String, - substitution: PsiElement?, - renameParamsObject: JsonObject, - isSearchInComments: Boolean, - isSearchTextOccurrences: Boolean - ) { - if (substitution == null) return - val renameProcessor = RenameProcessor(context.project, substitution, newName, isSearchInComments, isSearchTextOccurrences) - if (renameParamsObject["overloadRenamer.onlyPrimaryElement"]?.asBoolean ?: false) { - with(AutomaticOverloadsRenamer) { substitution.elementFilter = { false } } - } - Extensions.getExtensions(AutomaticRenamerFactory.EP_NAME).forEach { renameProcessor.addRenamerFactory(it) } - renameProcessor.run() - } - protected fun getTestDirName(lowercaseFirstLetter : Boolean) : String { val testName = getTestName(lowercaseFirstLetter) return testName.substring(0, testName.indexOf('_')) } - protected fun doTestCommittingDocuments(action : (VirtualFile, VirtualFile?) -> Unit) { - super.doTest(MultiFileTestCase.PerformAction { rootDir, rootAfter -> - action(rootDir, rootAfter) + protected fun doTestCommittingDocuments(context: TestContext, action: (VirtualFile) -> Unit) { + val beforeDir = context.testFile.parentFile.name + "/before" + val beforeVFile = myFixture.copyDirectoryToProject(beforeDir, "") + PsiDocumentManager.getInstance(myFixture.project).commitAllDocuments() - PsiDocumentManager.getInstance(project!!).commitAllDocuments() - FileDocumentManager.getInstance().saveAllDocuments() - }, getTestDirName(true)) - } + val afterDir = File(context.testFile.parentFile, "after") + val afterVFile = LocalFileSystem.getInstance().findFileByIoFile(afterDir)?.apply { + UsefulTestCase.refreshRecursively(this) + } - override fun getTestRoot() : String { - return "/refactoring/rename/" - } + action(beforeVFile) - override fun getTestDataPath() : String { - return PluginTestCaseBase.getTestDataPathBase() + PsiDocumentManager.getInstance(project).commitAllDocuments() + FileDocumentManager.getInstance().saveAllDocuments() + PlatformTestUtil.assertDirectoriesEqual(beforeVFile, afterVFile) } } - private fun String.toClassId(): ClassId { val relativeClassName = FqName(substringAfterLast('/')) val packageFqName = FqName(substringBeforeLast('/', "").replace('/', '.')) return ClassId(packageFqName, relativeClassName, false) } + +fun loadTestConfiguration(testFile: File): JsonObject { + val fileText = FileUtil.loadFile(testFile, true) + + val jsonParser = JsonParser() + val renameObject = jsonParser.parse(fileText) as JsonObject + return renameObject +} + +fun runRenameProcessor( + project: Project, + newName: String, + substitution: PsiElement?, + renameParamsObject: JsonObject, + isSearchInComments: Boolean, + isSearchTextOccurrences: Boolean +) { + if (substitution == null) return + val renameProcessor = RenameProcessor(project, substitution, newName, isSearchInComments, isSearchTextOccurrences) + if (renameParamsObject["overloadRenamer.onlyPrimaryElement"]?.asBoolean ?: false) { + with(AutomaticOverloadsRenamer) { substitution.elementFilter = { false } } + } + Extensions.getExtensions(AutomaticRenamerFactory.EP_NAME).forEach { renameProcessor.addRenamerFactory(it) } + renameProcessor.run() +} + diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/rename/MultiModuleRenameTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/refactoring/rename/MultiModuleRenameTestGenerated.java new file mode 100644 index 00000000000..1f5dad8a2a0 --- /dev/null +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/rename/MultiModuleRenameTestGenerated.java @@ -0,0 +1,44 @@ +/* + * Copyright 2010-2017 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. + */ + +package org.jetbrains.kotlin.idea.refactoring.rename; + +import com.intellij.testFramework.TestDataPath; +import org.jetbrains.kotlin.test.JUnit3RunnerWithInners; +import org.jetbrains.kotlin.test.KotlinTestUtils; +import org.jetbrains.kotlin.test.TargetBackend; +import org.jetbrains.kotlin.test.TestMetadata; +import org.junit.runner.RunWith; + +import java.io.File; +import java.util.regex.Pattern; + +/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@TestMetadata("idea/testData/refactoring/renameMultiModule") +@TestDataPath("$PROJECT_ROOT") +@RunWith(JUnit3RunnerWithInners.class) +public class MultiModuleRenameTestGenerated extends AbstractMultiModuleRenameTest { + public void testAllFilesPresentInRenameMultiModule() throws Exception { + KotlinTestUtils.assertAllTestsPresentInSingleGeneratedClass(this.getClass(), new File("idea/testData/refactoring/renameMultiModule"), Pattern.compile("^(.+)\\.test$"), TargetBackend.ANY); + } + + @TestMetadata("fileNotUnderSourceRootWithNamesakeUnderSourceRoot/fileNotUnderSourceRootWithNamesakeUnderSourceRoot.test") + public void testFileNotUnderSourceRootWithNamesakeUnderSourceRoot_FileNotUnderSourceRootWithNamesakeUnderSourceRoot() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/renameMultiModule/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/fileNotUnderSourceRootWithNamesakeUnderSourceRoot.test"); + doTest(fileName); + } +} diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/rename/RenameTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/refactoring/rename/RenameTestGenerated.java index f6d24e88c6f..8143158cf86 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/rename/RenameTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/rename/RenameTestGenerated.java @@ -198,12 +198,6 @@ public class RenameTestGenerated extends AbstractRenameTest { doTest(fileName); } - @TestMetadata("fileNotUnderSourceRootWithNamesakeUnderSourceRoot/fileNotUnderSourceRootWithNamesakeUnderSourceRoot.test") - public void testFileNotUnderSourceRootWithNamesakeUnderSourceRoot_FileNotUnderSourceRootWithNamesakeUnderSourceRoot() throws Exception { - String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/rename/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/fileNotUnderSourceRootWithNamesakeUnderSourceRoot.test"); - doTest(fileName); - } - @TestMetadata("funWithLabeledReturns/funWithLabeledReturns.test") public void testFunWithLabeledReturns_FunWithLabeledReturns() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/rename/funWithLabeledReturns/funWithLabeledReturns.test"); diff --git a/ultimate/tests/org/jetbrains/kotlin/idea/spring/tests/rename/AbstractSpringRenameTest.kt b/ultimate/tests/org/jetbrains/kotlin/idea/spring/tests/rename/AbstractSpringRenameTest.kt index d1d659d4b82..5a3239ab52e 100644 --- a/ultimate/tests/org/jetbrains/kotlin/idea/spring/tests/rename/AbstractSpringRenameTest.kt +++ b/ultimate/tests/org/jetbrains/kotlin/idea/spring/tests/rename/AbstractSpringRenameTest.kt @@ -22,7 +22,7 @@ import com.intellij.spring.facet.SpringFacet import org.jetbrains.kotlin.idea.rename.AbstractUltimateRenameTest abstract class AbstractSpringRenameTest : AbstractUltimateRenameTest() { - override fun getTestRoot() = "/spring/core/rename/" + override fun getTestDataPath() = super.getTestDataPath() + "/spring/core/rename/" override fun configExtra(rootDir: VirtualFile, renameParamsObject: JsonObject) { val fileSet = SpringFacet.getInstance(module)!!.addFileSet("default", "default")!!