rhyskeepence / clairvoyance

@@ -19,14 +19,16 @@
Loading
19 19
  private def tableOfContentsFor(suiteResult: SuiteResult): String = {
20 20
    s"""
21 21
    <ul class="contents">
22 -
    ${suiteResult.eventList
23 -
      .map {
24 -
        case event: TestSucceeded         => renderFragmentForTableOfContents(event)
25 -
        case TestFailedOrCancelled(event) => renderFragmentForTableOfContents(event)
26 -
        case TestPendingOrIgnored(event)  => renderFragmentForTableOfContents(event)
27 -
        case _                            => ""
28 -
      }
29 -
      .mkString("\n")}
22 +
    ${
23 +
      suiteResult.eventList
24 +
        .map {
25 +
          case event: TestSucceeded => renderFragmentForTableOfContents(event)
26 +
          case TestFailedOrCancelled(event) => renderFragmentForTableOfContents(event)
27 +
          case TestPendingOrIgnored(event) => renderFragmentForTableOfContents(event)
28 +
          case _ => ""
29 +
        }
30 +
        .mkString("\n")
31 +
    }
30 32
    </ul>
31 33
    """
32 34
  }
@@ -59,12 +61,12 @@
Loading
59 61
    )
60 62
61 63
  private def renderFragmentForTableOfContents(
62 -
      testName: String,
63 -
      testText: String,
64 -
      recordedEvents: IndexedSeq[RecordableEvent],
65 -
      listCssClass: String,
66 -
      cssClass: String
67 -
  ): String =
64 +
                                                testName: String,
65 +
                                                testText: String,
66 +
                                                recordedEvents: IndexedSeq[RecordableEvent],
67 +
                                                listCssClass: String,
68 +
                                                cssClass: String
69 +
                                              ): String =
68 70
    s"""<li class="$listCssClass">
69 71
      <a href="#${linkNameOf(testText)}">
70 72
        ${formatShortExampleName(testName)}
@@ -77,22 +79,24 @@
Loading
77 79
      <div id="container">
78 80
        <h1> ${wordify(specificationTitle)} </h1>
79 81
        ${tableOfContentsFor(suiteResult)}
80 -
        ${suiteResult.eventList
81 -
      .map {
82 -
        case event: TestSucceeded         => renderFragmentForBody(event)
83 -
        case TestFailedOrCancelled(event) => renderFragmentForBody(event)
84 -
        case TestPendingOrIgnored(event)  => renderFragmentForBody(event)
85 -
        // AlertProvided, InfoProvided, and NoteProvided must not show up in the HTML report
86 -
        case _ => ""
87 -
      }
88 -
      .mkString("\n")}
82 +
        ${
83 +
      suiteResult.eventList
84 +
        .map {
85 +
          case event: TestSucceeded => renderFragmentForBody(event)
86 +
          case TestFailedOrCancelled(event) => renderFragmentForBody(event)
87 +
          case TestPendingOrIgnored(event) => renderFragmentForBody(event)
88 +
          // AlertProvided, InfoProvided, and NoteProvided must not show up in the HTML report
89 +
          case _ => ""
90 +
        }
91 +
        .mkString("\n")
92 +
    }
89 93
      </div>
90 94
    </body>
91 95
    """
92 96
93 97
  private def renderFragmentForBody(event: TestSucceeded): String = {
94 -
    val (suiteClassName, testName, testText, duration) =
95 -
      (event.suiteClassName.get, event.testName, event.testText, event.duration)
98 +
    val (suiteClassName, testName, testText) =
99 +
      (event.suiteClassName.get, event.testName, event.testText)
96 100
    val annotations = annotationsFor(event.suiteName, event.testName)
97 101
98 102
    val testState = TestStates.dequeue(testName)
@@ -103,10 +107,6 @@
Loading
103 107
    <div class="testmethod test-passed">
104 108
      <div class="scenario" id="${testName.hashCode().toString}">
105 109
        ${renderSpecification(testName, annotations, suiteClassName, event)}
106 -
        <h2>Execution</h2>
107 -
        <pre class="highlight results highlighted">${duration.fold("")(
108 -
      milliseconds => s"Passed in $milliseconds ms"
109 -
    )}</pre>
110 110
        ${interestingGivensTable(testState, rendering)}
111 111
        ${capturedInputsAndOutputs(testState, rendering, annotations)}
112 112
      </div>
@@ -115,11 +115,11 @@
Loading
115 115
  }
