mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[type hierarchy] split hierarchy test logic and test project model
This commit is contained in:
+16
-119
@@ -16,144 +16,41 @@
|
||||
package com.intellij.testFramework.codeInsight.hierarchy;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightTestCase;
|
||||
import com.intellij.ide.hierarchy.HierarchyNodeDescriptor;
|
||||
import com.intellij.ide.hierarchy.HierarchyTreeStructure;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.JDOMUtil;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Checks tree structure for Type Hierarchy (Ctrl+H), Call Hierarchy (Ctrl+Alt+H), Method Hierarchy (Ctrl+Shift+H).
|
||||
*/
|
||||
public abstract class HierarchyViewTestBase extends CodeInsightTestCase {
|
||||
|
||||
private static final String NODE_ELEMENT_NAME = "node";
|
||||
private static final String ANY_NODES_ELEMENT_NAME = "any";
|
||||
private static final String TEXT_ATTR_NAME = "text";
|
||||
private static final String BASE_ATTR_NAME = "base";
|
||||
private final HierarchyViewTestFixture myFixture = new HierarchyViewTestFixture();
|
||||
|
||||
protected abstract String getBasePath();
|
||||
|
||||
protected void doHierarchyTest(final Computable<HierarchyTreeStructure> treeStructureComputable, final String... fileNames)
|
||||
throws Exception {
|
||||
protected void doHierarchyTest(@NotNull Computable<HierarchyTreeStructure> treeStructureComputable,
|
||||
@NotNull String... fileNames) throws Exception {
|
||||
configure(fileNames);
|
||||
String expectedStructure = loadExpectedStructure();
|
||||
|
||||
myFixture.doHierarchyTest(treeStructureComputable.compute(), expectedStructure);
|
||||
}
|
||||
|
||||
private void configure(@NotNull String[] fileNames) {
|
||||
final String[] relFilePaths = new String[fileNames.length];
|
||||
for (int i = 0; i < fileNames.length; i++) {
|
||||
relFilePaths[i] = "/" + getBasePath() + "/" + fileNames[i];
|
||||
}
|
||||
configureByFiles(null, relFilePaths);
|
||||
|
||||
final String verificationFilePath = getTestDataPath() + "/" + getBasePath() + "/" + getTestName(false) + "_verification.xml";
|
||||
HierarchyTreeStructure structure = treeStructureComputable.compute();
|
||||
try {
|
||||
checkHierarchyTreeStructure(structure, JDOMUtil.load(new File(verificationFilePath)));
|
||||
} catch (Throwable e) {
|
||||
assertEquals("XML structure comparison for your convenience, actual failure details BELOW",
|
||||
FileUtil.loadFile(new File(verificationFilePath)), dump(structure, null, 0));
|
||||
//noinspection CallToPrintStackTrace
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static String dump(final HierarchyTreeStructure treeStructure, @Nullable HierarchyNodeDescriptor descriptor, int level) {
|
||||
StringBuilder s = new StringBuilder();
|
||||
dump(treeStructure, descriptor, level, s);
|
||||
return s.toString();
|
||||
@NotNull
|
||||
private String loadExpectedStructure() throws IOException {
|
||||
String verificationFilePath = getTestDataPath() + "/" + getBasePath() + "/" + getTestName(false) + "_verification.xml";
|
||||
return FileUtil.loadFile(new File(verificationFilePath));
|
||||
}
|
||||
|
||||
private static void dump(final HierarchyTreeStructure treeStructure,
|
||||
@Nullable HierarchyNodeDescriptor descriptor,
|
||||
int level,
|
||||
StringBuilder b) {
|
||||
if (level > 10) {
|
||||
for(int i = 0; i<level; i++) b.append(" ");
|
||||
b.append("<Probably infinite part skipped>\n");
|
||||
return;
|
||||
}
|
||||
if(descriptor==null) descriptor = (HierarchyNodeDescriptor)treeStructure.getRootElement();
|
||||
for(int i = 0; i<level; i++) b.append(" ");
|
||||
descriptor.update();
|
||||
b.append("<node text=\"").append(descriptor.getHighlightedText().getText()).append("\"")
|
||||
.append(treeStructure.getBaseDescriptor() == descriptor ? " base=\"true\"" : "");
|
||||
|
||||
final Object[] children = treeStructure.getChildElements(descriptor);
|
||||
if(children.length>0) {
|
||||
b.append(">\n");
|
||||
for (Object o : children) {
|
||||
HierarchyNodeDescriptor d = (HierarchyNodeDescriptor)o;
|
||||
dump(treeStructure, d, level + 1, b);
|
||||
}
|
||||
for(int i = 0; i<level; i++) b.append(" ");
|
||||
b.append("</node>\n");
|
||||
} else {
|
||||
b.append("/>\n");
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkHierarchyTreeStructure(final HierarchyTreeStructure treeStructure, final Element rootElement) {
|
||||
final HierarchyNodeDescriptor rootNodeDescriptor = (HierarchyNodeDescriptor)treeStructure.getRootElement();
|
||||
rootNodeDescriptor.update();
|
||||
if (rootElement == null || !NODE_ELEMENT_NAME.equals(rootElement.getName())) {
|
||||
throw new IllegalArgumentException("Incorrect root element in verification resource");
|
||||
}
|
||||
checkNodeDescriptorRecursively(treeStructure, rootNodeDescriptor, rootElement);
|
||||
}
|
||||
|
||||
private static void checkNodeDescriptorRecursively(final HierarchyTreeStructure treeStructure,
|
||||
final HierarchyNodeDescriptor descriptor,
|
||||
final Element expectedElement) {
|
||||
checkBaseNode(treeStructure, descriptor, expectedElement);
|
||||
checkContent(descriptor, expectedElement);
|
||||
checkChildren(treeStructure, descriptor, expectedElement);
|
||||
}
|
||||
|
||||
private static void checkBaseNode(final HierarchyTreeStructure treeStructure,
|
||||
final HierarchyNodeDescriptor descriptor,
|
||||
final Element expectedElement) {
|
||||
final String baseAttrValue = expectedElement.getAttributeValue(BASE_ATTR_NAME);
|
||||
final HierarchyNodeDescriptor baseDescriptor = treeStructure.getBaseDescriptor();
|
||||
final boolean mustBeBase = "true".equalsIgnoreCase(baseAttrValue);
|
||||
assertTrue("Incorrect base node", mustBeBase ? baseDescriptor == descriptor : baseDescriptor != descriptor);
|
||||
}
|
||||
|
||||
private static void checkContent(final HierarchyNodeDescriptor descriptor, final Element expectedElement) {
|
||||
assertEquals(expectedElement.getAttributeValue(TEXT_ATTR_NAME), descriptor.getHighlightedText().getText());
|
||||
}
|
||||
|
||||
private static void checkChildren(final HierarchyTreeStructure treeStructure,
|
||||
final HierarchyNodeDescriptor descriptor,
|
||||
final Element element) {
|
||||
if (element.getChild(ANY_NODES_ELEMENT_NAME) != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Object[] children = treeStructure.getChildElements(descriptor);
|
||||
//noinspection unchecked
|
||||
final List<Element> expectedChildren = new ArrayList<>(element.getChildren(NODE_ELEMENT_NAME));
|
||||
|
||||
final StringBuilder messageBuilder = new StringBuilder("Actual children of [" + descriptor.getHighlightedText().getText() + "]:\n");
|
||||
for (Object child : children) {
|
||||
final HierarchyNodeDescriptor nodeDescriptor = (HierarchyNodeDescriptor)child;
|
||||
nodeDescriptor.update();
|
||||
messageBuilder.append(" [").append(nodeDescriptor.getHighlightedText().getText()).append("]\n");
|
||||
}
|
||||
assertEquals(messageBuilder.toString(), expectedChildren.size(), children.length);
|
||||
|
||||
Arrays.sort(children, (first, second) -> ((HierarchyNodeDescriptor)first).getHighlightedText().getText()
|
||||
.compareTo(((HierarchyNodeDescriptor)second).getHighlightedText().getText()));
|
||||
|
||||
Collections.sort(expectedChildren,
|
||||
(first, second) -> first.getAttributeValue(TEXT_ATTR_NAME).compareTo(second.getAttributeValue(TEXT_ATTR_NAME)));
|
||||
|
||||
//noinspection unchecked
|
||||
final Iterator<Element> iterator = expectedChildren.iterator();
|
||||
for (Object child : children) {
|
||||
checkNodeDescriptorRecursively(treeStructure, ((HierarchyNodeDescriptor)child), iterator.next());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+137
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
*/
|
||||
package com.intellij.testFramework.codeInsight.hierarchy;
|
||||
|
||||
import com.intellij.ide.hierarchy.HierarchyNodeDescriptor;
|
||||
import com.intellij.ide.hierarchy.HierarchyTreeStructure;
|
||||
import com.intellij.openapi.util.JDOMUtil;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static junit.framework.TestCase.assertEquals;
|
||||
import static junit.framework.TestCase.assertTrue;
|
||||
|
||||
public class HierarchyViewTestFixture {
|
||||
private static final String NODE_ELEMENT_NAME = "node";
|
||||
private static final String ANY_NODES_ELEMENT_NAME = "any";
|
||||
private static final String TEXT_ATTR_NAME = "text";
|
||||
private static final String BASE_ATTR_NAME = "base";
|
||||
|
||||
public void doHierarchyTest(@NotNull HierarchyTreeStructure treeStructure,
|
||||
@NotNull String expectedStructure) {
|
||||
try {
|
||||
checkHierarchyTreeStructure(treeStructure, JDOMUtil.load(expectedStructure));
|
||||
}
|
||||
catch (Throwable e) {
|
||||
assertEquals("XML structure comparison for your convenience, actual failure details BELOW",
|
||||
expectedStructure, dump(treeStructure, null, 0));
|
||||
//noinspection CallToPrintStackTrace
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String dump(@NotNull HierarchyTreeStructure treeStructure,
|
||||
@Nullable HierarchyNodeDescriptor descriptor,
|
||||
int level) {
|
||||
StringBuilder s = new StringBuilder();
|
||||
dump(treeStructure, descriptor, level, s);
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
private static void dump(@NotNull HierarchyTreeStructure treeStructure,
|
||||
@Nullable HierarchyNodeDescriptor descriptor,
|
||||
int level,
|
||||
@NotNull StringBuilder b) {
|
||||
if (level > 10) {
|
||||
for (int i = 0; i < level; i++) b.append(" ");
|
||||
b.append("<Probably infinite part skipped>\n");
|
||||
return;
|
||||
}
|
||||
if (descriptor == null) descriptor = (HierarchyNodeDescriptor)treeStructure.getRootElement();
|
||||
for (int i = 0; i < level; i++) b.append(" ");
|
||||
descriptor.update();
|
||||
b.append("<node text=\"").append(descriptor.getHighlightedText().getText()).append("\"")
|
||||
.append(treeStructure.getBaseDescriptor() == descriptor ? " base=\"true\"" : "");
|
||||
|
||||
Object[] children = treeStructure.getChildElements(descriptor);
|
||||
if (children.length > 0) {
|
||||
b.append(">\n");
|
||||
for (Object o : children) {
|
||||
HierarchyNodeDescriptor d = (HierarchyNodeDescriptor)o;
|
||||
dump(treeStructure, d, level + 1, b);
|
||||
}
|
||||
for (int i = 0; i < level; i++) b.append(" ");
|
||||
b.append("</node>\n");
|
||||
}
|
||||
else {
|
||||
b.append("/>\n");
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkHierarchyTreeStructure(@NotNull HierarchyTreeStructure treeStructure,
|
||||
@Nullable Element rootElement) {
|
||||
HierarchyNodeDescriptor rootNodeDescriptor = (HierarchyNodeDescriptor)treeStructure.getRootElement();
|
||||
rootNodeDescriptor.update();
|
||||
if (rootElement == null || !NODE_ELEMENT_NAME.equals(rootElement.getName())) {
|
||||
throw new IllegalArgumentException("Incorrect root element in verification resource");
|
||||
}
|
||||
checkNodeDescriptorRecursively(treeStructure, rootNodeDescriptor, rootElement);
|
||||
}
|
||||
|
||||
private static void checkNodeDescriptorRecursively(@NotNull HierarchyTreeStructure treeStructure,
|
||||
@NotNull HierarchyNodeDescriptor descriptor,
|
||||
@NotNull Element expectedElement) {
|
||||
checkBaseNode(treeStructure, descriptor, expectedElement);
|
||||
checkContent(descriptor, expectedElement);
|
||||
checkChildren(treeStructure, descriptor, expectedElement);
|
||||
}
|
||||
|
||||
private static void checkBaseNode(@NotNull HierarchyTreeStructure treeStructure,
|
||||
@NotNull HierarchyNodeDescriptor descriptor,
|
||||
@NotNull Element expectedElement) {
|
||||
String baseAttrValue = expectedElement.getAttributeValue(BASE_ATTR_NAME);
|
||||
HierarchyNodeDescriptor baseDescriptor = treeStructure.getBaseDescriptor();
|
||||
boolean mustBeBase = "true".equalsIgnoreCase(baseAttrValue);
|
||||
assertTrue("Incorrect base node", mustBeBase ? baseDescriptor == descriptor : baseDescriptor != descriptor);
|
||||
}
|
||||
|
||||
private static void checkContent(@NotNull HierarchyNodeDescriptor descriptor,
|
||||
@NotNull Element expectedElement) {
|
||||
assertEquals(expectedElement.getAttributeValue(TEXT_ATTR_NAME), descriptor.getHighlightedText().getText());
|
||||
}
|
||||
|
||||
private static void checkChildren(@NotNull HierarchyTreeStructure treeStructure,
|
||||
@NotNull HierarchyNodeDescriptor descriptor,
|
||||
@NotNull Element element) {
|
||||
if (element.getChild(ANY_NODES_ELEMENT_NAME) != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Object[] children = treeStructure.getChildElements(descriptor);
|
||||
//noinspection unchecked
|
||||
List<Element> expectedChildren = new ArrayList<>(element.getChildren(NODE_ELEMENT_NAME));
|
||||
|
||||
StringBuilder messageBuilder = new StringBuilder("Actual children of [" + descriptor.getHighlightedText().getText() + "]:\n");
|
||||
for (Object child : children) {
|
||||
HierarchyNodeDescriptor nodeDescriptor = (HierarchyNodeDescriptor)child;
|
||||
nodeDescriptor.update();
|
||||
messageBuilder.append(" [").append(nodeDescriptor.getHighlightedText().getText()).append("]\n");
|
||||
}
|
||||
assertEquals(messageBuilder.toString(), expectedChildren.size(), children.length);
|
||||
|
||||
Arrays.sort(children, Comparator.comparing(child -> ((HierarchyNodeDescriptor)child).getHighlightedText().getText()));
|
||||
|
||||
Collections.sort(expectedChildren, Comparator.comparing(child -> child.getAttributeValue(TEXT_ATTR_NAME)));
|
||||
|
||||
//noinspection unchecked
|
||||
Iterator<Element> iterator = expectedChildren.iterator();
|
||||
for (Object child : children) {
|
||||
checkNodeDescriptorRecursively(treeStructure, ((HierarchyNodeDescriptor)child), iterator.next());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,14 +17,12 @@ package com.jetbrains.python.hierarchy;
|
||||
|
||||
import com.intellij.codeInsight.TargetElementUtil;
|
||||
import com.intellij.ide.hierarchy.HierarchyBrowserBaseEx;
|
||||
import com.intellij.ide.hierarchy.HierarchyNodeDescriptor;
|
||||
import com.intellij.ide.hierarchy.HierarchyTreeStructure;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.testFramework.codeInsight.hierarchy.HierarchyViewTestFixture;
|
||||
import com.jetbrains.python.fixtures.PyTestCase;
|
||||
import com.jetbrains.python.hierarchy.call.PyCalleeFunctionTreeStructure;
|
||||
import com.jetbrains.python.hierarchy.call.PyCallerFunctionTreeStructure;
|
||||
import com.jetbrains.python.psi.PyFunction;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author novokrest
|
||||
@@ -33,41 +31,6 @@ public class PyCallHierarchyTest extends PyTestCase {
|
||||
private static final String CALLER_VERIFICATION_SUFFIX = "_caller_verification.xml";
|
||||
private static final String CALLEE_VERIFICATION_SUFFIX = "_callee_verification.xml";
|
||||
|
||||
public static String dump(final HierarchyTreeStructure treeStructure, @Nullable HierarchyNodeDescriptor descriptor) {
|
||||
StringBuilder s = new StringBuilder();
|
||||
dump(treeStructure, descriptor, 0, s);
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
private static void dump(final HierarchyTreeStructure treeStructure,
|
||||
@Nullable HierarchyNodeDescriptor descriptor,
|
||||
int level,
|
||||
StringBuilder b) {
|
||||
if (level > 10) {
|
||||
for(int i = 0; i<level; i++) b.append(" ");
|
||||
b.append("<Probably infinite part skipped>\n");
|
||||
return;
|
||||
}
|
||||
if(descriptor==null) descriptor = (HierarchyNodeDescriptor)treeStructure.getRootElement();
|
||||
for(int i = 0; i<level; i++) b.append(" ");
|
||||
descriptor.update();
|
||||
b.append("<node text=\"").append(descriptor.getHighlightedText().getText()).append("\"")
|
||||
.append(treeStructure.getBaseDescriptor() == descriptor ? " base=\"true\"" : "");
|
||||
|
||||
final Object[] children = treeStructure.getChildElements(descriptor);
|
||||
if(children.length>0) {
|
||||
b.append(">\n");
|
||||
for (Object o : children) {
|
||||
HierarchyNodeDescriptor d = (HierarchyNodeDescriptor)o;
|
||||
dump(treeStructure, d, level + 1, b);
|
||||
}
|
||||
for(int i = 0; i<level; i++) b.append(" ");
|
||||
b.append("</node>\n");
|
||||
} else {
|
||||
b.append("/>\n");
|
||||
}
|
||||
}
|
||||
|
||||
private String getBasePath() {
|
||||
return "hierarchy/call/Static/" + getTestName(false);
|
||||
}
|
||||
@@ -97,10 +60,10 @@ public class PyCallHierarchyTest extends PyTestCase {
|
||||
private void checkHierarchyTreeStructure(PyFunction function) {
|
||||
final PyCallerFunctionTreeStructure callerStructure = new PyCallerFunctionTreeStructure(myFixture.getProject(), function,
|
||||
HierarchyBrowserBaseEx.SCOPE_PROJECT);
|
||||
assertSameLinesWithFile(getVerificationCallerFilePath(), dump(callerStructure, null));
|
||||
assertSameLinesWithFile(getVerificationCallerFilePath(), HierarchyViewTestFixture.dump(callerStructure, null, 0));
|
||||
final PyCalleeFunctionTreeStructure calleeStructure = new PyCalleeFunctionTreeStructure(myFixture.getProject(), function,
|
||||
HierarchyBrowserBaseEx.SCOPE_PROJECT);
|
||||
assertSameLinesWithFile(getVerificationCalleeFilePath(), dump(calleeStructure, null));
|
||||
assertSameLinesWithFile(getVerificationCalleeFilePath(), HierarchyViewTestFixture.dump(calleeStructure, null, 0));
|
||||
}
|
||||
|
||||
private void doTestCallHierarchy(String ... fileNames) {
|
||||
|
||||
Reference in New Issue
Block a user