blob: 1c7ef93878f804be6cc734b5f691f1028236a71b [file] [log] [blame]
Bram Moolenaar296b1f22017-01-15 15:22:33 +01001" Test Vim profiler
Bram Moolenaarb0f94c12019-06-13 22:19:53 +02002
Bram Moolenaarb46fecd2019-06-15 17:58:09 +02003source check.vim
4CheckFeature profile
Bram Moolenaar296b1f22017-01-15 15:22:33 +01005
Bram Moolenaar93344c22019-08-14 21:12:05 +02006source shared.vim
Bram Moolenaar16358802019-08-30 18:37:26 +02007source screendump.vim
Bram Moolenaar93344c22019-08-14 21:12:05 +02008
Bram Moolenaar296b1f22017-01-15 15:22:33 +01009func Test_profile_func()
Bram Moolenaarb2049902021-01-24 12:53:53 +010010 call RunProfileFunc('func', 'let', 'let')
11 call RunProfileFunc('def', 'var', '')
12endfunc
13
14func RunProfileFunc(command, declare, assign)
Bram Moolenaarc79745a2019-05-20 22:12:34 +020015 let lines =<< trim [CODE]
16 profile start Xprofile_func.log
17 profile func Foo*
Bram Moolenaarb2049902021-01-24 12:53:53 +010018 XXX Foo1()
19 endXXX
20 XXX Foo2()
21 DDD counter = 100
22 while counter > 0
23 AAA counter = counter - 1
Bram Moolenaarc79745a2019-05-20 22:12:34 +020024 endwhile
Bram Moolenaara21df1d2020-03-17 20:57:09 +010025 sleep 1m
Bram Moolenaarb2049902021-01-24 12:53:53 +010026 endXXX
27 XXX Foo3()
28 endXXX
29 XXX Bar()
30 endXXX
Bram Moolenaarc79745a2019-05-20 22:12:34 +020031 call Foo1()
32 call Foo1()
33 profile pause
34 call Foo1()
35 profile continue
36 call Foo2()
37 call Foo3()
38 call Bar()
39 if !v:profiling
40 delfunc Foo2
41 endif
42 delfunc Foo3
43 [CODE]
Bram Moolenaar296b1f22017-01-15 15:22:33 +010044
Bram Moolenaarb2049902021-01-24 12:53:53 +010045 call map(lines, {k, v -> substitute(v, 'XXX', a:command, '') })
46 call map(lines, {k, v -> substitute(v, 'DDD', a:declare, '') })
47 call map(lines, {k, v -> substitute(v, 'AAA', a:assign, '') })
48
Bram Moolenaar296b1f22017-01-15 15:22:33 +010049 call writefile(lines, 'Xprofile_func.vim')
Bram Moolenaar93344c22019-08-14 21:12:05 +020050 call system(GetVimCommand()
Bram Moolenaar1fbfe7c2018-06-30 21:18:13 +020051 \ . ' -es --clean'
Bram Moolenaarc011a3d2017-01-16 22:37:42 +010052 \ . ' -c "so Xprofile_func.vim"'
53 \ . ' -c "qall!"')
54 call assert_equal(0, v:shell_error)
55
Bram Moolenaar296b1f22017-01-15 15:22:33 +010056 let lines = readfile('Xprofile_func.log')
57
Bram Moolenaar296b1f22017-01-15 15:22:33 +010058 " - Foo1() is called 3 times but should be reported as called twice
59 " since one call is in between "profile pause" .. "profile continue".
Bram Moolenaarc011a3d2017-01-16 22:37:42 +010060 " - Foo2() should come before Foo1() since Foo1() does much more work.
Bram Moolenaar296b1f22017-01-15 15:22:33 +010061 " - Foo3() is not reported because function is deleted.
62 " - Unlike Foo3(), Foo2() should not be deleted since there is a check
63 " for v:profiling.
64 " - Bar() is not reported since it does not match "profile func Foo*".
Bram Moolenaara21df1d2020-03-17 20:57:09 +010065 call assert_equal(31, len(lines))
Bram Moolenaarc011a3d2017-01-16 22:37:42 +010066
67 call assert_equal('FUNCTION Foo1()', lines[0])
Bram Moolenaar181d4f52019-09-18 22:04:56 +020068 call assert_match('Defined:.*Xprofile_func.vim:3', lines[1])
Bram Moolenaar4c7b08f2018-09-10 22:03:40 +020069 call assert_equal('Called 2 times', lines[2])
70 call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[3])
71 call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[4])
72 call assert_equal('', lines[5])
73 call assert_equal('count total (s) self (s)', lines[6])
74 call assert_equal('', lines[7])
75 call assert_equal('FUNCTION Foo2()', lines[8])
76 call assert_equal('Called 1 time', lines[10])
77 call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[11])
78 call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[12])
79 call assert_equal('', lines[13])
80 call assert_equal('count total (s) self (s)', lines[14])
Bram Moolenaarb2049902021-01-24 12:53:53 +010081 call assert_match('^\s*1\s\+.*\s\(let\|var\) counter = 100$', lines[15])
82 call assert_match('^\s*101\s\+.*\swhile counter > 0$', lines[16])
83 call assert_match('^\s*100\s\+.*\s \(let\)\= counter = counter - 1$', lines[17])
84 call assert_match('^\s*10[01]\s\+.*\sendwhile$', lines[18])
Bram Moolenaara21df1d2020-03-17 20:57:09 +010085 call assert_match('^\s*1\s\+.\+sleep 1m$', lines[19])
86 call assert_equal('', lines[20])
87 call assert_equal('FUNCTIONS SORTED ON TOTAL TIME', lines[21])
88 call assert_equal('count total (s) self (s) function', lines[22])
89 call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo2()$', lines[23])
90 call assert_match('^\s*2\s\+\d\+\.\d\+\s\+Foo1()$', lines[24])
91 call assert_equal('', lines[25])
92 call assert_equal('FUNCTIONS SORTED ON SELF TIME', lines[26])
93 call assert_equal('count total (s) self (s) function', lines[27])
94 call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo2()$', lines[28])
95 call assert_match('^\s*2\s\+\d\+\.\d\+\s\+Foo1()$', lines[29])
96 call assert_equal('', lines[30])
Bram Moolenaar296b1f22017-01-15 15:22:33 +010097
98 call delete('Xprofile_func.vim')
99 call delete('Xprofile_func.log')
100endfunc
101
Bram Moolenaar7feb35e2018-08-21 17:49:54 +0200102func Test_profile_func_with_ifelse()
Bram Moolenaar107e9ce2021-01-24 20:52:00 +0100103 call Run_profile_func_with_ifelse('func', 'let')
104 call Run_profile_func_with_ifelse('def', 'var')
Bram Moolenaarced68a02021-01-24 17:53:47 +0100105endfunc
106
Bram Moolenaar107e9ce2021-01-24 20:52:00 +0100107func Run_profile_func_with_ifelse(command, declare)
Bram Moolenaarc79745a2019-05-20 22:12:34 +0200108 let lines =<< trim [CODE]
Bram Moolenaarced68a02021-01-24 17:53:47 +0100109 XXX Foo1()
Bram Moolenaarc79745a2019-05-20 22:12:34 +0200110 if 1
Bram Moolenaarced68a02021-01-24 17:53:47 +0100111 DDD x = 0
Bram Moolenaarc79745a2019-05-20 22:12:34 +0200112 elseif 1
Bram Moolenaarced68a02021-01-24 17:53:47 +0100113 DDD x = 1
Bram Moolenaarc79745a2019-05-20 22:12:34 +0200114 else
Bram Moolenaarced68a02021-01-24 17:53:47 +0100115 DDD x = 2
Bram Moolenaarc79745a2019-05-20 22:12:34 +0200116 endif
Bram Moolenaarced68a02021-01-24 17:53:47 +0100117 endXXX
118 XXX Foo2()
Bram Moolenaarc79745a2019-05-20 22:12:34 +0200119 if 0
Bram Moolenaarced68a02021-01-24 17:53:47 +0100120 DDD x = 0
Bram Moolenaarc79745a2019-05-20 22:12:34 +0200121 elseif 1
Bram Moolenaarced68a02021-01-24 17:53:47 +0100122 DDD x = 1
Bram Moolenaarc79745a2019-05-20 22:12:34 +0200123 else
Bram Moolenaarced68a02021-01-24 17:53:47 +0100124 DDD x = 2
Bram Moolenaarc79745a2019-05-20 22:12:34 +0200125 endif
Bram Moolenaarced68a02021-01-24 17:53:47 +0100126 endXXX
127 XXX Foo3()
Bram Moolenaarc79745a2019-05-20 22:12:34 +0200128 if 0
Bram Moolenaarced68a02021-01-24 17:53:47 +0100129 DDD x = 0
Bram Moolenaarc79745a2019-05-20 22:12:34 +0200130 elseif 0
Bram Moolenaarced68a02021-01-24 17:53:47 +0100131 DDD x = 1
Bram Moolenaarc79745a2019-05-20 22:12:34 +0200132 else
Bram Moolenaarced68a02021-01-24 17:53:47 +0100133 DDD x = 2
Bram Moolenaarc79745a2019-05-20 22:12:34 +0200134 endif
Bram Moolenaarced68a02021-01-24 17:53:47 +0100135 endXXX
Bram Moolenaarc79745a2019-05-20 22:12:34 +0200136 call Foo1()
137 call Foo2()
138 call Foo3()
139 [CODE]
Bram Moolenaar7feb35e2018-08-21 17:49:54 +0200140
Bram Moolenaarced68a02021-01-24 17:53:47 +0100141 call map(lines, {k, v -> substitute(v, 'XXX', a:command, '') })
142 call map(lines, {k, v -> substitute(v, 'DDD', a:declare, '') })
Bram Moolenaarced68a02021-01-24 17:53:47 +0100143
Bram Moolenaar7feb35e2018-08-21 17:49:54 +0200144 call writefile(lines, 'Xprofile_func.vim')
Bram Moolenaar93344c22019-08-14 21:12:05 +0200145 call system(GetVimCommand()
146 \ . ' -es -i NONE --noplugin'
Bram Moolenaar7feb35e2018-08-21 17:49:54 +0200147 \ . ' -c "profile start Xprofile_func.log"'
148 \ . ' -c "profile func Foo*"'
149 \ . ' -c "so Xprofile_func.vim"'
150 \ . ' -c "qall!"')
151 call assert_equal(0, v:shell_error)
152
153 let lines = readfile('Xprofile_func.log')
154
155 " - Foo1() should pass 'if' block.
156 " - Foo2() should pass 'elseif' block.
157 " - Foo3() should pass 'else' block.
Bram Moolenaar4c7b08f2018-09-10 22:03:40 +0200158 call assert_equal(57, len(lines))
Bram Moolenaar7feb35e2018-08-21 17:49:54 +0200159
160 call assert_equal('FUNCTION Foo1()', lines[0])
Bram Moolenaar4c7b08f2018-09-10 22:03:40 +0200161 call assert_match('Defined:.*Xprofile_func.vim', lines[1])
162 call assert_equal('Called 1 time', lines[2])
163 call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[3])
164 call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[4])
165 call assert_equal('', lines[5])
166 call assert_equal('count total (s) self (s)', lines[6])
167 call assert_match('^\s*1\s\+.*\sif 1$', lines[7])
Bram Moolenaarced68a02021-01-24 17:53:47 +0100168 call assert_match('^\s*1\s\+.*\s \(let\|var\) x = 0$', lines[8])
Bram Moolenaar4c7b08f2018-09-10 22:03:40 +0200169 call assert_match( '^\s\+elseif 1$', lines[9])
Bram Moolenaarced68a02021-01-24 17:53:47 +0100170 call assert_match( '^\s\+\(let\|var\) x = 1$', lines[10])
Bram Moolenaar4c7b08f2018-09-10 22:03:40 +0200171 call assert_match( '^\s\+else$', lines[11])
Bram Moolenaarced68a02021-01-24 17:53:47 +0100172 call assert_match( '^\s\+\(let\|var\) x = 2$', lines[12])
Bram Moolenaar4c7b08f2018-09-10 22:03:40 +0200173 call assert_match('^\s*1\s\+.*\sendif$', lines[13])
174 call assert_equal('', lines[14])
175 call assert_equal('FUNCTION Foo2()', lines[15])
176 call assert_equal('Called 1 time', lines[17])
177 call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[18])
178 call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[19])
179 call assert_equal('', lines[20])
180 call assert_equal('count total (s) self (s)', lines[21])
181 call assert_match('^\s*1\s\+.*\sif 0$', lines[22])
Bram Moolenaarced68a02021-01-24 17:53:47 +0100182 call assert_match( '^\s\+\(let\|var\) x = 0$', lines[23])
Bram Moolenaar4c7b08f2018-09-10 22:03:40 +0200183 call assert_match('^\s*1\s\+.*\selseif 1$', lines[24])
Bram Moolenaarced68a02021-01-24 17:53:47 +0100184 call assert_match('^\s*1\s\+.*\s \(let\|var\) x = 1$', lines[25])
Bram Moolenaar4c7b08f2018-09-10 22:03:40 +0200185 call assert_match( '^\s\+else$', lines[26])
Bram Moolenaarced68a02021-01-24 17:53:47 +0100186 call assert_match( '^\s\+\(let\|var\) x = 2$', lines[27])
Bram Moolenaar4c7b08f2018-09-10 22:03:40 +0200187 call assert_match('^\s*1\s\+.*\sendif$', lines[28])
188 call assert_equal('', lines[29])
189 call assert_equal('FUNCTION Foo3()', lines[30])
190 call assert_equal('Called 1 time', lines[32])
191 call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[33])
192 call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[34])
193 call assert_equal('', lines[35])
194 call assert_equal('count total (s) self (s)', lines[36])
195 call assert_match('^\s*1\s\+.*\sif 0$', lines[37])
Bram Moolenaarced68a02021-01-24 17:53:47 +0100196 call assert_match( '^\s\+\(let\|var\) x = 0$', lines[38])
Bram Moolenaar4c7b08f2018-09-10 22:03:40 +0200197 call assert_match('^\s*1\s\+.*\selseif 0$', lines[39])
Bram Moolenaarced68a02021-01-24 17:53:47 +0100198 call assert_match( '^\s\+\(let\|var\) x = 1$', lines[40])
Bram Moolenaar4c7b08f2018-09-10 22:03:40 +0200199 call assert_match('^\s*1\s\+.*\selse$', lines[41])
Bram Moolenaarced68a02021-01-24 17:53:47 +0100200 call assert_match('^\s*1\s\+.*\s \(let\|var\) x = 2$', lines[42])
Bram Moolenaar4c7b08f2018-09-10 22:03:40 +0200201 call assert_match('^\s*1\s\+.*\sendif$', lines[43])
202 call assert_equal('', lines[44])
203 call assert_equal('FUNCTIONS SORTED ON TOTAL TIME', lines[45])
204 call assert_equal('count total (s) self (s) function', lines[46])
205 call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[47])
206 call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[48])
207 call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[49])
208 call assert_equal('', lines[50])
209 call assert_equal('FUNCTIONS SORTED ON SELF TIME', lines[51])
210 call assert_equal('count total (s) self (s) function', lines[52])
211 call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[53])
212 call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[54])
213 call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[55])
214 call assert_equal('', lines[56])
Bram Moolenaar7feb35e2018-08-21 17:49:54 +0200215
216 call delete('Xprofile_func.vim')
217 call delete('Xprofile_func.log')
218endfunc
219
220func Test_profile_func_with_trycatch()
Bram Moolenaar107e9ce2021-01-24 20:52:00 +0100221 call Run_profile_func_with_trycatch('func', 'let')
222 call Run_profile_func_with_trycatch('def', 'var')
223endfunc
224
225func Run_profile_func_with_trycatch(command, declare)
Bram Moolenaarc79745a2019-05-20 22:12:34 +0200226 let lines =<< trim [CODE]
Bram Moolenaar107e9ce2021-01-24 20:52:00 +0100227 XXX Foo1()
Bram Moolenaarc79745a2019-05-20 22:12:34 +0200228 try
Bram Moolenaar107e9ce2021-01-24 20:52:00 +0100229 DDD x = 0
Bram Moolenaarc79745a2019-05-20 22:12:34 +0200230 catch
Bram Moolenaar107e9ce2021-01-24 20:52:00 +0100231 DDD x = 1
Bram Moolenaarc79745a2019-05-20 22:12:34 +0200232 finally
Bram Moolenaar107e9ce2021-01-24 20:52:00 +0100233 DDD x = 2
Bram Moolenaarc79745a2019-05-20 22:12:34 +0200234 endtry
Bram Moolenaar107e9ce2021-01-24 20:52:00 +0100235 endXXX
236 XXX Foo2()
Bram Moolenaarc79745a2019-05-20 22:12:34 +0200237 try
238 throw 0
239 catch
Bram Moolenaar107e9ce2021-01-24 20:52:00 +0100240 DDD x = 1
Bram Moolenaarc79745a2019-05-20 22:12:34 +0200241 finally
Bram Moolenaar107e9ce2021-01-24 20:52:00 +0100242 DDD x = 2
Bram Moolenaarc79745a2019-05-20 22:12:34 +0200243 endtry
Bram Moolenaar107e9ce2021-01-24 20:52:00 +0100244 endXXX
245 XXX Foo3()
Bram Moolenaarc79745a2019-05-20 22:12:34 +0200246 try
247 throw 0
248 catch
249 throw 1
250 finally
Bram Moolenaar107e9ce2021-01-24 20:52:00 +0100251 DDD x = 2
Bram Moolenaarc79745a2019-05-20 22:12:34 +0200252 endtry
Bram Moolenaar107e9ce2021-01-24 20:52:00 +0100253 endXXX
Bram Moolenaarc79745a2019-05-20 22:12:34 +0200254 call Foo1()
255 call Foo2()
Bram Moolenaar107e9ce2021-01-24 20:52:00 +0100256 let rethrown = 0
Bram Moolenaarc79745a2019-05-20 22:12:34 +0200257 try
258 call Foo3()
259 catch
Bram Moolenaar107e9ce2021-01-24 20:52:00 +0100260 let rethrown = 1
Bram Moolenaarc79745a2019-05-20 22:12:34 +0200261 endtry
Bram Moolenaar107e9ce2021-01-24 20:52:00 +0100262 if rethrown != 1
263 " call Foo1 again so that the test fails
264 call Foo1()
265 endif
Bram Moolenaarc79745a2019-05-20 22:12:34 +0200266 [CODE]
Bram Moolenaar7feb35e2018-08-21 17:49:54 +0200267
Bram Moolenaar107e9ce2021-01-24 20:52:00 +0100268 call map(lines, {k, v -> substitute(v, 'XXX', a:command, '') })
269 call map(lines, {k, v -> substitute(v, 'DDD', a:declare, '') })
270
Bram Moolenaar7feb35e2018-08-21 17:49:54 +0200271 call writefile(lines, 'Xprofile_func.vim')
Bram Moolenaar93344c22019-08-14 21:12:05 +0200272 call system(GetVimCommand()
273 \ . ' -es -i NONE --noplugin'
Bram Moolenaar7feb35e2018-08-21 17:49:54 +0200274 \ . ' -c "profile start Xprofile_func.log"'
275 \ . ' -c "profile func Foo*"'
276 \ . ' -c "so Xprofile_func.vim"'
277 \ . ' -c "qall!"')
278 call assert_equal(0, v:shell_error)
279
280 let lines = readfile('Xprofile_func.log')
281
282 " - Foo1() should pass 'try' 'finally' blocks.
283 " - Foo2() should pass 'catch' 'finally' blocks.
284 " - Foo3() should not pass 'endtry'.
Bram Moolenaar4c7b08f2018-09-10 22:03:40 +0200285 call assert_equal(57, len(lines))
Bram Moolenaar7feb35e2018-08-21 17:49:54 +0200286
287 call assert_equal('FUNCTION Foo1()', lines[0])
Bram Moolenaar4c7b08f2018-09-10 22:03:40 +0200288 call assert_match('Defined:.*Xprofile_func.vim', lines[1])
289 call assert_equal('Called 1 time', lines[2])
290 call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[3])
291 call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[4])
292 call assert_equal('', lines[5])
293 call assert_equal('count total (s) self (s)', lines[6])
294 call assert_match('^\s*1\s\+.*\stry$', lines[7])
Bram Moolenaar107e9ce2021-01-24 20:52:00 +0100295 call assert_match('^\s*1\s\+.*\s \(let\|var\) x = 0$', lines[8])
Bram Moolenaar4c7b08f2018-09-10 22:03:40 +0200296 call assert_match( '^\s\+catch$', lines[9])
Bram Moolenaar107e9ce2021-01-24 20:52:00 +0100297 call assert_match( '^\s\+\(let\|var\) x = 1$', lines[10])
Bram Moolenaar4c7b08f2018-09-10 22:03:40 +0200298 call assert_match('^\s*1\s\+.*\sfinally$', lines[11])
Bram Moolenaar107e9ce2021-01-24 20:52:00 +0100299 call assert_match('^\s*1\s\+.*\s \(let\|var\) x = 2$', lines[12])
Bram Moolenaar4c7b08f2018-09-10 22:03:40 +0200300 call assert_match('^\s*1\s\+.*\sendtry$', lines[13])
301 call assert_equal('', lines[14])
302 call assert_equal('FUNCTION Foo2()', lines[15])
303 call assert_equal('Called 1 time', lines[17])
304 call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[18])
305 call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[19])
306 call assert_equal('', lines[20])
307 call assert_equal('count total (s) self (s)', lines[21])
308 call assert_match('^\s*1\s\+.*\stry$', lines[22])
309 call assert_match('^\s*1\s\+.*\s throw 0$', lines[23])
310 call assert_match('^\s*1\s\+.*\scatch$', lines[24])
Bram Moolenaar107e9ce2021-01-24 20:52:00 +0100311 call assert_match('^\s*1\s\+.*\s \(let\|var\) x = 1$', lines[25])
Bram Moolenaar4c7b08f2018-09-10 22:03:40 +0200312 call assert_match('^\s*1\s\+.*\sfinally$', lines[26])
Bram Moolenaar107e9ce2021-01-24 20:52:00 +0100313 call assert_match('^\s*1\s\+.*\s \(let\|var\) x = 2$', lines[27])
Bram Moolenaar4c7b08f2018-09-10 22:03:40 +0200314 call assert_match('^\s*1\s\+.*\sendtry$', lines[28])
315 call assert_equal('', lines[29])
316 call assert_equal('FUNCTION Foo3()', lines[30])
317 call assert_equal('Called 1 time', lines[32])
318 call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[33])
319 call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[34])
320 call assert_equal('', lines[35])
321 call assert_equal('count total (s) self (s)', lines[36])
322 call assert_match('^\s*1\s\+.*\stry$', lines[37])
323 call assert_match('^\s*1\s\+.*\s throw 0$', lines[38])
324 call assert_match('^\s*1\s\+.*\scatch$', lines[39])
325 call assert_match('^\s*1\s\+.*\s throw 1$', lines[40])
326 call assert_match('^\s*1\s\+.*\sfinally$', lines[41])
Bram Moolenaar107e9ce2021-01-24 20:52:00 +0100327 call assert_match('^\s*1\s\+.*\s \(let\|var\) x = 2$', lines[42])
Bram Moolenaar4c7b08f2018-09-10 22:03:40 +0200328 call assert_match( '^\s\+endtry$', lines[43])
329 call assert_equal('', lines[44])
330 call assert_equal('FUNCTIONS SORTED ON TOTAL TIME', lines[45])
331 call assert_equal('count total (s) self (s) function', lines[46])
332 call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[47])
333 call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[48])
334 call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[49])
335 call assert_equal('', lines[50])
336 call assert_equal('FUNCTIONS SORTED ON SELF TIME', lines[51])
337 call assert_equal('count total (s) self (s) function', lines[52])
338 call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[53])
339 call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[54])
340 call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[55])
341 call assert_equal('', lines[56])
Bram Moolenaar7feb35e2018-08-21 17:49:54 +0200342
343 call delete('Xprofile_func.vim')
344 call delete('Xprofile_func.log')
345endfunc
346
Bram Moolenaar296b1f22017-01-15 15:22:33 +0100347func Test_profile_file()
Bram Moolenaarc79745a2019-05-20 22:12:34 +0200348 let lines =<< trim [CODE]
Bram Moolenaare7eb9272019-06-24 00:58:07 +0200349 func! Foo()
350 endfunc
351 for i in range(10)
352 " a comment
353 call Foo()
354 endfor
Bram Moolenaarc79745a2019-05-20 22:12:34 +0200355 call Foo()
Bram Moolenaarc79745a2019-05-20 22:12:34 +0200356 [CODE]
Bram Moolenaar296b1f22017-01-15 15:22:33 +0100357
358 call writefile(lines, 'Xprofile_file.vim')
Bram Moolenaar93344c22019-08-14 21:12:05 +0200359 call system(GetVimCommandClean()
360 \ . ' -es'
Bram Moolenaarc011a3d2017-01-16 22:37:42 +0100361 \ . ' -c "profile start Xprofile_file.log"'
362 \ . ' -c "profile file Xprofile_file.vim"'
363 \ . ' -c "so Xprofile_file.vim"'
364 \ . ' -c "so Xprofile_file.vim"'
365 \ . ' -c "qall!"')
366 call assert_equal(0, v:shell_error)
Bram Moolenaar296b1f22017-01-15 15:22:33 +0100367
368 let lines = readfile('Xprofile_file.log')
369
370 call assert_equal(14, len(lines))
371
372 call assert_match('^SCRIPT .*Xprofile_file.vim$', lines[0])
373 call assert_equal('Sourced 2 times', lines[1])
374 call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[2])
375 call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[3])
376 call assert_equal('', lines[4])
377 call assert_equal('count total (s) self (s)', lines[5])
Bram Moolenaar67435d92017-10-19 21:04:37 +0200378 call assert_match(' 2 0.\d\+ func! Foo()', lines[6])
Bram Moolenaar296b1f22017-01-15 15:22:33 +0100379 call assert_equal(' endfunc', lines[7])
380 " Loop iterates 10 times. Since script runs twice, body executes 20 times.
381 " First line of loop executes one more time than body to detect end of loop.
382 call assert_match('^\s*22\s\+\d\+\.\d\+\s\+for i in range(10)$', lines[8])
383 call assert_equal(' " a comment', lines[9])
Bram Moolenaard21b16f2017-08-14 23:13:30 +0200384 " if self and total are equal we only get one number
385 call assert_match('^\s*20\s\+\(\d\+\.\d\+\s\+\)\=\d\+\.\d\+\s\+call Foo()$', lines[10])
Bram Moolenaar7feb35e2018-08-21 17:49:54 +0200386 call assert_match('^\s*22\s\+\d\+\.\d\+\s\+endfor$', lines[11])
Bram Moolenaare32bbde2017-01-15 21:12:48 +0100387 " if self and total are equal we only get one number
388 call assert_match('^\s*2\s\+\(\d\+\.\d\+\s\+\)\=\d\+\.\d\+\s\+call Foo()$', lines[12])
Bram Moolenaar296b1f22017-01-15 15:22:33 +0100389 call assert_equal('', lines[13])
390
391 call delete('Xprofile_file.vim')
392 call delete('Xprofile_file.log')
393endfunc
394
Bram Moolenaar67435d92017-10-19 21:04:37 +0200395func Test_profile_file_with_cont()
396 let lines = [
397 \ 'echo "hello',
398 \ ' \ world"',
399 \ 'echo "foo ',
400 \ ' \bar"',
401 \ ]
402
403 call writefile(lines, 'Xprofile_file.vim')
Bram Moolenaar93344c22019-08-14 21:12:05 +0200404 call system(GetVimCommandClean()
405 \ . ' -es'
Bram Moolenaar67435d92017-10-19 21:04:37 +0200406 \ . ' -c "profile start Xprofile_file.log"'
407 \ . ' -c "profile file Xprofile_file.vim"'
408 \ . ' -c "so Xprofile_file.vim"'
409 \ . ' -c "qall!"')
410 call assert_equal(0, v:shell_error)
411
412 let lines = readfile('Xprofile_file.log')
413 call assert_equal(11, len(lines))
414
Bram Moolenaar1fbfe7c2018-06-30 21:18:13 +0200415 call assert_match('^SCRIPT .*Xprofile_file.vim$', lines[0])
416 call assert_equal('Sourced 1 time', lines[1])
417 call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[2])
418 call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[3])
419 call assert_equal('', lines[4])
420 call assert_equal('count total (s) self (s)', lines[5])
421 call assert_match(' 1 0.\d\+ echo "hello', lines[6])
422 call assert_equal(' \ world"', lines[7])
423 call assert_match(' 1 0.\d\+ echo "foo ', lines[8])
424 call assert_equal(' \bar"', lines[9])
425 call assert_equal('', lines[10])
Bram Moolenaar67435d92017-10-19 21:04:37 +0200426
427 call delete('Xprofile_file.vim')
428 call delete('Xprofile_file.log')
429endfunc
430
Bram Moolenaar296b1f22017-01-15 15:22:33 +0100431func Test_profile_completion()
432 call feedkeys(":profile \<C-A>\<C-B>\"\<CR>", 'tx')
433 call assert_equal('"profile continue file func pause start', @:)
434
435 call feedkeys(":profile start test_prof\<C-A>\<C-B>\"\<CR>", 'tx')
436 call assert_match('^"profile start.* test_profile\.vim', @:)
437endfunc
438
439func Test_profile_errors()
440 call assert_fails("profile func Foo", 'E750:')
441 call assert_fails("profile pause", 'E750:')
442 call assert_fails("profile continue", 'E750:')
443endfunc
Bram Moolenaarac112f02017-12-05 16:46:28 +0100444
445func Test_profile_truncate_mbyte()
Bram Moolenaar30276f22019-01-24 17:59:39 +0100446 if &enc !=# 'utf-8'
Bram Moolenaarac112f02017-12-05 16:46:28 +0100447 return
448 endif
449
450 let lines = [
451 \ 'scriptencoding utf-8',
452 \ 'func! Foo()',
453 \ ' return [',
454 \ ' \ "' . join(map(range(0x4E00, 0x4E00 + 340), 'nr2char(v:val)'), '') . '",',
455 \ ' \ "' . join(map(range(0x4F00, 0x4F00 + 340), 'nr2char(v:val)'), '') . '",',
456 \ ' \ ]',
457 \ 'endfunc',
458 \ 'call Foo()',
459 \ ]
460
461 call writefile(lines, 'Xprofile_file.vim')
Bram Moolenaar93344c22019-08-14 21:12:05 +0200462 call system(GetVimCommandClean()
463 \ . ' -es --cmd "set enc=utf-8"'
Bram Moolenaarac112f02017-12-05 16:46:28 +0100464 \ . ' -c "profile start Xprofile_file.log"'
465 \ . ' -c "profile file Xprofile_file.vim"'
466 \ . ' -c "so Xprofile_file.vim"'
467 \ . ' -c "qall!"')
468 call assert_equal(0, v:shell_error)
469
470 split Xprofile_file.log
471 if &fenc != ''
472 call assert_equal('utf-8', &fenc)
473 endif
474 /func! Foo()
475 let lnum = line('.')
476 call assert_match('^\s*return \[$', getline(lnum + 1))
477 call assert_match("\u4F52$", getline(lnum + 2))
478 call assert_match("\u5052$", getline(lnum + 3))
479 call assert_match('^\s*\\ \]$', getline(lnum + 4))
480 bwipe!
481
482 call delete('Xprofile_file.vim')
483 call delete('Xprofile_file.log')
484endfunc
Bram Moolenaar1fbfe7c2018-06-30 21:18:13 +0200485
486func Test_profdel_func()
Bram Moolenaarc79745a2019-05-20 22:12:34 +0200487 let lines =<< trim [CODE]
488 profile start Xprofile_file.log
489 func! Foo1()
490 endfunc
491 func! Foo2()
492 endfunc
493 func! Foo3()
494 endfunc
495
496 profile func Foo1
497 profile func Foo2
498 call Foo1()
499 call Foo2()
500
501 profile func Foo3
502 profdel func Foo2
503 profdel func Foo3
504 call Foo1()
505 call Foo2()
506 call Foo3()
507 [CODE]
Bram Moolenaar1fbfe7c2018-06-30 21:18:13 +0200508 call writefile(lines, 'Xprofile_file.vim')
Bram Moolenaar93344c22019-08-14 21:12:05 +0200509 call system(GetVimCommandClean() . ' -es -c "so Xprofile_file.vim" -c q')
Bram Moolenaar1fbfe7c2018-06-30 21:18:13 +0200510 call assert_equal(0, v:shell_error)
511
512 let lines = readfile('Xprofile_file.log')
Bram Moolenaar4c7b08f2018-09-10 22:03:40 +0200513 call assert_equal(26, len(lines))
Bram Moolenaar1fbfe7c2018-06-30 21:18:13 +0200514
515 " Check that:
516 " - Foo1() is called twice (profdel not invoked)
517 " - Foo2() is called once (profdel invoked after it was called)
518 " - Foo3() is not called (profdel invoked before it was called)
519 call assert_equal('FUNCTION Foo1()', lines[0])
Bram Moolenaar4c7b08f2018-09-10 22:03:40 +0200520 call assert_match('Defined:.*Xprofile_file.vim', lines[1])
521 call assert_equal('Called 2 times', lines[2])
522 call assert_equal('FUNCTION Foo2()', lines[8])
523 call assert_equal('Called 1 time', lines[10])
524 call assert_equal('FUNCTIONS SORTED ON TOTAL TIME', lines[16])
525 call assert_equal('FUNCTIONS SORTED ON SELF TIME', lines[21])
Bram Moolenaar1fbfe7c2018-06-30 21:18:13 +0200526
527 call delete('Xprofile_file.vim')
528 call delete('Xprofile_file.log')
529endfunc
530
531func Test_profdel_star()
532 " Foo() is invoked once before and once after 'profdel *'.
533 " So profiling should report it only once.
Bram Moolenaarc79745a2019-05-20 22:12:34 +0200534 let lines =<< trim [CODE]
535 profile start Xprofile_file.log
536 func! Foo()
537 endfunc
538 profile func Foo
539 call Foo()
540 profdel *
541 call Foo()
542 [CODE]
Bram Moolenaar1fbfe7c2018-06-30 21:18:13 +0200543 call writefile(lines, 'Xprofile_file.vim')
Bram Moolenaar93344c22019-08-14 21:12:05 +0200544 call system(GetVimCommandClean() . ' -es -c "so Xprofile_file.vim" -c q')
Bram Moolenaar1fbfe7c2018-06-30 21:18:13 +0200545 call assert_equal(0, v:shell_error)
546
547 let lines = readfile('Xprofile_file.log')
Bram Moolenaar4c7b08f2018-09-10 22:03:40 +0200548 call assert_equal(16, len(lines))
Bram Moolenaar1fbfe7c2018-06-30 21:18:13 +0200549
550 call assert_equal('FUNCTION Foo()', lines[0])
Bram Moolenaar4c7b08f2018-09-10 22:03:40 +0200551 call assert_match('Defined:.*Xprofile_file.vim', lines[1])
552 call assert_equal('Called 1 time', lines[2])
553 call assert_equal('FUNCTIONS SORTED ON TOTAL TIME', lines[8])
554 call assert_equal('FUNCTIONS SORTED ON SELF TIME', lines[12])
Bram Moolenaar1fbfe7c2018-06-30 21:18:13 +0200555
556 call delete('Xprofile_file.vim')
557 call delete('Xprofile_file.log')
558endfunc
Bram Moolenaar16358802019-08-30 18:37:26 +0200559
560" When typing the function it won't have a script ID, test that this works.
561func Test_profile_typed_func()
562 CheckScreendump
563
564 let lines =<< trim END
565 profile start XprofileTypedFunc
566 END
567 call writefile(lines, 'XtestProfile')
568 let buf = RunVimInTerminal('-S XtestProfile', #{})
569
570 call term_sendkeys(buf, ":func DoSomething()\<CR>"
571 \ .. "echo 'hello'\<CR>"
572 \ .. "endfunc\<CR>")
573 call term_sendkeys(buf, ":profile func DoSomething\<CR>")
574 call term_sendkeys(buf, ":call DoSomething()\<CR>")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200575 call TermWait(buf, 100)
Bram Moolenaar16358802019-08-30 18:37:26 +0200576 call StopVimInTerminal(buf)
577 let lines = readfile('XprofileTypedFunc')
578 call assert_equal("FUNCTION DoSomething()", lines[0])
579 call assert_equal("Called 1 time", lines[1])
580
581 " clean up
582 call delete('XprofileTypedFunc')
583 call delete('XtestProfile')
584endfunc
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200585
Bram Moolenaare5ea3462021-01-25 21:01:48 +0100586func Test_vim9_profiling()
587 " only tests that compiling and calling functions doesn't crash
588 let lines =<< trim END
589 vim9script
590 def Func()
591 Crash()
592 enddef
593 def Crash()
594 enddef
Bram Moolenaar98989a02021-01-26 12:06:30 +0100595 prof start Xprofile_crash.log
Bram Moolenaare5ea3462021-01-25 21:01:48 +0100596 prof func Func
597 Func()
598 END
Bram Moolenaar98989a02021-01-26 12:06:30 +0100599 call writefile(lines, 'Xprofile_crash.vim')
600 call system(GetVimCommandClean() . ' -es -c "so Xprofile_crash.vim" -c q')
601 call assert_equal(0, v:shell_error)
Bram Moolenaar8c801b32021-03-05 20:58:22 +0100602 call assert_true(readfile('Xprofile_crash.log')->len() > 10)
Bram Moolenaar98989a02021-01-26 12:06:30 +0100603 call delete('Xprofile_crash.vim')
604 call delete('Xprofile_crash.log')
Bram Moolenaare5ea3462021-01-25 21:01:48 +0100605endfunc
606
Bram Moolenaar12d26532021-02-19 19:13:21 +0100607func Test_vim9_nested_call()
608 let lines =<< trim END
609 vim9script
610 var total = 0
611 def One(Ref: func(number))
612 for i in range(3)
613 Ref(i)
614 endfor
615 enddef
616 def Two(nr: number)
617 total += nr
618 enddef
619 prof start Xprofile_nested.log
620 prof func One
621 prof func Two
622 One((nr) => Two(nr))
623 assert_equal(3, total)
624 END
625 call writefile(lines, 'Xprofile_nested.vim')
626 call system(GetVimCommandClean() . ' -es -c "so Xprofile_nested.vim" -c q')
627 call assert_equal(0, v:shell_error)
628
629 let prof_lines = readfile('Xprofile_nested.log')->join('#')
630 call assert_match('FUNCTION <SNR>\d\+_One().*'
631 \ .. '#Called 1 time.*'
632 \ .. '# 1 \s*[0-9.]\+ for i in range(3)'
633 \ .. '# 3 \s*[0-9.]\+ \s*[0-9.]\+ Ref(i)'
634 \ .. '# 3 \s*[0-9.]\+ endfor', prof_lines)
635 call assert_match('FUNCTION <SNR>\d\+_Two().*'
636 \ .. '#Called 3 times.*'
637 \ .. '# 3 \s*[0-9.]\+ total += nr', prof_lines)
Bram Moolenaar4fa11752021-03-03 13:26:02 +0100638 call delete('Xprofile_nested.vim')
639 call delete('Xprofile_nested.log')
Bram Moolenaar12d26532021-02-19 19:13:21 +0100640endfunc
641
Bram Moolenaare5ea3462021-01-25 21:01:48 +0100642
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200643" vim: shiftwidth=2 sts=2 expandtab