116 116
117 117
  private def renderSpecification(
118 -
      testName: String,
119 -
      annotations: Set[Tag],
120 -
      suiteClassName: String,
121 -
      event: TestSucceeded
122 -
  ) = {
118 +
                                   testName: String,
119 +
                                   annotations: Set[Tag],
120 +
                                   suiteClassName: String,
121 +
                                   event: TestSucceeded
122 +
                                 ) = {
123 123
    if (!annotations.contains(SkipSpecification)) {
124 124
      val spec = SpecificationFormatter.format(
125 125
        getCodeFrom(suiteClassName, event),
@@ -127,27 +127,33 @@
Loading
127 127
        suiteClassName,
128 128
        codeFormatFor(suiteClassName)
129 129
      )
130 +
      renderSpecificationHeader(testName, event.duration, spec)
131 +
    } else ""
132 +
  }
130 133
131 -
      s"""
132 -
        <h2>$testName</h2>
133 -
        <code class="highlight specification">$spec</code>
134 +
  private def renderSpecificationHeader(testName: String, duration: Option[Long], spec: String) = {
135 +
    s"""
136 +
          <header>
137 +
            <h2>$testName</h2>
138 +
            ${duration.fold("")(milliseconds => s"""<div class="test-duration">$milliseconds ms</div>""")}
139 +
          </header>
140 +
          <code class="highlight specification">$spec</code>
134 141
        """
135 -
    } else ""
136 142
  }
137 143
138 144
  private def getCodeFrom(location: String, event: TestSucceeded): List[(Int, String)] = {
139 145
    event.location match {
140 146
      case Some(LineInFile(ln, _, _)) => FromSource.getCodeFrom(location, ln)
141 -
      case _                          => FromSource.getCodeFrom(location, event.testText)
147 +
      case _ => FromSource.getCodeFrom(location, event.testText)
142 148
    }
143 149
  }
144 150
145 151
  private def renderFragmentForBody(event: TestFailedOrCancelled): String = {
146 152
    val annotations = annotationsFor(event.suiteName, event.testName)
147 -
    val testState   = TestStates.dequeue(event.testName)
148 -
    val rendering   = renderingFor(event.suiteClassName)
153 +
    val testState = TestStates.dequeue(event.testName)
154 +
    val rendering = renderingFor(event.suiteClassName)
149 155
150 -
    val linkId    = UUID.randomUUID.toString
156 +
    val linkId = UUID.randomUUID.toString
151 157
    val contentId = UUID.randomUUID.toString
152 158
153 159
    val (grayStackTraceElements, blackStackTraceElements) =
@@ -174,10 +180,7 @@
Loading
174 180
          codeFormatFor(event.suiteClassName)
175 181
        )
176 182
177 -
        s"""
178 -
        <h2>${event.testName}</h2>
179 -
        <code class="highlight specification">$spec</code>
180 -
        """
183 +
        renderSpecificationHeader(event.testName, event.duration, spec)
181 184
      } else
182 185
        ""
183 186
    }
@@ -187,23 +190,23 @@
Loading
187 190
    <div class="testmethod test-failed">
188 191
      <div class="scenario" id="${event.testName.hashCode().toString}">
189 192
        $specification
190 -
        <h2>${event.testName}</h2>
191 -
        <div class="highlight results highlighted" style="margin-bottom: 1em">
192 -
          ${event.duration
193 -
      .map(milliseconds => s"<span>${event.name} after $milliseconds ms</span><br/>")
194 -
      .getOrElse("")}
193 +
        <div class="highlight results highlighted">
195 194
          <pre>&gt; ${event.message}</pre>
196 195
          <span class="detailstoggle">
197 196
            <a id="$linkId" href="#" onclick="{ toggleDetails('$contentId', '$linkId'); return false; }">[ show stacktrace ]</a>
198 197
          </span>
199 198
          <div id="$contentId" style="display: none; margin-top: 1em">
200 -
            ${grayStackTraceElements.map(
201 -
      ste => s"""<div style="color: #CCADAD">${ste.toString}</div>)"""
202 -
    )}
199 +
            ${
200 +
      grayStackTraceElements.map(
201 +
        ste => s"""<div style="color: #CCADAD">${ste.toString}</div>"""
202 +
      ).mkString("\n")
203 +
    }
203 204
            <div style="color: #9C3636; font-weight: bold">${blackStackTraceElements.head.toString}</div>
204 -
            ${blackStackTraceElements.tail.map(
205 -
      ste => s"""<div style="color: #9C3636">${ste.toString}</div>"""
206 -
    )}
205 +
            ${
206 +
      blackStackTraceElements.tail.map(
207 +
        ste => s"""<div style="color: #9C3636">${ste.toString}</div>"""
208 +
      ).mkString("\n")
209 +
    }
207 210
          </div>
208 211
        </div>
209 212
        ${interestingGivensTable(testState, rendering).mkString("\n")}
@@ -214,10 +217,10 @@
Loading
214 217
  }
215 218
216 219
  private def capturedInputsAndOutputs(
217 -
      testState: Option[TestState],
218 -
      rendering: Rendering,
219 -
      annotations: Set[Tag]
220 -
  ): String = {
220 +
                                        testState: Option[TestState],
221 +
                                        rendering: Rendering,
222 +
                                        annotations: Set[Tag]
223 +
                                      ): String = {
221 224
    val interactionStyle =
222 225
      if (annotations.contains(SkipInteractions)) "display: none" else "display: inline"
223 226
@@ -249,23 +252,25 @@
Loading
249 252
      """
