Skip to content

Commit 7c19454

Browse files
Write mutation-test-elements.js to separate file (#194)
1 parent 0f77220 commit 7c19454

4 files changed

Lines changed: 106 additions & 80 deletions

File tree

bin/scalafmt

11 Bytes
Binary file not shown.
Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,24 @@
11
package stryker4s.files
2-
import better.files.File
3-
4-
import scala.io.Source
2+
import better.files._
53

64
trait FileIO {
7-
def readResource(resource: String): Source
8-
9-
def createAndWrite(file: File, content: Iterator[Char]): Unit
5+
def createAndWriteFromResource(file: File, resource: String)
106

117
def createAndWrite(file: File, content: String): Unit
128
}
139

1410
object DiskFileIO extends FileIO {
15-
override def readResource(resource: String): Source = {
16-
val stream = getClass.getClassLoader.getResourceAsStream(resource)
17-
Source.fromInputStream(stream)
18-
}
11+
override def createAndWriteFromResource(file: File, resourceName: String): Unit = {
12+
file.createFileIfNotExists(createParents = true)
1913

20-
override def createAndWrite(file: File, content: Iterator[Char]): Unit = {
21-
file.createIfNotExists(asDirectory = false, createParents = true)
22-
file.writeBytes(content.map(_.toByte))
14+
for {
15+
in <- getClass.getClassLoader.getResourceAsStream(resourceName).autoClosed
16+
out <- file.newOutputStream.autoClosed
17+
} in pipeTo out
2318
}
2419

25-
override def createAndWrite(file: File, content: String): Unit = createAndWrite(file, content.iterator)
20+
override def createAndWrite(file: File, content: String): Unit = {
21+
file.createFileIfNotExists(createParents = true)
22+
file.writeText(content)
23+
}
2624
}
Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,63 @@
11
package stryker4s.report
2+
3+
import better.files.File
24
import grizzled.slf4j.Logging
35
import stryker4s.config.Config
46
import stryker4s.files.FileIO
57
import stryker4s.model.MutantRunResults
68
import stryker4s.report.mapper.MutantRunResultMapper
9+
import stryker4s.report.model.MutationTestReport
710

811
class HtmlReporter(fileIO: FileIO)(implicit config: Config)
912
extends FinishedRunReporter
1013
with MutantRunResultMapper
1114
with Logging {
1215

13-
private val htmlReportResource = s"mutation-testing-elements/mutation-test-elements.js"
1416
private val title = "Stryker4s report"
17+
private val mutationTestElementsName = "mutation-test-elements.js"
18+
private val htmlReportResource = s"mutation-testing-elements/$mutationTestElementsName"
1519
private val reportFilename = "report.js"
1620

17-
def indexHtml(): Iterator[Char] = {
18-
val mutationTestElementsScript = fileIO.readResource(htmlReportResource)
19-
20-
val startHtml = s"""<!DOCTYPE html>
21-
|<html>
21+
private val indexHtml: String =
22+
s"""<!DOCTYPE html>
23+
|<html lang="en">
24+
|<head>
25+
| <meta charset="UTF-8">
26+
| <meta name="viewport" content="width=device-width, initial-scale=1.0">
27+
| <script src="mutation-test-elements.js"></script>
28+
|</head>
2229
|<body>
2330
| <mutation-test-report-app title-postfix="$title">
2431
| Your browser doesn't support <a href="https://caniuse.com/#search=custom%20elements">custom elements</a>.
2532
| Please use a latest version of an evergreen browser (Firefox, Chrome, Safari, Opera, etc).
2633
| </mutation-test-report-app>
2734
| <script src="$reportFilename"></script>
28-
| <script>
29-
| """.stripMargin
30-
val endHtml = s"""
31-
| </script>
3235
|</body>
3336
|</html>""".stripMargin
3437

35-
startHtml.iterator ++
36-
mutationTestElementsScript ++
37-
endHtml
38-
}
38+
def writeMutationTestElementsJsTo(file: File): Unit =
39+
fileIO.createAndWriteFromResource(file, htmlReportResource)
3940

40-
def reportJs(json: String): String =
41-
s"document.querySelector('mutation-test-report-app').report = $json"
41+
def writeIndexHtmlTo(file: File): Unit =
42+
fileIO.createAndWrite(file, indexHtml)
4243

43-
override def reportRunFinished(runResults: MutantRunResults): Unit = {
44-
val mapped = toReport(runResults).toJson
44+
def writeReportJsTo(file: File, report: MutationTestReport): Unit = {
45+
val json = report.toJson
46+
val reportContent = s"document.querySelector('mutation-test-report-app').report = $json"
47+
fileIO.createAndWrite(file, reportContent)
48+
}
4549

50+
override def reportRunFinished(runResults: MutantRunResults): Unit = {
4651
val targetLocation = config.baseDir / s"target/stryker4s-report-${System.currentTimeMillis()}"
52+
53+
val mutationTestElementsLocation = targetLocation / mutationTestElementsName
4754
val indexLocation = targetLocation / "index.html"
4855
val reportLocation = targetLocation / reportFilename
49-
val indexContent = indexHtml()
50-
val reportContent = reportJs(mapped)
51-
fileIO.createAndWrite(indexLocation, indexContent)
52-
fileIO.createAndWrite(reportLocation, reportContent)
5356

54-
debug(s"Written HTML report to $targetLocation")
57+
writeIndexHtmlTo(indexLocation)
58+
writeReportJsTo(reportLocation, toReport(runResults))
59+
writeMutationTestElementsJsTo(mutationTestElementsLocation)
60+
61+
info(s"Written HTML report to $indexLocation")
5562
}
5663
}

core/src/test/scala/stryker4s/report/HtmlReporterTest.scala

Lines changed: 64 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -5,38 +5,40 @@ import org.mockito.{ArgumentMatchersSugar, MockitoSugar}
55
import stryker4s.config.Config
66
import stryker4s.files.{DiskFileIO, FileIO}
77
import stryker4s.model.MutantRunResults
8+
import stryker4s.report.model.{MutationTestReport, Thresholds}
89
import stryker4s.scalatest.LogMatchers
910
import stryker4s.testutil.Stryker4sSuite
1011

1112
import scala.concurrent.duration._
12-
import scala.io.Source
1313

1414
class HtmlReporterTest extends Stryker4sSuite with MockitoSugar with ArgumentMatchersSugar with LogMatchers {
1515

1616
describe("indexHtml") {
1717
it("should contain title") {
1818
implicit val config: Config = Config()
1919
val mockFileIO = mock[FileIO]
20-
val resourceLocation = "mutation-testing-elements/mutation-test-elements.js"
21-
when(mockFileIO.readResource(resourceLocation)) thenReturn Source.fromString("console.log('hello');")
2220
val sut = new HtmlReporter(mockFileIO)
23-
24-
val result = sut.indexHtml()
25-
26-
val expected = s"""<!DOCTYPE html>
27-
|<html>
28-
|<body>
29-
| <mutation-test-report-app title-postfix="Stryker4s report">
30-
| Your browser doesn't support <a href="https://caniuse.com/#search=custom%20elements">custom elements</a>.
31-
| Please use a latest version of an evergreen browser (Firefox, Chrome, Safari, Opera, etc).
32-
| </mutation-test-report-app>
33-
| <script src="report.js"></script>
34-
| <script>
35-
| console.log('hello');
36-
| </script>
37-
|</body>
38-
|</html>""".stripMargin
39-
result.mkString should equal(expected)
21+
val testFile = config.baseDir / "foo.bar"
22+
23+
sut.writeIndexHtmlTo(testFile)
24+
25+
val expected =
26+
"""<!DOCTYPE html>
27+
|<html lang="en">
28+
|<head>
29+
| <meta charset="UTF-8">
30+
| <meta name="viewport" content="width=device-width, initial-scale=1.0">
31+
| <script src="mutation-test-elements.js"></script>
32+
|</head>
33+
|<body>
34+
| <mutation-test-report-app title-postfix="Stryker4s report">
35+
| Your browser doesn't support <a href="https://caniuse.com/#search=custom%20elements">custom elements</a>.
36+
| Please use a latest version of an evergreen browser (Firefox, Chrome, Safari, Opera, etc).
37+
| </mutation-test-report-app>
38+
| <script src="report.js"></script>
39+
|</body>
40+
|</html>""".stripMargin
41+
verify(mockFileIO).createAndWrite(testFile, expected)
4042
}
4143
}
4244

@@ -45,57 +47,76 @@ class HtmlReporterTest extends Stryker4sSuite with MockitoSugar with ArgumentMat
4547
implicit val config: Config = Config()
4648
val mockFileIO = mock[FileIO]
4749
val sut = new HtmlReporter(mockFileIO)
50+
val testFile = config.baseDir / "foo.bar"
51+
val runResults = MutationTestReport("1.0", Thresholds(100, 0), Map.empty)
4852

49-
val result = sut.reportJs("""{ 'foo': 'bar' }""")
50-
51-
val expected = s"""document.querySelector('mutation-test-report-app').report = { 'foo': 'bar' }"""
52-
result.mkString should equal(expected)
53+
sut.writeReportJsTo(testFile, runResults)
5354

55+
val expectedJs =
56+
"""document.querySelector('mutation-test-report-app').report = {"schemaVersion":"1.0","thresholds":{"high":100,"low":0},"files":{}}"""
57+
verify(mockFileIO).createAndWrite(testFile, expectedJs)
5458
}
5559
}
5660

5761
describe("mutation-test-elements") {
58-
it("should find the resource") {
62+
it("should write the resource") {
5963
implicit val config: Config = Config()
6064
val fileIO = DiskFileIO
61-
62-
val sut = new HtmlReporter(fileIO)
63-
64-
val result = sut.indexHtml()
65-
result.mkString.length should be > 50
65+
File.usingTemporaryFile() { tempFile =>
66+
val sut = new HtmlReporter(fileIO)
67+
68+
sut.writeMutationTestElementsJsTo(tempFile)
69+
val atLeastSize: Long = 200 * 1024 // 200KB
70+
tempFile.size should be > atLeastSize
71+
tempFile.lineIterator.next() should startWith("!function(")
72+
}
6673
}
6774
}
6875

6976
describe("reportRunFinished") {
77+
implicit val config: Config = Config()
78+
val stryker4sReportFolderRegex = ".*target(/|\\\\)stryker4s-report-(\\d*)(/|\\\\)[a-z-]*\\.[a-z]*$"
79+
7080
it("should write the report files to the report directory") {
71-
implicit val config: Config = Config()
7281
val mockFileIO = mock[FileIO]
7382
val sut = new HtmlReporter(mockFileIO)
7483
val runResults = MutantRunResults(Nil, 50.0, 30.seconds)
7584

7685
sut.reportRunFinished(runResults)
7786

78-
val indexCaptor = ArgCaptor[File]
79-
val reportCaptor = ArgCaptor[File]
80-
verify(mockFileIO).createAndWrite(indexCaptor, any[Iterator[Char]])
81-
verify(mockFileIO).createAndWrite(reportCaptor, any[String])
82-
val paths = List(indexCaptor.value, reportCaptor.value).map(_.pathAsString)
87+
val writtenFilesCaptor = ArgCaptor[File]
88+
89+
verify(mockFileIO, times(2)).createAndWrite(writtenFilesCaptor, any[String])
8390

84-
// ends with target/stryker4s-report-$TIMESTAMP/filename.extension
85-
all(paths) should fullyMatch regex ".*target(/|\\\\)stryker4s-report-(\\d*)(/|\\\\)[a-z]*\\.[a-z]*$"
86-
indexCaptor.value.name should be("index.html")
87-
reportCaptor.value.name should be("report.js")
91+
val paths = writtenFilesCaptor.values.map(_.pathAsString)
92+
all(paths) should fullyMatch regex stryker4sReportFolderRegex
93+
94+
writtenFilesCaptor.values.map(_.name) should contain only ("index.html", "report.js")
8895
}
8996

90-
it("should debug log a message") {
91-
implicit val config: Config = Config()
97+
it("should write the mutation-test-elements.js file to the report directory") {
98+
val mockFileIO = mock[FileIO]
99+
val sut = new HtmlReporter(mockFileIO)
100+
val runResults = MutantRunResults(Nil, 50.0, 30.seconds)
101+
102+
sut.reportRunFinished(runResults)
103+
104+
val elementsCaptor = ArgCaptor[File]
105+
verify(mockFileIO).createAndWriteFromResource(elementsCaptor,
106+
eqTo("mutation-testing-elements/mutation-test-elements.js"))
107+
108+
elementsCaptor.value.pathAsString should fullyMatch regex stryker4sReportFolderRegex
109+
elementsCaptor.value.name equals "mutation-test-elements.js"
110+
}
111+
112+
it("should info log a message") {
92113
val mockFileIO = mock[FileIO]
93114
val sut = new HtmlReporter(mockFileIO)
94115
val runResults = MutantRunResults(Nil, 50.0, 30.seconds)
95116

96117
sut.reportRunFinished(runResults)
97118

98-
"Written HTML report to " shouldBe loggedAsDebug
119+
"Written HTML report to " shouldBe loggedAsInfo
99120
}
100121
}
101122
}

0 commit comments

Comments
 (0)