Convert AbstractQuickFixMultiFileTest to light fixture test case

This commit is contained in:
Dmitry Jemerov
2017-03-24 11:25:25 +01:00
parent 387dbdf3bb
commit 4f229c3fdc
7 changed files with 149 additions and 268 deletions
@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.idea.quickfix.AbstractQuickFixMultiFileTest;
public abstract class AbstractAndroidQuickFixMultiFileTest extends AbstractQuickFixMultiFileTest {
@Override
protected void setUp() throws Exception {
protected void setUp() {
super.setUp();
addAndroidFacet();
}
@@ -36,12 +36,6 @@ public abstract class AbstractAndroidQuickFixMultiFileTest extends AbstractQuick
super.doTestWithExtraFile(beforeFileName);
}
@Override
protected void doTestWithoutExtraFile(String beforeFileName) throws Exception {
addManifest();
super.doTestWithoutExtraFile(beforeFileName);
}
private void addAndroidFacet() {
FacetManager facetManager = FacetManager.getInstance(myModule);
AndroidFacet facet = facetManager.createFacet(AndroidFacet.getFacetType(), "Android", null);
@@ -57,6 +51,6 @@ public abstract class AbstractAndroidQuickFixMultiFileTest extends AbstractQuick
}
private void addManifest() throws Exception {
configureByFile("idea/testData/android/AndroidManifest.xml");
myFixture.configureByFile("idea/testData/android/AndroidManifest.xml");
}
}
@@ -23,7 +23,7 @@ operator fun Some.component1() = 1
operator fun Some.component2() = 3
//-----------------------
// FILE: second.kt
// FILE: other_second.kt
package other
@@ -23,7 +23,7 @@ operator fun Some.component1() = 1
operator fun Some.component2() = 3
//-----------------------
// FILE: second.kt
// FILE: other_second.kt
package other
@@ -24,7 +24,7 @@ operator fun Some.component1() = 1
operator fun Some.component2() = 3
//-----------------------
// FILE: second.kt
// FILE: other_second.kt
package other
@@ -20,7 +20,7 @@ public class Some
operator fun Some.plusAssign(i: Int) {}
// FILE: second.kt
// FILE: other_second.kt
// Lexicography is before "some"
package aaa
@@ -17,55 +17,41 @@
package org.jetbrains.kotlin.idea.quickfix
import com.intellij.codeInsight.CodeInsightSettings
import com.intellij.codeInsight.daemon.impl.HighlightInfo
import com.intellij.codeInsight.daemon.quickFix.ActionHint
import com.intellij.codeInsight.daemon.quickFix.LightQuickFixTestCase
import com.intellij.codeInsight.intention.IntentionAction
import com.intellij.codeInsight.intention.impl.ShowIntentionActionsHandler
import com.intellij.codeInspection.InspectionEP
import com.intellij.codeInspection.InspectionProfileEntry
import com.intellij.codeInspection.LocalInspectionEP
import com.intellij.ide.highlighter.JavaFileType
import com.intellij.openapi.application.Result
import com.intellij.openapi.application.WriteAction
import com.intellij.openapi.command.CommandProcessor
import com.intellij.openapi.extensions.Extensions
import com.intellij.openapi.fileTypes.FileType
import com.intellij.openapi.fileTypes.PlainTextFileType
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.util.Pair
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.text.StringUtil
import com.intellij.openapi.vfs.CharsetToolkit
import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.openapi.vfs.VfsUtil
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiFile
import com.intellij.testFramework.PsiTestUtil
import com.intellij.testFramework.VfsTestUtil
import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl
import com.intellij.util.ArrayUtil
import com.intellij.util.containers.ContainerUtil
import com.intellij.util.ui.UIUtil
import junit.framework.ComparisonFailure
import junit.framework.TestCase
import org.jetbrains.kotlin.idea.KotlinDaemonAnalyzerTestCase
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.idea.quickfix.utils.*
import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil
import org.jetbrains.kotlin.idea.quickfix.utils.findInspectionFile
import org.jetbrains.kotlin.idea.test.DirectiveBasedActionUtils
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.InTextDirectivesUtils
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.testFramework.runWriteAction
import java.io.File
import java.io.FilenameFilter
import java.io.IOException
import java.util.*
import java.util.regex.Pattern
abstract class AbstractQuickFixMultiFileTest : KotlinDaemonAnalyzerTestCase() {
abstract class AbstractQuickFixMultiFileTest : KotlinLightCodeInsightFixtureTestCase() {
@Throws(Exception::class)
protected open fun doTestWithoutExtraFile(beforeFileName: String) {
@@ -107,16 +93,14 @@ abstract class AbstractQuickFixMultiFileTest : KotlinDaemonAnalyzerTestCase() {
}
assert(tool != null) { "Could not find inspection tool for class: " + klass }
enableInspectionTools(tool!!)
myFixture.enableInspections(tool!!)
}
@Throws(Exception::class)
override fun setUp() {
super.setUp()
CodeInsightSettings.getInstance().EXCLUDED_PACKAGES = arrayOf("excludedPackage", "somePackage.ExcludedClass")
}
@Throws(Exception::class)
override fun tearDown() {
CodeInsightSettings.getInstance().EXCLUDED_PACKAGES = ArrayUtil.EMPTY_STRING_ARRAY
super.tearDown()
@@ -127,213 +111,179 @@ abstract class AbstractQuickFixMultiFileTest : KotlinDaemonAnalyzerTestCase() {
* *
* @param beforeFile will be added last, as subFiles are dependencies of it
*/
protected fun configureMultiFileTest(subFiles: List<TestFile>, beforeFile: TestFile) {
try {
val sourceRootDir = createTempDirectory()
val virtualFiles = HashMap<TestFile, VirtualFile>()
for (file in subFiles) {
virtualFiles.put(file, createVirtualFileFromTestFile(sourceRootDir, file))
}
virtualFiles.put(beforeFile, createVirtualFileFromTestFile(sourceRootDir, beforeFile))
val sourceRootVFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(sourceRootDir)
PsiTestUtil.addSourceRoot(myModule, sourceRootVFile)
for (file in subFiles) {
configureByExistingFile(virtualFiles[file]!!)
TestCase.assertEquals(guessFileType(file), myFile.virtualFile.fileType)
}
configureByExistingFile(virtualFiles[beforeFile]!!)
TestCase.assertEquals(guessFileType(beforeFile), myFile.virtualFile.fileType)
TestCase.assertTrue("\"<caret>\" is probably missing in file \"" + beforeFile.path + "\"", myEditor.caretModel.offset != 0)
}
catch (e: IOException) {
throw RuntimeException(e)
protected fun configureMultiFileTest(subFiles: List<TestFile>, beforeFile: TestFile): List<VirtualFile> {
val vFiles = mutableListOf<VirtualFile>()
for (subFile in subFiles) {
vFiles.add(createTestFile(subFile))
}
val beforeVFile = createTestFile(beforeFile)
vFiles.add(beforeVFile)
myFixture.configureFromExistingVirtualFile(beforeVFile)
TestCase.assertEquals(guessFileType(beforeFile), myFixture.file.virtualFile.fileType)
TestCase.assertTrue("\"<caret>\" is probably missing in file \"" + beforeFile.path + "\"", myFixture.editor.caretModel.offset != 0)
return vFiles
}
private fun createTestFile(testFile: TestFile): VirtualFile {
return runWriteAction {
val vFile = myFixture.tempDirFixture.createFile(testFile.path)
vFile.setCharset(CharsetToolkit.UTF8_CHARSET)
VfsUtil.saveText(vFile, testFile.content)
vFile
}
}
@Throws(Exception::class)
protected fun doMultiFileTest(beforeFileName: String) {
val multifileText = FileUtil.loadFile(File(beforeFileName), true)
val withRuntime = InTextDirectivesUtils.isDirectiveDefined(multifileText, "// WITH_RUNTIME")
if (withRuntime) {
ConfigLibraryUtil.configureKotlinRuntimeAndSdk(myModule, PluginTestCaseBase.mockJdk())
}
val subFiles = KotlinTestUtils.createTestFiles(
"single.kt",
multifileText,
object : KotlinTestUtils.TestFileFactoryNoModules<TestFile>() {
override fun create(fileName: String, text: String, directives: Map<String, String>): TestFile {
var text = text
if (text.startsWith("// FILE")) {
val firstLineDropped = StringUtil.substringAfter(text, "\n")!!
try {
val subFiles = KotlinTestUtils.createTestFiles(
"single.kt",
multifileText,
object : KotlinTestUtils.TestFileFactoryNoModules<TestFile>() {
override fun create(fileName: String, text: String, directives: Map<String, String>): TestFile {
var text = text
if (text.startsWith("// FILE")) {
val firstLineDropped = StringUtil.substringAfter(text, "\n")!!
text = firstLineDropped
}
return TestFile(fileName, text)
text = firstLineDropped
}
})
val afterFile = subFiles.firstOrNull { file -> file.path.contains(".after") }
val beforeFile = subFiles.firstOrNull { file -> file.path.contains(".before") }!!
subFiles.remove(beforeFile)
if (afterFile != null) {
subFiles.remove(afterFile)
}
configureMultiFileTest(subFiles, beforeFile)
CommandProcessor.getInstance().executeCommand(project, {
try {
val psiFile = file
val actionHint = ActionHint.parse(psiFile, beforeFile.content)
val text = actionHint.expectedText
val actionShouldBeAvailable = actionHint.shouldPresent()
if (psiFile is KtFile) {
DirectiveBasedActionUtils.checkForUnexpectedErrors(psiFile)
return TestFile(fileName, text)
}
})
doAction(text, actionShouldBeAvailable, getTestName(false))
val afterFile = subFiles.firstOrNull { file -> file.path.contains(".after") }
val beforeFile = subFiles.firstOrNull { file -> file.path.contains(".before") }!!
val actualText = file.text
val afterText = StringBuilder(actualText).insert(editor.caretModel.offset, "<caret>").toString()
subFiles.remove(beforeFile)
if (afterFile != null) {
subFiles.remove(afterFile)
}
if (actionShouldBeAvailable) {
TestCase.assertNotNull(".after file should exist", afterFile)
if (afterText != afterFile!!.content) {
val actualTestFile = StringBuilder()
actualTestFile.append("// FILE: ").append(beforeFile.path).append("\n").append(beforeFile.content)
for (file in subFiles) {
actualTestFile.append("// FILE: ").append(file.path).append("\n").append(file.content)
}
actualTestFile.append("// FILE: ").append(afterFile.path).append("\n").append(afterText)
configureMultiFileTest(subFiles, beforeFile)
KotlinTestUtils.assertEqualsToFile(File(beforeFileName), actualTestFile.toString())
CommandProcessor.getInstance().executeCommand(project, {
try {
val psiFile = file
val actionHint = ActionHint.parse(psiFile, beforeFile.content)
val text = actionHint.expectedText
val actionShouldBeAvailable = actionHint.shouldPresent()
if (psiFile is KtFile) {
DirectiveBasedActionUtils.checkForUnexpectedErrors(psiFile)
}
doAction(text, actionShouldBeAvailable, getTestName(false))
val actualText = file.text
val afterText = StringBuilder(actualText).insert(editor.caretModel.offset, "<caret>").toString()
if (actionShouldBeAvailable) {
TestCase.assertNotNull(".after file should exist", afterFile)
if (afterText != afterFile!!.content) {
val actualTestFile = StringBuilder()
actualTestFile.append("// FILE: ").append(beforeFile.path).append("\n").append(beforeFile.content)
for (file in subFiles) {
actualTestFile.append("// FILE: ").append(file.path).append("\n").append(file.content)
}
}
else {
TestCase.assertNull(".after file should not exist", afterFile)
actualTestFile.append("// FILE: ").append(afterFile.path).append("\n").append(afterText)
KotlinTestUtils.assertEqualsToFile(File(beforeFileName), actualTestFile.toString())
}
}
catch (e: ComparisonFailure) {
throw e
else {
TestCase.assertNull(".after file should not exist", afterFile)
}
catch (e: AssertionError) {
throw e
}
catch (e: Throwable) {
e.printStackTrace()
TestCase.fail(getTestName(true))
}
}, "", "")
}
finally {
if (withRuntime) {
ConfigLibraryUtil.unConfigureKotlinRuntimeAndSdk(myModule, PluginTestCaseBase.mockJdk())
}
}
catch (e: ComparisonFailure) {
throw e
}
catch (e: AssertionError) {
throw e
}
catch (e: Throwable) {
e.printStackTrace()
TestCase.fail(getTestName(true))
}
}, "", "")
}
@Throws(Exception::class)
private fun doTest(beforeFileName: String, withExtraFile: Boolean) {
val testDataPath = testDataPath
val mainFile = File(testDataPath + beforeFileName)
val mainFile = File(beforeFileName)
val originalFileText = FileUtil.loadFile(mainFile, true)
val withRuntime = InTextDirectivesUtils.isDirectiveDefined(originalFileText, "// WITH_RUNTIME")
val fullJdk = InTextDirectivesUtils.isDirectiveDefined(originalFileText, "// FULL_JDK")
if (withRuntime) {
ConfigLibraryUtil.configureKotlinRuntimeAndSdk(myModule, if (fullJdk) PluginTestCaseBase.fullJdk() else PluginTestCaseBase.mockJdk())
if (withExtraFile) {
val mainFileDir = mainFile.parentFile!!
val mainFileName = mainFile.name
val extraFiles = mainFileDir.listFiles { dir, name -> name.startsWith(extraFileNamePrefix(mainFileName)) && name != mainFileName }!!
val testFiles = ArrayList<String>()
testFiles.add(mainFile.name)
extraFiles.mapTo(testFiles) { file -> file.name }
myFixture.configureByFiles(*testFiles.toTypedArray())
}
else {
myFixture.configureByFile(beforeFileName)
}
try {
if (withExtraFile) {
val mainFileDir = mainFile.parentFile!!
CommandProcessor.getInstance().executeCommand(project, {
try {
val psiFile = file
val mainFileName = mainFile.name
val extraFiles = mainFileDir.listFiles { dir, name -> name.startsWith(extraFileNamePrefix(mainFileName)) && name != mainFileName }!!
val actionHint = ActionHint.parse(psiFile, originalFileText)
val text = actionHint.expectedText
val testFiles = ArrayList<String>()
testFiles.add(beforeFileName)
extraFiles.mapTo(testFiles) { file -> beforeFileName.replace(mainFileName, file.name) }
val actionShouldBeAvailable = actionHint.shouldPresent()
configureByFiles(null, *ArrayUtil.toStringArray(testFiles))
}
else {
configureByFiles(null, beforeFileName)
}
if (psiFile is KtFile) {
DirectiveBasedActionUtils.checkForUnexpectedErrors(psiFile)
}
CommandProcessor.getInstance().executeCommand(project, {
try {
val psiFile = file
doAction(text, actionShouldBeAvailable, beforeFileName)
val actionHint = ActionHint.parse(psiFile, originalFileText)
val text = actionHint.expectedText
val actionShouldBeAvailable = actionHint.shouldPresent()
if (psiFile is KtFile) {
DirectiveBasedActionUtils.checkForUnexpectedErrors(psiFile)
if (actionShouldBeAvailable) {
val afterFilePath = beforeFileName.replace(".before.Main.", ".after.")
try {
myFixture.checkResultByFile(mainFile.name.replace(".before.Main.", ".after."))
}
catch (e: ComparisonFailure) {
KotlinTestUtils.assertEqualsToFile(File(afterFilePath), editor)
}
doAction(text, actionShouldBeAvailable, beforeFileName)
val mainFile = myFixture.file
val mainFileName = mainFile.name
for (file in mainFile.containingDirectory.files) {
val fileName = file.name
if (fileName == mainFileName || !fileName.startsWith(extraFileNamePrefix(myFixture.file.name))) continue
if (actionShouldBeAvailable) {
val afterFilePath = beforeFileName.replace(".before.Main.", ".after.")
try {
checkResultByFile(afterFilePath)
val extraFileFullPath = beforeFileName.replace(mainFileName, fileName)
val afterFile = File(extraFileFullPath.replace(".before.", ".after."))
if (afterFile.exists()) {
KotlinTestUtils.assertEqualsToFile(afterFile, file.text)
}
catch (e: ComparisonFailure) {
KotlinTestUtils.assertEqualsToFile(File(afterFilePath), editor)
}
val mainFile = myFile
val mainFileName = mainFile.name
for (file in mainFile.containingDirectory.files) {
val fileName = file.name
if (fileName == mainFileName || !fileName.startsWith(extraFileNamePrefix(myFile.name))) continue
val extraFileFullPath = beforeFileName.replace(mainFileName, fileName)
val afterFile = File(extraFileFullPath.replace(".before.", ".after."))
if (afterFile.exists()) {
KotlinTestUtils.assertEqualsToFile(afterFile, file.text)
}
else {
KotlinTestUtils.assertEqualsToFile(File(extraFileFullPath), file.text)
}
else {
KotlinTestUtils.assertEqualsToFile(File(extraFileFullPath), file.text)
}
}
}
catch (e: ComparisonFailure) {
throw e
}
catch (e: AssertionError) {
throw e
}
catch (e: Throwable) {
e.printStackTrace()
TestCase.fail(getTestName(true))
}
}, "", "")
}
finally {
if (withRuntime) {
ConfigLibraryUtil
.unConfigureKotlinRuntimeAndSdk(myModule, if (fullJdk) PluginTestCaseBase.fullJdk() else PluginTestCaseBase.mockJdk())
}
}
catch (e: ComparisonFailure) {
throw e
}
catch (e: AssertionError) {
throw e
}
catch (e: Throwable) {
e.printStackTrace()
TestCase.fail(getTestName(true))
}
}, "", "")
}
@Throws(Exception::class)
@@ -349,7 +299,7 @@ abstract class AbstractQuickFixMultiFileTest : KotlinDaemonAnalyzerTestCase() {
if (action == null) {
if (actionShouldBeAvailable) {
val texts = getActionsTexts(availableActions)
val infos = doHighlighting()
val infos = myFixture.doHighlighting()
TestCase.fail("Action with text '" + text + "' is not available in test " + testFilePath + "\n" +
"Available actions (" + texts.size + "): \n" +
StringUtil.join(texts, "\n") +
@@ -367,13 +317,10 @@ abstract class AbstractQuickFixMultiFileTest : KotlinDaemonAnalyzerTestCase() {
TestCase.fail("Action '$text' is available (but must not) in test $testFilePath")
}
ShowIntentionActionsHandler.chooseActionAndInvoke(file, editor, action, action.text)
UIUtil.dispatchAllInvocationEvents()
CodeInsightTestFixtureImpl.invokeIntention(action, file, editor, action.text)
if (!shouldBeAvailableAfterExecution()) {
val afterAction = findActionByPattern(pattern, availableActions)
val afterAction = findActionByPattern(pattern, this.availableActions)
if (afterAction != null) {
TestCase.fail("Action '$text' is still available after its invocation in test $testFilePath")
@@ -385,23 +332,10 @@ abstract class AbstractQuickFixMultiFileTest : KotlinDaemonAnalyzerTestCase() {
private val availableActions: List<IntentionAction>
get() {
doHighlighting()
return LightQuickFixTestCase.getAvailableActions(editor, file)
myFixture.doHighlighting()
return myFixture.availableIntentions
}
override fun getTestProjectJdk(): Sdk? {
return PluginTestCaseBase.mockJdk()
}
override fun getTestDataPath(): String {
return KotlinTestUtils.getHomeDirectory() + "/"
}
private fun findVirtualFile(filePath: String): VirtualFile {
val absolutePath = testDataPath + filePath
return VfsTestUtil.findFileByCaseSensitivePath(absolutePath)
}
class TestFile internal constructor(val path: String, val content: String)
companion object {
@@ -434,51 +368,6 @@ abstract class AbstractQuickFixMultiFileTest : KotlinDaemonAnalyzerTestCase() {
}
}
/**
* @param sourceRootDir Base path of test file(Test source directory)
* *
* @param testFile source of VFile content
* *
* @return created VirtualFile
*/
protected fun createVirtualFileFromTestFile(sourceRootDir: File, testFile: TestFile): VirtualFile {
try {
TestCase.assertFalse("Please don't use absolute path for multifile test 'FILE' directive: " + testFile.path,
FileUtil.isAbsolutePlatformIndependent(testFile.path))
val fileType = guessFileType(testFile)
val extension = fileType.defaultExtension
val fileInSourceRoot = File(testFile.path)
var container = FileUtil.getParentFile(fileInSourceRoot)
if (container == null) {
container = sourceRootDir
}
else {
container = File(sourceRootDir, container.path)
}
if (!container.exists()) {
TestCase.assertTrue(container.mkdirs())
}
val tempFile = FileUtil.createTempFile(container, FileUtil.getNameWithoutExtension(testFile.path), "." + extension, true)
val vFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(tempFile)!!
runWriteAction {
vFile.setCharset(CharsetToolkit.UTF8_CHARSET)
VfsUtil.saveText(vFile, testFile.content)
}
return vFile
}
catch (e: IOException) {
throw RuntimeException(e)
}
}
private fun findActionByPattern(pattern: Pattern, availableActions: List<IntentionAction>): IntentionAction? {
for (availableAction in availableActions) {
if (pattern.matcher(availableAction.text).matches()) {
@@ -16,13 +16,10 @@
package org.jetbrains.kotlin.idea.quickfix;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.testFramework.PsiTestUtil;
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase;
import org.jetbrains.kotlin.test.LocalFileSystemUtils;
public class AddOpenToClassDeclarationTest extends AbstractQuickFixMultiFileTest {
/*
@Override
protected void setUp() throws Exception {
super.setUp();
@@ -33,6 +30,7 @@ public class AddOpenToClassDeclarationTest extends AbstractQuickFixMultiFileTest
addSourceContentToRoots(myModule, rootDir);
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
}
*/
public void testFinalJavaSupertype() throws Exception {
doTestWithoutExtraFile("FinalJavaSupertype.before.kt");