From bf3697af30a3901113d7ae54b418d450b712f69e Mon Sep 17 00:00:00 2001 From: nikomall34 Date: Sun, 3 Dec 2023 00:43:38 +0100 Subject: [PATCH 1/8] Rewrote the Custom Progress Bar so that it looks like in the Pitest Report Signed-off-by: nikomall34 --- .../visualization/CustomProgressBar.kt | 92 +++++++++++++------ 1 file changed, 63 insertions(+), 29 deletions(-) diff --git a/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/visualization/CustomProgressBar.kt b/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/visualization/CustomProgressBar.kt index 7affe15e..6054d09e 100644 --- a/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/visualization/CustomProgressBar.kt +++ b/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/visualization/CustomProgressBar.kt @@ -5,36 +5,70 @@ package com.amos.pitmutationmate.pitmutationmate.visualization import java.awt.Color +import java.awt.Font +import java.awt.FontMetrics import java.awt.Graphics import javax.swing.JComponent -import javax.swing.JPanel -import javax.swing.JProgressBar -import javax.swing.plaf.basic.BasicProgressBarUI - -internal class CustomProgressBar : JPanel() { - - private val progressBar = JProgressBar(0, 100) - - init { - //UIManager.put("ProgressBar.background", Color.ORANGE); - //UIManager.put("ProgressBar.foreground", Color.BLUE); - progressBar.setStringPainted(true) - //progressBar.setValue(0) - progressBar.setBackground(Color.RED) - progressBar.setForeground(Color.GREEN) - //progressBar.setString("49%") - progressBar.setValue(35) - progressBar.setUI(object : BasicProgressBarUI() { - override fun paint(g: Graphics, c: JComponent) { - c.foreground = Color.GREEN - c.background = Color.RED - g.color = Color.BLACK - super.paint(g, c) - } - }) - this.add(progressBar) - //this.isVisible = true; - - //UIManager.put("nimbusOrange", Color(38, 139, 210)) + +internal class CustomProgressBar(coveragePercentage: Int, ratioText: String) : JComponent() { + private val coveragePercentage = coveragePercentage + private val ratioText = ratioText + private val font = Font("Arial", Font.BOLD, 12) // You can adjust the font as needed + private val barWidth = 150 + private val barHeight = 20 + private val ratioTextStartX = 5 + private val spaceBetweenTextAndBar = 5 + + override fun getWidth(): Int { + return barWidth + getTextWidth(ratioText) + ratioTextStartX + spaceBetweenTextAndBar + } + + override fun getHeight(): Int { + return barHeight + } + override fun paintComponent(g: Graphics) { + super.paintComponent(g) + + val greenWidth = (coveragePercentage * barWidth) / 100 + val redWidth = barWidth - greenWidth + + // add space between ratio Text and the bar + var barStartX = getTextWidth(ratioText) + ratioTextStartX + spaceBetweenTextAndBar + + drawText(g, ratioText, ratioTextStartX) + + // Draw grey border + g.color = Color(170, 170, 170) + g.drawRect(barStartX, 0, barWidth - 1, barHeight - 1) + + // Draw green segment + g.color = Color(221, 255, 221) + g.fillRect(barStartX + 1, 1, greenWidth, barHeight - 2) + + // Draw red segment + g.color = Color(255, 170, 170) + g.fillRect(barStartX + greenWidth + 1, 1, redWidth - 2, barHeight - 2) + + val percentageText = "$coveragePercentage%" + drawText(g, percentageText, barStartX + (barWidth - getTextWidth(percentageText)) / 2) + } + + private fun getTextWidth(text: String): Int { + return getFontMetrics(font).stringWidth(text) + } + + private fun drawText(g: Graphics, text: String, x: Int): Int { + g.font = font + + val fontMetrics: FontMetrics = g.fontMetrics + val textWidth: Int = fontMetrics.stringWidth(text) + val textHeight: Int = fontMetrics.height + + val y = (barHeight - textHeight) / 2 + fontMetrics.ascent + + g.color = Color.BLACK // Set the color for the text + g.drawString(text, x, y) + + return textWidth } } From eaea820a35c89ef1e7f31301ed865cc21048e0e1 Mon Sep 17 00:00:00 2001 From: nikomall34 Date: Sun, 3 Dec 2023 00:45:11 +0100 Subject: [PATCH 2/8] Added a table where one can display the lates Pitest run results Signed-off-by: nikomall34 --- .../visualization/LatestPiTestReport.kt | 103 ++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/visualization/LatestPiTestReport.kt diff --git a/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/visualization/LatestPiTestReport.kt b/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/visualization/LatestPiTestReport.kt new file mode 100644 index 00000000..200c29f8 --- /dev/null +++ b/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/visualization/LatestPiTestReport.kt @@ -0,0 +1,103 @@ +// SPDX-FileCopyrightText: 2023 2023 +// +// SPDX-License-Identifier: MIT + +package com.amos.pitmutationmate.pitmutationmate.visualization + +import com.intellij.ui.components.JBLabel +import com.intellij.ui.components.JBScrollPane +import com.intellij.ui.table.JBTable +import java.awt.* +import javax.swing.JPanel +import javax.swing.JTable +import javax.swing.table.DefaultTableCellRenderer +import javax.swing.table.DefaultTableModel + +class LatestPiTestReport : JPanel() { + + init { + val lineCoverageBar = CustomProgressBar(30, "1/5") + val mutationCoverageBar = CustomProgressBar(50, "3000/30000") + val testStrengthBar = CustomProgressBar(93, "200/2000") + + val title = "Latest Pit Test Coverage Report" + val titleLabel = JBLabel(title) + titleLabel.font = Font("Arial", Font.BOLD, 18) + + val className = "Test.java" + val classNameLabel = JBLabel(className) + classNameLabel.font = Font("Arial", Font.BOLD, 12) + + val data = arrayOf(arrayOf(classNameLabel, lineCoverageBar, mutationCoverageBar, testStrengthBar)) + val columnNames = arrayOf("Class Name", "Line Coverage", "Mutation Coverage", "Test Strength") + val model = DefaultTableModel(data, columnNames) + val table = JBTable(model) + + table.setRowHeight(lineCoverageBar.height + 1) + table.tableHeader.reorderingAllowed = false + table.setShowGrid(false) + table.intercellSpacing = Dimension(0, 0) + table.tableHeader.font = Font("Arial", Font.BOLD, 12) + + for (i in columnNames.indices) { + val progressCol = table.columnModel.getColumn(i) + val curr = data[0][i] + + var newWidth = -1 + if(curr is CustomProgressBar) { + newWidth = curr.width + } else if(curr is JBLabel) { + val tableHeaderFont = table.tableHeader.font + var columnNameWidth = table.tableHeader.getFontMetrics(tableHeaderFont).stringWidth(columnNames[i]) + columnNameWidth += 14 // add some padding + newWidth = getLabelWidthDynamically(classNameLabel) + newWidth = if (newWidth < columnNameWidth) columnNameWidth else newWidth + } + + if(newWidth != -1) { + progressCol.preferredWidth = newWidth + 2 + progressCol.maxWidth = newWidth + 2 + progressCol.minWidth = newWidth + 2 + progressCol.cellRenderer = CustomProgressBarRenderer() + } + } + + // Set up layout with FlowLayout + layout = BorderLayout() + + // Add title label to the North region + add(titleLabel, BorderLayout.NORTH) + + // Create a panel for the table with FlowLayout + val tablePanel = JPanel(FlowLayout(FlowLayout.LEFT)) + tablePanel.add(JBScrollPane(table)) + + // Add the table panel to the Center region + add(tablePanel, BorderLayout.CENTER) + } + + private fun getLabelWidthDynamically(label: JBLabel) : Int { + val fontMetrics = label.getFontMetrics(label.font) + return fontMetrics.stringWidth(label.text) + } + + private class CustomProgressBarRenderer : DefaultTableCellRenderer() { + + override fun getTableCellRendererComponent( + table: JTable?, + value: Any?, + isSelected: Boolean, + hasFocus: Boolean, + row: Int, + column: Int + ): Component { + if (value is CustomProgressBar) { + return value + } else if(value is JBLabel) { + return value + } else { + return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column) + } + } + } +} From c5cbef17a34ec1fddc0cb0e213b413377bcbec77 Mon Sep 17 00:00:00 2001 From: nikomall34 Date: Sun, 3 Dec 2023 00:46:55 +0100 Subject: [PATCH 3/8] Replaced the Progresbar with the LatesPitestRun Table in the ToolWindowFactory and fixed the other files for the pre-commit Signed-off-by: nikomall34 --- .github/workflows/build-and-test.yml | 29 +++++++++---------- .github/workflows/lint.yml | 1 - README.md | 2 +- .../MutationTestToolWindowFactory.kt | 7 +++-- .../reporting/MyMutationResultListener.kt | 1 + .../visualization/HighlightGutterRenderer.kt | 2 +- 6 files changed, 21 insertions(+), 21 deletions(-) diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index b9d4ef3c..faa3d6eb 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -14,20 +14,19 @@ jobs: os: [ubuntu-latest, macos-latest, windows-latest] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v4 - - uses: actions/setup-java@v3 - with: - distribution: temurin - java-version: 11 - - - name: Setup Gradle - uses: gradle/gradle-build-action@v2 + - uses: actions/checkout@v4 + - uses: actions/setup-java@v3 + with: + distribution: temurin + java-version: 11 - - name: Build with Gradle - run: ./gradlew build --no-daemon - working-directory: 'pitmutationmate' - - - name: Run Tests - run: ./gradlew test --no-daemon - working-directory: 'pitmutationmate' + - name: Setup Gradle + uses: gradle/gradle-build-action@v2 + - name: Build with Gradle + run: ./gradlew build --no-daemon + working-directory: "pitmutationmate" + + - name: Run Tests + run: ./gradlew test --no-daemon + working-directory: "pitmutationmate" diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 3d747a45..6a2389ec 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -31,4 +31,3 @@ jobs: VALIDATE_ALL_CODEBASE: false DEFAULT_BRANCH: main GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - diff --git a/README.md b/README.md index a78489e1..0173035b 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,6 @@ Dynamic Test Configuration: A core feature of our plugin will be to enable dynam Result Visualization: The plugin will provide visualizations of Mutation Testing results. This will make it more comfortable for developers to interpret PiTest outputs. -User-Centric Design: The interface and functionality of the plugin will be designed with a strong focus on user experience, ensuring that it is both powerful and easy to use. +User-Centric Design: The interface and functionality of the plugin will be designed with a strong focus on user experience, ensuring that it is both powerful and easy to use. By following these steps, we aim to not only enhance PiTest’s functionality within IntelliJ IDE but also empower developers with more efficient, precise, and user-friendly software testing tools, ultimately leading to higher quality software development. diff --git a/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/MutationTestToolWindowFactory.kt b/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/MutationTestToolWindowFactory.kt index 117289b2..73f442b0 100644 --- a/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/MutationTestToolWindowFactory.kt +++ b/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/MutationTestToolWindowFactory.kt @@ -3,7 +3,7 @@ package com.amos.pitmutationmate.pitmutationmate import com.amos.pitmutationmate.pitmutationmate.visualization.BarGraph -import com.amos.pitmutationmate.pitmutationmate.visualization.CustomProgressBar +import com.amos.pitmutationmate.pitmutationmate.visualization.LatestPiTestReport import com.amos.pitmutationmate.pitmutationmate.visualization.LineGraph import com.amos.pitmutationmate.pitmutationmate.visualization.treetable.JTreeTable import com.intellij.openapi.project.DumbAware @@ -15,12 +15,13 @@ import com.intellij.ui.content.ContentFactory internal class MutationTestToolWindowFactory : ToolWindowFactory, DumbAware { override fun createToolWindowContent(project: Project, toolWindow: ToolWindow) { - val progressBar = ContentFactory.getInstance().createContent(CustomProgressBar(), "Progressbar", false) + + val latestPiTestReport = ContentFactory.getInstance().createContent(LatestPiTestReport(), "Progressbar", false) val table = ContentFactory.getInstance().createContent(JTreeTable(), "Mutationtest Coverage", false) val lineChart = ContentFactory.getInstance().createContent(LineGraph(), "Line Chart", false) val barChart = ContentFactory.getInstance().createContent(BarGraph(), "Bar Chart", false) - toolWindow.contentManager.addContent(progressBar) + toolWindow.contentManager.addContent(latestPiTestReport) toolWindow.contentManager.addContent(table) toolWindow.contentManager.addContent(lineChart) toolWindow.contentManager.addContent(barChart) diff --git a/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/reporting/MyMutationResultListener.kt b/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/reporting/MyMutationResultListener.kt index 5c6e51e0..41545a32 100644 --- a/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/reporting/MyMutationResultListener.kt +++ b/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/reporting/MyMutationResultListener.kt @@ -17,6 +17,7 @@ class MyMutationResultListener : MutationResultListener { } override fun handleMutationResult(results: ClassMutationResults) { + for (result in results.mutations) { val details: MutationDetails = result.details val status: DetectionStatus = result.status diff --git a/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/visualization/HighlightGutterRenderer.kt b/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/visualization/HighlightGutterRenderer.kt index 9a62c8ab..abb6baea 100644 --- a/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/visualization/HighlightGutterRenderer.kt +++ b/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/visualization/HighlightGutterRenderer.kt @@ -80,4 +80,4 @@ class HighlightGutterRenderer(color: String): GutterIconRenderer() { return 16 } } -} \ No newline at end of file +} From 057b8f746ddda802589388ca164d5e59e9329143 Mon Sep 17 00:00:00 2001 From: nikomall34 Date: Mon, 4 Dec 2023 01:15:39 +0100 Subject: [PATCH 4/8] Changed the layout of the table. This kept the implementation simpler so I removed unnecessary code. Adjusted the displayed names Signed-off-by: nikomall34 --- .../MutationTestToolWindowFactory.kt | 2 +- .../visualization/CustomProgressBar.kt | 14 ++-- .../visualization/LatestPiTestReport.kt | 72 +++++++------------ .../src/main/resources/META-INF/plugin.xml | 2 +- 4 files changed, 34 insertions(+), 56 deletions(-) diff --git a/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/MutationTestToolWindowFactory.kt b/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/MutationTestToolWindowFactory.kt index 73f442b0..b0c1cbaf 100644 --- a/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/MutationTestToolWindowFactory.kt +++ b/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/MutationTestToolWindowFactory.kt @@ -16,7 +16,7 @@ import com.intellij.ui.content.ContentFactory internal class MutationTestToolWindowFactory : ToolWindowFactory, DumbAware { override fun createToolWindowContent(project: Project, toolWindow: ToolWindow) { - val latestPiTestReport = ContentFactory.getInstance().createContent(LatestPiTestReport(), "Progressbar", false) + val latestPiTestReport = ContentFactory.getInstance().createContent(LatestPiTestReport(), "Latest Result", false) val table = ContentFactory.getInstance().createContent(JTreeTable(), "Mutationtest Coverage", false) val lineChart = ContentFactory.getInstance().createContent(LineGraph(), "Line Chart", false) val barChart = ContentFactory.getInstance().createContent(BarGraph(), "Bar Chart", false) diff --git a/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/visualization/CustomProgressBar.kt b/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/visualization/CustomProgressBar.kt index 6054d09e..b790bb02 100644 --- a/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/visualization/CustomProgressBar.kt +++ b/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/visualization/CustomProgressBar.kt @@ -16,16 +16,16 @@ internal class CustomProgressBar(coveragePercentage: Int, ratioText: String) : J private val font = Font("Arial", Font.BOLD, 12) // You can adjust the font as needed private val barWidth = 150 private val barHeight = 20 - private val ratioTextStartX = 5 private val spaceBetweenTextAndBar = 5 override fun getWidth(): Int { - return barWidth + getTextWidth(ratioText) + ratioTextStartX + spaceBetweenTextAndBar + return barWidth + getTextWidth(ratioText) + spaceBetweenTextAndBar } override fun getHeight(): Int { return barHeight } + override fun paintComponent(g: Graphics) { super.paintComponent(g) @@ -33,24 +33,24 @@ internal class CustomProgressBar(coveragePercentage: Int, ratioText: String) : J val redWidth = barWidth - greenWidth // add space between ratio Text and the bar - var barStartX = getTextWidth(ratioText) + ratioTextStartX + spaceBetweenTextAndBar + var ratioTextStartX = barWidth + spaceBetweenTextAndBar drawText(g, ratioText, ratioTextStartX) // Draw grey border g.color = Color(170, 170, 170) - g.drawRect(barStartX, 0, barWidth - 1, barHeight - 1) + g.drawRect(0, 0, barWidth - 1, barHeight - 1) // Draw green segment g.color = Color(221, 255, 221) - g.fillRect(barStartX + 1, 1, greenWidth, barHeight - 2) + g.fillRect(1, 1, greenWidth, barHeight - 2) // Draw red segment g.color = Color(255, 170, 170) - g.fillRect(barStartX + greenWidth + 1, 1, redWidth - 2, barHeight - 2) + g.fillRect(greenWidth + 1, 1, redWidth - 2, barHeight - 2) val percentageText = "$coveragePercentage%" - drawText(g, percentageText, barStartX + (barWidth - getTextWidth(percentageText)) / 2) + drawText(g, percentageText, (barWidth - getTextWidth(percentageText)) / 2) } private fun getTextWidth(text: String): Int { diff --git a/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/visualization/LatestPiTestReport.kt b/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/visualization/LatestPiTestReport.kt index 200c29f8..5dd36532 100644 --- a/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/visualization/LatestPiTestReport.kt +++ b/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/visualization/LatestPiTestReport.kt @@ -7,9 +7,14 @@ package com.amos.pitmutationmate.pitmutationmate.visualization import com.intellij.ui.components.JBLabel import com.intellij.ui.components.JBScrollPane import com.intellij.ui.table.JBTable -import java.awt.* +import com.intellij.util.ui.JBUI +import java.awt.BorderLayout +import java.awt.Component +import java.awt.Dimension +import java.awt.Font import javax.swing.JPanel import javax.swing.JTable +import javax.swing.ListSelectionModel import javax.swing.table.DefaultTableCellRenderer import javax.swing.table.DefaultTableModel @@ -20,65 +25,38 @@ class LatestPiTestReport : JPanel() { val mutationCoverageBar = CustomProgressBar(50, "3000/30000") val testStrengthBar = CustomProgressBar(93, "200/2000") - val title = "Latest Pit Test Coverage Report" - val titleLabel = JBLabel(title) - titleLabel.font = Font("Arial", Font.BOLD, 18) + val data = arrayOf(arrayOf(getLabel("Class Name"), getLabel("Test.java")), + arrayOf(getLabel("Line Coverage"), lineCoverageBar), + arrayOf(getLabel("Mutation Coverage"), mutationCoverageBar), + arrayOf(getLabel("Test Strength"), testStrengthBar)) - val className = "Test.java" - val classNameLabel = JBLabel(className) - classNameLabel.font = Font("Arial", Font.BOLD, 12) - - val data = arrayOf(arrayOf(classNameLabel, lineCoverageBar, mutationCoverageBar, testStrengthBar)) - val columnNames = arrayOf("Class Name", "Line Coverage", "Mutation Coverage", "Test Strength") + val columnNames = arrayOf("Pit Test Coverage Report", "") val model = DefaultTableModel(data, columnNames) val table = JBTable(model) - table.setRowHeight(lineCoverageBar.height + 1) + table.setRowHeight(lineCoverageBar.height + 2) table.tableHeader.reorderingAllowed = false + table.tableHeader.resizingAllowed = false + table.tableHeader.font = Font("Arial", Font.BOLD, 16) + + table.border = JBUI.Borders.empty() table.setShowGrid(false) + table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION) + table.columnSelectionAllowed = false table.intercellSpacing = Dimension(0, 0) - table.tableHeader.font = Font("Arial", Font.BOLD, 12) - for (i in columnNames.indices) { - val progressCol = table.columnModel.getColumn(i) - val curr = data[0][i] + table.columnModel.getColumn(0).cellRenderer = CustomProgressBarRenderer() + table.columnModel.getColumn(1).cellRenderer = CustomProgressBarRenderer() - var newWidth = -1 - if(curr is CustomProgressBar) { - newWidth = curr.width - } else if(curr is JBLabel) { - val tableHeaderFont = table.tableHeader.font - var columnNameWidth = table.tableHeader.getFontMetrics(tableHeaderFont).stringWidth(columnNames[i]) - columnNameWidth += 14 // add some padding - newWidth = getLabelWidthDynamically(classNameLabel) - newWidth = if (newWidth < columnNameWidth) columnNameWidth else newWidth - } - - if(newWidth != -1) { - progressCol.preferredWidth = newWidth + 2 - progressCol.maxWidth = newWidth + 2 - progressCol.minWidth = newWidth + 2 - progressCol.cellRenderer = CustomProgressBarRenderer() - } - } - - // Set up layout with FlowLayout layout = BorderLayout() - // Add title label to the North region - add(titleLabel, BorderLayout.NORTH) - - // Create a panel for the table with FlowLayout - val tablePanel = JPanel(FlowLayout(FlowLayout.LEFT)) - tablePanel.add(JBScrollPane(table)) - - // Add the table panel to the Center region - add(tablePanel, BorderLayout.CENTER) + add(JBScrollPane(table)) } - private fun getLabelWidthDynamically(label: JBLabel) : Int { - val fontMetrics = label.getFontMetrics(label.font) - return fontMetrics.stringWidth(label.text) + private fun getLabel(text: String) : JBLabel { + val label = JBLabel(text) + label.font = Font("Arial", Font.BOLD, 12) + return label } private class CustomProgressBarRenderer : DefaultTableCellRenderer() { diff --git a/pitmutationmate/src/main/resources/META-INF/plugin.xml b/pitmutationmate/src/main/resources/META-INF/plugin.xml index 4157a58e..ba2b92fd 100644 --- a/pitmutationmate/src/main/resources/META-INF/plugin.xml +++ b/pitmutationmate/src/main/resources/META-INF/plugin.xml @@ -31,7 +31,7 @@ Read more: https://plugins.jetbrains.com/docs/intellij/plugin-extension-points.html --> - Date: Mon, 4 Dec 2023 01:36:47 +0100 Subject: [PATCH 5/8] fixed linting Signed-off-by: nikomall34 --- pitmutationmate/build.gradle.kts | 78 +++++++++---------- .../MutationTestToolWindowFactory.kt | 3 - .../reporting/MyMutationResultListener.kt | 1 - .../visualization/HighlightGutterRenderer.kt | 8 +- .../visualization/LatestPiTestReport.kt | 12 +-- 5 files changed, 49 insertions(+), 53 deletions(-) diff --git a/pitmutationmate/build.gradle.kts b/pitmutationmate/build.gradle.kts index 704d3cfa..0ad6a1c6 100644 --- a/pitmutationmate/build.gradle.kts +++ b/pitmutationmate/build.gradle.kts @@ -2,67 +2,67 @@ // SPDX-FileCopyrightText: 2023 plugins { - id("java") - id("org.jetbrains.kotlin.jvm") version "1.9.0" - id("org.jetbrains.intellij") version "1.15.0" - id("info.solidsoft.pitest") version "1.15.0" + id("java") + id("org.jetbrains.kotlin.jvm") version "1.9.0" + id("org.jetbrains.intellij") version "1.15.0" + id("info.solidsoft.pitest") version "1.15.0" } tasks.test { - useJUnitPlatform() + useJUnitPlatform() } dependencies { - implementation("org.pitest:pitest-command-line:1.7.0") - implementation("org.junit.jupiter:junit-jupiter:5.8.1") - implementation("org.junit.jupiter:junit-jupiter:5.8.1") - testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.1") - testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.1") - // https://mvnrepository.com/artifact/org.jfree/jfreechart - implementation("org.jfree:jfreechart:1.0.19") - // https://mvnrepository.com/artifact/jfree/jcommon - implementation("org.jfree:jcommon:1.0.24") - implementation("org.jetbrains.kotlin:kotlin-stdlib:1.9.0") + implementation("org.pitest:pitest-command-line:1.7.0") + implementation("org.junit.jupiter:junit-jupiter:5.8.1") + implementation("org.junit.jupiter:junit-jupiter:5.8.1") + testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.1") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.1") + // https://mvnrepository.com/artifact/org.jfree/jfreechart + implementation("org.jfree:jfreechart:1.0.19") + // https://mvnrepository.com/artifact/jfree/jcommon + implementation("org.jfree:jcommon:1.0.24") + implementation("org.jetbrains.kotlin:kotlin-stdlib:1.9.0") } group = "com.amos.pitmutationmate" version = "1.0-SNAPSHOT" repositories { - mavenCentral() + mavenCentral() } // Configure Gradle IntelliJ Plugin // Read more: https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html intellij { - version.set("2022.2.5") - type.set("IC") // Target IDE Platform + version.set("2022.2.5") + type.set("IC") // Target IDE Platform - plugins.set(listOf("org.jetbrains.kotlin", "com.intellij.java")) + plugins.set(listOf("org.jetbrains.kotlin", "com.intellij.java")) } tasks { - // Set the JVM compatibility versions - withType { - sourceCompatibility = "17" - targetCompatibility = "17" - } - withType { - kotlinOptions.jvmTarget = "17" - } + // Set the JVM compatibility versions + withType { + sourceCompatibility = "17" + targetCompatibility = "17" + } + withType { + kotlinOptions.jvmTarget = "17" + } - patchPluginXml { - sinceBuild.set("222") - untilBuild.set("232.*") - } + patchPluginXml { + sinceBuild.set("222") + untilBuild.set("232.*") + } - signPlugin { - certificateChain.set(System.getenv("CERTIFICATE_CHAIN")) - privateKey.set(System.getenv("PRIVATE_KEY")) - password.set(System.getenv("PRIVATE_KEY_PASSWORD")) - } + signPlugin { + certificateChain.set(System.getenv("CERTIFICATE_CHAIN")) + privateKey.set(System.getenv("PRIVATE_KEY")) + password.set(System.getenv("PRIVATE_KEY_PASSWORD")) + } - publishPlugin { - token.set(System.getenv("PUBLISH_TOKEN")) - } + publishPlugin { + token.set(System.getenv("PUBLISH_TOKEN")) + } } diff --git a/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/MutationTestToolWindowFactory.kt b/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/MutationTestToolWindowFactory.kt index b0c1cbaf..85de683a 100644 --- a/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/MutationTestToolWindowFactory.kt +++ b/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/MutationTestToolWindowFactory.kt @@ -12,10 +12,8 @@ import com.intellij.openapi.wm.ToolWindow import com.intellij.openapi.wm.ToolWindowFactory import com.intellij.ui.content.ContentFactory - internal class MutationTestToolWindowFactory : ToolWindowFactory, DumbAware { override fun createToolWindowContent(project: Project, toolWindow: ToolWindow) { - val latestPiTestReport = ContentFactory.getInstance().createContent(LatestPiTestReport(), "Latest Result", false) val table = ContentFactory.getInstance().createContent(JTreeTable(), "Mutationtest Coverage", false) val lineChart = ContentFactory.getInstance().createContent(LineGraph(), "Line Chart", false) @@ -25,6 +23,5 @@ internal class MutationTestToolWindowFactory : ToolWindowFactory, DumbAware { toolWindow.contentManager.addContent(table) toolWindow.contentManager.addContent(lineChart) toolWindow.contentManager.addContent(barChart) - } } diff --git a/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/reporting/MyMutationResultListener.kt b/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/reporting/MyMutationResultListener.kt index 41545a32..5c6e51e0 100644 --- a/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/reporting/MyMutationResultListener.kt +++ b/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/reporting/MyMutationResultListener.kt @@ -17,7 +17,6 @@ class MyMutationResultListener : MutationResultListener { } override fun handleMutationResult(results: ClassMutationResults) { - for (result in results.mutations) { val details: MutationDetails = result.details val status: DetectionStatus = result.status diff --git a/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/visualization/HighlightGutterRenderer.kt b/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/visualization/HighlightGutterRenderer.kt index abb6baea..25846f43 100644 --- a/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/visualization/HighlightGutterRenderer.kt +++ b/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/visualization/HighlightGutterRenderer.kt @@ -8,8 +8,7 @@ import java.awt.Component import java.awt.Graphics import javax.swing.Icon - -class HighlightGutterRenderer(color: String): GutterIconRenderer() { +class HighlightGutterRenderer(color: String) : GutterIconRenderer() { private val toolTip = "PITest run" val toolTipProvider: (PsiElement) -> String = { _ -> toolTip } val color: String = color @@ -24,9 +23,9 @@ class HighlightGutterRenderer(color: String): GutterIconRenderer() { override fun getIcon(): Icon { return if (this.color == "red") { RedBarIcon() - }else if (this.color == "green") { + } else if (this.color == "green") { GreenBarIcon() - }else { + } else { YellowBarIcon() } } @@ -35,7 +34,6 @@ class HighlightGutterRenderer(color: String): GutterIconRenderer() { return Alignment.LEFT } - private class RedBarIcon : Icon { override fun paintIcon(c: Component?, g: Graphics, x: Int, y: Int) { g.setColor(Color.RED) diff --git a/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/visualization/LatestPiTestReport.kt b/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/visualization/LatestPiTestReport.kt index 5dd36532..75f148ce 100644 --- a/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/visualization/LatestPiTestReport.kt +++ b/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/visualization/LatestPiTestReport.kt @@ -25,10 +25,12 @@ class LatestPiTestReport : JPanel() { val mutationCoverageBar = CustomProgressBar(50, "3000/30000") val testStrengthBar = CustomProgressBar(93, "200/2000") - val data = arrayOf(arrayOf(getLabel("Class Name"), getLabel("Test.java")), - arrayOf(getLabel("Line Coverage"), lineCoverageBar), - arrayOf(getLabel("Mutation Coverage"), mutationCoverageBar), - arrayOf(getLabel("Test Strength"), testStrengthBar)) + val data = arrayOf( + arrayOf(getLabel("Class Name"), getLabel("Test.java")), + arrayOf(getLabel("Line Coverage"), lineCoverageBar), + arrayOf(getLabel("Mutation Coverage"), mutationCoverageBar), + arrayOf(getLabel("Test Strength"), testStrengthBar) + ) val columnNames = arrayOf("Pit Test Coverage Report", "") val model = DefaultTableModel(data, columnNames) @@ -71,7 +73,7 @@ class LatestPiTestReport : JPanel() { ): Component { if (value is CustomProgressBar) { return value - } else if(value is JBLabel) { + } else if (value is JBLabel) { return value } else { return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column) From 657baf3073bed565f6367a4029bbb3c0e5a78ff9 Mon Sep 17 00:00:00 2001 From: nikomall34 Date: Mon, 4 Dec 2023 01:45:32 +0100 Subject: [PATCH 6/8] Fixed linting Signed-off-by: nikomall34 --- README.md | 2 +- .../pitmutationmate/visualization/LatestPiTestReport.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0173035b..71dcec77 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ SPDX-FileCopyrightText: 2023 ## About the Project [PIT (Pitest)](https://pitest.org/) is a popular mutation testing framework for Java / JVM-based languages. -This project is to develop a plugin for the [IntelliJ](https://www.jetbrains.com/idea/) / [Android Studio (Jetbrains)](https://developer.android.com/studio) IDE so that mutation tests can be conveniently run from within the IDE, similar to the JUnit plugins available for most IDEs. +This project is to develop a plugin for the [IntelliJ](https://www.jetbrains.com/idea/) / [Android Studio (JetBrains)](https://developer.android.com/studio) IDE so that mutation tests can be conveniently run from within the IDE, similar to the JUnit plugins available for most IDEs. Users of the IDE shall be able to - Start a Pitest run for a class directly in the code editor diff --git a/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/visualization/LatestPiTestReport.kt b/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/visualization/LatestPiTestReport.kt index 75f148ce..193f1b29 100644 --- a/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/visualization/LatestPiTestReport.kt +++ b/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/visualization/LatestPiTestReport.kt @@ -55,7 +55,7 @@ class LatestPiTestReport : JPanel() { add(JBScrollPane(table)) } - private fun getLabel(text: String) : JBLabel { + private fun getLabel(text: String): JBLabel { val label = JBLabel(text) label.font = Font("Arial", Font.BOLD, 12) return label From 736f3251b8ff6abcbb5b27cfdac288524e18004f Mon Sep 17 00:00:00 2001 From: nikomall34 Date: Mon, 4 Dec 2023 02:54:31 +0100 Subject: [PATCH 7/8] Width of the first column is fixed now Signed-off-by: nikomall34 --- .../pitmutationmate/visualization/LatestPiTestReport.kt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/visualization/LatestPiTestReport.kt b/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/visualization/LatestPiTestReport.kt index 193f1b29..8fae9256 100644 --- a/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/visualization/LatestPiTestReport.kt +++ b/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/visualization/LatestPiTestReport.kt @@ -48,6 +48,13 @@ class LatestPiTestReport : JPanel() { table.intercellSpacing = Dimension(0, 0) table.columnModel.getColumn(0).cellRenderer = CustomProgressBarRenderer() + + val firstColumnWidth = table.tableHeader.getFontMetrics(table.tableHeader.font).stringWidth(" Pit Test Coverage Report ") + 5 + table.columnModel.getColumn(0).maxWidth = firstColumnWidth + table.columnModel.getColumn(0).minWidth = firstColumnWidth + table.columnModel.getColumn(0).preferredWidth = firstColumnWidth + table.columnModel.getColumn(0).width = firstColumnWidth + table.columnModel.getColumn(1).cellRenderer = CustomProgressBarRenderer() layout = BorderLayout() From b17e9f71341d7cd2c73392bee8c782a3f36d0130 Mon Sep 17 00:00:00 2001 From: nikomall34 Date: Mon, 4 Dec 2023 17:01:00 +0100 Subject: [PATCH 8/8] Made the cells not editable in the table Signed-off-by: nikomall34 --- .../pitmutationmate/visualization/LatestPiTestReport.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/visualization/LatestPiTestReport.kt b/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/visualization/LatestPiTestReport.kt index 8fae9256..7fe98f1d 100644 --- a/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/visualization/LatestPiTestReport.kt +++ b/pitmutationmate/src/main/kotlin/com/amos/pitmutationmate/pitmutationmate/visualization/LatestPiTestReport.kt @@ -33,7 +33,13 @@ class LatestPiTestReport : JPanel() { ) val columnNames = arrayOf("Pit Test Coverage Report", "") - val model = DefaultTableModel(data, columnNames) + + val model = object : DefaultTableModel(data, columnNames) { + override fun isCellEditable(row: Int, column: Int): Boolean { + return false + } + } + val table = JBTable(model) table.setRowHeight(lineCoverageBar.height + 2)