Skip to content

Commit

Permalink
Merge pull request #10 from jatcwang/fix_sbt_output_coloring
Browse files Browse the repository at this point in the history
Fix sbt output coloring
  • Loading branch information
jatcwang authored Jul 12, 2021
2 parents 7f1d964 + ca83b22 commit c483063
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 12 deletions.
9 changes: 8 additions & 1 deletion docs/docs/docs/LibraryIntegrations.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,14 @@ Add this to your SBT build
"com.github.jatcwang" %% "difflicious-scalatest" % "{{ site.version }}" % Test
```

and then in your test suites you can call `assertNoDiff` on any `Differ`.
Tests should be run with the `-oW` option to disable Scalatest from coloring test failures all red as it interferes with
difflicious color display.

```
testOnly -- -oW
```

Here's an example of what a test using difflicious looks like:

```scala mdoc:nest
import org.scalatest.funsuite.AnyFunSuite
Expand Down
30 changes: 23 additions & 7 deletions modules/core/src/main/scala/difflicious/DiffResultPrinter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package difflicious

import difflicious.DiffResult.MapResult.Entry
import difflicious.DiffResult.ValueResult
import fansi.{Str, Color}
import fansi.{Color, EscapeAttr, Str}

object DiffResultPrinter {
private val colorObtained = Color.Red
Expand All @@ -29,9 +29,7 @@ object DiffResultPrinter {
case r: DiffResult.ListResult => {
val indentForFields = Str("\n" ++ indentLevel.asSpacesPlus1)
val listStrs = r.items
.map { res =>
consoleOutput(res, indentLevel + 1) ++ ","
}
.map { res => consoleOutput(res, indentLevel + 1) ++ "," }
.foldLeft(Str("")) { case (accum, next) => accum ++ indentForFields ++ next }
val allStr = Str(s"${r.typeName.short}(") ++ listStrs ++ Str(s"\n${indentLevel.asSpaces})")
colorOnMatchType(str = allStr, matchType = r.pairType)
Expand Down Expand Up @@ -98,14 +96,32 @@ object DiffResultPrinter {
}
}

private val dummyColoSeparator = Str(" ").overlay(Color.Reset)
private def colorOnMatchType(
str: Str,
matchType: PairType,
): Str = {
// Because SBT (and maybe other tools) put their own logging prefix on each line (e.g. [info])
// they effectively resets the color of each line. Therefore we need to ensure every line is "recolored"
// Because we always indent with spaces, we do this by recoloring the first space we find on each line.
def recolorEachLine(orig: Str, color: EscapeAttr) = {
orig.plainText.linesIterator
.map { s =>
if (s.startsWith(" "))
dummyColoSeparator ++ Str(s.drop(1)).overlay(color)
else
Str(s).overlay(color)
}
.reduceLeft((accum, next) => accum ++ Str("\n") ++ next)
}

matchType match {
case PairType.Both => str
case PairType.ObtainedOnly => str.overlay(colorObtained)
case PairType.ExpectedOnly => str.overlay(colorExpected)
case PairType.Both => str
case PairType.ObtainedOnly => {
recolorEachLine(str, colorObtained)
}
case PairType.ExpectedOnly =>
recolorEachLine(str, colorExpected)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package difflicious.differ

import difflicious.{DiffResult, ConfigureOp, ConfigureError, ConfigurePath, DiffInput}
import difflicious.{ConfigureError, ConfigureOp, ConfigurePath, DiffInput, DiffResult}

/**
* A Differ that transforms any input of [[diff]] method and pass it to its underlying Differ.
* A Differ that transforms any input of diff method and pass it to its underlying Differ.
* See [[ValueDiffer.contramap]]
*/
class TransformedDiffer[T, U](underlyingDiffer: ValueDiffer[U], transformFunc: T => U) extends ValueDiffer[T] {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package difflicious
import difflicious.DiffResultPrinter.consoleOutput
import munit.Assertions.assertEquals
import org.scalacheck.Prop.{forAll, propBoolean}
import org.scalacheck.{Prop, Arbitrary}
import org.scalacheck.{Arbitrary, Prop}
import difflicious.internal.EitherGetSyntax._

package object testutils {
Expand Down Expand Up @@ -51,7 +51,17 @@ package object testutils {
res: DiffResult,
expectedOutputStr: String,
): Unit = {
val obtainedOutputStr = consoleOutput(res, 0).render

// Reverse "recolor each line" difflicious.DiffResultPrinter.colorOnMatchType
// to make test expectations easier to read and write
def removeMultilineRecoloring(str: String): String = {
val k = s"$X\n $R"
val j = s"$X\n $G"
val replaced = str.replace(k, "\n ").replace(j, "\n ")
replaced
}

val obtainedOutputStr = removeMultilineRecoloring(consoleOutput(res, 0).render)

if (obtainedOutputStr != expectedOutputStr) {
println("=== Obtained Output === ")
Expand Down

0 comments on commit c483063

Please sign in to comment.