250 253
  }
251 254
252 -
  private def renderFragmentForBody(event: TestPendingOrIgnored): String =
255 +
  private def renderFragmentForBody(event: TestPendingOrIgnored): String = {
256 +
    println(event)
253 257
    s"""
254 258
    <a id={linkNameOf(event.testText)}></a>
255 259
    <div class="testmethod test-not-run">
256 260
      <div class="scenario" id=${event.testName.hashCode().toString}>
257 -
        <h2>Specification</h2>
258 -
        <pre class="highlight specification">${SpecificationFormatter.format(
259 -
      FromSource.getCodeFrom(event.suiteClassName, event.testText),
260 -
      Seq.empty,
261 -
      event.suiteClassName,
262 -
      codeFormatFor(event.suiteClassName)
263 -
    )}</pre>
264 -
        <h2>Execution</h2>
261 +
        ${
262 +
      renderSpecificationHeader(event.testName, None, SpecificationFormatter.format(
263 +
        FromSource.getCodeFrom(event.suiteClassName, event.testText),
264 +
        Seq.empty,
265 +
        event.suiteClassName,
266 +
        codeFormatFor(event.suiteClassName)
267 +
      ))
268 +
    }
265 269
        <pre class="highlight specification">${event.name}</pre>
266 270
      </div>
267 271
    </div>
268 272
  """
273 +
  }
269 274
270 275
  private def renderingFor(className: String): Rendering =
271 276
    new Rendering(tryToCreateObject[CustomRendering](className))

@@ -27,11 +27,16 @@
Loading
27 27
    val content                           = readLines(sourceFile).getOrElse(Seq.empty)
28 28
    val zippedContent: Seq[(String, Int)] = content.zipWithIndex
29 29
    val joined                            = join(zippedContent)
30 -
    val (line, lineNumber)                = joined.find(_._1.replace("\"", "").contains(testName)).get
31 -
    readToEndOfMethod(
32 -
      content,
33 -
      if (line.trim().matches(".+\\{.+\\}|.+ =\\s+[^\\{]+")) lineNumber else lineNumber + 1
34 -
    )
30 +
    val firstLine                         = joined.find(_._1.replace("\"", "").contains(testName.replace("must", "").replace("should", "").trim))
31 +
    firstLine match {
32 +
      case Some((line, lineNumber)) =>
33 +
        readToEndOfMethod(
34 +
          content,
35 +
          if (line.trim().matches(".+\\{.+\\}|.+ =\\s+[^\\{]+")) lineNumber else lineNumber + 1
36 +
        )
37 +
      case None =>
38 +
        Nil
39 +
    }
35 40
  }
36 41
37 42
  @tailrec
Files Coverage
core/src/main/scala/clairvoyance 74.38%
scalatest/src/main/scala/clairvoyance/scalatest 60.30%
Project Totals (29 files) 68.03%
140.2
TRAVIS_JDK_VERSION=openjdk11
TRAVIS_OS_NAME=linux
140.1
TRAVIS_JDK_VERSION=openjdk11
TRAVIS_OS_NAME=linux

No yaml found.

Create your codecov.yml to customize your Codecov experience

Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files. The size and color of each slice is representing the number of statements and the coverage, respectively.
Grid
Each block represents a single file in the project. The size and color of each block is represented by the number of statements and the coverage, respectively.
Loading