Skip to content

Commit ca83b22

Browse files
committed
Fix sbt output coloring
SBT puts a [info] prefix on the output of the tests framework which resets the color each line, therefore this commits ensures that every line in difflicious rendered string is recolored. Fixes #6
1 parent 7f1d964 commit ca83b22

File tree

4 files changed

+45
-12
lines changed

4 files changed

+45
-12
lines changed

docs/docs/docs/LibraryIntegrations.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,14 @@ Add this to your SBT build
3434
"com.github.jatcwang" %% "difflicious-scalatest" % "{{ site.version }}" % Test
3535
```
3636

37-
and then in your test suites you can call `assertNoDiff` on any `Differ`.
37+
Tests should be run with the `-oW` option to disable Scalatest from coloring test failures all red as it interferes with
38+
difflicious color display.
39+
40+
```
41+
testOnly -- -oW
42+
```
43+
44+
Here's an example of what a test using difflicious looks like:
3845

3946
```scala mdoc:nest
4047
import org.scalatest.funsuite.AnyFunSuite

modules/core/src/main/scala/difflicious/DiffResultPrinter.scala

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package difflicious
22

33
import difflicious.DiffResult.MapResult.Entry
44
import difflicious.DiffResult.ValueResult
5-
import fansi.{Str, Color}
5+
import fansi.{Color, EscapeAttr, Str}
66

77
object DiffResultPrinter {
88
private val colorObtained = Color.Red
@@ -29,9 +29,7 @@ object DiffResultPrinter {
2929
case r: DiffResult.ListResult => {
3030
val indentForFields = Str("\n" ++ indentLevel.asSpacesPlus1)
3131
val listStrs = r.items
32-
.map { res =>
33-
consoleOutput(res, indentLevel + 1) ++ ","
34-
}
32+
.map { res => consoleOutput(res, indentLevel + 1) ++ "," }
3533
.foldLeft(Str("")) { case (accum, next) => accum ++ indentForFields ++ next }
3634
val allStr = Str(s"${r.typeName.short}(") ++ listStrs ++ Str(s"\n${indentLevel.asSpaces})")
3735
colorOnMatchType(str = allStr, matchType = r.pairType)
@@ -98,14 +96,32 @@ object DiffResultPrinter {
9896
}
9997
}
10098

99+
private val dummyColoSeparator = Str(" ").overlay(Color.Reset)
101100
private def colorOnMatchType(
102101
str: Str,
103102
matchType: PairType,
104103
): Str = {
104+
// Because SBT (and maybe other tools) put their own logging prefix on each line (e.g. [info])
105+
// they effectively resets the color of each line. Therefore we need to ensure every line is "recolored"
106+
// Because we always indent with spaces, we do this by recoloring the first space we find on each line.
107+
def recolorEachLine(orig: Str, color: EscapeAttr) = {
108+
orig.plainText.linesIterator
109+
.map { s =>
110+
if (s.startsWith(" "))
111+
dummyColoSeparator ++ Str(s.drop(1)).overlay(color)
112+
else
113+
Str(s).overlay(color)
114+
}
115+
.reduceLeft((accum, next) => accum ++ Str("\n") ++ next)
116+
}
117+
105118
matchType match {
106-
case PairType.Both => str
107-
case PairType.ObtainedOnly => str.overlay(colorObtained)
108-
case PairType.ExpectedOnly => str.overlay(colorExpected)
119+
case PairType.Both => str
120+
case PairType.ObtainedOnly => {
121+
recolorEachLine(str, colorObtained)
122+
}
123+
case PairType.ExpectedOnly =>
124+
recolorEachLine(str, colorExpected)
109125
}
110126
}
111127

modules/core/src/main/scala/difflicious/differ/TransformedDiffer.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
package difflicious.differ
22

3-
import difflicious.{DiffResult, ConfigureOp, ConfigureError, ConfigurePath, DiffInput}
3+
import difflicious.{ConfigureError, ConfigureOp, ConfigurePath, DiffInput, DiffResult}
44

55
/**
6-
* A Differ that transforms any input of [[diff]] method and pass it to its underlying Differ.
6+
* A Differ that transforms any input of diff method and pass it to its underlying Differ.
77
* See [[ValueDiffer.contramap]]
88
*/
99
class TransformedDiffer[T, U](underlyingDiffer: ValueDiffer[U], transformFunc: T => U) extends ValueDiffer[T] {

modules/coretest/src/test/scala/difflicious/testutils/package.scala

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package difflicious
33
import difflicious.DiffResultPrinter.consoleOutput
44
import munit.Assertions.assertEquals
55
import org.scalacheck.Prop.{forAll, propBoolean}
6-
import org.scalacheck.{Prop, Arbitrary}
6+
import org.scalacheck.{Arbitrary, Prop}
77
import difflicious.internal.EitherGetSyntax._
88

99
package object testutils {
@@ -51,7 +51,17 @@ package object testutils {
5151
res: DiffResult,
5252
expectedOutputStr: String,
5353
): Unit = {
54-
val obtainedOutputStr = consoleOutput(res, 0).render
54+
55+
// Reverse "recolor each line" difflicious.DiffResultPrinter.colorOnMatchType
56+
// to make test expectations easier to read and write
57+
def removeMultilineRecoloring(str: String): String = {
58+
val k = s"$X\n $R"
59+
val j = s"$X\n $G"
60+
val replaced = str.replace(k, "\n ").replace(j, "\n ")
61+
replaced
62+
}
63+
64+
val obtainedOutputStr = removeMultilineRecoloring(consoleOutput(res, 0).render)
5565

5666
if (obtainedOutputStr != expectedOutputStr) {
5767
println("=== Obtained Output === ")

0 commit comments

Comments
 (0)