Skip to content

Commit 8b07406

Browse files
committed
fix linenumbers in failed assertion traces
1 parent 76e7fe5 commit 8b07406

File tree

3 files changed

+79
-3
lines changed

3 files changed

+79
-3
lines changed

utest/src-3/utest/TestBuilder.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@ object TestBuilder:
2929
import quotes.reflect._
3030
val inner =
3131
if nestedBodyTrees.nonEmpty then Block(setupStats, '{Right(${Expr.ofList(nestedBodyTrees)}.toIndexedSeq)}.asTerm)
32-
else Block(setupStats.dropRight(1), '{Left(${setupStats.takeRight(1).head.asInstanceOf[Term].asExpr})}.asTerm)
32+
else
33+
val term = setupStats.takeRight(1).head.asInstanceOf[Term]
34+
val inlinedTerm = Inlined(None,Nil,term) //Inlined results in proper line number generation
35+
Block(setupStats.dropRight(1), '{Left(${inlinedTerm.asExpr})}.asTerm)
3336
'{ TestCallTree(${inner.asExprOf[Either[Any, IndexedSeq[TestCallTree]]]}) }
3437

3538
private def processTest(using Quotes)(test: quotes.reflect.Apply, pathOld: Seq[String], index: Int): (Expr[UTree[String]], Expr[TestCallTree]) =
@@ -66,6 +69,7 @@ object TestBuilder:
6669

6770
def unapply(using Quotes)(tree: quotes.reflect.Tree): Option[(Option[String], quotes.reflect.Tree)] =
6871
import quotes.reflect._
72+
import quotes.reflect.given
6973

7074
Option(tree).collect { case tree: Term => tree.asExpr }.collect {
7175
// case q"""utest.`package`.*.-($body)""" => (None, body)

utest/src-3/utest/asserts/Tracer.scala

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,27 @@ object Tracer {
1717
Expr.betaReduce('{ $func($tree)})
1818
}
1919

20-
def apply[T](func: Expr[Seq[AssertEntry[T]] => Unit], exprs: Expr[Seq[T]])(using Quotes, Type[T]): Expr[Unit] = {
20+
21+
//direct call to betareduce provides different context (quotes) in case of Inlined terms,this results in borken linenumbers
22+
private def betaReduceKeepLineNumbers(using quotes: Quotes)(tree: quotes.reflect.Term): quotes.reflect.Term = {
2123
import quotes.reflect._
24+
new TreeMap {
25+
override def transformTerm(tree: quotes.reflect.Term)(owner: quotes.reflect.Symbol): quotes.reflect.Term = tree match {
26+
case Inlined(_, Nil, _) =>
27+
super.transformTerm(tree)(owner)
28+
case _ =>
29+
Term.betaReduce(tree).getOrElse(tree)
30+
}
31+
}
32+
.transformTerm(tree)(Symbol.spliceOwner)
33+
}
34+
35+
def apply[T](func: Expr[Seq[AssertEntry[T]] => Unit], exprs: Expr[Seq[T]])(using Quotes, Type[T]): Expr[Unit] = {
36+
import quotes.reflect.*
2237
exprs match {
2338
case Varargs(ess) =>
2439
val trees: Expr[Seq[AssertEntry[T]]] = Expr.ofSeq(ess.map(e => makeAssertEntry(e, codeOf(e))))
25-
Expr.betaReduce('{ $func($trees)})
40+
betaReduceKeepLineNumbers('{ $func($trees)}.asTerm).asExprOf[Unit]
2641

2742
case _ => throw new RuntimeException(s"Only varargs are supported. Got: ${exprs.asTerm}")
2843
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package test.utest
2+
3+
import utest._
4+
import utest.framework.{TestCallTree, Tree}
5+
6+
object LineNumbersTests extends utest.TestSuite {
7+
8+
val testsToRun = Tests {
9+
test("test1") {
10+
val x = 1
11+
assert(x == 2)
12+
}
13+
test("test2") {
14+
assert(1 == 2)
15+
}
16+
test("test3") {
17+
test("innerTest3")(assert(1 == 2))
18+
}
19+
test("test4") {
20+
test("innerTest4") {
21+
assert(1 == 2)
22+
}
23+
}
24+
25+
test("test5") {
26+
test("innerTest5") {
27+
println("extra statement")
28+
assert(1 == 2)
29+
}
30+
}
31+
}
32+
33+
val testBody = {
34+
35+
val results = TestRunner.run(
36+
testsToRun
37+
)
38+
39+
val stackTraceLinesFromThisFile = results.mapLeaves(_.value.failed.get.getStackTrace.toList.filter(_.getFileName == "LineNumbersTests.scala").toList).leaves.toList
40+
41+
assert(
42+
stackTraceLinesFromThisFile(0).exists(_.getLineNumber == 11),
43+
stackTraceLinesFromThisFile(1).exists(_.getLineNumber == 14),
44+
stackTraceLinesFromThisFile(2).exists(_.getLineNumber == 17),
45+
stackTraceLinesFromThisFile(3).exists(_.getLineNumber == 21),
46+
stackTraceLinesFromThisFile(4).exists(_.getLineNumber == 28),
47+
48+
)
49+
50+
}
51+
52+
val tests = Tests(Tree(""), new TestCallTree(Left(testBody))) //don't use Tests macro for stability
53+
54+
}
55+
56+
57+

0 commit comments

Comments
 (0)