From dcd374eb82b83d645b6df2f42d6fe0d5e1cff129 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Thu, 13 Jan 2022 17:28:56 +0100 Subject: [PATCH] refactor HierarchyTester to allow node descriptor comparator to test the children order GitOrigin-RevId: 0e307b174a68169e37d66e8ef4432fcdaab0f02d --- .../ide/hierarchy/JavaCallHierarchyTest.java | 9 ++-- .../hierarchy/JavaMethodHierarchyTest.java | 3 +- .../hierarchy/HierarchyViewTestBase.java | 10 ++-- .../hierarchy/HierarchyViewTestFixture.java | 54 +++++++++++++------ .../python/hierarchy/PyCallHierarchyTest.java | 4 +- 5 files changed, 55 insertions(+), 25 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/java/ide/hierarchy/JavaCallHierarchyTest.java b/java/java-tests/testSrc/com/intellij/java/ide/hierarchy/JavaCallHierarchyTest.java index f8d135b17e66..08e647830cf8 100644 --- a/java/java-tests/testSrc/com/intellij/java/ide/hierarchy/JavaCallHierarchyTest.java +++ b/java/java-tests/testSrc/com/intellij/java/ide/hierarchy/JavaCallHierarchyTest.java @@ -3,6 +3,7 @@ package com.intellij.java.ide.hierarchy; import com.intellij.JavaTestUtil; import com.intellij.ide.hierarchy.HierarchyBrowserBaseEx; +import com.intellij.ide.hierarchy.JavaHierarchyUtil; import com.intellij.ide.hierarchy.actions.BrowseTypeHierarchyAction; import com.intellij.ide.hierarchy.call.CalleeMethodsTreeStructure; import com.intellij.ide.hierarchy.call.CallerMethodsTreeStructure; @@ -47,14 +48,14 @@ public class JavaCallHierarchyTest extends HierarchyViewTestBase { assertNotNull("Method '" + methodName + "' not found in " + classFqn + ". Available methods are " + Arrays.toString(psiClass.getMethods()), method); return new CallerMethodsTreeStructure(getProject(), method, HierarchyBrowserBaseEx.SCOPE_PROJECT); - }, fileNames); + }, JavaHierarchyUtil.getComparator(myProject), fileNames); } private void doJavaCalleeTypeHierarchyTest(@NotNull String classFqn, @NotNull String methodName, String @NotNull ... fileNames) throws Exception { doHierarchyTest(() -> { PsiClass psiClass = JavaPsiFacade.getInstance(getProject()).findClass(classFqn, ProjectScope.getProjectScope(getProject())); PsiMember method = psiClass.findMethodsByName(methodName, false) [0]; return new CalleeMethodsTreeStructure(getProject(), method, HierarchyBrowserBaseEx.SCOPE_PROJECT); - }, fileNames); + }, JavaHierarchyUtil.getComparator(myProject),fileNames); } public void testDirectRecursion() throws Exception { @@ -98,7 +99,7 @@ public class JavaCallHierarchyTest extends HierarchyViewTestBase { PsiClass psiClass = JavaPsiFacade.getInstance(getProject()).findClass("A", ProjectScope.getProjectScope(getProject())); PsiMember method = psiClass.findMethodsByName("testMethod", false) [0]; return new CalleeMethodsTreeStructure(getProject(), method, HierarchyBrowserBaseEx.SCOPE_PROJECT); - }, "A.java"); + }, JavaHierarchyUtil.getComparator(myProject),"A.java"); } public void testField() throws Exception { @@ -106,7 +107,7 @@ public class JavaCallHierarchyTest extends HierarchyViewTestBase { PsiClass psiClass = JavaPsiFacade.getInstance(getProject()).findClass("A", ProjectScope.getProjectScope(getProject())); PsiField field = psiClass.findFieldByName("testField", false); return new CallerMethodsTreeStructure(getProject(), field, HierarchyBrowserBaseEx.SCOPE_PROJECT); - }, "A.java"); + }, JavaHierarchyUtil.getComparator(myProject),"A.java"); } public void testAnonymous2() throws Exception { diff --git a/java/java-tests/testSrc/com/intellij/java/ide/hierarchy/JavaMethodHierarchyTest.java b/java/java-tests/testSrc/com/intellij/java/ide/hierarchy/JavaMethodHierarchyTest.java index 4dc8dbc93dcd..0246a0872266 100644 --- a/java/java-tests/testSrc/com/intellij/java/ide/hierarchy/JavaMethodHierarchyTest.java +++ b/java/java-tests/testSrc/com/intellij/java/ide/hierarchy/JavaMethodHierarchyTest.java @@ -18,6 +18,7 @@ package com.intellij.java.ide.hierarchy; import com.intellij.JavaTestUtil; import com.intellij.ide.hierarchy.HierarchyBrowserBaseEx; import com.intellij.ide.hierarchy.HierarchyBrowserManager; +import com.intellij.ide.hierarchy.JavaHierarchyUtil; import com.intellij.ide.hierarchy.method.MethodHierarchyTreeStructure; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.pom.java.LanguageLevel; @@ -91,7 +92,7 @@ public class JavaMethodHierarchyTest extends HierarchyViewTestBase { final PsiClass psiClass = JavaPsiFacade.getInstance(getProject()).findClass(classFqn, ProjectScope.getProjectScope(getProject())); final PsiMethod method = psiClass.findMethodsByName(methodName, false) [0]; return new MethodHierarchyTreeStructure(getProject(), method, HierarchyBrowserBaseEx.SCOPE_PROJECT); - }, fileNames); + }, JavaHierarchyUtil.getComparator(myProject), fileNames); } private void doTestHideIrrelevantClasses(String classFqn, String methodName, String... fileNames) throws Exception { diff --git a/java/testFramework/src/com/intellij/testFramework/codeInsight/hierarchy/HierarchyViewTestBase.java b/java/testFramework/src/com/intellij/testFramework/codeInsight/hierarchy/HierarchyViewTestBase.java index 46abc4a9d509..f183e5686745 100755 --- a/java/testFramework/src/com/intellij/testFramework/codeInsight/hierarchy/HierarchyViewTestBase.java +++ b/java/testFramework/src/com/intellij/testFramework/codeInsight/hierarchy/HierarchyViewTestBase.java @@ -17,15 +17,18 @@ package com.intellij.testFramework.codeInsight.hierarchy; import com.intellij.codeInsight.daemon.DaemonAnalyzerTestCase; import com.intellij.ide.hierarchy.HierarchyTreeStructure; +import com.intellij.ide.util.treeView.NodeDescriptor; import com.intellij.openapi.application.PathManager; -import com.intellij.openapi.util.Computable; import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess; import com.intellij.testFramework.ExpectedHighlightingData; import groovy.lang.GroovyObject; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.IOException; +import java.util.Comparator; +import java.util.function.Supplier; /** * Checks tree structure for Type Hierarchy (Ctrl+H), Call Hierarchy (Ctrl+Alt+H), Method Hierarchy (Ctrl+Shift+H). @@ -43,11 +46,12 @@ public abstract class HierarchyViewTestBase extends DaemonAnalyzerTestCase { protected abstract String getBasePath(); - protected void doHierarchyTest(@NotNull Computable treeStructureComputable, + protected void doHierarchyTest(@NotNull Supplier treeStructure, + @Nullable Comparator> comparator, String @NotNull ... fileNames) throws IOException { configure(fileNames); String verificationFilePath = getTestDataPath() + "/" + getBasePath() + "/verification.xml"; - HierarchyViewTestFixture.doHierarchyTest(treeStructureComputable.compute(), new File(verificationFilePath)); + HierarchyViewTestFixture.doHierarchyTest(treeStructure.get(), comparator, new File(verificationFilePath)); } private void configure(String @NotNull [] fileNames) { diff --git a/platform/testFramework/src/com/intellij/testFramework/codeInsight/hierarchy/HierarchyViewTestFixture.java b/platform/testFramework/src/com/intellij/testFramework/codeInsight/hierarchy/HierarchyViewTestFixture.java index 8d184bf93cd7..e9e0ae6e3bdd 100644 --- a/platform/testFramework/src/com/intellij/testFramework/codeInsight/hierarchy/HierarchyViewTestFixture.java +++ b/platform/testFramework/src/com/intellij/testFramework/codeInsight/hierarchy/HierarchyViewTestFixture.java @@ -3,6 +3,7 @@ package com.intellij.testFramework.codeInsight.hierarchy; import com.intellij.ide.hierarchy.HierarchyNodeDescriptor; import com.intellij.ide.hierarchy.HierarchyTreeStructure; +import com.intellij.ide.util.treeView.NodeDescriptor; import com.intellij.openapi.util.JDOMUtil; import com.intellij.openapi.util.io.FileUtil; import com.intellij.rt.execution.junit.FileComparisonFailure; @@ -31,7 +32,7 @@ public final class HierarchyViewTestFixture { */ public static void doHierarchyTest(@NotNull HierarchyTreeStructure treeStructure, @NotNull String expectedStructure) { - doHierarchyTest(treeStructure, expectedStructure, null); + doHierarchyTest(treeStructure, expectedStructure, null, null); } /** @@ -43,18 +44,24 @@ public final class HierarchyViewTestFixture { */ public static void doHierarchyTest(@NotNull HierarchyTreeStructure treeStructure, @NotNull File expectedFile) throws IOException { - doHierarchyTest(treeStructure, FileUtil.loadFile(expectedFile), expectedFile); + doHierarchyTest(treeStructure, null, expectedFile); + } + public static void doHierarchyTest(@NotNull HierarchyTreeStructure treeStructure, + @Nullable Comparator> comparator, + @NotNull File expectedFile) throws IOException { + doHierarchyTest(treeStructure, FileUtil.loadFile(expectedFile), comparator, expectedFile); } private static void doHierarchyTest(@NotNull HierarchyTreeStructure treeStructure, @NotNull String expectedStructure, + @Nullable Comparator> comparator, @Nullable File expectedFile) { Element element; try { element = JDOMUtil.load(expectedStructure); } catch (Throwable e) { - String actual = dump(treeStructure, null, 0); + String actual = dump(treeStructure, null, comparator, 0); if (!expectedStructure.equals(actual)) { throw new FileComparisonFailure("XML structure comparison for your convenience, actual failure details BELOW", expectedStructure, actual, @@ -62,20 +69,22 @@ public final class HierarchyViewTestFixture { } throw new RuntimeException(e); } - checkHierarchyTreeStructure(treeStructure, element); + checkHierarchyTreeStructure(treeStructure, element, comparator); } @NotNull public static String dump(@NotNull HierarchyTreeStructure treeStructure, @Nullable HierarchyNodeDescriptor descriptor, + @Nullable Comparator> comparator, int level) { StringBuilder s = new StringBuilder(); - dump(treeStructure, descriptor, level, s); + dump(treeStructure, descriptor, comparator,level, s); return s.toString(); } private static void dump(@NotNull HierarchyTreeStructure treeStructure, @Nullable HierarchyNodeDescriptor descriptor, + @Nullable Comparator> comparator, int level, @NotNull StringBuilder b) { if (level > 10) { @@ -89,12 +98,12 @@ public final class HierarchyViewTestFixture { b.append(" 0) { b.append(">\n"); for (Object o : children) { HierarchyNodeDescriptor d = (HierarchyNodeDescriptor)o; - dump(treeStructure, d, level + 1, b); + dump(treeStructure, d, comparator, level + 1, b); } b.append(" ".repeat(level)); b.append("\n"); @@ -104,21 +113,34 @@ public final class HierarchyViewTestFixture { } } - private static void checkHierarchyTreeStructure(@NotNull HierarchyTreeStructure treeStructure, @Nullable Element rootElement) { + @NotNull + private static Object @NotNull [] getSortedChildren(@NotNull HierarchyTreeStructure treeStructure, + @NotNull HierarchyNodeDescriptor descriptor, + @Nullable Comparator> comparator) { + Object[] children = treeStructure.getChildElements(descriptor); + if (comparator == null) comparator = Comparator.comparingInt(NodeDescriptor::getIndex); + Arrays.sort(children, (Comparator)comparator); + return children; + } + + private static void checkHierarchyTreeStructure(@NotNull HierarchyTreeStructure treeStructure, + @Nullable Element rootElement, + @Nullable Comparator> comparator) { 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); + checkNodeDescriptorRecursively(treeStructure, rootNodeDescriptor, rootElement, comparator); } private static void checkNodeDescriptorRecursively(@NotNull HierarchyTreeStructure treeStructure, @NotNull HierarchyNodeDescriptor descriptor, - @NotNull Element expectedElement) { + @NotNull Element expectedElement, + @Nullable Comparator> comparator) { checkBaseNode(treeStructure, descriptor, expectedElement); checkContent(descriptor, expectedElement); - checkChildren(treeStructure, descriptor, expectedElement); + checkChildren(treeStructure, descriptor, expectedElement, comparator); } private static void checkBaseNode(@NotNull HierarchyTreeStructure treeStructure, @@ -131,17 +153,19 @@ public final class HierarchyViewTestFixture { } private static void checkContent(@NotNull HierarchyNodeDescriptor descriptor, @NotNull Element expectedElement) { - assertEquals("parent: "+descriptor.getParentDescriptor(), expectedElement.getAttributeValue(TEXT_ATTR_NAME), descriptor.getHighlightedText().getText()); + assertEquals("parent: " + descriptor.getParentDescriptor(), expectedElement.getAttributeValue(TEXT_ATTR_NAME), + descriptor.getHighlightedText().getText()); } private static void checkChildren(@NotNull HierarchyTreeStructure treeStructure, @NotNull HierarchyNodeDescriptor descriptor, - @NotNull Element element) { + @NotNull Element element, + @Nullable Comparator> comparator) { if (element.getChild(ANY_NODES_ELEMENT_NAME) != null) { return; } - Object[] children = treeStructure.getChildElements(descriptor); + Object[] children = getSortedChildren(treeStructure, descriptor, comparator); List expectedChildren = new ArrayList<>(element.getChildren(NODE_ELEMENT_NAME)); StringBuilder messageBuilder = new StringBuilder("Actual children of [" + descriptor.getHighlightedText().getText() + "]:\n"); @@ -158,7 +182,7 @@ public final class HierarchyViewTestFixture { Iterator iterator = expectedChildren.iterator(); for (Object child : children) { - checkNodeDescriptorRecursively(treeStructure, (HierarchyNodeDescriptor)child, iterator.next()); + checkNodeDescriptorRecursively(treeStructure, (HierarchyNodeDescriptor)child, iterator.next(), comparator); } } } diff --git a/python/testSrc/com/jetbrains/python/hierarchy/PyCallHierarchyTest.java b/python/testSrc/com/jetbrains/python/hierarchy/PyCallHierarchyTest.java index ca58c820954e..09cb386198a3 100644 --- a/python/testSrc/com/jetbrains/python/hierarchy/PyCallHierarchyTest.java +++ b/python/testSrc/com/jetbrains/python/hierarchy/PyCallHierarchyTest.java @@ -60,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(), HierarchyViewTestFixture.dump(callerStructure, null, 0)); + assertSameLinesWithFile(getVerificationCallerFilePath(), HierarchyViewTestFixture.dump(callerStructure, null, null,0)); final PyCalleeFunctionTreeStructure calleeStructure = new PyCalleeFunctionTreeStructure(myFixture.getProject(), function, HierarchyBrowserBaseEx.SCOPE_PROJECT); - assertSameLinesWithFile(getVerificationCalleeFilePath(), HierarchyViewTestFixture.dump(calleeStructure, null, 0)); + assertSameLinesWithFile(getVerificationCalleeFilePath(), HierarchyViewTestFixture.dump(calleeStructure, null, null,0)); } private void doTestCallHierarchy(String ... fileNames) {