Rewrite KotlinHierarchyViewTestBase with light fixture tests

This commit is contained in:
Nikolay Krasko
2018-12-03 14:49:40 +03:00
parent 5055308064
commit 9cc88c13f5
4 changed files with 57 additions and 307 deletions
@@ -16,23 +16,36 @@
package org.jetbrains.kotlin.idea;
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess;
import com.intellij.testFramework.codeInsight.hierarchy.HierarchyViewTestBase;
import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil;
import org.jetbrains.kotlin.test.KotlinTestUtils;
import com.intellij.ide.hierarchy.HierarchyTreeStructure;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.testFramework.codeInsight.hierarchy.HierarchyViewTestFixture;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase;
public abstract class KotlinHierarchyViewTestBase extends HierarchyViewTestBase {
@Override
protected void setUp() throws Exception {
VfsRootAccess.allowRootAccess(KotlinTestUtils.getHomeDirectory());
super.setUp();
ConfigLibraryUtil.INSTANCE.configureKotlinRuntime(myModule);
import java.io.File;
import java.io.IOException;
public abstract class KotlinHierarchyViewTestBase extends KotlinLightCodeInsightFixtureTestCase {
private final HierarchyViewTestFixture hierarchyFixture = new HierarchyViewTestFixture();
protected void doHierarchyTest(
@NotNull Computable<? extends HierarchyTreeStructure> treeStructureComputable,
@NotNull String... fileNames
) throws Exception {
configure(fileNames);
String expectedStructure = loadExpectedStructure();
hierarchyFixture.doHierarchyTest(treeStructureComputable.compute(), expectedStructure);
}
@Override
protected void tearDown() throws Exception {
ConfigLibraryUtil.INSTANCE.unConfigureKotlinRuntime(myModule);
super.tearDown();
VfsRootAccess.disallowRootAccess(KotlinTestUtils.getHomeDirectory());
private void configure(@NotNull String[] fileNames) {
myFixture.configureByFiles(fileNames);
}
@NotNull
private String loadExpectedStructure() throws IOException {
String verificationFilePath = getTestDataPath() + "/" + getTestName(false) + "_verification.xml";
return FileUtil.loadFile(new File(verificationFilePath));
}
}
@@ -27,12 +27,12 @@ import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.impl.text.TextEditorPsiDataProvider;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.psi.*;
import com.intellij.refactoring.util.CommonRefactoringUtil.RefactoringErrorHintException;
import com.intellij.rt.execution.junit.ComparisonDetailsExtractor;
import com.intellij.testFramework.LightProjectDescriptor;
import com.intellij.testFramework.MapDataContext;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Processor;
@@ -42,7 +42,7 @@ import org.jetbrains.kotlin.idea.KotlinHierarchyViewTestBase;
import org.jetbrains.kotlin.idea.hierarchy.calls.KotlinCalleeTreeStructure;
import org.jetbrains.kotlin.idea.hierarchy.calls.KotlinCallerTreeStructure;
import org.jetbrains.kotlin.idea.hierarchy.overrides.KotlinOverrideTreeStructure;
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase;
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor;
import org.jetbrains.kotlin.psi.KtCallableDeclaration;
import org.jetbrains.kotlin.psi.KtElement;
import org.jetbrains.kotlin.test.KotlinTestUtils;
@@ -84,6 +84,7 @@ public abstract class AbstractHierarchyTest extends KotlinHierarchyViewTestBase
protected void doCallerJavaHierarchyTest(@NotNull String folderName) throws Exception {
this.folderName = folderName;
doHierarchyTest(getCallerJavaHierarchyStructure(), getFilesToConfigure());
}
protected void doCalleeHierarchyTest(@NotNull String folderName) throws Exception {
@@ -223,7 +224,9 @@ public abstract class AbstractHierarchyTest extends KotlinHierarchyViewTestBase
}
@Override
protected void doHierarchyTest(Computable<HierarchyTreeStructure> treeStructureComputable, String... fileNames) throws Exception {
protected void doHierarchyTest(
@NotNull Computable<? extends HierarchyTreeStructure> treeStructureComputable, @NotNull String... fileNames
) throws Exception {
try {
super.doHierarchyTest(treeStructureComputable, fileNames);
}
@@ -240,23 +243,22 @@ public abstract class AbstractHierarchyTest extends KotlinHierarchyViewTestBase
catch (ComparisonFailure failure) {
String actual = ComparisonDetailsExtractor.getActual(failure);
String verificationFilePath =
getTestDataPath() + "/" + getBasePath() + "/" + getTestName(false) + "_verification.xml";
getTestDataPath() + "/" + getTestName(false) + "_verification.xml";
KotlinTestUtils.assertEqualsToFile(new File(verificationFilePath), actual);
}
}
@Override
protected String getBasePath() {
return folderName.substring("idea/testData/".length());
@NotNull
protected LightProjectDescriptor getProjectDescriptor() {
return KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE;
}
@NotNull
@Override
protected String getTestDataPath() {
return PluginTestCaseBase.getTestDataPathBase();
}
@Override
protected Sdk getTestProjectJdk() {
return PluginTestCaseBase.mockJdk();
String testRoot = super.getTestDataPath();
String testDir = KotlinTestUtils.getTestDataFileName(this.getClass(), getName());
return testRoot + "/" + testDir;
}
}
@@ -1,264 +0,0 @@
/*
* Copyright 2010-2015 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.hierarchy;
import com.intellij.ide.hierarchy.*;
import com.intellij.ide.hierarchy.actions.BrowseHierarchyActionBase;
import com.intellij.ide.hierarchy.call.CallerMethodsTreeStructure;
import com.intellij.ide.hierarchy.type.SubtypesHierarchyTreeStructure;
import com.intellij.ide.hierarchy.type.SupertypesHierarchyTreeStructure;
import com.intellij.ide.hierarchy.type.TypeHierarchyTreeStructure;
import com.intellij.lang.LanguageExtension;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.impl.text.TextEditorPsiDataProvider;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.psi.*;
import com.intellij.refactoring.util.CommonRefactoringUtil.RefactoringErrorHintException;
import com.intellij.rt.execution.junit.ComparisonDetailsExtractor;
import com.intellij.testFramework.MapDataContext;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Processor;
import junit.framework.ComparisonFailure;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.idea.KotlinHierarchyViewTestBase;
import org.jetbrains.kotlin.idea.hierarchy.calls.KotlinCalleeTreeStructure;
import org.jetbrains.kotlin.idea.hierarchy.calls.KotlinCallerTreeStructure;
import org.jetbrains.kotlin.idea.hierarchy.overrides.KotlinOverrideTreeStructure;
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase;
import org.jetbrains.kotlin.psi.KtCallableDeclaration;
import org.jetbrains.kotlin.psi.KtElement;
import org.jetbrains.kotlin.test.KotlinTestUtils;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/*
Test Hierarchy view
Format: test build hierarchy for element at caret, file with caret should be the first in the sorted list of files.
Test accept more than one file, file extension should be .java or .kt
*/
public abstract class AbstractHierarchyTest extends KotlinHierarchyViewTestBase {
protected String folderName;
protected void doTypeClassHierarchyTest(@NotNull String folderName) throws Exception {
this.folderName = folderName;
doHierarchyTest(getTypeHierarchyStructure(), getFilesToConfigure());
}
protected void doSuperClassHierarchyTest(@NotNull String folderName) throws Exception {
this.folderName = folderName;
doHierarchyTest(getSuperTypesHierarchyStructure(), getFilesToConfigure());
}
protected void doSubClassHierarchyTest(@NotNull String folderName) throws Exception {
this.folderName = folderName;
doHierarchyTest(getSubTypesHierarchyStructure(), getFilesToConfigure());
}
protected void doCallerHierarchyTest(@NotNull String folderName) throws Exception {
this.folderName = folderName;
doHierarchyTest(getCallerHierarchyStructure(), getFilesToConfigure());
}
protected void doCallerJavaHierarchyTest(@NotNull String folderName) throws Exception {
this.folderName = folderName;
doHierarchyTest(getCallerJavaHierarchyStructure(), getFilesToConfigure());
}
protected void doCalleeHierarchyTest(@NotNull String folderName) throws Exception {
this.folderName = folderName;
doHierarchyTest(getCalleeHierarchyStructure(), getFilesToConfigure());
}
protected void doOverrideHierarchyTest(@NotNull String folderName) throws Exception {
this.folderName = folderName;
doHierarchyTest(getOverrideHierarchyStructure(), getFilesToConfigure());
}
private Computable<HierarchyTreeStructure> getSuperTypesHierarchyStructure() {
return new Computable<HierarchyTreeStructure>() {
@Override
public HierarchyTreeStructure compute() {
return new SupertypesHierarchyTreeStructure(
getProject(),
(PsiClass) getElementAtCaret(LanguageTypeHierarchy.INSTANCE)
);
}
};
}
private Computable<HierarchyTreeStructure> getSubTypesHierarchyStructure() {
return new Computable<HierarchyTreeStructure>() {
@Override
public HierarchyTreeStructure compute() {
return new SubtypesHierarchyTreeStructure(
getProject(),
(PsiClass) getElementAtCaret(LanguageTypeHierarchy.INSTANCE),
HierarchyBrowserBaseEx.SCOPE_PROJECT
);
}
};
}
private Computable<HierarchyTreeStructure> getTypeHierarchyStructure() {
return new Computable<HierarchyTreeStructure>() {
@Override
public HierarchyTreeStructure compute() {
return new TypeHierarchyTreeStructure(
getProject(),
(PsiClass) getElementAtCaret(LanguageTypeHierarchy.INSTANCE),
HierarchyBrowserBaseEx.SCOPE_PROJECT
);
}
};
}
private Computable<HierarchyTreeStructure> getCallerHierarchyStructure() {
return new Computable<HierarchyTreeStructure>() {
@Override
public HierarchyTreeStructure compute() {
return new KotlinCallerTreeStructure(
(KtElement) getElementAtCaret(LanguageCallHierarchy.INSTANCE),
HierarchyBrowserBaseEx.SCOPE_PROJECT
);
}
};
}
private Computable<HierarchyTreeStructure> getCallerJavaHierarchyStructure() {
return new Computable<HierarchyTreeStructure>() {
@Override
public HierarchyTreeStructure compute() {
return new CallerMethodsTreeStructure(
getProject(),
(PsiMethod) getElementAtCaret(LanguageCallHierarchy.INSTANCE),
HierarchyBrowserBaseEx.SCOPE_PROJECT
);
}
};
}
private Computable<HierarchyTreeStructure> getCalleeHierarchyStructure() {
return new Computable<HierarchyTreeStructure>() {
@Override
public HierarchyTreeStructure compute() {
return new KotlinCalleeTreeStructure(
(KtElement) getElementAtCaret(LanguageCallHierarchy.INSTANCE),
HierarchyBrowserBaseEx.SCOPE_PROJECT
);
}
};
}
private Computable<HierarchyTreeStructure> getOverrideHierarchyStructure() {
return new Computable<HierarchyTreeStructure>() {
@Override
public HierarchyTreeStructure compute() {
return new KotlinOverrideTreeStructure(
getProject(),
(KtCallableDeclaration) getElementAtCaret(LanguageMethodHierarchy.INSTANCE)
);
}
};
}
private PsiElement getElementAtCaret(LanguageExtension<HierarchyProvider> extension) {
PsiFile file = PsiDocumentManager.getInstance(getProject()).getPsiFile(getEditor().getDocument());
HierarchyProvider provider = BrowseHierarchyActionBase.findProvider(extension, file, file, getDataContext());
PsiElement target = provider != null ? provider.getTarget(getDataContext()) : null;
if (target == null) throw new RefactoringErrorHintException("Cannot apply action for element at caret");
return target;
}
private DataContext getDataContext() {
Editor editor = getEditor();
MapDataContext context = new MapDataContext();
context.put(CommonDataKeys.PROJECT, getProject());
context.put(CommonDataKeys.EDITOR, editor);
PsiElement targetElement = (PsiElement) new TextEditorPsiDataProvider().getData(
CommonDataKeys.PSI_ELEMENT.getName(),
editor,
editor.getCaretModel().getCurrentCaret()
);
context.put(CommonDataKeys.PSI_ELEMENT, targetElement);
return context;
}
protected String[] getFilesToConfigure() {
final List<String> files = new ArrayList<String>(2);
FileUtil.processFilesRecursively(new File(folderName), new Processor<File>() {
@Override
public boolean process(File file) {
String fileName = file.getName();
if (fileName.endsWith(".kt") || fileName.endsWith(".java")) {
files.add(fileName);
}
return true;
}
});
Collections.sort(files);
return ArrayUtil.toStringArray(files);
}
@Override
protected void doHierarchyTest(
@NotNull Computable<? extends HierarchyTreeStructure> treeStructureComputable, @NotNull String... fileNames
) throws Exception {
try {
super.doHierarchyTest(treeStructureComputable, fileNames);
}
catch (RefactoringErrorHintException e) {
File file = new File(folderName, "messages.txt");
if (file.exists()) {
String expectedMessage = FileUtil.loadFile(file, true);
assertEquals(expectedMessage, e.getLocalizedMessage());
}
else {
fail("Unexpected error: " + e.getLocalizedMessage());
}
}
catch (ComparisonFailure failure) {
String actual = ComparisonDetailsExtractor.getActual(failure);
String verificationFilePath =
getTestDataPath() + "/" + getBasePath() + "/" + getTestName(false) + "_verification.xml";
KotlinTestUtils.assertEqualsToFile(new File(verificationFilePath), actual);
}
}
@Override
protected String getBasePath() {
return folderName.substring("idea/testData/".length());
}
@Override
protected String getTestDataPath() {
return PluginTestCaseBase.getTestDataPathBase();
}
@Override
protected Sdk getTestProjectJdk() {
return PluginTestCaseBase.mockJdk();
}
}
@@ -22,37 +22,34 @@ import com.intellij.openapi.util.Computable
import com.intellij.psi.PsiClass
import com.intellij.psi.impl.java.stubs.index.JavaFullClassNameIndex
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.idea.test.ModuleKind
import org.jetbrains.kotlin.idea.test.configureAs
import com.intellij.testFramework.LightProjectDescriptor
import org.jetbrains.kotlin.idea.test.ProjectDescriptorWithStdlibSources
import org.jetbrains.kotlin.test.InTextDirectivesUtils
import org.jetbrains.kotlin.test.KotlinTestUtils
import java.io.File
abstract class AbstractHierarchyWithLibTest : AbstractHierarchyTest() {
override fun setUp() {
super.setUp()
myModule.configureAs(ModuleKind.KOTLIN_JVM_WITH_STDLIB_SOURCES)
}
protected fun doTest(folderName: String) {
this.folderName = folderName
val filesToConfigure = filesToConfigure
val file = filesToConfigure.first()
val directive = InTextDirectivesUtils.findLinesWithPrefixesRemoved(
File("${KotlinTestUtils.getHomeDirectory()}/$folderName/$file").readText(),
"// BASE_CLASS: "
File("${KotlinTestUtils.getHomeDirectory()}/$folderName/$file").readText(),
"// BASE_CLASS: "
).singleOrNull() ?: error("File should contain BASE_CLASS directive")
doHierarchyTest(
Computable {
val targetClass = findTargetJavaClass(directive.trim())
Computable {
val targetClass = findTargetJavaClass(directive.trim())
TypeHierarchyTreeStructure(
project,
targetClass,
HierarchyBrowserBaseEx.SCOPE_PROJECT)
}, *filesToConfigure)
TypeHierarchyTreeStructure(
project,
targetClass,
HierarchyBrowserBaseEx.SCOPE_PROJECT
)
}, *filesToConfigure
)
}
private fun findTargetJavaClass(targetClass: String): PsiClass {
@@ -60,4 +57,6 @@ abstract class AbstractHierarchyWithLibTest : AbstractHierarchyTest() {
it.qualifiedName == targetClass
} ?: error("Could not find java class: $targetClass")
}
override fun getProjectDescriptor(): LightProjectDescriptor = ProjectDescriptorWithStdlibSources.INSTANCE
}