[#411] Display callstack in Nettest errors
Description
Say we have a test like this:
test_Example :: TestTree
test_Example =
nettestScenarioCaps "Example" $ do
addr <- originateSimple "" 2 countdown
call addr CallDefault ()
call addr CallDefault ()
call addr CallDefault ()
call addr CallDefault ()
call addr CallDefault ()
countdown :: Contract () Integer
countdown = defaultContract $
cdr # push @Integer 1 # L.swap # sub # dup #
ifLt0
fail_
(nil @Operation # pair)
When this test fails, all we get is an error message with little context, and in some cases it's impossible to tell which call was responsible for the error.
Personally, in order to diagnose the issue, my workflow is usually to sprinkle the code with comment
/traceM
, maybe comment out some things, but that's a poor dev experience.
With this MR, the tasty logs now show the full Haskell expression that lead to that error, and where in the source code it's located.
This is very similar to Hedghog's logs, with some notable differences:
- We show (by default) 5 lines before and after the error location, whereas Hedgehog is smarter and displays the full top-level declaration. We actually do not want hedgehog's behaviour, because we usually have lots of small tests embedded in a single top-level Tasty
TestTree
, and we don't want to display all of that when a single test fails. - Hedgehog uses
ansi-terminal
to colourize its output (which tasty then overrides and just prints everything in red anyway😞 ). We could implement this (in a way that cannot be overridden by tasty), but this MR is already big enough and it's a good improvement over what we have, so I'll leave this for some other time, it's not that important. - Our implementation also displays the full callstack at the bottom, with the filepath/line/column. I think this is helpful because:
- in some editors/terminals, you can click on the filepath link and have the editor jump straight to that location in the source code.
- in more complex tests, where you have helper functions and layers of abstractions, an exception will have a callstack with multiple stack frames, but we'll only print the source code for the top-most frame. By printing the callstack as well, we can trace back the origin of the call and see exactly what happened.
Related issue(s)
Resolves part of #411
✅ Checklist for your Merge Request
Related changes (conditional)
-
Tests (see short guidelines)
-
If I added new functionality, I added tests covering it. -
If I fixed a bug, I added a regression test to prevent the bug from silently reappearing again.
-
-
Documentation
Stylistic guide (mandatory)
-
My commits comply with the following policy. -
My code complies with the style guide.
Edited by Diogo Castro