summaryrefslogtreecommitdiff
path: root/examples/scala-js/jasmine-test-framework/src/main/scala/org/scalajs/jasminetest/JasmineTestReporter.scala
blob: 79a7c75443fb76158ee6e02d495c8a9a6f2b8a9a (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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*                     __                                               *\
**     ________ ___   / /  ___      __ ____  Scala.js Test Framework    **
**    / __/ __// _ | / /  / _ | __ / // __/  (c) 2013, LAMP/EPFL        **
**  __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \    http://scala-js.org/       **
** /____/\___/_/ |_/____/_/ | |__/ /____/                               **
**                          |/____/                                     **
\*                                                                      */


package org.scalajs.jasminetest

import scala.scalajs.js
import scala.scalajs.js.annotation.JSExport

import scala.scalajs.runtime.StackTrace

import scala.scalajs.testbridge._

import org.scalajs.jasmine.ExpectationResult
import org.scalajs.jasmine.Result
import org.scalajs.jasmine.Spec
import org.scalajs.jasmine.Suite

/** This class is passed to the actual jasmine framework as a reporter */
class JasmineTestReporter(testOutput: TestOutput) {
  private var currentSuite: Suite = _

  @JSExport
  def reportRunnerStarting(): Unit = {
    testOutput.log.info("")
  }

  @JSExport
  def reportSpecStarting(spec: Spec): Unit = {
    if (currentSuite != spec.suite) {
      currentSuite = spec.suite
      info(currentSuite.description)
    }
  }

  @JSExport
  def reportSpecResults(spec: Spec): Unit = {
    val results = spec.results()
    val description = spec.description

    if (results.passed) {
      testOutput.succeeded(s"  $success $description")
    } else {
      error(s" $failure $description")

      results.getItems foreach displayResult
    }
  }

  @JSExport
  def reportSuiteResults(suite: Suite): Unit = {
    var results = suite.results()

    info("")
    val title = "Total for suite " + suite.description
    val message =
      s"${results.totalCount} specs, ${results.failedCount} failure"

    if (results.passedCount != results.totalCount) {
      error(title)
      errorWithInfoColor(message)
    } else {
      info(title)
      infoWithInfoColor(message)
    }
    info("")
  }

  @JSExport
  def reportRunnerResults(): Unit = {
    // no need to report
  }

  private def info(str: String) =
    testOutput.log.info(str)

  private def infoWithInfoColor(str: String) =
    info(withColor(testOutput.infoColor, str))

  private def errorWithInfoColor(str: String) =
    error(withColor(testOutput.infoColor, str))

  private def error(msg: js.Any) =
    testOutput.log.error(msg.toString)

  private def withColor(color: testOutput.Color, message: String) =
    testOutput.color(message, color)

  private def sanitizeMessage(message: String) = {
    val FilePattern = """^(.+?) [^ ]+\.js \(line \d+\)\.*?$""".r
    val EvalPattern = """^(.+?) in eval.+\(eval\).+?\(line \d+\).*?$""".r

    message match {
      case FilePattern(originalMessage) => originalMessage
      case EvalPattern(originalMessage) => originalMessage
      case message => message
    }
  }

  private def failure = withColor(testOutput.errorColor, "x")
  private def success = withColor(testOutput.successColor, "+")

  private def displayResult(result: Result) = {
    (result.`type`: String) match {
      case "log" =>
        info(s"    ${result.toString}")
      case "expect" =>
        val r = result.asInstanceOf[ExpectationResult]

        if (!r.passed()) {
          val message = sanitizeMessage(r.message)
          val stack = StackTrace.extract(r.trace).takeWhile { stackElem =>
            (stackElem.getFileName == null ||
                !stackElem.getFileName.endsWith("jasmine.js"))
          }

          if (stack.isEmpty)
            testOutput.failure(s"    $message")
          else
            testOutput.error(s"    $message", stack)
        }
    }
  }

}