Skip to content

Commit

Permalink
Merge pull request #64 from JetBrains-Research/test-execution-error-v…
Browse files Browse the repository at this point in the history
…isualization

Test execution error visualization
  • Loading branch information
arksap2002 authored Sep 11, 2023
2 parents 2d33a8a + 1473083 commit 91b18a3
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ class TestCaseDisplayService(private val project: Project) {

// Set border
languageTextField.border = getBorder(testCase.testName)
testCasePanel.toolTipText = project.service<TestsExecutionResultService>().getError(testCase.testName)

addListeners(
resetButton,
Expand All @@ -260,6 +261,7 @@ class TestCaseDisplayService(private val project: Project) {
checkbox,
testCase,
languageTextField.border,
testCasePanel,
)

val bottomPanel = JPanel()
Expand Down Expand Up @@ -638,7 +640,7 @@ class TestCaseDisplayService(private val project: Project) {
*/
private fun updateTestsPassedLabel() {
testsPassedLabel.text =
String.format(testsPassedText, project.service<TestsExecutionResultService>().size(), testCasePanels.size)
String.format(testsPassedText, testCasePanels.size - project.service<TestsExecutionResultService>().size(), testCasePanels.size)
}

/**
Expand Down Expand Up @@ -750,7 +752,7 @@ class TestCaseDisplayService(private val project: Project) {
updateTestsSelectedLabel()

// Passed tests update
project.service<TestsExecutionResultService>().removeFromPassingTest(test.testName)
project.service<TestsExecutionResultService>().removeFromFailingTest(test.testName)
updateTestsPassedLabel()

// If no more tests are remaining, close the tool window
Expand Down Expand Up @@ -863,6 +865,7 @@ class TestCaseDisplayService(private val project: Project) {
checkbox: JCheckBox,
testCase: TestCase,
initialBorder: Border,
testCasePanel: JPanel,
) {
languageTextField.document.addDocumentListener(object : DocumentListener {
override fun documentChanged(event: DocumentEvent) {
Expand All @@ -882,6 +885,8 @@ class TestCaseDisplayService(private val project: Project) {
else -> JBUI.Borders.empty()
}

testCasePanel.toolTipText = project.service<TestsExecutionResultService>().getError(testCase.testName)

val modifiedLineIndexes = getModifiedLines(
lastRunCode.split("\n"),
languageTextField.document.text.split("\n"),
Expand All @@ -905,14 +910,15 @@ class TestCaseDisplayService(private val project: Project) {
languageTextField.document.setText(testCase.testCode)
project.service<Workspace>().updateTestCase(testCase)
resetButton.isEnabled = false
resetToLastRunButton.isEnabled = false
runTestButton.isEnabled = false
if ((initialBorder as MatteBorder).matteColor == JBColor.GREEN) {
project.service<TestsExecutionResultService>().addPassingTest(testCase.testName)
project.service<TestsExecutionResultService>().removeFromFailingTest(testCase.testName)
} else {
project.service<TestsExecutionResultService>().removeFromPassingTest(testCase.testName)
project.service<TestsExecutionResultService>().addFailedTest(testCase.testName, testCasePanel.toolTipText)
}
resetToLastRunButton.isEnabled = false
runTestButton.isEnabled = false
languageTextField.border = initialBorder
testCasePanel.toolTipText = project.service<TestsExecutionResultService>().getError(testCase.testName)
languageTextField.editor!!.markupModel.removeAllHighlighters()

updateTestsPassedLabel()
Expand All @@ -925,7 +931,10 @@ class TestCaseDisplayService(private val project: Project) {
resetToLastRunButton.isEnabled = false
runTestButton.isEnabled = false
languageTextField.border = getBorder(testCase.testName)
testCasePanel.toolTipText = project.service<TestsExecutionResultService>().getError(testCase.testName)
languageTextField.editor!!.markupModel.removeAllHighlighters()

updateTestsPassedLabel()
}
}

Expand All @@ -934,10 +943,10 @@ class TestCaseDisplayService(private val project: Project) {
project.service<TestCoverageCollectorService>()
.updateDataWithTestCase(languageTextField.document.text, testCase.testName),
)

resetToLastRunButton.isEnabled = false
runTestButton.isEnabled = false
languageTextField.border = getBorder(testCase.testName)
testCasePanel.toolTipText = project.service<TestsExecutionResultService>().getError(testCase.testName)
languageTextField.editor!!.markupModel.removeAllHighlighters()

updateTestsPassedLabel()
Expand Down Expand Up @@ -1027,10 +1036,10 @@ class TestCaseDisplayService(private val project: Project) {
*/
private fun getBorder(testCaseName: String): Border {
val size = 3
return if (project.service<TestsExecutionResultService>().isTestCasePassing(testCaseName)) {
MatteBorder(size, size, size, size, JBColor.GREEN)
} else {
return if (project.service<TestsExecutionResultService>().isTestCaseFailing(testCaseName)) {
MatteBorder(size, size, size, size, JBColor.RED)
} else {
MatteBorder(size, size, size, size, JBColor.GREEN)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,11 +158,11 @@ class TestCoverageCollectorService(private val project: Project) {

log.info("Test execution error message: $testExecutionError")

// add passing test
if (!getExceptionData(testExecutionError).first) {
project.service<TestsExecutionResultService>().addPassingTest(testCaseName)
// add failing test
if (getExceptionData(testExecutionError).first) {
project.service<TestsExecutionResultService>().addFailedTest(testCaseName, testExecutionError)
} else {
project.service<TestsExecutionResultService>().removeFromPassingTest(testCaseName)
project.service<TestsExecutionResultService>().removeFromFailingTest(testCaseName)
}

// Prepare the command for generating the Jacoco report
Expand Down Expand Up @@ -299,8 +299,9 @@ class TestCoverageCollectorService(private val project: Project) {
)

// compilation checking
if (!project.service<TestCoverageCollectorService>().compileCode(generatedTestPath, buildPath).first) {
project.service<TestsExecutionResultService>().removeFromPassingTest(testName)
val compilationResult = project.service<TestCoverageCollectorService>().compileCode(generatedTestPath, buildPath)
if (!compilationResult.first) {
project.service<TestsExecutionResultService>().addFailedTest(testName, compilationResult.second)
} else {
val dataFileName = "${project.service<Workspace>().resultPath!!}/jacoco-${fileName.split(".")[0]}"

Expand All @@ -313,7 +314,7 @@ class TestCoverageCollectorService(private val project: Project) {
)

if (!File("$dataFileName.xml").exists()) {
project.service<TestsExecutionResultService>().removeFromPassingTest(testName)
project.service<TestsExecutionResultService>().addFailedTest(testName, testExecutionError)
} else {
val testCase = project.service<TestCoverageCollectorService>().getTestCaseFromXml(
testName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,39 +3,53 @@ package org.jetbrains.research.testspark.services
import com.intellij.openapi.project.Project

class TestsExecutionResultService(private val project: Project) {
private val passingTests: MutableSet<String> = mutableSetOf()
// test case name --> test error
private val testErrors: MutableMap<String, String> = mutableMapOf()

/**
* Adds a passing test to the collection.
* Adds a failed test to the collection.
*
* @param testName the name of the passing test to add
* @param testError the error
*/
fun addPassingTest(testName: String) { passingTests.add(testName) }
fun addFailedTest(testName: String, testError: String) {
testErrors[testName] = "<html>${testError.replace("===", "").replace("\t", "<br/>").trimEnd()}</html>"
}

/**
* Checks if a test case with the given name is passing.
* Checks if a test case with the given name is failing.
*
* @param testName The name of the test case to check.
* @return Returns true if the test case is passing, false otherwise.
*/
fun isTestCasePassing(testName: String): Boolean = passingTests.contains(testName)
fun isTestCaseFailing(testName: String): Boolean = testErrors.contains(testName)

/**
* Removes the specified test from the failing tests list.
*
* @param testName The name of the test to be removed.
*/
fun removeFromFailingTest(testName: String) {
if (testErrors.contains(testName)) testErrors.remove(testName)
}

/**
* Removes the specified test from the passing tests list.
* Gets error message.
*
* @param testName The name of the test to be removed.
*/
fun removeFromPassingTest(testName: String) {
if (passingTests.contains(testName)) passingTests.remove(testName)
fun getError(testName: String): String {
if (testErrors.contains(testName)) return testErrors[testName]!!
return ""
}

/**
* Number of passing tests
* Number of failing tests
*/
fun size() = passingTests.size
fun size() = testErrors.size

/**
* Clear passing tests
* Clear failing tests
*/
fun clear() = passingTests.clear()
fun clear() = testErrors.clear()
}

0 comments on commit 91b18a3

Please sign in to comment.