Skip to content

Commit 712b576

Browse files
committed
add char-diff highlighting within line diffs
1 parent 88ee0e0 commit 712b576

File tree

2 files changed

+37
-30
lines changed

2 files changed

+37
-30
lines changed

utest/src/utest/Errors.scala

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,39 @@ object AssertionError {
5454
case DiffElement.InBoth(x) => render0(" ", x, fansi.Attrs.Empty)
5555
case DiffElement.InFirst(x) => renderRed(x)
5656
case DiffElement.InSecond(x) => renderGreen(x)
57-
case DiffElement.Diff(x, y) => renderRed(x) ++ renderGreen(y)
57+
case DiffElement.Diff(x, y) =>
58+
// Within any adjacent blocks of differing text, do a char-by-char
59+
// diff between the two versions so we can underline the characters
60+
// that differ between them
61+
val subDiff = StringDiff.diff(x.map(_.plainText).mkString, y.map(_.plainText).mkString)
62+
val sectionsX = subDiff.collect{
63+
case DiffElement.InBoth(x) => (false, x.length)
64+
case DiffElement.InFirst(x) => (true, x.length)
65+
case DiffElement.Diff(x, y) => (true, x.length)
66+
}
67+
68+
val sectionsY = subDiff.collect{
69+
case DiffElement.InBoth(x) => (false, x.length)
70+
case DiffElement.InSecond(x) => (true, x.length)
71+
case DiffElement.Diff(x, y) => (true, y.length)
72+
}
73+
74+
def sectionsToOverlays(sections: Seq[(Boolean, Int)]) = {
75+
val buffer = collection.mutable.Buffer.empty[(fansi.Attrs, Int, Int)]
76+
var index = 0
77+
for ((underline, length) <- sections) {
78+
val nextIndex = index + length
79+
if (underline) buffer.append((fansi.Underlined.On, index, nextIndex))
80+
index = nextIndex
81+
}
82+
buffer.toSeq
83+
}
84+
85+
val overlaysX = sectionsToOverlays(sectionsX)
86+
val overlaysY = sectionsToOverlays(sectionsY)
87+
88+
renderRed(splitLines(fansi.Str.join(x).overlayAll(overlaysX))) ++
89+
renderGreen(splitLines(fansi.Str.join(y).overlayAll(overlaysY)))
5890
}
5991
}
6092
def render(msgPrefix: String, captured: Seq[TestValue]) = {
Lines changed: 4 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,12 @@
11
package test.utest
22
import utest._
3-
import scala.concurrent.{ExecutionContext, Future}
43

54
object Main {
65
def main(args: Array[String]): Unit = {
7-
val tests = Tests{
8-
test("test1"){
9-
// throw new Exception("test1")
10-
}
11-
test("test2"){
12-
test("inner"){
13-
val a = 1
14-
val b = 2
15-
val c = 3
16-
val d = 4
17-
assertAll(
18-
a == 1,
19-
c == d,
20-
???
21-
)
22-
}
23-
}
24-
test("test3"){
25-
val a = List[Byte](1, 2)
26-
// a(10)
27-
}
28-
}
29-
30-
31-
// Run, return results, and print streaming output with the default formatter
32-
val results2 = TestRunner.runAndPrint(
33-
tests,
34-
"MyTestSuiteA"
6+
try assert(
7+
Seq("i am cow", "hear me moo", "i weigh twice as much as you", "and I look good on the barbecue", "!!!!!") ==
8+
Seq("I AM COW", "hear me moo", "I weigh twice as much as you", "AND I look good on the barbecue", "???"),
359
)
10+
catch{case e: utest.AssertionError => println(e.coloredMessage)}
3611
}
3712
}

0 commit comments

Comments
 (0)