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
142
|
" Test for getstacktrace() and v:stacktrace
source vim9.vim
let s:thisfile = expand('%:p')
let s:testdir = s:thisfile->fnamemodify(':h')
func Filepath(name)
return s:testdir .. '/' .. a:name
endfunc
func AssertStacktrace(expect, actual)
call assert_equal(Filepath('runtest.vim'), a:actual[0]['filepath'])
call assert_equal(a:expect, a:actual[-len(a:expect):])
endfunc
func Test_getstacktrace()
let g:stacktrace = []
let lines1 =<< trim [SCRIPT]
" Xscript1
source Xscript2
func Xfunc1()
" Xfunc1
call Xfunc2()
endfunc
[SCRIPT]
let lines2 =<< trim [SCRIPT]
" Xscript2
func Xfunc2()
" Xfunc2
let g:stacktrace = getstacktrace()
endfunc
[SCRIPT]
call writefile(lines1, 'Xscript1', 'D')
call writefile(lines2, 'Xscript2', 'D')
source Xscript1
call Xfunc1()
call AssertStacktrace([
\ #{funcref: funcref('Test_getstacktrace'), lnum: 37, filepath: s:thisfile},
\ #{funcref: funcref('Xfunc1'), lnum: 5, filepath: Filepath('Xscript1')},
\ #{funcref: funcref('Xfunc2'), lnum: 4, filepath: Filepath('Xscript2')},
\ ], g:stacktrace)
unlet g:stacktrace
endfunc
func Test_getstacktrace_event()
let g:stacktrace = []
let lines1 =<< trim [SCRIPT]
" Xscript1
func Xfunc()
" Xfunc
let g:stacktrace = getstacktrace()
endfunc
augroup test_stacktrace
autocmd SourcePre * call Xfunc()
augroup END
[SCRIPT]
let lines2 =<< trim [SCRIPT]
" Xscript2
[SCRIPT]
call writefile(lines1, 'Xscript1', 'D')
call writefile(lines2, 'Xscript2', 'D')
source Xscript1
source Xscript2
call AssertStacktrace([
\ #{funcref: funcref('Test_getstacktrace_event'), lnum: 64, filepath: s:thisfile},
\ #{event: 'SourcePre Autocommands for "*"', lnum: 7, filepath: Filepath('Xscript1')},
\ #{funcref: funcref('Xfunc'), lnum: 4, filepath: Filepath('Xscript1')},
\ ], g:stacktrace)
augroup test_stacktrace
autocmd!
augroup END
unlet g:stacktrace
endfunc
func Test_vstacktrace()
let lines1 =<< trim [SCRIPT]
" Xscript1
source Xscript2
func Xfunc1()
" Xfunc1
call Xfunc2()
endfunc
[SCRIPT]
let lines2 =<< trim [SCRIPT]
" Xscript2
func Xfunc2()
" Xfunc2
throw 'Exception from Xfunc2'
endfunc
[SCRIPT]
call writefile(lines1, 'Xscript1', 'D')
call writefile(lines2, 'Xscript2', 'D')
source Xscript1
call assert_equal([], v:stacktrace)
try
call Xfunc1()
catch
let stacktrace = v:stacktrace
try
call Xfunc1()
catch
let stacktrace_inner = v:stacktrace
endtry
let stacktrace_after = v:stacktrace " should be restored by the exception stack to the previous one
endtry
call assert_equal([], v:stacktrace)
call AssertStacktrace([
\ #{funcref: funcref('Test_vstacktrace'), lnum: 97, filepath: s:thisfile},
\ #{funcref: funcref('Xfunc1'), lnum: 5, filepath: Filepath('Xscript1')},
\ #{funcref: funcref('Xfunc2'), lnum: 4, filepath: Filepath('Xscript2')},
\ ], stacktrace)
call AssertStacktrace([
\ #{funcref: funcref('Test_vstacktrace'), lnum: 101, filepath: s:thisfile},
\ #{funcref: funcref('Xfunc1'), lnum: 5, filepath: Filepath('Xscript1')},
\ #{funcref: funcref('Xfunc2'), lnum: 4, filepath: Filepath('Xscript2')},
\ ], stacktrace_inner)
call assert_equal(stacktrace, stacktrace_after)
endfunc
func Test_stacktrace_vim9()
let lines =<< trim [SCRIPT]
var stacktrace = getstacktrace()
assert_notequal([], stacktrace)
for d in stacktrace
assert_true(has_key(d, 'lnum'))
endfor
try
throw 'Exception from s:Func'
catch
assert_notequal([], v:stacktrace)
assert_equal(len(stacktrace), len(v:stacktrace))
for d in v:stacktrace
assert_true(has_key(d, 'lnum'))
endfor
endtry
call assert_equal([], v:stacktrace)
[SCRIPT]
call CheckDefSuccess(lines)
endfunc
" vim: shiftwidth=2 sts=2 expandtab
|