tproper_stacktrace.nim 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. discard """
  2. output: '''ok'''
  3. """
  4. import strscans, strutils
  5. proc raiseTestException*() =
  6. raise newException(Exception, "test")
  7. proc matchStackTrace(actualEntries: openarray[StackTraceEntry], expected: string) =
  8. var expectedEntries = newSeq[StackTraceEntry]()
  9. var i = 0
  10. template checkEqual(actual, expected: typed, subject: string) =
  11. if actual != expected:
  12. echo "Unexpected ", subject, " on line ", i
  13. echo "Actual: ", actual
  14. echo "Expected: ", expected
  15. doAssert(false)
  16. for l in splitLines(expected.strip):
  17. var procname, filename: string
  18. var line: int
  19. if not scanf(l, "$s$w.nim($i) $w", filename, line, procname):
  20. doAssert(false, "Wrong expected stack trace")
  21. checkEqual(actualEntries[i].filename.`$`.split('/')[^1], filename & ".nim", "file name")
  22. if line != 0:
  23. checkEqual(actualEntries[i].line, line, "line number")
  24. checkEqual($actualEntries[i].procname, procname, "proc name")
  25. inc i
  26. doAssert(i == actualEntries.len, "Unexpected number of lines in stack trace")
  27. template verifyStackTrace*(expectedStackTrace: string, body: untyped) =
  28. var verified = false
  29. try:
  30. body
  31. except Exception as e:
  32. verified = true
  33. # echo "Stack trace:"
  34. # echo e.getStackTrace
  35. matchStackTrace(e.getStackTraceEntries(), expectedStackTrace)
  36. doAssert(verified, "No exception was raised")
  37. when true:
  38. # <-- Align with line 70 in the text editor
  39. block:
  40. proc bar() =
  41. raiseTestException()
  42. proc foo() =
  43. bar()
  44. const expectedStackTrace = """
  45. tproper_stacktrace.nim(86) tproper_stacktrace
  46. tproper_stacktrace.nim(76) foo
  47. tproper_stacktrace.nim(73) bar
  48. tproper_stacktrace.nim(7) raiseTestException
  49. """
  50. verifyStackTrace expectedStackTrace:
  51. foo()
  52. block:
  53. proc bar(x: int) =
  54. raiseTestException()
  55. template foo(x: int) =
  56. bar(x)
  57. const expectedStackTrace = """
  58. tproper_stacktrace.nim(103) tproper_stacktrace
  59. tproper_stacktrace.nim(90) bar
  60. tproper_stacktrace.nim(7) raiseTestException
  61. """
  62. verifyStackTrace expectedStackTrace:
  63. var x: int
  64. foo(x)
  65. block: #6803
  66. proc bar(x = 500) =
  67. raiseTestException()
  68. proc foo() =
  69. bar()
  70. const expectedStackTrace = """
  71. tproper_stacktrace.nim(120) tproper_stacktrace
  72. tproper_stacktrace.nim(110) foo
  73. tproper_stacktrace.nim(107) bar
  74. tproper_stacktrace.nim(7) raiseTestException
  75. """
  76. verifyStackTrace expectedStackTrace:
  77. foo()
  78. block:
  79. proc bar() {.stackTrace: off.} =
  80. proc baz() = # Stack trace should be enabled
  81. raiseTestException()
  82. baz()
  83. proc foo() =
  84. bar()
  85. const expectedStackTrace = """
  86. tproper_stacktrace.nim(139) tproper_stacktrace
  87. tproper_stacktrace.nim(129) foo
  88. tproper_stacktrace.nim(125) baz
  89. tproper_stacktrace.nim(7) raiseTestException
  90. """
  91. verifyStackTrace expectedStackTrace:
  92. foo()
  93. echo "ok"