@@ -19,14 +19,45 @@ private[debug] object DebugStepAssert:
1919 val break = s " break ( $sym) ( $line) $trailing" .r
2020 val step = s " step ( $sym| $line) $trailing" .r
2121 val next = s " next ( $sym| $line) $trailing" .r
22- readLines(checkFile).flatMap:
23- case break(className , lineStr) =>
24- val line = lineStr.toInt
25- Some (DebugStepAssert (Break (className, line), checkClassAndLine(className, line)))
26- case step(pattern) => Some (DebugStepAssert (Step , checkLineOrMethod(pattern)))
27- case next(pattern) => Some (DebugStepAssert (Next , checkLineOrMethod(pattern)))
28- case trailing() => None
29- case invalid => throw new Exception (s " Cannot parse debug step: $invalid" )
22+ val multiLineEval = s " eval $trailing" .r
23+ val eval = s " eval (.*) " .r
24+ val result = " result (.*)" .r
25+ val error = " error (.*)" .r
26+
27+ def loop (lines : List [String ], acc : List [DebugStepAssert [? ]]): List [DebugStepAssert [? ]] =
28+ lines match
29+ case Nil => acc.reverse
30+ case break(className , lineStr) :: tail =>
31+ val line = lineStr.toInt
32+ val step = DebugStepAssert (Break (className, line), checkClassAndLine(className, line))
33+ loop(tail, step :: acc)
34+ case step(pattern) :: tail =>
35+ val step = DebugStepAssert (Step , checkLineOrMethod(pattern))
36+ loop(tail, step :: acc)
37+ case next(pattern) :: tail =>
38+ val step = DebugStepAssert (Next , checkLineOrMethod(pattern))
39+ loop(tail, step :: acc)
40+ case eval(expr) :: resOrError :: tail =>
41+ val expected = parseResultOrError(resOrError)
42+ val step = DebugStepAssert (Eval (expr), checkEval(expected))
43+ loop(tail, step :: acc)
44+ case multiLineEval() :: tail0 =>
45+ val (exprLines, tail1) = tail0.span(_.startsWith(" " ))
46+ val expr = exprLines.map(s => s.stripPrefix(" " )).mkString(" \n " )
47+ val expected = parseResultOrError(tail1.head)
48+ val step = DebugStepAssert (Eval (expr), checkEval(expected))
49+ loop(tail1.tail, step :: acc)
50+ case trailing() :: tail => loop(tail, acc)
51+ case invalid :: tail => throw new Exception (s " Cannot parse debug step: $invalid" )
52+
53+ def parseResultOrError (line : String ): Either [String , String ] =
54+ line match
55+ case result(expected) => Right (expected)
56+ case error(expected) => Left (expected)
57+ case invalid => throw new Exception (s " Cannot parse as result or error: $invalid" )
58+
59+ loop(readLines(checkFile), Nil )
60+ end parseCheckFile
3061
3162 private def checkClassAndLine (className : String , line : Int )(location : Location ): Unit =
3263 assert(className == location.declaringType.name, s " obtained ${location.declaringType.name}, expected ${className}" )
@@ -39,12 +70,21 @@ private[debug] object DebugStepAssert:
3970 assert(location.lineNumber == line, s " obtained ${location.lineNumber}, expected $line" )
4071
4172 private def checkMethod (methodName : String )(location : Location ): Unit = assert(methodName == location.method.name)
73+
74+ private def checkEval (expected : Either [String , String ])(obtained : Either [String , String ]): Unit =
75+ (expected, obtained) match
76+ case (Left (expected), Left (obtained)) => assert(expected.r.matches(obtained), s " obtained $obtained, expected $expected" )
77+ case (Right (expected), Right (obtained)) => assert(expected.r.matches(obtained.toString), s " obtained $obtained, expected $expected" )
78+ case (Left (_), Right (_)) => throw new AssertionError (" evaluation succeeded but error expected" )
79+ case (Right (_), Left (_)) => throw new AssertionError (" evaluation failed" )
80+
4281end DebugStepAssert
4382
4483private [debug] enum DebugStep [T ]:
4584 case Break (className : String , line : Int ) extends DebugStep [Location ]
4685 case Step extends DebugStep [Location ]
4786 case Next extends DebugStep [Location ]
87+ case Eval (expression : String ) extends DebugStep [Either [String , String ]]
4888
4989
5090
0 commit comments