Skip to content
This repository has been archived by the owner on Jan 24, 2025. It is now read-only.

Properly handle newlines in diff results #432

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 16 additions & 14 deletions core/src/main/scala/com/softwaremill/diffx/DiffResultPrinter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ object DiffResultPrinter {
case dr: DiffResultString => s"${dr.diffs.map(ds => showIndented(ds, indent)).mkString("\n")}"
case dr: DiffResultStringLine => mergeChunks(dr.diffs).map(ds => showIndented(ds, indent)).mkString
case dr: DiffResultStringWord => mergeChunks(dr.diffs).map(ds => showIndented(ds, indent)).mkString
case dr: DiffResultChunk => arrowColor("[") + showChange(s"${dr.left}", s"${dr.right}") + arrowColor("]")
case dr: DiffResultValue[_] => showChange(s"${dr.left}", s"${dr.right}")
case dr: IdenticalValue[_] => defaultColor(s"${dr.value}")
case dr: DiffResultMissing[_] => missingColor(s"${dr.value}")
case dr: DiffResultMissingChunk => missingColor(s"[${dr.value}]")
case dr: DiffResultAdditional[_] => additionalColor(s"${dr.value}")
case dr: DiffResultAdditionalChunk => additionalColor(s"[${dr.value}]")
case dr: DiffResultChunk => arrowColor("[") + showChange(s"${dr.left}", s"${dr.right}", indent) + arrowColor("]")
case dr: DiffResultValue[_] => showChange(s"${dr.left}", s"${dr.right}", indent)
case dr: IdenticalValue[_] => defaultColor(s"${dr.value}", indent)
case dr: DiffResultMissing[_] => missingColor(s"${dr.value}", indent)
case dr: DiffResultMissingChunk => missingColor(s"[${dr.value}]", indent)
case dr: DiffResultAdditional[_] => additionalColor(s"${dr.value}", indent)
case dr: DiffResultAdditionalChunk => additionalColor(s"[${dr.value}]", indent)
}
}

Expand Down Expand Up @@ -89,12 +89,14 @@ object DiffResultPrinter {
}
}

private def leftColor(s: String)(implicit c: ShowConfig): String = c.left(s)
private def missingColor(s: String)(implicit c: ShowConfig): String = c.missing(s)
private def additionalColor(s: String)(implicit c: ShowConfig): String = c.additional(s)
private def rightColor(s: String)(implicit c: ShowConfig): String = c.right(s)
private def defaultColor(s: String)(implicit c: ShowConfig): String = c.default(s)
private def missingColor(s: String, indent: Int)(implicit c: ShowConfig): String = withColor(s, c.missing, indent)
private def additionalColor(s: String, indent: Int)(implicit c: ShowConfig): String = withColor(s, c.additional, indent)
private def defaultColor(s: String, indent: Int = 0)(implicit c: ShowConfig): String = withColor(s, c.default, indent)
private def arrowColor(s: String)(implicit c: ShowConfig): String = c.arrow(s)
private def showChange(l: String, r: String)(implicit c: ShowConfig): String =
leftColor(l) + arrowColor(" -> ") + rightColor(r)
private def showChange(l: String, r: String, indent: Int)(implicit c: ShowConfig): String =
withColor(l, c.left, indent) + arrowColor(" -> ") + withColor(r, c.right, indent)

private def withColor(value: String, color: String => String, indent: Int): String = {
value.split("\n", -1).map(color(_)).mkString("\n" + " ".repeat(indent))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -168,4 +168,34 @@ class DiffResultTest extends AnyFreeSpec with Matchers {
).show() shouldBe "abc abc-[ ]"
}
}

"diff iterable output" - {
"it should show an indented diff for objects with multiline toString" in {
val john = new VerboseNonCaseClass("John", 33)
val mary = new VerboseNonCaseClass("Mary", 28)
val jane = new VerboseNonCaseClass("Jane", 5)
DiffResultIterable(
"List",
Map(
"0" -> IdenticalValue(john),
"1" -> DiffResultAdditional(mary),
"2" -> DiffResultMissing(jane),
)
).show() shouldBe
"""List(
| 0: VerboseNonCaseClass(
| key: John,
| value: 33
| ),
| 1: +VerboseNonCaseClass(
| + key: Mary,
| + value: 28
| +),
| 2: -VerboseNonCaseClass(
| - key: Jane,
| - value: 5
| -))""".stripMargin

}
}
}
13 changes: 13 additions & 0 deletions core/src/test/scala/com/softwaremill/diffx/test/examples.scala
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,16 @@ class NonCaseClass(private val field: String) {
}
}
}

class VerboseNonCaseClass(private val key: String, private val value: Int) {
override def toString: String =
s"""VerboseNonCaseClass(
| key: $key,
| value: $value
|)""".stripMargin

override def equals(obj: Any): Boolean = obj match {
case other: VerboseNonCaseClass => other.key == key && other.value == value
case _ => false
}
}