AbstractQuickFixMultiFileTest: J2K
This commit is contained in:
@@ -14,524 +14,478 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.quickfix;
|
||||
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.util.ArrayUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import junit.framework.ComparisonFailure;
|
||||
import kotlin.collections.ArraysKt;
|
||||
import kotlin.collections.CollectionsKt;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.idea.KotlinDaemonAnalyzerTestCase;
|
||||
import org.jetbrains.kotlin.idea.KotlinFileType;
|
||||
import org.jetbrains.kotlin.idea.quickfix.utils.QuickfixTestUtilsKt;
|
||||
import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil;
|
||||
import org.jetbrains.kotlin.idea.test.DirectiveBasedActionUtils;
|
||||
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase;
|
||||
import org.jetbrains.kotlin.psi.KtFile;
|
||||
import org.jetbrains.kotlin.test.InTextDirectivesUtils;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
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.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.test.DirectiveBasedActionUtils
|
||||
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase
|
||||
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;
|
||||
import java.io.File
|
||||
import java.io.FilenameFilter
|
||||
import java.io.IOException
|
||||
import java.util.*
|
||||
import java.util.regex.Pattern
|
||||
|
||||
public abstract class AbstractQuickFixMultiFileTest extends KotlinDaemonAnalyzerTestCase {
|
||||
abstract class AbstractQuickFixMultiFileTest : KotlinDaemonAnalyzerTestCase() {
|
||||
|
||||
protected static boolean shouldBeAvailableAfterExecution() {
|
||||
return false;
|
||||
@Throws(Exception::class)
|
||||
protected open fun doTestWithoutExtraFile(beforeFileName: String) {
|
||||
doTest(beforeFileName, false)
|
||||
}
|
||||
|
||||
private static List<String> getActionsTexts(List<IntentionAction> availableActions) {
|
||||
List<String> texts = new ArrayList<String>();
|
||||
for (IntentionAction intentionAction : availableActions) {
|
||||
texts.add(intentionAction.getText());
|
||||
}
|
||||
return texts;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String extraFileNamePrefix(@NotNull String mainFileName) {
|
||||
return mainFileName.replace(".Main.kt", ".").replace(".Main.java", ".");
|
||||
}
|
||||
|
||||
protected static FileType guessFileType(TestFile file) {
|
||||
if (file.path.contains("." + KotlinFileType.EXTENSION)) {
|
||||
return KotlinFileType.INSTANCE;
|
||||
}
|
||||
else if (file.path.contains("." + JavaFileType.DEFAULT_EXTENSION)) {
|
||||
return JavaFileType.INSTANCE;
|
||||
}
|
||||
else {
|
||||
return PlainTextFileType.INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param sourceRootDir Base path of test file(Test source directory)
|
||||
* @param testFile source of VFile content
|
||||
* @return created VirtualFile
|
||||
*/
|
||||
protected static VirtualFile createVirtualFileFromTestFile(File sourceRootDir, final TestFile testFile) {
|
||||
try {
|
||||
assertFalse("Please don't use absolute path for multifile test 'FILE' directive: " + testFile.path,
|
||||
FileUtil.isAbsolutePlatformIndependent(testFile.path));
|
||||
FileType fileType = guessFileType(testFile);
|
||||
String extension = fileType.getDefaultExtension();
|
||||
|
||||
|
||||
final File fileInSourceRoot = new File(testFile.path);
|
||||
File container = FileUtil.getParentFile(fileInSourceRoot);
|
||||
if (container == null) {
|
||||
container = sourceRootDir;
|
||||
}
|
||||
else {
|
||||
container = new File(sourceRootDir, container.getPath());
|
||||
}
|
||||
|
||||
if (!container.exists()) {
|
||||
assertTrue(container.mkdirs());
|
||||
}
|
||||
|
||||
final File tempFile =
|
||||
FileUtil.createTempFile(container, FileUtil.getNameWithoutExtension(testFile.path), "." + extension, true);
|
||||
|
||||
|
||||
final VirtualFile vFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(tempFile);
|
||||
assert vFile != null;
|
||||
new WriteAction() {
|
||||
@Override
|
||||
protected void run(@NotNull Result result) throws Throwable {
|
||||
vFile.setCharset(CharsetToolkit.UTF8_CHARSET);
|
||||
VfsUtil.saveText(vFile, testFile.content);
|
||||
}
|
||||
}.execute();
|
||||
|
||||
|
||||
return vFile;
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected void doTestWithoutExtraFile(String beforeFileName) throws Exception {
|
||||
doTest(beforeFileName, false);
|
||||
}
|
||||
|
||||
protected void doTestWithExtraFile(String beforeFileName) throws Exception {
|
||||
enableInspections(beforeFileName);
|
||||
@Throws(Exception::class)
|
||||
protected open fun doTestWithExtraFile(beforeFileName: String) {
|
||||
enableInspections(beforeFileName)
|
||||
|
||||
if (beforeFileName.endsWith(".test")) {
|
||||
doMultiFileTest(beforeFileName);
|
||||
doMultiFileTest(beforeFileName)
|
||||
}
|
||||
else {
|
||||
doTest(beforeFileName, true);
|
||||
doTest(beforeFileName, true)
|
||||
}
|
||||
}
|
||||
|
||||
private void enableInspections(String beforeFileName) throws IOException, ClassNotFoundException {
|
||||
File inspectionFile = QuickfixTestUtilsKt.findInspectionFile(new File(beforeFileName).getParentFile());
|
||||
@Throws(IOException::class, ClassNotFoundException::class)
|
||||
private fun enableInspections(beforeFileName: String) {
|
||||
val inspectionFile = findInspectionFile(File(beforeFileName).parentFile)
|
||||
if (inspectionFile != null) {
|
||||
String className = FileUtil.loadFile(inspectionFile).trim();
|
||||
Class<?> inspectionClass = Class.forName(className);
|
||||
enableInspectionTools(inspectionClass);
|
||||
val className = FileUtil.loadFile(inspectionFile).trim { it <= ' ' }
|
||||
val inspectionClass = Class.forName(className)
|
||||
enableInspectionTools(inspectionClass)
|
||||
}
|
||||
}
|
||||
|
||||
private void enableInspectionTools(@NotNull Class<?> klass) {
|
||||
List<InspectionEP> eps = ContainerUtil.newArrayList();
|
||||
ContainerUtil.addAll(eps, Extensions.getExtensions(LocalInspectionEP.LOCAL_INSPECTION));
|
||||
ContainerUtil.addAll(eps, Extensions.getExtensions(InspectionEP.GLOBAL_INSPECTION));
|
||||
private fun enableInspectionTools(klass: Class<*>) {
|
||||
val eps = ContainerUtil.newArrayList<InspectionEP>()
|
||||
ContainerUtil.addAll<InspectionEP, LocalInspectionEP, List<InspectionEP>>(eps, *Extensions.getExtensions(LocalInspectionEP.LOCAL_INSPECTION))
|
||||
ContainerUtil.addAll<InspectionEP, InspectionEP, List<InspectionEP>>(eps, *Extensions.getExtensions(InspectionEP.GLOBAL_INSPECTION))
|
||||
|
||||
InspectionProfileEntry tool = null;
|
||||
for (InspectionEP ep : eps) {
|
||||
if (klass.getName().equals(ep.implementationClass)) {
|
||||
tool = ep.instantiateTool();
|
||||
var tool: InspectionProfileEntry? = null
|
||||
for (ep in eps) {
|
||||
if (klass.name == ep.implementationClass) {
|
||||
tool = ep.instantiateTool()
|
||||
}
|
||||
}
|
||||
assert tool != null : "Could not find inspection tool for class: " + klass;
|
||||
assert(tool != null) { "Could not find inspection tool for class: " + klass }
|
||||
|
||||
enableInspectionTools(tool);
|
||||
enableInspectionTools(tool!!)
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
CodeInsightSettings.getInstance().EXCLUDED_PACKAGES = new String[] {"excludedPackage", "somePackage.ExcludedClass"};
|
||||
@Throws(Exception::class)
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
CodeInsightSettings.getInstance().EXCLUDED_PACKAGES = arrayOf("excludedPackage", "somePackage.ExcludedClass")
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
CodeInsightSettings.getInstance().EXCLUDED_PACKAGES = ArrayUtil.EMPTY_STRING_ARRAY;
|
||||
super.tearDown();
|
||||
@Throws(Exception::class)
|
||||
override fun tearDown() {
|
||||
CodeInsightSettings.getInstance().EXCLUDED_PACKAGES = ArrayUtil.EMPTY_STRING_ARRAY
|
||||
super.tearDown()
|
||||
}
|
||||
|
||||
/**
|
||||
* @param subFiles subFiles of multiFile test
|
||||
* *
|
||||
* @param beforeFile will be added last, as subFiles are dependencies of it
|
||||
*/
|
||||
protected void configureMultiFileTest(List<TestFile> subFiles, TestFile beforeFile) {
|
||||
protected fun configureMultiFileTest(subFiles: List<TestFile>, beforeFile: TestFile) {
|
||||
try {
|
||||
File sourceRootDir = createTempDirectory();
|
||||
Map<TestFile, VirtualFile> virtualFiles = new HashMap<TestFile, VirtualFile>();
|
||||
val sourceRootDir = createTempDirectory()
|
||||
val virtualFiles = HashMap<TestFile, VirtualFile>()
|
||||
|
||||
for (TestFile file : subFiles) {
|
||||
virtualFiles.put(file, createVirtualFileFromTestFile(sourceRootDir, file));
|
||||
for (file in subFiles) {
|
||||
virtualFiles.put(file, createVirtualFileFromTestFile(sourceRootDir, file))
|
||||
}
|
||||
virtualFiles.put(beforeFile, createVirtualFileFromTestFile(sourceRootDir, beforeFile));
|
||||
virtualFiles.put(beforeFile, createVirtualFileFromTestFile(sourceRootDir, beforeFile))
|
||||
|
||||
VirtualFile sourceRootVFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(sourceRootDir);
|
||||
PsiTestUtil.addSourceRoot(myModule, sourceRootVFile);
|
||||
val sourceRootVFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(sourceRootDir)
|
||||
PsiTestUtil.addSourceRoot(myModule, sourceRootVFile)
|
||||
|
||||
for (TestFile file : subFiles) {
|
||||
configureByExistingFile(virtualFiles.get(file));
|
||||
assertEquals(guessFileType(file), myFile.getVirtualFile().getFileType());
|
||||
for (file in subFiles) {
|
||||
configureByExistingFile(virtualFiles[file]!!)
|
||||
TestCase.assertEquals(guessFileType(file), myFile.virtualFile.fileType)
|
||||
}
|
||||
|
||||
configureByExistingFile(virtualFiles.get(beforeFile));
|
||||
assertEquals(guessFileType(beforeFile), myFile.getVirtualFile().getFileType());
|
||||
configureByExistingFile(virtualFiles[beforeFile]!!)
|
||||
TestCase.assertEquals(guessFileType(beforeFile), myFile.virtualFile.fileType)
|
||||
|
||||
assertTrue("\"<caret>\" is probably missing in file \"" + beforeFile.path + "\"", myEditor.getCaretModel().getOffset() != 0);
|
||||
TestCase.assertTrue("\"<caret>\" is probably missing in file \"" + beforeFile.path + "\"", myEditor.caretModel.offset != 0)
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
catch (e: IOException) {
|
||||
throw RuntimeException(e)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected void doMultiFileTest(final String beforeFileName) throws Exception {
|
||||
String multifileText = FileUtil.loadFile(new File(beforeFileName), true);
|
||||
@Throws(Exception::class)
|
||||
protected fun doMultiFileTest(beforeFileName: String) {
|
||||
val multifileText = FileUtil.loadFile(File(beforeFileName), true)
|
||||
|
||||
boolean withRuntime = InTextDirectivesUtils.isDirectiveDefined(multifileText, "// WITH_RUNTIME");
|
||||
val withRuntime = InTextDirectivesUtils.isDirectiveDefined(multifileText, "// WITH_RUNTIME")
|
||||
if (withRuntime) {
|
||||
ConfigLibraryUtil.configureKotlinRuntimeAndSdk(myModule, PluginTestCaseBase.mockJdk());
|
||||
ConfigLibraryUtil.configureKotlinRuntimeAndSdk(myModule, PluginTestCaseBase.mockJdk())
|
||||
}
|
||||
|
||||
try {
|
||||
final List<TestFile> subFiles = KotlinTestUtils.createTestFiles(
|
||||
val subFiles = KotlinTestUtils.createTestFiles(
|
||||
"single.kt",
|
||||
multifileText,
|
||||
new KotlinTestUtils.TestFileFactoryNoModules<TestFile>() {
|
||||
@NotNull
|
||||
@Override
|
||||
public TestFile create(@NotNull String fileName, @NotNull String text, @NotNull Map<String, String> directives) {
|
||||
object : KotlinTestUtils.TestFileFactoryNoModules<TestFile>() {
|
||||
override fun create(fileName: String, text: String, directives: Map<String, String>): TestFile {
|
||||
var text = text
|
||||
if (text.startsWith("// FILE")) {
|
||||
String firstLineDropped = StringUtil.substringAfter(text, "\n");
|
||||
assert firstLineDropped != null;
|
||||
val firstLineDropped = StringUtil.substringAfter(text, "\n")!!
|
||||
|
||||
text = firstLineDropped;
|
||||
text = firstLineDropped
|
||||
}
|
||||
return new TestFile(fileName, text);
|
||||
return TestFile(fileName, text)
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
final TestFile afterFile = CollectionsKt.firstOrNull(subFiles, new Function1<TestFile, Boolean>() {
|
||||
@Override
|
||||
public Boolean invoke(TestFile file) {
|
||||
return file.path.contains(".after");
|
||||
}
|
||||
});
|
||||
final TestFile beforeFile = CollectionsKt.firstOrNull(subFiles, new Function1<TestFile, Boolean>() {
|
||||
@Override
|
||||
public Boolean invoke(TestFile file) {
|
||||
return file.path.contains(".before");
|
||||
}
|
||||
});
|
||||
val afterFile = subFiles.firstOrNull { file -> file.path.contains(".after") }
|
||||
val beforeFile = subFiles.firstOrNull { file -> file.path.contains(".before") }!!
|
||||
|
||||
assert beforeFile != null;
|
||||
|
||||
subFiles.remove(beforeFile);
|
||||
subFiles.remove(beforeFile)
|
||||
if (afterFile != null) {
|
||||
subFiles.remove(afterFile);
|
||||
subFiles.remove(afterFile)
|
||||
}
|
||||
|
||||
configureMultiFileTest(subFiles, beforeFile);
|
||||
configureMultiFileTest(subFiles, beforeFile)
|
||||
|
||||
CommandProcessor.getInstance().executeCommand(getProject(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
PsiFile psiFile = getFile();
|
||||
CommandProcessor.getInstance().executeCommand(project, {
|
||||
try {
|
||||
val psiFile = file
|
||||
|
||||
ActionHint actionHint = ActionHint.parse(psiFile, beforeFile.content);
|
||||
String text = actionHint.getExpectedText();
|
||||
val actionHint = ActionHint.parse(psiFile, beforeFile.content)
|
||||
val text = actionHint.expectedText
|
||||
|
||||
boolean actionShouldBeAvailable = actionHint.shouldPresent();
|
||||
val actionShouldBeAvailable = actionHint.shouldPresent()
|
||||
|
||||
if (psiFile instanceof KtFile) {
|
||||
DirectiveBasedActionUtils.INSTANCE.checkForUnexpectedErrors((KtFile) psiFile);
|
||||
}
|
||||
if (psiFile is KtFile) {
|
||||
DirectiveBasedActionUtils.checkForUnexpectedErrors(psiFile)
|
||||
}
|
||||
|
||||
doAction(text, actionShouldBeAvailable, getTestName(false));
|
||||
doAction(text, actionShouldBeAvailable, getTestName(false))
|
||||
|
||||
String actualText = getFile().getText();
|
||||
String afterText =
|
||||
new StringBuilder(actualText).insert(getEditor().getCaretModel().getOffset(), "<caret>").toString();
|
||||
val actualText = file.text
|
||||
val afterText = StringBuilder(actualText).insert(editor.caretModel.offset, "<caret>").toString()
|
||||
|
||||
if (actionShouldBeAvailable) {
|
||||
assertNotNull(".after file should exist", afterFile);
|
||||
if (!afterText.equals(afterFile.content)) {
|
||||
StringBuilder actualTestFile = new StringBuilder();
|
||||
actualTestFile.append("// FILE: ").append(beforeFile.path).append("\n").append(beforeFile.content);
|
||||
for (TestFile file : subFiles) {
|
||||
actualTestFile.append("// FILE: ").append(file.path).append("\n").append(file.content);
|
||||
}
|
||||
actualTestFile.append("// FILE: ").append(afterFile.path).append("\n").append(afterText);
|
||||
|
||||
KotlinTestUtils.assertEqualsToFile(new File(beforeFileName), actualTestFile.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 {
|
||||
assertNull(".after file should not exist", afterFile);
|
||||
actualTestFile.append("// FILE: ").append(afterFile.path).append("\n").append(afterText)
|
||||
|
||||
KotlinTestUtils.assertEqualsToFile(File(beforeFileName), actualTestFile.toString())
|
||||
}
|
||||
}
|
||||
catch (ComparisonFailure e) {
|
||||
throw e;
|
||||
}
|
||||
catch (AssertionError e) {
|
||||
throw e;
|
||||
}
|
||||
catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
fail(getTestName(true));
|
||||
else {
|
||||
TestCase.assertNull(".after file should not exist", afterFile)
|
||||
}
|
||||
}
|
||||
}, "", "");
|
||||
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, PluginTestCaseBase.mockJdk());
|
||||
ConfigLibraryUtil.unConfigureKotlinRuntimeAndSdk(myModule, PluginTestCaseBase.mockJdk())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void doTest(final String beforeFileName, boolean withExtraFile) throws Exception {
|
||||
String testDataPath = getTestDataPath();
|
||||
File mainFile = new File(testDataPath + beforeFileName);
|
||||
final String originalFileText = FileUtil.loadFile(mainFile, true);
|
||||
@Throws(Exception::class)
|
||||
private fun doTest(beforeFileName: String, withExtraFile: Boolean) {
|
||||
val testDataPath = testDataPath
|
||||
val mainFile = File(testDataPath + beforeFileName)
|
||||
val originalFileText = FileUtil.loadFile(mainFile, true)
|
||||
|
||||
boolean withRuntime = InTextDirectivesUtils.isDirectiveDefined(originalFileText, "// WITH_RUNTIME");
|
||||
boolean fullJdk = InTextDirectivesUtils.isDirectiveDefined(originalFileText, "// FULL_JDK");
|
||||
val withRuntime = InTextDirectivesUtils.isDirectiveDefined(originalFileText, "// WITH_RUNTIME")
|
||||
val fullJdk = InTextDirectivesUtils.isDirectiveDefined(originalFileText, "// FULL_JDK")
|
||||
if (withRuntime) {
|
||||
ConfigLibraryUtil.configureKotlinRuntimeAndSdk(myModule, fullJdk ? PluginTestCaseBase.fullJdk() : PluginTestCaseBase.mockJdk());
|
||||
ConfigLibraryUtil.configureKotlinRuntimeAndSdk(myModule, if (fullJdk) PluginTestCaseBase.fullJdk() else PluginTestCaseBase.mockJdk())
|
||||
}
|
||||
|
||||
try {
|
||||
if (withExtraFile) {
|
||||
File mainFileDir = mainFile.getParentFile();
|
||||
assert mainFileDir != null;
|
||||
val mainFileDir = mainFile.parentFile!!
|
||||
|
||||
final String mainFileName = mainFile.getName();
|
||||
File[] extraFiles = mainFileDir.listFiles(
|
||||
new FilenameFilter() {
|
||||
@Override
|
||||
public boolean accept(@NotNull File dir, @NotNull String name) {
|
||||
return name.startsWith(extraFileNamePrefix(mainFileName)) && !name.equals(mainFileName);
|
||||
}
|
||||
}
|
||||
);
|
||||
assert extraFiles != null;
|
||||
val mainFileName = mainFile.name
|
||||
val extraFiles = mainFileDir.listFiles { dir, name -> name.startsWith(extraFileNamePrefix(mainFileName)) && name != mainFileName }!!
|
||||
|
||||
List<String> testFiles = new ArrayList<String>();
|
||||
testFiles.add(beforeFileName);
|
||||
ArraysKt.mapTo(
|
||||
extraFiles,
|
||||
testFiles,
|
||||
new Function1<File, String>() {
|
||||
@Override
|
||||
public String invoke(File file) {
|
||||
return beforeFileName.replace(mainFileName, file.getName());
|
||||
}
|
||||
}
|
||||
);
|
||||
val testFiles = ArrayList<String>()
|
||||
testFiles.add(beforeFileName)
|
||||
extraFiles.mapTo(testFiles) { file -> beforeFileName.replace(mainFileName, file.name) }
|
||||
|
||||
configureByFiles(null, ArrayUtil.toStringArray(testFiles));
|
||||
configureByFiles(null, *ArrayUtil.toStringArray(testFiles))
|
||||
}
|
||||
else {
|
||||
configureByFiles(null, beforeFileName);
|
||||
configureByFiles(null, beforeFileName)
|
||||
}
|
||||
|
||||
CommandProcessor.getInstance().executeCommand(getProject(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
PsiFile psiFile = getFile();
|
||||
CommandProcessor.getInstance().executeCommand(project, {
|
||||
try {
|
||||
val psiFile = file
|
||||
|
||||
ActionHint actionHint = ActionHint.parse(psiFile, originalFileText);
|
||||
String text = actionHint.getExpectedText();
|
||||
val actionHint = ActionHint.parse(psiFile, originalFileText)
|
||||
val text = actionHint.expectedText
|
||||
|
||||
boolean actionShouldBeAvailable = actionHint.shouldPresent();
|
||||
val actionShouldBeAvailable = actionHint.shouldPresent()
|
||||
|
||||
if (psiFile instanceof KtFile) {
|
||||
DirectiveBasedActionUtils.INSTANCE.checkForUnexpectedErrors((KtFile) psiFile);
|
||||
if (psiFile is KtFile) {
|
||||
DirectiveBasedActionUtils.checkForUnexpectedErrors(psiFile)
|
||||
}
|
||||
|
||||
doAction(text, actionShouldBeAvailable, beforeFileName)
|
||||
|
||||
if (actionShouldBeAvailable) {
|
||||
val afterFilePath = beforeFileName.replace(".before.Main.", ".after.")
|
||||
try {
|
||||
checkResultByFile(afterFilePath)
|
||||
}
|
||||
catch (e: ComparisonFailure) {
|
||||
KotlinTestUtils.assertEqualsToFile(File(afterFilePath), editor)
|
||||
}
|
||||
|
||||
doAction(text, actionShouldBeAvailable, beforeFileName);
|
||||
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
|
||||
|
||||
if (actionShouldBeAvailable) {
|
||||
String 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 (ComparisonFailure e) {
|
||||
KotlinTestUtils.assertEqualsToFile(new File(afterFilePath), getEditor());
|
||||
}
|
||||
|
||||
PsiFile mainFile = myFile;
|
||||
String mainFileName = mainFile.getName();
|
||||
for (PsiFile file : mainFile.getContainingDirectory().getFiles()) {
|
||||
String fileName = file.getName();
|
||||
if (fileName.equals(mainFileName) || !fileName.startsWith(extraFileNamePrefix(myFile.getName()))) continue;
|
||||
|
||||
String extraFileFullPath = beforeFileName.replace(mainFileName, fileName);
|
||||
File afterFile = new File(extraFileFullPath.replace(".before.", ".after."));
|
||||
if (afterFile.exists()) {
|
||||
KotlinTestUtils.assertEqualsToFile(afterFile, file.getText());
|
||||
}
|
||||
else {
|
||||
KotlinTestUtils.assertEqualsToFile(new File(extraFileFullPath), file.getText());
|
||||
}
|
||||
else {
|
||||
KotlinTestUtils.assertEqualsToFile(File(extraFileFullPath), file.text)
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ComparisonFailure e) {
|
||||
throw e;
|
||||
}
|
||||
catch (AssertionError e) {
|
||||
throw e;
|
||||
}
|
||||
catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
fail(getTestName(true));
|
||||
}
|
||||
}
|
||||
}, "", "");
|
||||
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, fullJdk ? PluginTestCaseBase.fullJdk() : PluginTestCaseBase.mockJdk());
|
||||
.unConfigureKotlinRuntimeAndSdk(myModule, if (fullJdk) PluginTestCaseBase.fullJdk() else PluginTestCaseBase.mockJdk())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({"HardCodedStringLiteral"})
|
||||
public void doAction(String text, boolean actionShouldBeAvailable, String testFilePath) throws Exception {
|
||||
Pattern pattern = text.startsWith("/")
|
||||
? Pattern.compile(text.substring(1, text.length()-1))
|
||||
: Pattern.compile(StringUtil.escapeToRegexp(text));
|
||||
@Throws(Exception::class)
|
||||
fun doAction(text: String, actionShouldBeAvailable: Boolean, testFilePath: String) {
|
||||
val pattern = if (text.startsWith("/"))
|
||||
Pattern.compile(text.substring(1, text.length - 1))
|
||||
else
|
||||
Pattern.compile(StringUtil.escapeToRegexp(text))
|
||||
|
||||
List<IntentionAction> availableActions = getAvailableActions();
|
||||
IntentionAction action = findActionByPattern(pattern, availableActions);
|
||||
val availableActions = availableActions
|
||||
val action = findActionByPattern(pattern, availableActions)
|
||||
|
||||
if (action == null) {
|
||||
if (actionShouldBeAvailable) {
|
||||
List<String> texts = getActionsTexts(availableActions);
|
||||
Collection<HighlightInfo> infos = doHighlighting();
|
||||
fail("Action with text '" + text + "' is not available in test " + testFilePath + "\n" +
|
||||
"Available actions (" + texts.size() + "): \n" +
|
||||
StringUtil.join(texts, "\n") +
|
||||
"\nActions:\n" +
|
||||
StringUtil.join(availableActions, "\n") +
|
||||
"\nInfos:\n" +
|
||||
StringUtil.join(infos, "\n"));
|
||||
val texts = getActionsTexts(availableActions)
|
||||
val infos = doHighlighting()
|
||||
TestCase.fail("Action with text '" + text + "' is not available in test " + testFilePath + "\n" +
|
||||
"Available actions (" + texts.size + "): \n" +
|
||||
StringUtil.join(texts, "\n") +
|
||||
"\nActions:\n" +
|
||||
StringUtil.join(availableActions, "\n") +
|
||||
"\nInfos:\n" +
|
||||
StringUtil.join(infos, "\n"))
|
||||
}
|
||||
else {
|
||||
DirectiveBasedActionUtils.INSTANCE.checkAvailableActionsAreExpected(getFile(), availableActions);
|
||||
DirectiveBasedActionUtils.checkAvailableActionsAreExpected(file, availableActions)
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!actionShouldBeAvailable) {
|
||||
fail("Action '" + text + "' is available (but must not) in test " + testFilePath);
|
||||
TestCase.fail("Action '$text' is available (but must not) in test $testFilePath")
|
||||
}
|
||||
|
||||
ShowIntentionActionsHandler.chooseActionAndInvoke(getFile(), getEditor(), action, action.getText());
|
||||
ShowIntentionActionsHandler.chooseActionAndInvoke(file, editor, action, action.text)
|
||||
|
||||
UIUtil.dispatchAllInvocationEvents()
|
||||
|
||||
UIUtil.dispatchAllInvocationEvents();
|
||||
|
||||
//noinspection ConstantConditions
|
||||
if (!shouldBeAvailableAfterExecution()) {
|
||||
IntentionAction afterAction = findActionByPattern(pattern, getAvailableActions());
|
||||
val afterAction = findActionByPattern(pattern, availableActions)
|
||||
|
||||
if (afterAction != null) {
|
||||
fail("Action '" + text + "' is still available after its invocation in test " + testFilePath);
|
||||
TestCase.fail("Action '$text' is still available after its invocation in test $testFilePath")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static IntentionAction findActionByPattern(Pattern pattern, List<IntentionAction> availableActions) {
|
||||
for (IntentionAction availableAction : availableActions) {
|
||||
if (pattern.matcher(availableAction.getText()).matches()) {
|
||||
return availableAction;
|
||||
|
||||
private val availableActions: List<IntentionAction>
|
||||
get() {
|
||||
doHighlighting()
|
||||
return LightQuickFixTestCase.getAvailableActions(editor, file)
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
protected fun shouldBeAvailableAfterExecution(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
private fun getActionsTexts(availableActions: List<IntentionAction>): List<String> {
|
||||
val texts = ArrayList<String>()
|
||||
for (intentionAction in availableActions) {
|
||||
texts.add(intentionAction.text)
|
||||
}
|
||||
return texts
|
||||
}
|
||||
|
||||
private fun extraFileNamePrefix(mainFileName: String): String {
|
||||
return mainFileName.replace(".Main.kt", ".").replace(".Main.java", ".")
|
||||
}
|
||||
|
||||
protected fun guessFileType(file: TestFile): FileType {
|
||||
if (file.path.contains("." + KotlinFileType.EXTENSION)) {
|
||||
return KotlinFileType.INSTANCE
|
||||
}
|
||||
else if (file.path.contains("." + JavaFileType.DEFAULT_EXTENSION)) {
|
||||
return JavaFileType.INSTANCE
|
||||
}
|
||||
else {
|
||||
return PlainTextFileType.INSTANCE
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
|
||||
|
||||
private List<IntentionAction> getAvailableActions() {
|
||||
doHighlighting();
|
||||
return LightQuickFixTestCase.getAvailableActions(getEditor(), getFile());
|
||||
}
|
||||
val fileInSourceRoot = File(testFile.path)
|
||||
var container = FileUtil.getParentFile(fileInSourceRoot)
|
||||
if (container == null) {
|
||||
container = sourceRootDir
|
||||
}
|
||||
else {
|
||||
container = File(sourceRootDir, container.path)
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Sdk getTestProjectJdk() {
|
||||
return PluginTestCaseBase.mockJdk();
|
||||
}
|
||||
if (!container.exists()) {
|
||||
TestCase.assertTrue(container.mkdirs())
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
return KotlinTestUtils.getHomeDirectory() + "/";
|
||||
}
|
||||
val tempFile = FileUtil.createTempFile(container, FileUtil.getNameWithoutExtension(testFile.path), "." + extension, true)
|
||||
|
||||
@NotNull
|
||||
private VirtualFile findVirtualFile(@NotNull String filePath) {
|
||||
String absolutePath = getTestDataPath() + filePath;
|
||||
return VfsTestUtil.findFileByCaseSensitivePath(absolutePath);
|
||||
}
|
||||
|
||||
private static class TestFile {
|
||||
public final String path;
|
||||
public final String content;
|
||||
val vFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(tempFile)!!
|
||||
runWriteAction {
|
||||
vFile.setCharset(CharsetToolkit.UTF8_CHARSET)
|
||||
VfsUtil.saveText(vFile, testFile.content)
|
||||
|
||||
TestFile(String path, String content) {
|
||||
this.path = path;
|
||||
this.content = 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()) {
|
||||
return availableAction
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user