summaryrefslogtreecommitdiff
path: root/contrib/bsp/src/mill/contrib/bsp/BspTestReporter.scala
blob: 694716752287796d8b446b7e0207f6491ea55943 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package mill.contrib.bsp

import ch.epfl.scala.bsp4j._
import mill.api.{BspContext, TestReporter}
import sbt.testing._


class BspTestReporter(
                       client: BuildClient,
                       targetId: BuildTargetIdentifier,
                       taskId: TaskId,
                       arguments: Seq[String]) extends BspContext {

  var passed = 0
  var failed = 0
  var cancelled = 0
  var ignored = 0
  var skipped = 0
  var totalTime: Long = 0

  override def args: Seq[String] = arguments

  override def logStart(event: Event): Unit = {
    val taskStartParams = new TaskStartParams(taskId)
    taskStartParams.setEventTime(System.currentTimeMillis())
    taskStartParams.setDataKind("test-started")
    taskStartParams.setData(new TestStart(getDisplayName(event)))
    taskStartParams.setMessage("Starting running: " + getDisplayName(event))
    client.onBuildTaskStart(taskStartParams)
  }

  override def logFinish(event: Event): Unit = {
    totalTime += event.duration()
    val taskFinishParams = new TaskFinishParams(taskId,
      event.status()  match {
        case sbt.testing.Status.Canceled => StatusCode.CANCELLED
        case sbt.testing.Status.Error => StatusCode.ERROR
        case default => StatusCode.OK
      })
    taskFinishParams.setDataKind("test-finished")
    val status = event.status match {
      case sbt.testing.Status.Success =>
        passed += 1
        TestStatus.PASSED
      case sbt.testing.Status.Canceled =>
        cancelled += 1
        TestStatus.CANCELLED
      case sbt.testing.Status.Error =>
        failed += 1
        TestStatus.FAILED
      case sbt.testing.Status.Failure =>
        failed += 1
        TestStatus.FAILED
      case sbt.testing.Status.Ignored =>
        ignored += 1
        TestStatus.IGNORED
      case sbt.testing.Status.Skipped =>
        skipped += 1
        TestStatus.SKIPPED
      case sbt.testing.Status.Pending =>
        skipped += 1
        TestStatus.SKIPPED //TODO: what to do here
    }
    val testFinish = new TestFinish(getDisplayName(event), status)
    taskFinishParams.setData(testFinish)
    taskFinishParams.setEventTime(System.currentTimeMillis())
    taskFinishParams.setMessage("Finished running: " + getDisplayName(event))

    if (event.throwable.isDefined) {
      val exception = event.throwable.get
      taskFinishParams.setData( // send data about any potential exceptions thrown during testing
        TestException(exception.getStackTrace.toString,
          exception.getMessage,
          exception.getClass.toString))
    }
    client.onBuildTaskFinish(taskFinishParams)
  }

  def getDisplayName(e: Event): String = {
    e.selector() match{
      case s: NestedSuiteSelector => s.suiteId()
      case s: NestedTestSelector => s.suiteId() + "." + s.testName()
      case s: SuiteSelector => s.toString
      case s: TestSelector => s.testName()
      case s: TestWildcardSelector => s.testWildcard()
    }
  }

  def getTestReport: TestReport = {
    val report = new TestReport(targetId, passed, failed, ignored, cancelled, skipped)
    report.setTime(totalTime)
    report
  }

}

case class TestException(stackTrace: String, message: String, exClass: String)