Skip to content

Commit 6feaf4e

Browse files
timherziglheimbs
andauthored
Feature/144 enable to have a complete folder as scope (#170)
* enable contextmenuaction on folders Signed-off-by: Tim Herzig <[email protected]> * add functionality to run on all classes in dir + subdirs Signed-off-by: Tim Herzig <[email protected]> * edit visualization to easier show where results came from Signed-off-by: Tim Herzig <[email protected]> * change pipeline to call updateAndExecuteRunConfig once with all classes Signed-off-by: Tim Herzig <[email protected]> * lint correction Signed-off-by: Tim Herzig <[email protected]> * restrict context menu to only main subbranches Signed-off-by: Tim Herzig <[email protected]> * Update pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/actions/ContextMenuAction.kt Co-authored-by: Lennart Heimbs <[email protected]> * modify rules for which directories can be executed exclude files ending in Test for the pitest run Signed-off-by: Tim Herzig <[email protected]> * lint correction Signed-off-by: Tim Herzig <[email protected]> --------- Signed-off-by: Tim Herzig <[email protected]> Co-authored-by: Lennart Heimbs <[email protected]>
1 parent 8b4501e commit 6feaf4e

File tree

4 files changed

+100
-32
lines changed

4 files changed

+100
-32
lines changed

pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/actions/ContextMenuAction.kt

Lines changed: 93 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// SPDX-License-Identifier: MIT
2-
// SPDX-FileCopyrightText: 2023 Brianne Oberson <[email protected]>
2+
// SPDX-FileCopyrightText: 2023 Brianne Oberson <[email protected]>, Tim Herzig <[email protected]>
33

44
package com.amos.pitmutationmate.pitmutationmate.actions
55

@@ -9,49 +9,102 @@ import com.intellij.openapi.actionSystem.AnActionEvent
99
import com.intellij.openapi.actionSystem.CommonDataKeys
1010
import com.intellij.openapi.components.service
1111
import com.intellij.openapi.diagnostic.Logger
12+
import com.intellij.openapi.project.Project
13+
import com.intellij.openapi.vfs.LocalFileSystem
1214
import com.intellij.psi.PsiClass
1315
import com.intellij.psi.PsiClassOwner
16+
import com.intellij.psi.PsiDirectory
1417
import com.intellij.psi.PsiElement
18+
import com.intellij.psi.PsiFile
19+
import com.intellij.psi.PsiManager
1520
import org.jetbrains.kotlin.psi.KtClass
21+
import java.io.File
1622

1723
class ContextMenuAction : RunConfigurationAction() {
1824
private val logger = Logger.getInstance(ContextMenuAction::class.java)
19-
override fun actionPerformed(e: AnActionEvent) {
20-
val editor = e.getData(CommonDataKeys.EDITOR)
21-
val psiFile = e.getData(CommonDataKeys.PSI_FILE)
22-
if (e.place == "EditorPopup") {
23-
logger.info("ContextMenuAction: actionPerformed in EditorPopup for file $psiFile")
24-
val psiElement = psiFile?.findElementAt(editor?.caretModel!!.offset)
25-
val selectedClass = findEnclosingClass(psiElement)
26-
if (selectedClass != null) {
27-
var classFQN = ""
28-
if (selectedClass is PsiClass) {
29-
classFQN = selectedClass.qualifiedName.toString()
30-
}
31-
if (selectedClass is KtClass) {
32-
classFQN = selectedClass.fqName.toString()
33-
}
3425

35-
logger.info("ContextMenuAction: selected class is $classFQN.")
36-
updateAndExecuteRunConfig(classFQN, e.project!!)
37-
}
38-
}
39-
if (e.place == "ProjectViewPopup") {
26+
private fun updateAndExecuteForFile(psiFileArray: Array<PsiFile>, project: Project) {
27+
var classFQNs: String = ""
28+
for (psiFile in psiFileArray) {
4029
logger.info("ContextMenuAction: actionPerformed in ProjectViewPopup for file $psiFile")
4130
val psiClasses = (psiFile as PsiClassOwner).classes
42-
var classFQNs = ""
4331
for (psiClass in psiClasses) {
4432
val fqn = psiClass.qualifiedName
4533
if (fqn != null) {
46-
classFQNs = if (classFQNs != "") {
47-
"$classFQNs,$fqn"
48-
} else {
49-
fqn
34+
if (!fqn.endsWith("Test")) {
35+
classFQNs = if (classFQNs != "") {
36+
"$classFQNs,$fqn"
37+
} else {
38+
fqn
39+
}
5040
}
5141
}
5242
}
53-
logger.info("ContextMenuAction: selected classes are $classFQNs.")
54-
updateAndExecuteRunConfig(classFQNs, e.project!!)
43+
}
44+
logger.info("ContextMenuAction: selected classes are $classFQNs.")
45+
updateAndExecuteRunConfig(classFQNs, project)
46+
}
47+
48+
private fun getPsiFileFromPath(project: Project, filePath: String): PsiFile? {
49+
return LocalFileSystem.getInstance().findFileByPath(filePath)
50+
?.let { PsiManager.getInstance(project).findFile(it) }
51+
}
52+
53+
private fun actionEditorPopup(e: AnActionEvent) {
54+
val editor = e.getData(CommonDataKeys.EDITOR)
55+
val psiFile = e.getData(CommonDataKeys.PSI_FILE)
56+
57+
logger.info("ContextMenuAction: actionPerformed in EditorPopup for file $psiFile")
58+
val psiElement = psiFile?.findElementAt(editor?.caretModel!!.offset)
59+
val selectedClass = findEnclosingClass(psiElement)
60+
if (selectedClass != null) {
61+
var classFQN = ""
62+
if (selectedClass is PsiClass) {
63+
classFQN = selectedClass.qualifiedName.toString()
64+
}
65+
if (selectedClass is KtClass) {
66+
classFQN = selectedClass.fqName.toString()
67+
}
68+
69+
logger.info("ContextMenuAction: selected class is $classFQN.")
70+
updateAndExecuteRunConfig(classFQN, e.project!!)
71+
}
72+
}
73+
74+
private fun actionProjectViewPopupFile(e: AnActionEvent) {
75+
val psiFile = e.getData(CommonDataKeys.PSI_FILE)
76+
77+
if (psiFile != null) {
78+
updateAndExecuteForFile(arrayOf(psiFile), e.project!!)
79+
}
80+
}
81+
82+
private fun actionProjectViewPopupDir(e: AnActionEvent) {
83+
val psiElement = e.getData(CommonDataKeys.PSI_ELEMENT)
84+
var psiFileArray: Array<PsiFile> = emptyArray()
85+
if (psiElement != null) {
86+
if (psiElement is PsiDirectory) {
87+
val path = psiElement.virtualFile.path.toString()
88+
val directory = File(path)
89+
90+
directory.walk()
91+
.filter { it.isFile && (it.extension == "kt" || it.extension == "java") }
92+
.forEach { getPsiFileFromPath(e.project!!, it.toString())?.let { it1 -> psiFileArray += it1 } }
93+
}
94+
}
95+
96+
updateAndExecuteForFile(psiFileArray, e.project!!)
97+
}
98+
99+
override fun actionPerformed(e: AnActionEvent) {
100+
if (e.place == "EditorPopup") {
101+
actionEditorPopup(e)
102+
} else if (e.place == "ProjectViewPopup") {
103+
if (e.getData(CommonDataKeys.PSI_ELEMENT).toString().startsWith("PsiDirectory")) {
104+
actionProjectViewPopupDir(e)
105+
} else {
106+
actionProjectViewPopupFile(e)
107+
}
55108
}
56109
}
57110

@@ -78,6 +131,18 @@ class ContextMenuAction : RunConfigurationAction() {
78131
val validClass = (findEnclosingClass(psiElement) != null)
79132
return validFile && validClass
80133
}
134+
if (e.place == "ProjectViewPopup" && e.getData(CommonDataKeys.PSI_ELEMENT).toString().startsWith("PsiDirectory")) {
135+
val psiElement = e.getData(CommonDataKeys.PSI_ELEMENT)
136+
if (psiElement is PsiDirectory) {
137+
val directory: File = File(psiElement.virtualFile.path.toString())
138+
var returnValue: Boolean = false
139+
directory.walk()
140+
.filter { it.isFile && (it.extension == "kt" || it.extension == "java") }
141+
.forEach { if (!it.name.contains("Test")) { returnValue = true } }
142+
return returnValue
143+
}
144+
return false
145+
}
81146
return validFile
82147
}
83148

pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/actions/RunConfigurationAction.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ abstract class RunConfigurationAction : AnAction() {
5151
// TODO: replace this by real results extracted by the HTMLParser
5252
val toolWindow: ToolWindow? = ToolWindowManager.getInstance(project).getToolWindow("Pitest")
5353
val coverageReport: XMLParser.CoverageReport = XMLParser.CoverageReport(
54-
"Test",
54+
classFQN.toString(),
5555
"Test",
5656
"Test",
5757
lineCoveragePercentage = 80,

pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/visualization/PiTestReports.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,10 @@ class PiTestClassReport(
119119
fun getCustomHeight(): Int {
120120
return this.height
121121
}
122+
123+
fun getCoverageReport(): XMLParser.CoverageReport {
124+
return this.coverageReport
125+
}
122126
}
123127

124128
class PiTestReports : JPanel() {
@@ -164,7 +168,7 @@ class PiTestReports : JPanel() {
164168
if (i < 5) {
165169
this.reports[i].renderer()
166170
heights += this.reports[i].getCustomHeight()
167-
rows += arrayOf(getLabel("Placeholder Class"), this.reports[i])
171+
rows += arrayOf(getLabel(this.reports[i].getCoverageReport().fileName), this.reports[i])
168172
} else {
169173
this.summary.renderer()
170174
heights += this.summary.getCustomHeight()

pitmutationmate/src/main/resources/META-INF/plugin.xml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,7 @@
7575
<add-to-group group-id="EditorPopupMenu" anchor="first"/>
7676
</action>
7777
<action id="com.amos.pitmutationmate.pitmutationmate.actions.ContextMenuAction"
78-
class="com.amos.pitmutationmate.pitmutationmate.actions.ContextMenuAction"
79-
text="Run MutationMate on This Class"
78+
class="com.amos.pitmutationmate.pitmutationmate.actions.ContextMenuAction" text="Run PIT MutationMate"
8079
description="Initializes a PiTest run on the selected class"
8180
icon="com.amos.pitmutationmate.pitmutationmate.icons.Icons.Logo16">
8281
<add-to-group group-id="EditorPopupMenu" anchor="first"/>

0 commit comments

Comments
 (0)