1" Test Vim profiler 2if !has('profile') 3 finish 4endif 5 6func Test_profile_func() 7 let lines = [ 8 \ 'profile start Xprofile_func.log', 9 \ 'profile func Foo*"', 10 \ "func! Foo1()", 11 \ "endfunc", 12 \ "func! Foo2()", 13 \ " let l:count = 100", 14 \ " while l:count > 0", 15 \ " let l:count = l:count - 1", 16 \ " endwhile", 17 \ "endfunc", 18 \ "func! Foo3()", 19 \ "endfunc", 20 \ "func! Bar()", 21 \ "endfunc", 22 \ "call Foo1()", 23 \ "call Foo1()", 24 \ "profile pause", 25 \ "call Foo1()", 26 \ "profile continue", 27 \ "call Foo2()", 28 \ "call Foo3()", 29 \ "call Bar()", 30 \ "if !v:profiling", 31 \ " delfunc Foo2", 32 \ "endif", 33 \ "delfunc Foo3", 34 \ ] 35 36 call writefile(lines, 'Xprofile_func.vim') 37 call system(v:progpath 38 \ . ' -es --clean' 39 \ . ' -c "so Xprofile_func.vim"' 40 \ . ' -c "qall!"') 41 call assert_equal(0, v:shell_error) 42 43 let lines = readfile('Xprofile_func.log') 44 45 " - Foo1() is called 3 times but should be reported as called twice 46 " since one call is in between "profile pause" .. "profile continue". 47 " - Foo2() should come before Foo1() since Foo1() does much more work. 48 " - Foo3() is not reported because function is deleted. 49 " - Unlike Foo3(), Foo2() should not be deleted since there is a check 50 " for v:profiling. 51 " - Bar() is not reported since it does not match "profile func Foo*". 52 call assert_equal(28, len(lines)) 53 54 call assert_equal('FUNCTION Foo1()', lines[0]) 55 call assert_equal('Called 2 times', lines[1]) 56 call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[2]) 57 call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[3]) 58 call assert_equal('', lines[4]) 59 call assert_equal('count total (s) self (s)', lines[5]) 60 call assert_equal('', lines[6]) 61 call assert_equal('FUNCTION Foo2()', lines[7]) 62 call assert_equal('Called 1 time', lines[8]) 63 call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[9]) 64 call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[10]) 65 call assert_equal('', lines[11]) 66 call assert_equal('count total (s) self (s)', lines[12]) 67 call assert_match('^\s*1\s\+.*\slet l:count = 100$', lines[13]) 68 call assert_match('^\s*101\s\+.*\swhile l:count > 0$', lines[14]) 69 call assert_match('^\s*100\s\+.*\s let l:count = l:count - 1$', lines[15]) 70 call assert_match('^\s*101\s\+.*\sendwhile$', lines[16]) 71 call assert_equal('', lines[17]) 72 call assert_equal('FUNCTIONS SORTED ON TOTAL TIME', lines[18]) 73 call assert_equal('count total (s) self (s) function', lines[19]) 74 call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo2()$', lines[20]) 75 call assert_match('^\s*2\s\+\d\+\.\d\+\s\+Foo1()$', lines[21]) 76 call assert_equal('', lines[22]) 77 call assert_equal('FUNCTIONS SORTED ON SELF TIME', lines[23]) 78 call assert_equal('count total (s) self (s) function', lines[24]) 79 call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo2()$', lines[25]) 80 call assert_match('^\s*2\s\+\d\+\.\d\+\s\+Foo1()$', lines[26]) 81 call assert_equal('', lines[27]) 82 83 call delete('Xprofile_func.vim') 84 call delete('Xprofile_func.log') 85endfunc 86 87func Test_profile_func_with_ifelse() 88 let lines = [ 89 \ "func! Foo1()", 90 \ " if 1", 91 \ " let x = 0", 92 \ " elseif 1", 93 \ " let x = 1", 94 \ " else", 95 \ " let x = 2", 96 \ " endif", 97 \ "endfunc", 98 \ "func! Foo2()", 99 \ " if 0", 100 \ " let x = 0", 101 \ " elseif 1", 102 \ " let x = 1", 103 \ " else", 104 \ " let x = 2", 105 \ " endif", 106 \ "endfunc", 107 \ "func! Foo3()", 108 \ " if 0", 109 \ " let x = 0", 110 \ " elseif 0", 111 \ " let x = 1", 112 \ " else", 113 \ " let x = 2", 114 \ " endif", 115 \ "endfunc", 116 \ "call Foo1()", 117 \ "call Foo2()", 118 \ "call Foo3()", 119 \ ] 120 121 call writefile(lines, 'Xprofile_func.vim') 122 call system(v:progpath 123 \ . ' -es -u NONE -U NONE -i NONE --noplugin' 124 \ . ' -c "profile start Xprofile_func.log"' 125 \ . ' -c "profile func Foo*"' 126 \ . ' -c "so Xprofile_func.vim"' 127 \ . ' -c "qall!"') 128 call assert_equal(0, v:shell_error) 129 130 let lines = readfile('Xprofile_func.log') 131 132 " - Foo1() should pass 'if' block. 133 " - Foo2() should pass 'elseif' block. 134 " - Foo3() should pass 'else' block. 135 call assert_equal(54, len(lines)) 136 137 call assert_equal('FUNCTION Foo1()', lines[0]) 138 call assert_equal('Called 1 time', lines[1]) 139 call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[2]) 140 call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[3]) 141 call assert_equal('', lines[4]) 142 call assert_equal('count total (s) self (s)', lines[5]) 143 call assert_match('^\s*1\s\+.*\sif 1$', lines[6]) 144 call assert_match('^\s*1\s\+.*\s let x = 0$', lines[7]) 145 call assert_match( '^\s\+elseif 1$', lines[8]) 146 call assert_match( '^\s\+let x = 1$', lines[9]) 147 call assert_match( '^\s\+else$', lines[10]) 148 call assert_match( '^\s\+let x = 2$', lines[11]) 149 call assert_match('^\s*1\s\+.*\sendif$', lines[12]) 150 call assert_equal('', lines[13]) 151 call assert_equal('FUNCTION Foo2()', lines[14]) 152 call assert_equal('Called 1 time', lines[15]) 153 call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[16]) 154 call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[17]) 155 call assert_equal('', lines[18]) 156 call assert_equal('count total (s) self (s)', lines[19]) 157 call assert_match('^\s*1\s\+.*\sif 0$', lines[20]) 158 call assert_match( '^\s\+let x = 0$', lines[21]) 159 call assert_match('^\s*1\s\+.*\selseif 1$', lines[22]) 160 call assert_match('^\s*1\s\+.*\s let x = 1$', lines[23]) 161 call assert_match( '^\s\+else$', lines[24]) 162 call assert_match( '^\s\+let x = 2$', lines[25]) 163 call assert_match('^\s*1\s\+.*\sendif$', lines[26]) 164 call assert_equal('', lines[27]) 165 call assert_equal('FUNCTION Foo3()', lines[28]) 166 call assert_equal('Called 1 time', lines[29]) 167 call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[30]) 168 call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[31]) 169 call assert_equal('', lines[32]) 170 call assert_equal('count total (s) self (s)', lines[33]) 171 call assert_match('^\s*1\s\+.*\sif 0$', lines[34]) 172 call assert_match( '^\s\+let x = 0$', lines[35]) 173 call assert_match('^\s*1\s\+.*\selseif 0$', lines[36]) 174 call assert_match( '^\s\+let x = 1$', lines[37]) 175 call assert_match('^\s*1\s\+.*\selse$', lines[38]) 176 call assert_match('^\s*1\s\+.*\s let x = 2$', lines[39]) 177 call assert_match('^\s*1\s\+.*\sendif$', lines[40]) 178 call assert_equal('', lines[41]) 179 call assert_equal('FUNCTIONS SORTED ON TOTAL TIME', lines[42]) 180 call assert_equal('count total (s) self (s) function', lines[43]) 181 call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[44]) 182 call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[45]) 183 call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[46]) 184 call assert_equal('', lines[47]) 185 call assert_equal('FUNCTIONS SORTED ON SELF TIME', lines[48]) 186 call assert_equal('count total (s) self (s) function', lines[49]) 187 call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[50]) 188 call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[51]) 189 call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[52]) 190 call assert_equal('', lines[53]) 191 192 call delete('Xprofile_func.vim') 193 call delete('Xprofile_func.log') 194endfunc 195 196func Test_profile_func_with_trycatch() 197 let lines = [ 198 \ "func! Foo1()", 199 \ " try", 200 \ " let x = 0", 201 \ " catch", 202 \ " let x = 1", 203 \ " finally", 204 \ " let x = 2", 205 \ " endtry", 206 \ "endfunc", 207 \ "func! Foo2()", 208 \ " try", 209 \ " throw 0", 210 \ " catch", 211 \ " let x = 1", 212 \ " finally", 213 \ " let x = 2", 214 \ " endtry", 215 \ "endfunc", 216 \ "func! Foo3()", 217 \ " try", 218 \ " throw 0", 219 \ " catch", 220 \ " throw 1", 221 \ " finally", 222 \ " let x = 2", 223 \ " endtry", 224 \ "endfunc", 225 \ "call Foo1()", 226 \ "call Foo2()", 227 \ "try", 228 \ " call Foo3()", 229 \ "catch", 230 \ "endtry", 231 \ ] 232 233 call writefile(lines, 'Xprofile_func.vim') 234 call system(v:progpath 235 \ . ' -es -u NONE -U NONE -i NONE --noplugin' 236 \ . ' -c "profile start Xprofile_func.log"' 237 \ . ' -c "profile func Foo*"' 238 \ . ' -c "so Xprofile_func.vim"' 239 \ . ' -c "qall!"') 240 call assert_equal(0, v:shell_error) 241 242 let lines = readfile('Xprofile_func.log') 243 244 " - Foo1() should pass 'try' 'finally' blocks. 245 " - Foo2() should pass 'catch' 'finally' blocks. 246 " - Foo3() should not pass 'endtry'. 247 call assert_equal(54, len(lines)) 248 249 call assert_equal('FUNCTION Foo1()', lines[0]) 250 call assert_equal('Called 1 time', lines[1]) 251 call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[2]) 252 call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[3]) 253 call assert_equal('', lines[4]) 254 call assert_equal('count total (s) self (s)', lines[5]) 255 call assert_match('^\s*1\s\+.*\stry$', lines[6]) 256 call assert_match('^\s*1\s\+.*\s let x = 0$', lines[7]) 257 call assert_match( '^\s\+catch$', lines[8]) 258 call assert_match( '^\s\+let x = 1$', lines[9]) 259 call assert_match('^\s*1\s\+.*\sfinally$', lines[10]) 260 call assert_match('^\s*1\s\+.*\s let x = 2$', lines[11]) 261 call assert_match('^\s*1\s\+.*\sendtry$', lines[12]) 262 call assert_equal('', lines[13]) 263 call assert_equal('FUNCTION Foo2()', lines[14]) 264 call assert_equal('Called 1 time', lines[15]) 265 call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[16]) 266 call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[17]) 267 call assert_equal('', lines[18]) 268 call assert_equal('count total (s) self (s)', lines[19]) 269 call assert_match('^\s*1\s\+.*\stry$', lines[20]) 270 call assert_match('^\s*1\s\+.*\s throw 0$', lines[21]) 271 call assert_match('^\s*1\s\+.*\scatch$', lines[22]) 272 call assert_match('^\s*1\s\+.*\s let x = 1$', lines[23]) 273 call assert_match('^\s*1\s\+.*\sfinally$', lines[24]) 274 call assert_match('^\s*1\s\+.*\s let x = 2$', lines[25]) 275 call assert_match('^\s*1\s\+.*\sendtry$', lines[26]) 276 call assert_equal('', lines[27]) 277 call assert_equal('FUNCTION Foo3()', lines[28]) 278 call assert_equal('Called 1 time', lines[29]) 279 call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[30]) 280 call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[31]) 281 call assert_equal('', lines[32]) 282 call assert_equal('count total (s) self (s)', lines[33]) 283 call assert_match('^\s*1\s\+.*\stry$', lines[34]) 284 call assert_match('^\s*1\s\+.*\s throw 0$', lines[35]) 285 call assert_match('^\s*1\s\+.*\scatch$', lines[36]) 286 call assert_match('^\s*1\s\+.*\s throw 1$', lines[37]) 287 call assert_match('^\s*1\s\+.*\sfinally$', lines[38]) 288 call assert_match('^\s*1\s\+.*\s let x = 2$', lines[39]) 289 call assert_match( '^\s\+endtry$', lines[40]) 290 call assert_equal('', lines[41]) 291 call assert_equal('FUNCTIONS SORTED ON TOTAL TIME', lines[42]) 292 call assert_equal('count total (s) self (s) function', lines[43]) 293 call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[44]) 294 call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[45]) 295 call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[46]) 296 call assert_equal('', lines[47]) 297 call assert_equal('FUNCTIONS SORTED ON SELF TIME', lines[48]) 298 call assert_equal('count total (s) self (s) function', lines[49]) 299 call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[50]) 300 call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[51]) 301 call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[52]) 302 call assert_equal('', lines[53]) 303 304 call delete('Xprofile_func.vim') 305 call delete('Xprofile_func.log') 306endfunc 307 308func Test_profile_file() 309 let lines = [ 310 \ 'func! Foo()', 311 \ 'endfunc', 312 \ 'for i in range(10)', 313 \ ' " a comment', 314 \ ' call Foo()', 315 \ 'endfor', 316 \ 'call Foo()', 317 \ ] 318 319 call writefile(lines, 'Xprofile_file.vim') 320 call system(v:progpath 321 \ . ' -es --clean' 322 \ . ' -c "profile start Xprofile_file.log"' 323 \ . ' -c "profile file Xprofile_file.vim"' 324 \ . ' -c "so Xprofile_file.vim"' 325 \ . ' -c "so Xprofile_file.vim"' 326 \ . ' -c "qall!"') 327 call assert_equal(0, v:shell_error) 328 329 let lines = readfile('Xprofile_file.log') 330 331 call assert_equal(14, len(lines)) 332 333 call assert_match('^SCRIPT .*Xprofile_file.vim$', lines[0]) 334 call assert_equal('Sourced 2 times', lines[1]) 335 call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[2]) 336 call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[3]) 337 call assert_equal('', lines[4]) 338 call assert_equal('count total (s) self (s)', lines[5]) 339 call assert_match(' 2 0.\d\+ func! Foo()', lines[6]) 340 call assert_equal(' endfunc', lines[7]) 341 " Loop iterates 10 times. Since script runs twice, body executes 20 times. 342 " First line of loop executes one more time than body to detect end of loop. 343 call assert_match('^\s*22\s\+\d\+\.\d\+\s\+for i in range(10)$', lines[8]) 344 call assert_equal(' " a comment', lines[9]) 345 " if self and total are equal we only get one number 346 call assert_match('^\s*20\s\+\(\d\+\.\d\+\s\+\)\=\d\+\.\d\+\s\+call Foo()$', lines[10]) 347 call assert_match('^\s*22\s\+\d\+\.\d\+\s\+endfor$', lines[11]) 348 " if self and total are equal we only get one number 349 call assert_match('^\s*2\s\+\(\d\+\.\d\+\s\+\)\=\d\+\.\d\+\s\+call Foo()$', lines[12]) 350 call assert_equal('', lines[13]) 351 352 call delete('Xprofile_file.vim') 353 call delete('Xprofile_file.log') 354endfunc 355 356func Test_profile_file_with_cont() 357 let lines = [ 358 \ 'echo "hello', 359 \ ' \ world"', 360 \ 'echo "foo ', 361 \ ' \bar"', 362 \ ] 363 364 call writefile(lines, 'Xprofile_file.vim') 365 call system(v:progpath 366 \ . ' -es --clean' 367 \ . ' -c "profile start Xprofile_file.log"' 368 \ . ' -c "profile file Xprofile_file.vim"' 369 \ . ' -c "so Xprofile_file.vim"' 370 \ . ' -c "qall!"') 371 call assert_equal(0, v:shell_error) 372 373 let lines = readfile('Xprofile_file.log') 374 call assert_equal(11, len(lines)) 375 376 call assert_match('^SCRIPT .*Xprofile_file.vim$', lines[0]) 377 call assert_equal('Sourced 1 time', lines[1]) 378 call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[2]) 379 call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[3]) 380 call assert_equal('', lines[4]) 381 call assert_equal('count total (s) self (s)', lines[5]) 382 call assert_match(' 1 0.\d\+ echo "hello', lines[6]) 383 call assert_equal(' \ world"', lines[7]) 384 call assert_match(' 1 0.\d\+ echo "foo ', lines[8]) 385 call assert_equal(' \bar"', lines[9]) 386 call assert_equal('', lines[10]) 387 388 call delete('Xprofile_file.vim') 389 call delete('Xprofile_file.log') 390endfunc 391 392func Test_profile_completion() 393 call feedkeys(":profile \<C-A>\<C-B>\"\<CR>", 'tx') 394 call assert_equal('"profile continue file func pause start', @:) 395 396 call feedkeys(":profile start test_prof\<C-A>\<C-B>\"\<CR>", 'tx') 397 call assert_match('^"profile start.* test_profile\.vim', @:) 398endfunc 399 400func Test_profile_errors() 401 call assert_fails("profile func Foo", 'E750:') 402 call assert_fails("profile pause", 'E750:') 403 call assert_fails("profile continue", 'E750:') 404endfunc 405 406func Test_profile_truncate_mbyte() 407 if !has('multi_byte') || &enc !=# 'utf-8' 408 return 409 endif 410 411 let lines = [ 412 \ 'scriptencoding utf-8', 413 \ 'func! Foo()', 414 \ ' return [', 415 \ ' \ "' . join(map(range(0x4E00, 0x4E00 + 340), 'nr2char(v:val)'), '') . '",', 416 \ ' \ "' . join(map(range(0x4F00, 0x4F00 + 340), 'nr2char(v:val)'), '') . '",', 417 \ ' \ ]', 418 \ 'endfunc', 419 \ 'call Foo()', 420 \ ] 421 422 call writefile(lines, 'Xprofile_file.vim') 423 call system(v:progpath 424 \ . ' -es --clean --cmd "set enc=utf-8"' 425 \ . ' -c "profile start Xprofile_file.log"' 426 \ . ' -c "profile file Xprofile_file.vim"' 427 \ . ' -c "so Xprofile_file.vim"' 428 \ . ' -c "qall!"') 429 call assert_equal(0, v:shell_error) 430 431 split Xprofile_file.log 432 if &fenc != '' 433 call assert_equal('utf-8', &fenc) 434 endif 435 /func! Foo() 436 let lnum = line('.') 437 call assert_match('^\s*return \[$', getline(lnum + 1)) 438 call assert_match("\u4F52$", getline(lnum + 2)) 439 call assert_match("\u5052$", getline(lnum + 3)) 440 call assert_match('^\s*\\ \]$', getline(lnum + 4)) 441 bwipe! 442 443 call delete('Xprofile_file.vim') 444 call delete('Xprofile_file.log') 445endfunc 446 447func Test_profdel_func() 448 let lines = [ 449 \ 'profile start Xprofile_file.log', 450 \ 'func! Foo1()', 451 \ 'endfunc', 452 \ 'func! Foo2()', 453 \ 'endfunc', 454 \ 'func! Foo3()', 455 \ 'endfunc', 456 \ '', 457 \ 'profile func Foo1', 458 \ 'profile func Foo2', 459 \ 'call Foo1()', 460 \ 'call Foo2()', 461 \ '', 462 \ 'profile func Foo3', 463 \ 'profdel func Foo2', 464 \ 'profdel func Foo3', 465 \ 'call Foo1()', 466 \ 'call Foo2()', 467 \ 'call Foo3()' ] 468 call writefile(lines, 'Xprofile_file.vim') 469 call system(v:progpath . ' -es --clean -c "so Xprofile_file.vim" -c q') 470 call assert_equal(0, v:shell_error) 471 472 let lines = readfile('Xprofile_file.log') 473 call assert_equal(24, len(lines)) 474 475 " Check that: 476 " - Foo1() is called twice (profdel not invoked) 477 " - Foo2() is called once (profdel invoked after it was called) 478 " - Foo3() is not called (profdel invoked before it was called) 479 call assert_equal('FUNCTION Foo1()', lines[0]) 480 call assert_equal('Called 2 times', lines[1]) 481 call assert_equal('FUNCTION Foo2()', lines[7]) 482 call assert_equal('Called 1 time', lines[8]) 483 call assert_equal('FUNCTIONS SORTED ON TOTAL TIME', lines[14]) 484 call assert_equal('FUNCTIONS SORTED ON SELF TIME', lines[19]) 485 486 call delete('Xprofile_file.vim') 487 call delete('Xprofile_file.log') 488endfunc 489 490func Test_profdel_star() 491 " Foo() is invoked once before and once after 'profdel *'. 492 " So profiling should report it only once. 493 let lines = [ 494 \ 'profile start Xprofile_file.log', 495 \ 'func! Foo()', 496 \ 'endfunc', 497 \ 'profile func Foo', 498 \ 'call Foo()', 499 \ 'profdel *', 500 \ 'call Foo()' ] 501 call writefile(lines, 'Xprofile_file.vim') 502 call system(v:progpath . ' -es --clean -c "so Xprofile_file.vim" -c q') 503 call assert_equal(0, v:shell_error) 504 505 let lines = readfile('Xprofile_file.log') 506 call assert_equal(15, len(lines)) 507 508 call assert_equal('FUNCTION Foo()', lines[0]) 509 call assert_equal('Called 1 time', lines[1]) 510 call assert_equal('FUNCTIONS SORTED ON TOTAL TIME', lines[7]) 511 call assert_equal('FUNCTIONS SORTED ON SELF TIME', lines[11]) 512 513 call delete('Xprofile_file.vim') 514 call delete('Xprofile_file.log') 515endfunc 516