mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-13 15:52:01 +07:00
IDEA-361348 Spring Structure: inconsistent representation of @Bean methods
(cherry picked from commit 543f5219ac51fea0a6d1c0a50745a34460bc125f) IJ-CR-151083 GitOrigin-RevId: 8f750b5983445b9d0e5456d179a21d51855cd967
This commit is contained in:
committed by
intellij-monorepo-bot
parent
958784b947
commit
e8b1cfd99a
@@ -0,0 +1,112 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.testFramework
|
||||
|
||||
import com.intellij.ide.projectView.PresentationData
|
||||
import com.intellij.ide.structureView.StructureViewTreeElement
|
||||
import com.intellij.ide.structureView.logical.impl.LogicalStructureViewService
|
||||
import com.intellij.ide.util.treeView.PresentableNodeDescriptor
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.ui.SimpleTextAttributes
|
||||
import junit.framework.AssertionFailedError
|
||||
import junit.framework.ComparisonFailure
|
||||
import javax.swing.Icon
|
||||
|
||||
object LogicalStructureTestUtils {
|
||||
|
||||
private const val MAX_DEPTH = 20
|
||||
|
||||
fun assertLogicalStructureForFile(
|
||||
psiFile: PsiFile,
|
||||
expectedStructureInitializer: LogicalStructureNode.() -> Unit,
|
||||
) {
|
||||
val project = psiFile.project
|
||||
val builder = LogicalStructureViewService.getInstance(project).getLogicalStructureBuilder(psiFile)
|
||||
val structureView = builder!!.createStructureView(null, project)
|
||||
val actualRoot = createActualNode(structureView.treeModel.root)
|
||||
val expectedRoot = LogicalStructureNode(null, "root", "")
|
||||
expectedRoot.expectedStructureInitializer()
|
||||
if (!expectedRoot.isEqualTo(actualRoot, false)) {
|
||||
throw ComparisonFailure("The models are not equals: ",
|
||||
expectedRoot.print("", false),
|
||||
actualRoot.print("", false))
|
||||
}
|
||||
}
|
||||
|
||||
private fun createActualNode(element: StructureViewTreeElement): LogicalStructureNode {
|
||||
val presentation = element.presentation
|
||||
val node = LogicalStructureNode(
|
||||
presentation.getIcon(false),
|
||||
presentation.presentableText ?: "",
|
||||
presentation.locationString ?: "",
|
||||
(presentation as? PresentationData)?.coloredText ?: emptyList()
|
||||
)
|
||||
for (child in element.children) {
|
||||
if (child !is StructureViewTreeElement) continue
|
||||
node.subNode(createActualNode(child))
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
class LogicalStructureNode(
|
||||
val icon: Icon?,
|
||||
val name: String,
|
||||
val location: String,
|
||||
val coloredTextElements: List<PresentableNodeDescriptor.ColoredFragment> = emptyList(),
|
||||
) {
|
||||
|
||||
private val subNodes = mutableListOf<LogicalStructureNode>()
|
||||
|
||||
fun subNode(subNode: LogicalStructureNode) {
|
||||
subNodes.add(subNode)
|
||||
}
|
||||
|
||||
fun node(icon: Icon?, name: String, location: String? = "", initializer: (LogicalStructureNode.() -> Unit)? = null) {
|
||||
val subNode = LogicalStructureNode(icon, name, location ?: "")
|
||||
initializer?.invoke(subNode)
|
||||
subNodes.add(subNode)
|
||||
}
|
||||
|
||||
fun node(icon: Icon?, vararg coloredText: Pair<String, SimpleTextAttributes>, initializer: (LogicalStructureNode.() -> Unit)? = null) {
|
||||
val subNode = LogicalStructureNode(icon, "", "", coloredText.map { PresentableNodeDescriptor.ColoredFragment(it.first, it.second) })
|
||||
initializer?.invoke(subNode)
|
||||
subNodes.add(subNode)
|
||||
}
|
||||
|
||||
fun isEqualTo(other: LogicalStructureNode, compareItSelf: Boolean, availableDepth: Int = MAX_DEPTH): Boolean {
|
||||
if (availableDepth <= 0) throw AssertionFailedError("The structure is too deep. Most probably there is cyclic nodes here.")
|
||||
if (compareItSelf) {
|
||||
if (coloredTextElements.isNotEmpty()) {
|
||||
if (coloredTextElements.size != other.coloredTextElements.size) return false
|
||||
for (i in coloredTextElements.indices) {
|
||||
if (coloredTextElements[i] != other.coloredTextElements[i]) return false
|
||||
}
|
||||
} else {
|
||||
if (icon != other.icon || name != other.name || location != other.location) return false
|
||||
}
|
||||
}
|
||||
if (subNodes.size != other.subNodes.size) return false
|
||||
for (i in subNodes.indices) {
|
||||
if (!subNodes[i].isEqualTo(other.subNodes[i], true, availableDepth - 1)) return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
fun print(indent: String = "", printItself: Boolean = true): String {
|
||||
var result = indent
|
||||
icon?.toString()?.let { result += "[$it] " }
|
||||
if (coloredTextElements.isNotEmpty()) {
|
||||
result += coloredTextElements.joinToString(" | ") { it.text }
|
||||
} else {
|
||||
result += name
|
||||
if (location.isNotEmpty()) result += " | $location"
|
||||
}
|
||||
for (subNode in subNodes) {
|
||||
result += "\n" + subNode.print(if (printItself) "$indent " else indent)
|
||||
}
|
||||
if (!printItself) result = result.substringAfter("\n")
|
||||
return result
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user