summary refs log tree commit diff stats
path: root/tests/errmsgs/tproper_stacktrace.nim
blob: c7dfbaf2a766cf8866af4de03a96b4d920b35e23 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
discard """
  output: '''ok'''
"""
import strscans, strutils

proc raiseTestException*() =
  raise newException(Exception, "test")

proc matchStackTrace(actualEntries: openarray[StackTraceEntry], expected: string) =
  var expectedEntries = newSeq[StackTraceEntry]()
  var i = 0

  template checkEqual(actual, expected: typed, subject: string) =
    if actual != expected:
      echo "Unexpected ", subject, " on line ", i
      echo "Actual: ", actual
      echo "Expected: ", expected
      doAssert(false)

  for l in splitLines(expected.strip):
    var procname, filename: string
    var line: int
    if not scanf(l, "$s$w.nim($i) $w", filename, line, procname):
      doAssert(false, "Wrong expected stack trace")
    checkEqual(actualEntries[i].filename.`$`.split('/')[^1], filename & ".nim", "file name")
    if line != 0:
      checkEqual(actualEntries[i].line, line, "line number")
    checkEqual($actualEntries[i].procname, procname, "proc name")
    inc i

  doAssert(i == actualEntries.len, "Unexpected number of lines in stack trace")

template verifyStackTrace*(expectedStackTrace: string, body: untyped) =
  var verified = false
  try:
    body
  except Exception as e:
    verified = true
    # echo "Stack trace:"
    # echo e.getStackTrace
    matchStackTrace(e.getStackTraceEntries(), expectedStackTrace)

  doAssert(verified, "No exception was raised")

























when true:
# <-- Align with line 70 in the text editor
  block:
    proc bar() =
      raiseTestException()

    proc foo() =
      bar()

    const expectedStackTrace = """
      tproper_stacktrace.nim(86) tproper_stacktrace
      tproper_stacktrace.nim(76) foo
      tproper_stacktrace.nim(73) bar
      tproper_stacktrace.nim(7) raiseTestException
    """

    verifyStackTrace expectedStackTrace:
      foo()

  block:
    proc bar(x: int) =
      raiseTestException()

    template foo(x: int) =
      bar(x)

    const expectedStackTrace = """
      tproper_stacktrace.nim(103) tproper_stacktrace
      tproper_stacktrace.nim(90) bar
      tproper_stacktrace.nim(7) raiseTestException
    """

    verifyStackTrace expectedStackTrace:
      var x: int
      foo(x)

  block: #6803
    proc bar(x = 500) =
      raiseTestException()

    proc foo() =
      bar()

    const expectedStackTrace = """
      tproper_stacktrace.nim(120) tproper_stacktrace
      tproper_stacktrace.nim(110) foo
      tproper_stacktrace.nim(107) bar
      tproper_stacktrace.nim(7) raiseTestException
    """

    verifyStackTrace expectedStackTrace:
      foo()

  block:
    proc bar() {.stackTrace: off.} =
      proc baz() = # Stack trace should be enabled
        raiseTestException()
      baz()

    proc foo() =
      bar()

    const expectedStackTrace = """
      tproper_stacktrace.nim(139) tproper_stacktrace
      tproper_stacktrace.nim(129) foo
      tproper_stacktrace.nim(125) baz
      tproper_stacktrace.nim(7) raiseTestException
    """

    verifyStackTrace expectedStackTrace:
      foo()

  echo "ok"