# HG changeset patch # User Bram Moolenaar # Date 1596619803 -7200 # Node ID 792398a9fe399dca8b522a5a9dc223306eb7d8a5 # Parent e55aba8c214647bcbf58c1dfae5d3e6120b2c078 patch 8.2.1366: test 49 is old style Commit: https://github.com/vim/vim/commit/a6296200bd5191bab7efcdcc16c9e79eb498e8e0 Author: Bram Moolenaar Date: Wed Aug 5 11:23:13 2020 +0200 patch 8.2.1366: test 49 is old style Problem: Test 49 is old style. Solution: Convert several tests to new style. (Yegappan Lakshmanan, closes #6629) diff --git a/src/testdir/script_util.vim b/src/testdir/script_util.vim new file mode 100644 --- /dev/null +++ b/src/testdir/script_util.vim @@ -0,0 +1,69 @@ +" Functions shared by the tests for Vim Script + +" Commands to track the execution path of a script +com! XpathINIT let g:Xpath = '' +com! -nargs=1 -bar Xpath let g:Xpath ..= +com! XloopINIT let g:Xloop = 1 +com! -nargs=1 -bar Xloop let g:Xpath ..= .. g:Xloop +com! XloopNEXT let g:Xloop += 1 + +" MakeScript() - Make a script file from a function. {{{2 +" +" Create a script that consists of the body of the function a:funcname. +" Replace any ":return" by a ":finish", any argument variable by a global +" variable, and every ":call" by a ":source" for the next following argument +" in the variable argument list. This function is useful if similar tests are +" to be made for a ":return" from a function call or a ":finish" in a script +" file. +func MakeScript(funcname, ...) + let script = tempname() + execute "redir! >" . script + execute "function" a:funcname + redir END + execute "edit" script + " Delete the "function" and the "endfunction" lines. Do not include the + " word "function" in the pattern since it might be translated if LANG is + " set. When MakeScript() is being debugged, this deletes also the debugging + " output of its line 3 and 4. + exec '1,/.*' . a:funcname . '(.*)/d' + /^\d*\s*endfunction\>/,$d + %s/^\d*//e + %s/return/finish/e + %s/\ 0 + let cnt = cnt + 1 + s/\) + diff --git a/src/testdir/test49.ok b/src/testdir/test49.ok --- a/src/testdir/test49.ok +++ b/src/testdir/test49.ok @@ -1,25 +1,4 @@ Results of test49.vim: -*** Test 18: OK (67224583) -*** Test 19: OK (69275973) -*** Test 20: OK (1874575085) -*** Test 21: OK (147932225) -*** Test 22: OK (4161) -*** Test 23: OK (49) -*** Test 24: OK (41) -*** Test 27: OK (1996459) -*** Test 28: OK (1996459) -*** Test 29: OK (170428555) -*** Test 30: OK (190905173) -*** Test 31: OK (190905173) -*** Test 34: OK (2146584868) -*** Test 35: OK (2146584868) -*** Test 36: OK (1071644672) -*** Test 37: OK (1071644672) -*** Test 38: OK (357908480) -*** Test 39: OK (357908480) -*** Test 40: OK (357908480) -*** Test 49: OK (179000669) -*** Test 50: OK (363550045) *** Test 52: OK (1247112011) *** Test 53: OK (131071) *** Test 54: OK (2047) diff --git a/src/testdir/test49.vim b/src/testdir/test49.vim --- a/src/testdir/test49.vim +++ b/src/testdir/test49.vim @@ -1,6 +1,6 @@ " Vim script language tests " Author: Servatius Brandt -" Last Change: 2019 Nov 03 +" Last Change: 2020 Jun 07 "------------------------------------------------------------------------------- " Test environment {{{1 @@ -607,1647 +607,10 @@ com! -nargs=1 -bar ExecAsScript call Exe " END_OF_TEST_ENVIRONMENT - do not change or remove this line. - -" Tests 1 to 17 were moved to test_vimscript.vim -let Xtest = 18 - -"------------------------------------------------------------------------------- -" Test 18: Interrupt (Ctrl-C pressed) {{{1 -" -" On an interrupt, the script processing is terminated immediately. -"------------------------------------------------------------------------------- - -XpathINIT - -if ExtraVim() - if 1 - Xpath 1 " X: 1 - while 1 - Xpath 2 " X: 2 - if 1 - Xpath 4 " X: 4 - "INTERRUPT - Xpath 8 " X: 0 - break - finish - endif | Xpath 16 " X: 0 - Xpath 32 " X: 0 - endwhile | Xpath 64 " X: 0 - Xpath 128 " X: 0 - endif | Xpath 256 " X: 0 - Xpath 512 " X: 0 -endif - -if ExtraVim() - try - Xpath 1024 " X: 1024 - "INTERRUPT - Xpath 2048 " X: 0 - endtry | Xpath 4096 " X: 0 - Xpath 8192 " X: 0 -endif - -if ExtraVim() - function! F() - if 1 - Xpath 16384 " X: 16384 - while 1 - Xpath 32768 " X: 32768 - if 1 - Xpath 65536 " X: 65536 - "INTERRUPT - Xpath 131072 " X: 0 - break - return - endif | Xpath 262144 " X: 0 - Xpath Xpath 524288 " X: 0 - endwhile | Xpath 1048576 " X: 0 - Xpath Xpath 2097152 " X: 0 - endif | Xpath Xpath 4194304 " X: 0 - Xpath Xpath 8388608 " X: 0 - endfunction - - call F() | Xpath 16777216 " X: 0 - Xpath 33554432 " X: 0 -endif - -if ExtraVim() - function! G() - try - Xpath 67108864 " X: 67108864 - "INTERRUPT - Xpath 134217728 " X: 0 - endtry | Xpath 268435456 " X: 0 - Xpath 536870912 " X: 0 - endfunction - - call G() | Xpath 1073741824 " X: 0 - " The Xpath command does not accept 2^31 (negative); display explicitly: - exec "!echo 2147483648 >>" . g:ExtraVimResult - " X: 0 -endif - -Xcheck 67224583 - - -"------------------------------------------------------------------------------- -" Test 19: Aborting on errors inside :try/:endtry {{{1 -" -" An error in a command dynamically enclosed in a :try/:endtry region -" aborts script processing immediately. It does not matter whether -" the failing command is outside or inside a function and whether a -" function has an "abort" attribute. -"------------------------------------------------------------------------------- - -XpathINIT - -if ExtraVim() - function! F() abort - Xpath 1 " X: 1 - asdf - Xpath 2 " X: 0 - endfunction - - try - Xpath 4 " X: 4 - call F() - Xpath 8 " X: 0 - endtry | Xpath 16 " X: 0 - Xpath 32 " X: 0 -endif - -if ExtraVim() - function! G() - Xpath 64 " X: 64 - asdf - Xpath 128 " X: 0 - endfunction - - try - Xpath 256 " X: 256 - call G() - Xpath 512 " X: 0 - endtry | Xpath 1024 " X: 0 - Xpath 2048 " X: 0 -endif - -if ExtraVim() - try - Xpath 4096 " X: 4096 - asdf - Xpath 8192 " X: 0 - endtry | Xpath 16384 " X: 0 - Xpath 32768 " X: 0 -endif - -if ExtraVim() - if 1 - try - Xpath 65536 " X: 65536 - asdf - Xpath 131072 " X: 0 - endtry | Xpath 262144 " X: 0 - endif | Xpath 524288 " X: 0 - Xpath 1048576 " X: 0 -endif - -if ExtraVim() - let p = 1 - while p - let p = 0 - try - Xpath 2097152 " X: 2097152 - asdf - Xpath 4194304 " X: 0 - endtry | Xpath 8388608 " X: 0 - endwhile | Xpath 16777216 " X: 0 - Xpath 33554432 " X: 0 -endif - -if ExtraVim() - let p = 1 - while p - let p = 0 -" try - Xpath 67108864 " X: 67108864 - endwhile | Xpath 134217728 " X: 0 - Xpath 268435456 " X: 0 -endif - -Xcheck 69275973 -"------------------------------------------------------------------------------- -" Test 20: Aborting on errors after :try/:endtry {{{1 -" -" When an error occurs after the last active :try/:endtry region has -" been left, termination behavior is as if no :try/:endtry has been -" seen. -"------------------------------------------------------------------------------- - -XpathINIT - -if ExtraVim() - let p = 1 - while p - let p = 0 - try - Xpath 1 " X: 1 - endtry - asdf - endwhile | Xpath 2 " X: 0 - Xpath 4 " X: 4 -endif - -if ExtraVim() - while 1 - try - Xpath 8 " X: 8 - break - Xpath 16 " X: 0 - endtry - endwhile - Xpath 32 " X: 32 - asdf - Xpath 64 " X: 64 -endif - -if ExtraVim() - while 1 - try - Xpath 128 " X: 128 - break - Xpath 256 " X: 0 - finally - Xpath 512 " X: 512 - endtry - endwhile - Xpath 1024 " X: 1024 - asdf - Xpath 2048 " X: 2048 -endif - -if ExtraVim() - while 1 - try - Xpath 4096 " X: 4096 - finally - Xpath 8192 " X: 8192 - break - Xpath 16384 " X: 0 - endtry - endwhile - Xpath 32768 " X: 32768 - asdf - Xpath 65536 " X: 65536 -endif - -if ExtraVim() - let p = 1 - while p - let p = 0 - try - Xpath 131072 " X: 131072 - continue - Xpath 262144 " X: 0 - endtry - endwhile - Xpath 524288 " X: 524288 - asdf - Xpath 1048576 " X: 1048576 -endif - -if ExtraVim() - let p = 1 - while p - let p = 0 - try - Xpath 2097152 " X: 2097152 - continue - Xpath 4194304 " X: 0 - finally - Xpath 8388608 " X: 8388608 - endtry - endwhile - Xpath 16777216 " X: 16777216 - asdf - Xpath 33554432 " X: 33554432 -endif - -if ExtraVim() - let p = 1 - while p - let p = 0 - try - Xpath 67108864 " X: 67108864 - finally - Xpath 134217728 " X: 134217728 - continue - Xpath 268435456 " X: 0 - endtry - endwhile - Xpath 536870912 " X: 536870912 - asdf - Xpath 1073741824 " X: 1073741824 -endif - -Xcheck 1874575085 - - -"------------------------------------------------------------------------------- -" Test 21: :finally for :try after :continue/:break/:return/:finish {{{1 -" -" If a :try conditional stays inactive due to a preceding :continue, -" :break, :return, or :finish, its :finally clause should not be -" executed. -"------------------------------------------------------------------------------- - -XpathINIT - -if ExtraVim() - function F() - let loops = 2 - XloopINIT! 1 256 - while loops > 0 - XloopNEXT - let loops = loops - 1 - try - if loops == 1 - Xloop 1 " X: 1 - continue - Xloop 2 " X: 0 - elseif loops == 0 - Xloop 4 " X: 4*256 - break - Xloop 8 " X: 0 - endif - - try " inactive - Xloop 16 " X: 0 - finally - Xloop 32 " X: 0 - endtry - finally - Xloop 64 " X: 64 + 64*256 - endtry - Xloop 128 " X: 0 - endwhile - - try - Xpath 65536 " X: 65536 - return - Xpath 131072 " X: 0 - try " inactive - Xpath 262144 " X: 0 - finally - Xpath 524288 " X: 0 - endtry - finally - Xpath 1048576 " X: 1048576 - endtry - Xpath 2097152 " X: 0 - endfunction - - try - Xpath 4194304 " X: 4194304 - call F() - Xpath 8388608 " X: 8388608 - finish - Xpath 16777216 " X: 0 - try " inactive - Xpath 33554432 " X: 0 - finally - Xpath 67108864 " X: 0 - endtry - finally - Xpath 134217728 " X: 134217728 - endtry - Xpath 268435456 " X: 0 -endif - -Xcheck 147932225 - - -"------------------------------------------------------------------------------- -" Test 22: :finally for a :try after an error/interrupt/:throw {{{1 -" -" If a :try conditional stays inactive due to a preceding error or -" interrupt or :throw, its :finally clause should not be executed. -"------------------------------------------------------------------------------- - -XpathINIT - -if ExtraVim() - function! Error() - try - asdf " aborting error, triggering error exception - endtry - endfunction - - Xpath 1 " X: 1 - call Error() - Xpath 2 " X: 0 - - if 1 " not active due to error - try " not active since :if inactive - Xpath 4 " X: 0 - finally - Xpath 8 " X: 0 - endtry - endif - - try " not active due to error - Xpath 16 " X: 0 - finally - Xpath 32 " X: 0 - endtry -endif - -if ExtraVim() - function! Interrupt() - try - "INTERRUPT " triggering interrupt exception - endtry - endfunction - - Xpath 64 " X: 64 - call Interrupt() - Xpath 128 " X: 0 - - if 1 " not active due to interrupt - try " not active since :if inactive - Xpath 256 " X: 0 - finally - Xpath 512 " X: 0 - endtry - endif - - try " not active due to interrupt - Xpath 1024 " X: 0 - finally - Xpath 2048 " X: 0 - endtry -endif - -if ExtraVim() - function! Throw() - throw "xyz" - endfunction - - Xpath 4096 " X: 4096 - call Throw() - Xpath 8192 " X: 0 - - if 1 " not active due to :throw - try " not active since :if inactive - Xpath 16384 " X: 0 - finally - Xpath 32768 " X: 0 - endtry - endif - - try " not active due to :throw - Xpath 65536 " X: 0 - finally - Xpath 131072 " X: 0 - endtry -endif - -Xcheck 4161 - - -"------------------------------------------------------------------------------- -" Test 23: :catch clauses for a :try after a :throw {{{1 -" -" If a :try conditional stays inactive due to a preceding :throw, -" none of its :catch clauses should be executed. -"------------------------------------------------------------------------------- - -XpathINIT - -if ExtraVim() - try - Xpath 1 " X: 1 - throw "xyz" - Xpath 2 " X: 0 - - if 1 " not active due to :throw - try " not active since :if inactive - Xpath 4 " X: 0 - catch /xyz/ - Xpath 8 " X: 0 - endtry - endif - catch /xyz/ - Xpath 16 " X: 16 - endtry - - Xpath 32 " X: 32 - throw "abc" - Xpath 64 " X: 0 - - try " not active due to :throw - Xpath 128 " X: 0 - catch /abc/ - Xpath 256 " X: 0 - endtry -endif - -Xcheck 49 - - -"------------------------------------------------------------------------------- -" Test 24: :endtry for a :try after a :throw {{{1 -" -" If a :try conditional stays inactive due to a preceding :throw, -" its :endtry should not rethrow the exception to the next surrounding -" active :try conditional. -"------------------------------------------------------------------------------- - -XpathINIT - -if ExtraVim() - try " try 1 - try " try 2 - Xpath 1 " X: 1 - throw "xyz" " makes try 2 inactive - Xpath 2 " X: 0 - - try " try 3 - Xpath 4 " X: 0 - endtry " no rethrow to try 1 - catch /xyz/ " should catch although try 2 inactive - Xpath 8 " X: 8 - endtry - catch /xyz/ " try 1 active, but exception already caught - Xpath 16 " X: 0 - endtry - Xpath 32 " X: 32 -endif - -Xcheck 41 - -" Tests 25 and 26 were moved to test_trycatch.vim -let Xtest = 27 - - -"------------------------------------------------------------------------------- -" Test 27: Executing :finally clauses after :return {{{1 -" -" For a :return command dynamically enclosed in a :try/:endtry region, -" :finally clauses are executed and the called function is ended. -"------------------------------------------------------------------------------- - -XpathINIT - -function! F() - try - Xpath 1 " X: 1 - try - Xpath 2 " X: 2 - return - Xpath 4 " X: 0 - finally - Xpath 8 " X: 8 - endtry - Xpath 16 " X: 0 - finally - Xpath 32 " X: 32 - endtry - Xpath 64 " X: 0 -endfunction - -function! G() - try - Xpath 128 " X: 128 - return - Xpath 256 " X: 0 - finally - Xpath 512 " X: 512 - call F() - Xpath 1024 " X: 1024 - endtry - Xpath 2048 " X: 0 -endfunction - -function! H() - try - Xpath 4096 " X: 4096 - call G() - Xpath 8192 " X: 8192 - finally - Xpath 16384 " X: 16384 - return - Xpath 32768 " X: 0 - endtry - Xpath 65536 " X: 0 -endfunction - -try - Xpath 131072 " X: 131072 - call H() - Xpath 262144 " X: 262144 -finally - Xpath 524288 " X: 524288 -endtry -Xpath 1048576 " X: 1048576 - -Xcheck 1996459 - -" Leave F, G, and H for execution as scripts in the next test. - - -"------------------------------------------------------------------------------- -" Test 28: Executing :finally clauses after :finish {{{1 -" -" For a :finish command dynamically enclosed in a :try/:endtry region, -" :finally clauses are executed and the sourced file is finished. -" -" This test executes the bodies of the functions F, G, and H from the -" previous test as script files (:return replaced by :finish). -"------------------------------------------------------------------------------- - -XpathINIT - -let scriptF = MakeScript("F") " X: 1 + 2 + 8 + 32 -let scriptG = MakeScript("G", scriptF) " X: 128 + 512 + 1024 -let scriptH = MakeScript("H", scriptG) " X: 4096 + 8192 + 16384 - -try - Xpath 131072 " X: 131072 - exec "source" scriptH - Xpath 262144 " X: 262144 -finally - Xpath 524288 " X: 524288 -endtry -Xpath 1048576 " X: 1048576 - -call delete(scriptF) -call delete(scriptG) -call delete(scriptH) -unlet scriptF scriptG scriptH -delfunction F -delfunction G -delfunction H - -Xcheck 1996459 - - -"------------------------------------------------------------------------------- -" Test 29: Executing :finally clauses on errors {{{1 -" -" After an error in a command dynamically enclosed in a :try/:endtry -" region, :finally clauses are executed and the script processing is -" terminated. -"------------------------------------------------------------------------------- - -XpathINIT - -if ExtraVim() - function! F() - while 1 - try - Xpath 1 " X: 1 - while 1 - try - Xpath 2 " X: 2 - asdf " error - Xpath 4 " X: 0 - finally - Xpath 8 " X: 8 - endtry | Xpath 16 " X: 0 - Xpath 32 " X: 0 - break - endwhile - Xpath 64 " X: 0 - finally - Xpath 128 " X: 128 - endtry | Xpath 256 " X: 0 - Xpath 512 " X: 0 - break - endwhile - Xpath 1024 " X: 0 - endfunction - - while 1 - try - Xpath 2048 " X: 2048 - while 1 - call F() - Xpath 4096 " X: 0 - break - endwhile | Xpath 8192 " X: 0 - Xpath 16384 " X: 0 - finally - Xpath 32768 " X: 32768 - endtry | Xpath 65536 " X: 0 - endwhile | Xpath 131072 " X: 0 - Xpath 262144 " X: 0 -endif - -if ExtraVim() - function! G() abort - if 1 - try - Xpath 524288 " X: 524288 - asdf " error - Xpath 1048576 " X: 0 - finally - Xpath 2097152 " X: 2097152 - endtry | Xpath 4194304 " X: 0 - endif | Xpath 8388608 " X: 0 - Xpath 16777216 " X: 0 - endfunction - - if 1 - try - Xpath 33554432 " X: 33554432 - call G() - Xpath 67108864 " X: 0 - finally - Xpath 134217728 " X: 134217728 - endtry | Xpath 268435456 " X: 0 - endif | Xpath 536870912 " X: 0 - Xpath 1073741824 " X: 0 -endif - -Xcheck 170428555 - - -"------------------------------------------------------------------------------- -" Test 30: Executing :finally clauses on interrupt {{{1 -" -" After an interrupt in a command dynamically enclosed in -" a :try/:endtry region, :finally clauses are executed and the -" script processing is terminated. -"------------------------------------------------------------------------------- - -XpathINIT - -if ExtraVim() - XloopINIT 1 16 - - function! F() - try - Xloop 1 " X: 1 + 1*16 - "INTERRUPT - Xloop 2 " X: 0 - finally - Xloop 4 " X: 4 + 4*16 - endtry - Xloop 8 " X: 0 - endfunction - - try - Xpath 256 " X: 256 - try - Xpath 512 " X: 512 - "INTERRUPT - Xpath 1024 " X: 0 - finally - Xpath 2048 " X: 2048 - try - Xpath 4096 " X: 4096 - try - Xpath 8192 " X: 8192 - finally - Xpath 16384 " X: 16384 - try - Xpath 32768 " X: 32768 - "INTERRUPT - Xpath 65536 " X: 0 - endtry - Xpath 131072 " X: 0 - endtry - Xpath 262144 " X: 0 - endtry - Xpath 524288 " X: 0 - endtry - Xpath 1048576 " X: 0 - finally - Xpath 2097152 " X: 2097152 - try - Xpath 4194304 " X: 4194304 - call F() - Xpath 8388608 " X: 0 - finally - Xpath 16777216 " X: 16777216 - try - Xpath 33554432 " X: 33554432 - XloopNEXT - ExecAsScript F - Xpath 67108864 " X: 0 - finally - Xpath 134217728 " X: 134217728 - endtry - Xpath 268435456 " X: 0 - endtry - Xpath 536870912 " X: 0 - endtry - Xpath 1073741824 " X: 0 -endif - -Xcheck 190905173 - - -"------------------------------------------------------------------------------- -" Test 31: Executing :finally clauses after :throw {{{1 -" -" After a :throw dynamically enclosed in a :try/:endtry region, -" :finally clauses are executed and the script processing is -" terminated. -"------------------------------------------------------------------------------- - -XpathINIT - -if ExtraVim() - XloopINIT 1 16 - - function! F() - try - Xloop 1 " X: 1 + 1*16 - throw "exception" - Xloop 2 " X: 0 - finally - Xloop 4 " X: 4 + 4*16 - endtry - Xloop 8 " X: 0 - endfunction - - try - Xpath 256 " X: 256 - try - Xpath 512 " X: 512 - throw "exception" - Xpath 1024 " X: 0 - finally - Xpath 2048 " X: 2048 - try - Xpath 4096 " X: 4096 - try - Xpath 8192 " X: 8192 - finally - Xpath 16384 " X: 16384 - try - Xpath 32768 " X: 32768 - throw "exception" - Xpath 65536 " X: 0 - endtry - Xpath 131072 " X: 0 - endtry - Xpath 262144 " X: 0 - endtry - Xpath 524288 " X: 0 - endtry - Xpath 1048576 " X: 0 - finally - Xpath 2097152 " X: 2097152 - try - Xpath 4194304 " X: 4194304 - call F() - Xpath 8388608 " X: 0 - finally - Xpath 16777216 " X: 16777216 - try - Xpath 33554432 " X: 33554432 - XloopNEXT - ExecAsScript F - Xpath 67108864 " X: 0 - finally - Xpath 134217728 " X: 134217728 - endtry - Xpath 268435456 " X: 0 - endtry - Xpath 536870912 " X: 0 - endtry - Xpath 1073741824 " X: 0 -endif - -Xcheck 190905173 - -" Tests 32 and 33 were moved to test_trycatch.vim -let Xtest = 34 - - -"------------------------------------------------------------------------------- -" Test 34: :finally reason discarded by :continue {{{1 -" -" When a :finally clause is executed due to a :continue, :break, -" :return, :finish, error, interrupt or :throw, the jump reason is -" discarded by a :continue in the finally clause. -"------------------------------------------------------------------------------- - -XpathINIT - -if ExtraVim() - - XloopINIT! 1 8 - - function! C(jump) - XloopNEXT - let loop = 0 - while loop < 2 - let loop = loop + 1 - if loop == 1 - try - if a:jump == "continue" - continue - elseif a:jump == "break" - break - elseif a:jump == "return" || a:jump == "finish" - return - elseif a:jump == "error" - asdf - elseif a:jump == "interrupt" - "INTERRUPT - let dummy = 0 - elseif a:jump == "throw" - throw "abc" - endif - finally - continue " discards jump that caused the :finally - Xloop 1 " X: 0 - endtry - Xloop 2 " X: 0 - elseif loop == 2 - Xloop 4 " X: 4*(1+8+64+512+4096+32768+262144) - endif - endwhile - endfunction - - call C("continue") - Xpath 2097152 " X: 2097152 - call C("break") - Xpath 4194304 " X: 4194304 - call C("return") - Xpath 8388608 " X: 8388608 - let g:jump = "finish" - ExecAsScript C - unlet g:jump - Xpath 16777216 " X: 16777216 - try - call C("error") - Xpath 33554432 " X: 33554432 - finally - Xpath 67108864 " X: 67108864 - try - call C("interrupt") - Xpath 134217728 " X: 134217728 - finally - Xpath 268435456 " X: 268435456 - call C("throw") - Xpath 536870912 " X: 536870912 - endtry - endtry - Xpath 1073741824 " X: 1073741824 - - delfunction C - -endif - -Xcheck 2146584868 - - -"------------------------------------------------------------------------------- -" Test 35: :finally reason discarded by :break {{{1 -" -" When a :finally clause is executed due to a :continue, :break, -" :return, :finish, error, interrupt or :throw, the jump reason is -" discarded by a :break in the finally clause. -"------------------------------------------------------------------------------- - -XpathINIT - -if ExtraVim() - - XloopINIT! 1 8 - - function! B(jump) - XloopNEXT - let loop = 0 - while loop < 2 - let loop = loop + 1 - if loop == 1 - try - if a:jump == "continue" - continue - elseif a:jump == "break" - break - elseif a:jump == "return" || a:jump == "finish" - return - elseif a:jump == "error" - asdf - elseif a:jump == "interrupt" - "INTERRUPT - let dummy = 0 - elseif a:jump == "throw" - throw "abc" - endif - finally - break " discards jump that caused the :finally - Xloop 1 " X: 0 - endtry - elseif loop == 2 - Xloop 2 " X: 0 - endif - endwhile - Xloop 4 " X: 4*(1+8+64+512+4096+32768+262144) - endfunction - - call B("continue") - Xpath 2097152 " X: 2097152 - call B("break") - Xpath 4194304 " X: 4194304 - call B("return") - Xpath 8388608 " X: 8388608 - let g:jump = "finish" - ExecAsScript B - unlet g:jump - Xpath 16777216 " X: 16777216 - try - call B("error") - Xpath 33554432 " X: 33554432 - finally - Xpath 67108864 " X: 67108864 - try - call B("interrupt") - Xpath 134217728 " X: 134217728 - finally - Xpath 268435456 " X: 268435456 - call B("throw") - Xpath 536870912 " X: 536870912 - endtry - endtry - Xpath 1073741824 " X: 1073741824 - - delfunction B - -endif - -Xcheck 2146584868 - - -"------------------------------------------------------------------------------- -" Test 36: :finally reason discarded by :return {{{1 -" -" When a :finally clause is executed due to a :continue, :break, -" :return, :finish, error, interrupt or :throw, the jump reason is -" discarded by a :return in the finally clause. -"------------------------------------------------------------------------------- - -XpathINIT - -if ExtraVim() - - XloopINIT! 1 8 - - function! R(jump, retval) abort - XloopNEXT - let loop = 0 - while loop < 2 - let loop = loop + 1 - if loop == 1 - try - if a:jump == "continue" - continue - elseif a:jump == "break" - break - elseif a:jump == "return" - return - elseif a:jump == "error" - asdf - elseif a:jump == "interrupt" - "INTERRUPT - let dummy = 0 - elseif a:jump == "throw" - throw "abc" - endif - finally - return a:retval " discards jump that caused the :finally - Xloop 1 " X: 0 - endtry - elseif loop == 2 - Xloop 2 " X: 0 - endif - endwhile - Xloop 4 " X: 0 - endfunction - - let sum = -R("continue", -8) - Xpath 2097152 " X: 2097152 - let sum = sum - R("break", -16) - Xpath 4194304 " X: 4194304 - let sum = sum - R("return", -32) - Xpath 8388608 " X: 8388608 - try - let sum = sum - R("error", -64) - Xpath 16777216 " X: 16777216 - finally - Xpath 33554432 " X: 33554432 - try - let sum = sum - R("interrupt", -128) - Xpath 67108864 " X: 67108864 - finally - Xpath 134217728 " X: 134217728 - let sum = sum - R("throw", -256) - Xpath 268435456 " X: 268435456 - endtry - endtry - Xpath 536870912 " X: 536870912 - - let expected = 8 + 16 + 32 + 64 + 128 + 256 - if sum != expected - Xpath 1073741824 " X: 0 - Xout "sum =" . sum . ", expected: " . expected - endif - - unlet sum expected - delfunction R - -endif - -Xcheck 1071644672 - - -"------------------------------------------------------------------------------- -" Test 37: :finally reason discarded by :finish {{{1 -" -" When a :finally clause is executed due to a :continue, :break, -" :return, :finish, error, interrupt or :throw, the jump reason is -" discarded by a :finish in the finally clause. -"------------------------------------------------------------------------------- - -XpathINIT - -if ExtraVim() - - XloopINIT! 1 8 - - function! F(jump) " not executed as function, transformed to a script - XloopNEXT - let loop = 0 - while loop < 2 - let loop = loop + 1 - if loop == 1 - try - if a:jump == "continue" - continue - elseif a:jump == "break" - break - elseif a:jump == "finish" - finish - elseif a:jump == "error" - asdf - elseif a:jump == "interrupt" - "INTERRUPT - let dummy = 0 - elseif a:jump == "throw" - throw "abc" - endif - finally - finish " discards jump that caused the :finally - Xloop 1 " X: 0 - endtry - elseif loop == 2 - Xloop 2 " X: 0 - endif - endwhile - Xloop 4 " X: 0 - endfunction - - let scriptF = MakeScript("F") - delfunction F - - let g:jump = "continue" - exec "source" scriptF - Xpath 2097152 " X: 2097152 - let g:jump = "break" - exec "source" scriptF - Xpath 4194304 " X: 4194304 - let g:jump = "finish" - exec "source" scriptF - Xpath 8388608 " X: 8388608 - try - let g:jump = "error" - exec "source" scriptF - Xpath 16777216 " X: 16777216 - finally - Xpath 33554432 " X: 33554432 - try - let g:jump = "interrupt" - exec "source" scriptF - Xpath 67108864 " X: 67108864 - finally - Xpath 134217728 " X: 134217728 - try - let g:jump = "throw" - exec "source" scriptF - Xpath 268435456 " X: 268435456 - finally - Xpath 536870912 " X: 536870912 - endtry - endtry - endtry - unlet g:jump - - call delete(scriptF) - unlet scriptF - -endif - -Xcheck 1071644672 - - -"------------------------------------------------------------------------------- -" Test 38: :finally reason discarded by an error {{{1 -" -" When a :finally clause is executed due to a :continue, :break, -" :return, :finish, error, interrupt or :throw, the jump reason is -" discarded by an error in the finally clause. -"------------------------------------------------------------------------------- - -XpathINIT - -if ExtraVim() - - XloopINIT! 1 4 - - function! E(jump) - XloopNEXT - let loop = 0 - while loop < 2 - let loop = loop + 1 - if loop == 1 - try - if a:jump == "continue" - continue - elseif a:jump == "break" - break - elseif a:jump == "return" || a:jump == "finish" - return - elseif a:jump == "error" - asdf - elseif a:jump == "interrupt" - "INTERRUPT - let dummy = 0 - elseif a:jump == "throw" - throw "abc" - endif - finally - asdf " error; discards jump that caused the :finally - endtry - elseif loop == 2 - Xloop 1 " X: 0 - endif - endwhile - Xloop 2 " X: 0 - endfunction - - try - Xpath 16384 " X: 16384 - call E("continue") - Xpath 32768 " X: 0 - finally - try - Xpath 65536 " X: 65536 - call E("break") - Xpath 131072 " X: 0 - finally - try - Xpath 262144 " X: 262144 - call E("return") - Xpath 524288 " X: 0 - finally - try - Xpath 1048576 " X: 1048576 - let g:jump = "finish" - ExecAsScript E - Xpath 2097152 " X: 0 - finally - unlet g:jump - try - Xpath 4194304 " X: 4194304 - call E("error") - Xpath 8388608 " X: 0 - finally - try - Xpath 16777216 " X: 16777216 - call E("interrupt") - Xpath 33554432 " X: 0 - finally - try - Xpath 67108864 " X: 67108864 - call E("throw") - Xpath 134217728 " X: 0 - finally - Xpath 268435456 " X: 268435456 - delfunction E - endtry - endtry - endtry - endtry - endtry - endtry - endtry - Xpath 536870912 " X: 0 - -endif - -Xcheck 357908480 - - -"------------------------------------------------------------------------------- -" Test 39: :finally reason discarded by an interrupt {{{1 -" -" When a :finally clause is executed due to a :continue, :break, -" :return, :finish, error, interrupt or :throw, the jump reason is -" discarded by an interrupt in the finally clause. -"------------------------------------------------------------------------------- - -XpathINIT - -if ExtraVim() - - XloopINIT! 1 4 - - function! I(jump) - XloopNEXT - let loop = 0 - while loop < 2 - let loop = loop + 1 - if loop == 1 - try - if a:jump == "continue" - continue - elseif a:jump == "break" - break - elseif a:jump == "return" || a:jump == "finish" - return - elseif a:jump == "error" - asdf - elseif a:jump == "interrupt" - "INTERRUPT - let dummy = 0 - elseif a:jump == "throw" - throw "abc" - endif - finally - "INTERRUPT - discards jump that caused the :finally - let dummy = 0 - endtry - elseif loop == 2 - Xloop 1 " X: 0 - endif - endwhile - Xloop 2 " X: 0 - endfunction - - try - Xpath 16384 " X: 16384 - call I("continue") - Xpath 32768 " X: 0 - finally - try - Xpath 65536 " X: 65536 - call I("break") - Xpath 131072 " X: 0 - finally - try - Xpath 262144 " X: 262144 - call I("return") - Xpath 524288 " X: 0 - finally - try - Xpath 1048576 " X: 1048576 - let g:jump = "finish" - ExecAsScript I - Xpath 2097152 " X: 0 - finally - unlet g:jump - try - Xpath 4194304 " X: 4194304 - call I("error") - Xpath 8388608 " X: 0 - finally - try - Xpath 16777216 " X: 16777216 - call I("interrupt") - Xpath 33554432 " X: 0 - finally - try - Xpath 67108864 " X: 67108864 - call I("throw") - Xpath 134217728 " X: 0 - finally - Xpath 268435456 " X: 268435456 - delfunction I - endtry - endtry - endtry - endtry - endtry - endtry - endtry - Xpath 536870912 " X: 0 - -endif - -Xcheck 357908480 - - -"------------------------------------------------------------------------------- -" Test 40: :finally reason discarded by :throw {{{1 -" -" When a :finally clause is executed due to a :continue, :break, -" :return, :finish, error, interrupt or :throw, the jump reason is -" discarded by a :throw in the finally clause. -"------------------------------------------------------------------------------- - -XpathINIT - -if ExtraVim() - - XloopINIT! 1 4 - - function! T(jump) - XloopNEXT - let loop = 0 - while loop < 2 - let loop = loop + 1 - if loop == 1 - try - if a:jump == "continue" - continue - elseif a:jump == "break" - break - elseif a:jump == "return" || a:jump == "finish" - return - elseif a:jump == "error" - asdf - elseif a:jump == "interrupt" - "INTERRUPT - let dummy = 0 - elseif a:jump == "throw" - throw "abc" - endif - finally - throw "xyz" " discards jump that caused the :finally - endtry - elseif loop == 2 - Xloop 1 " X: 0 - endif - endwhile - Xloop 2 " X: 0 - endfunction - - try - Xpath 16384 " X: 16384 - call T("continue") - Xpath 32768 " X: 0 - finally - try - Xpath 65536 " X: 65536 - call T("break") - Xpath 131072 " X: 0 - finally - try - Xpath 262144 " X: 262144 - call T("return") - Xpath 524288 " X: 0 - finally - try - Xpath 1048576 " X: 1048576 - let g:jump = "finish" - ExecAsScript T - Xpath 2097152 " X: 0 - finally - unlet g:jump - try - Xpath 4194304 " X: 4194304 - call T("error") - Xpath 8388608 " X: 0 - finally - try - Xpath 16777216 " X: 16777216 - call T("interrupt") - Xpath 33554432 " X: 0 - finally - try - Xpath 67108864 " X: 67108864 - call T("throw") - Xpath 134217728 " X: 0 - finally - Xpath 268435456 " X: 268435456 - delfunction T - endtry - endtry - endtry - endtry - endtry - endtry - endtry - Xpath 536870912 " X: 0 - -endif - -Xcheck 357908480 - -" Tests 41 to 48 were moved to test_trycatch.vim -let Xtest = 49 - - -"------------------------------------------------------------------------------- -" Test 49: Throwing exceptions across functions {{{1 -" -" When an exception is thrown but not caught inside a function, the -" caller is checked for a matching :catch clause. -"------------------------------------------------------------------------------- - -XpathINIT - -function! C() - try - Xpath 1 " X: 1 - throw "arrgh" - Xpath 2 " X: 0 - catch /arrgh/ - Xpath 4 " X: 4 - endtry - Xpath 8 " X: 8 -endfunction - -XloopINIT! 16 16 - -function! T1() - XloopNEXT - try - Xloop 1 " X: 16 + 16*16 - throw "arrgh" - Xloop 2 " X: 0 - finally - Xloop 4 " X: 64 + 64*16 - endtry - Xloop 8 " X: 0 -endfunction - -function! T2() - try - Xpath 4096 " X: 4096 - call T1() - Xpath 8192 " X: 0 - finally - Xpath 16384 " X: 16384 - endtry - Xpath 32768 " X: 0 -endfunction - -try - Xpath 65536 " X: 65536 - call C() " throw and catch - Xpath 131072 " X: 131072 -catch /.*/ - Xpath 262144 " X: 0 - Xout v:exception "in" v:throwpoint -endtry - -try - Xpath 524288 " X: 524288 - call T1() " throw, one level - Xpath 1048576 " X: 0 -catch /arrgh/ - Xpath 2097152 " X: 2097152 -catch /.*/ - Xpath 4194304 " X: 0 - Xout v:exception "in" v:throwpoint -endtry - -try - Xpath 8388608 " X: 8388608 - call T2() " throw, two levels - Xpath 16777216 " X: 0 -catch /arrgh/ - Xpath 33554432 " X: 33554432 -catch /.*/ - Xpath 67108864 " X: 0 - Xout v:exception "in" v:throwpoint -endtry -Xpath 134217728 " X: 134217728 - -Xcheck 179000669 - -" Leave C, T1, and T2 for execution as scripts in the next test. - - -"------------------------------------------------------------------------------- -" Test 50: Throwing exceptions across script files {{{1 -" -" When an exception is thrown but not caught inside a script file, -" the sourcing script or function is checked for a matching :catch -" clause. -" -" This test executes the bodies of the functions C, T1, and T2 from -" the previous test as script files (:return replaced by :finish). -"------------------------------------------------------------------------------- - -XpathINIT - -let scriptC = MakeScript("C") " X: 1 + 4 + 8 -delfunction C - -XloopINIT! 16 16 - -let scriptT1 = MakeScript("T1") " X: 16 + 64 + 16*16 + 64*16 -delfunction T1 - -let scriptT2 = MakeScript("T2", scriptT1) " X: 4096 + 16384 -delfunction T2 - -function! F() - try - Xpath 65536 " X: 65536 - exec "source" g:scriptC - Xpath 131072 " X: 131072 - catch /.*/ - Xpath 262144 " X: 0 - Xout v:exception "in" v:throwpoint - endtry - - try - Xpath 524288 " X: 524288 - exec "source" g:scriptT1 - Xpath 1048576 " X: 0 - catch /arrgh/ - Xpath 2097152 " X: 2097152 - catch /.*/ - Xpath 4194304 " X: 0 - Xout v:exception "in" v:throwpoint - endtry -endfunction - -try - Xpath 8388608 " X: 8388608 - call F() - Xpath 16777216 " X: 16777216 - exec "source" scriptT2 - Xpath 33554432 " X: 0 -catch /arrgh/ - Xpath 67108864 " X: 67108864 -catch /.*/ - Xpath 134217728 " X: 0 - Xout v:exception "in" v:throwpoint -endtry -Xpath 268435456 " X: 268435456 - -call delete(scriptC) -call delete(scriptT1) -call delete(scriptT2) -unlet scriptC scriptT1 scriptT2 -delfunction F - -Xcheck 363550045 - -" Test 51 was moved to test_trycatch.vim +" Tests 1 to 50, 87 were moved to test_vimscript.vim +" Tests 25, 26, 32, 33, 41-48, 51, 69-75 were moved to test_trycatch.vim let Xtest = 52 - "------------------------------------------------------------------------------- " Test 52: Uncaught exceptions {{{1 " diff --git a/src/testdir/test_vimscript.vim b/src/testdir/test_vimscript.vim --- a/src/testdir/test_vimscript.vim +++ b/src/testdir/test_vimscript.vim @@ -3,14 +3,12 @@ source check.vim source shared.vim +source script_util.vim "------------------------------------------------------------------------------- " Test environment {{{1 "------------------------------------------------------------------------------- -com! XpathINIT let g:Xpath = '' -com! -nargs=1 -bar Xpath let g:Xpath = g:Xpath . - " Append a message to the "messages" file func Xout(text) split messages @@ -20,67 +18,30 @@ endfunc com! -nargs=1 Xout call Xout() -" MakeScript() - Make a script file from a function. {{{2 -" -" Create a script that consists of the body of the function a:funcname. -" Replace any ":return" by a ":finish", any argument variable by a global -" variable, and every ":call" by a ":source" for the next following argument -" in the variable argument list. This function is useful if similar tests are -" to be made for a ":return" from a function call or a ":finish" in a script -" file. -func MakeScript(funcname, ...) - let script = tempname() - execute "redir! >" . script - execute "function" a:funcname - redir END - execute "edit" script - " Delete the "function" and the "endfunction" lines. Do not include the - " word "function" in the pattern since it might be translated if LANG is - " set. When MakeScript() is being debugged, this deletes also the debugging - " output of its line 3 and 4. - exec '1,/.*' . a:funcname . '(.*)/d' - /^\d*\s*endfunction\>/,$d - %s/^\d*//e - %s/return/finish/e - %s/\ 0 - let cnt = cnt + 1 - s/\) - - "------------------------------------------------------------------------------- " Test 1: :endwhile in function {{{1 " @@ -90,7 +51,7 @@ com! -nargs=1 -bar ExecAsScript call Exe " tests will hang. "------------------------------------------------------------------------------- -function! T1_F() +func T1_F() Xpath 'a' let first = 1 while 1 @@ -104,9 +65,9 @@ function! T1_F() return endif endwhile -endfunction - -function! T1_G() +endfunc + +func T1_G() Xpath 'h' let first = 1 while 1 @@ -121,7 +82,7 @@ function! T1_G() endif if 1 " unmatched :if endwhile -endfunction +endfunc func Test_endwhile_function() XpathINIT @@ -175,7 +136,7 @@ endfunc " Test 3: :if, :elseif, :while, :continue, :break {{{1 "------------------------------------------------------------------------------- -function Test_if_while() +func Test_if_while() XpathINIT if 1 Xpath 'a' @@ -235,7 +196,7 @@ endfunc " Test 4: :return {{{1 "------------------------------------------------------------------------------- -function! T4_F() +func T4_F() if 1 Xpath 'a' let loops = 3 @@ -253,15 +214,15 @@ function! T4_F() else Xpath 'g' endif -endfunction - -function Test_return() +endfunc + +func Test_return() XpathINIT call T4_F() Xpath '4' call assert_equal('ab3e3b2c24', g:Xpath) -endfunction +endfunc "------------------------------------------------------------------------------- @@ -271,14 +232,14 @@ endfunction " test as a script file (:return replaced by :finish). "------------------------------------------------------------------------------- -function Test_finish() +func Test_finish() XpathINIT ExecAsScript T4_F Xpath '5' call DeleteTheScript() call assert_equal('ab3e3b2c25', g:Xpath) -endfunction +endfunc @@ -412,7 +373,7 @@ delfunction G31 delfunction G32 delfunction G33 -function Test_defining_functions() +func Test_defining_functions() call assert_equal('ade2ie3ibcg0h1g1h2g2h3fg0h1g1h2g2h3m', g:test6_result) call assert_equal('F1G1F2G21G22G23F3G31G32G33', g:test6_calls) endfunc @@ -476,7 +437,7 @@ endfunc XpathINIT -function! T8_F() +func T8_F() if 1 Xpath 'a' while 1 @@ -508,9 +469,9 @@ function! T8_F() return novar " returns (default return value 0) Xpath 'q' return 1 " not reached -endfunction - -function! T8_G() abort +endfunc + +func T8_G() abort if 1 Xpath 'r' while 1 @@ -524,9 +485,9 @@ function! T8_G() abort Xpath 'x' return -4 " not reached -endfunction - -function! T8_H() abort +endfunc + +func T8_H() abort while 1 Xpath 'A' if 1 @@ -540,7 +501,7 @@ function! T8_H() abort Xpath 'F' return -4 " not reached -endfunction +endfunc " Aborted functions (T8_G and T8_H) return -1. let g:test8_sum = (T8_F() + 1) - 4 * T8_G() - 8 * T8_H() @@ -567,7 +528,7 @@ endfunc XpathINIT -function! F() abort +func F() abort Xpath 'a' let result = G() " not aborted Xpath 'b' @@ -575,30 +536,30 @@ function! F() abort Xpath 'c' endif return 1 -endfunction - -function! G() " no abort attribute +endfunc + +func G() " no abort attribute Xpath 'd' if H() != -1 " aborted Xpath 'e' endif Xpath 'f' return 2 -endfunction - -function! H() abort +endfunc + +func H() abort Xpath 'g' call I() " aborted Xpath 'h' return 4 -endfunction - -function! I() abort +endfunc + +func I() abort Xpath 'i' asdf " error Xpath 'j' return 8 -endfunction +endfunc if F() != 1 Xpath 'k' @@ -626,7 +587,7 @@ endfunc XpathINIT -function! MSG(enr, emsg) +func MSG(enr, emsg) let english = v:lang == "C" || v:lang =~ '^[Ee]n' if a:enr == "" Xout "TODO: Add message number for:" a:emsg @@ -710,10 +671,10 @@ XpathINIT let calls = 0 -function! P(num) +func P(num) let g:calls = g:calls + a:num " side effect on call return 0 -endfunction +endfunc if 1 Xpath 'a' @@ -1092,7 +1053,1716 @@ func Test_unmatched_if_in_while() endfunc "------------------------------------------------------------------------------- +" Test 18: Interrupt (Ctrl-C pressed) {{{1 +" +" On an interrupt, the script processing is terminated immediately. "------------------------------------------------------------------------------- + +func Test_interrupt_while_if() + let test =<< trim [CODE] + try + if 1 + Xpath 'a' + while 1 + Xpath 'b' + if 1 + Xpath 'c' + call interrupt() + call assert_report('should not get here') + break + finish + endif | call assert_report('should not get here') + call assert_report('should not get here') + endwhile | call assert_report('should not get here') + call assert_report('should not get here') + endif | call assert_report('should not get here') + call assert_report('should not get here') + catch /^Vim:Interrupt$/ + Xpath 'd' + endtry | Xpath 'e' + Xpath 'f' + [CODE] + let verify =<< trim [CODE] + call assert_equal('abcdef', g:Xpath) + [CODE] + call RunInNewVim(test, verify) +endfunc + +func Test_interrupt_try() + let test =<< trim [CODE] + try + try + Xpath 'a' + call interrupt() + call assert_report('should not get here') + endtry | call assert_report('should not get here') + call assert_report('should not get here') + catch /^Vim:Interrupt$/ + Xpath 'b' + endtry | Xpath 'c' + Xpath 'd' + [CODE] + let verify =<< trim [CODE] + call assert_equal('abcd', g:Xpath) + [CODE] + call RunInNewVim(test, verify) +endfunc + +func Test_interrupt_func_while_if() + let test =<< trim [CODE] + func F() + if 1 + Xpath 'a' + while 1 + Xpath 'b' + if 1 + Xpath 'c' + call interrupt() + call assert_report('should not get here') + break + return + endif | call assert_report('should not get here') + call assert_report('should not get here') + endwhile | call assert_report('should not get here') + call assert_report('should not get here') + endif | call assert_report('should not get here') + call assert_report('should not get here') + endfunc + + Xpath 'd' + try + call F() | call assert_report('should not get here') + catch /^Vim:Interrupt$/ + Xpath 'e' + endtry | Xpath 'f' + Xpath 'g' + [CODE] + let verify =<< trim [CODE] + call assert_equal('dabcefg', g:Xpath) + [CODE] + call RunInNewVim(test, verify) +endfunc + +func Test_interrupt_func_try() + let test =<< trim [CODE] + func G() + try + Xpath 'a' + call interrupt() + call assert_report('should not get here') + endtry | call assert_report('should not get here') + call assert_report('should not get here') + endfunc + + Xpath 'b' + try + call G() | call assert_report('should not get here') + catch /^Vim:Interrupt$/ + Xpath 'c' + endtry | Xpath 'd' + Xpath 'e' + [CODE] + let verify =<< trim [CODE] + call assert_equal('bacde', g:Xpath) + [CODE] + call RunInNewVim(test, verify) +endfunc + +"------------------------------------------------------------------------------- +" Test 19: Aborting on errors inside :try/:endtry {{{1 +" +" An error in a command dynamically enclosed in a :try/:endtry region +" aborts script processing immediately. It does not matter whether +" the failing command is outside or inside a function and whether a +" function has an "abort" attribute. +"------------------------------------------------------------------------------- + +func Test_try_error_abort_1() + let test =<< trim [CODE] + func F() abort + Xpath 'a' + asdf + call assert_report('should not get here') + endfunc + + try + Xpath 'b' + call F() + call assert_report('should not get here') + endtry | call assert_report('should not get here') + call assert_report('should not get here') + [CODE] + let verify =<< trim [CODE] + call assert_equal('ba', g:Xpath) + [CODE] + call RunInNewVim(test, verify) +endfunc + +func Test_try_error_abort_2() + let test =<< trim [CODE] + func G() + Xpath 'a' + asdf + call assert_report('should not get here') + endfunc + + try + Xpath 'b' + call G() + call assert_report('should not get here') + endtry | call assert_report('should not get here') + call assert_report('should not get here') + [CODE] + let verify =<< trim [CODE] + call assert_equal('ba', g:Xpath) + [CODE] + call RunInNewVim(test, verify) +endfunc + +func Test_try_error_abort_3() + let test =<< trim [CODE] + try + Xpath 'a' + asdf + call assert_report('should not get here') + endtry | call assert_report('should not get here') + call assert_report('should not get here') + [CODE] + let verify =<< trim [CODE] + call assert_equal('a', g:Xpath) + [CODE] + call RunInNewVim(test, verify) +endfunc + +func Test_try_error_abort_4() + let test =<< trim [CODE] + if 1 + try + Xpath 'a' + asdf + call assert_report('should not get here') + endtry | call assert_report('should not get here') + endif | call assert_report('should not get here') + call assert_report('should not get here') + [CODE] + let verify =<< trim [CODE] + call assert_equal('a', g:Xpath) + [CODE] + call RunInNewVim(test, verify) +endfunc + +func Test_try_error_abort_5() + let test =<< trim [CODE] + let p = 1 + while p + let p = 0 + try + Xpath 'a' + asdf + call assert_report('should not get here') + endtry | call assert_report('should not get here') + endwhile | call assert_report('should not get here') + call assert_report('should not get here') + [CODE] + let verify =<< trim [CODE] + call assert_equal('a', g:Xpath) + [CODE] + call RunInNewVim(test, verify) +endfunc + +func Test_try_error_abort_6() + let test =<< trim [CODE] + let p = 1 + Xpath 'a' + while p + Xpath 'b' + let p = 0 + try + Xpath 'c' + endwhile | call assert_report('should not get here') + call assert_report('should not get here') + [CODE] + let verify =<< trim [CODE] + call assert_equal('abc', g:Xpath) + [CODE] + call RunInNewVim(test, verify) +endfunc + +"------------------------------------------------------------------------------- +" Test 20: Aborting on errors after :try/:endtry {{{1 +" +" When an error occurs after the last active :try/:endtry region has +" been left, termination behavior is as if no :try/:endtry has been +" seen. +"------------------------------------------------------------------------------- + +func Test_error_after_try_1() + let test =<< trim [CODE] + let p = 1 + while p + let p = 0 + Xpath 'a' + try + Xpath 'b' + endtry + asdf + call assert_report('should not get here') + endwhile | call assert_report('should not get here') + Xpath 'c' + [CODE] + let verify =<< trim [CODE] + call assert_equal('abc', g:Xpath) + [CODE] + call RunInNewVim(test, verify) +endfunc + +func Test_error_after_try_2() + let test =<< trim [CODE] + while 1 + try + Xpath 'a' + break + call assert_report('should not get here') + endtry + endwhile + Xpath 'b' + asdf + Xpath 'c' + [CODE] + let verify =<< trim [CODE] + call assert_equal('abc', g:Xpath) + [CODE] + call RunInNewVim(test, verify) +endfunc + +func Test_error_after_try_3() + let test =<< trim [CODE] + while 1 + try + Xpath 'a' + break + call assert_report('should not get here') + finally + Xpath 'b' + endtry + endwhile + Xpath 'c' + asdf + Xpath 'd' + [CODE] + let verify =<< trim [CODE] + call assert_equal('abcd', g:Xpath) + [CODE] + call RunInNewVim(test, verify) +endfunc + +func Test_error_after_try_4() + let test =<< trim [CODE] + while 1 + try + Xpath 'a' + finally + Xpath 'b' + break + call assert_report('should not get here') + endtry + endwhile + Xpath 'c' + asdf + Xpath 'd' + [CODE] + let verify =<< trim [CODE] + call assert_equal('abcd', g:Xpath) + [CODE] + call RunInNewVim(test, verify) +endfunc + +func Test_error_after_try_5() + let test =<< trim [CODE] + let p = 1 + while p + let p = 0 + try + Xpath 'a' + continue + call assert_report('should not get here') + endtry + endwhile + Xpath 'b' + asdf + Xpath 'c' + [CODE] + let verify =<< trim [CODE] + call assert_equal('abc', g:Xpath) + [CODE] + call RunInNewVim(test, verify) +endfunc + +func Test_error_after_try_6() + let test =<< trim [CODE] + let p = 1 + while p + let p = 0 + try + Xpath 'a' + continue + call assert_report('should not get here') + finally + Xpath 'b' + endtry + endwhile + Xpath 'c' + asdf + Xpath 'd' + [CODE] + let verify =<< trim [CODE] + call assert_equal('abcd', g:Xpath) + [CODE] + call RunInNewVim(test, verify) +endfunc + +func Test_error_after_try_7() + let test =<< trim [CODE] + let p = 1 + while p + let p = 0 + try + Xpath 'a' + finally + Xpath 'b' + continue + call assert_report('should not get here') + endtry + endwhile + Xpath 'c' + asdf + Xpath 'd' + [CODE] + let verify =<< trim [CODE] + call assert_equal('abcd', g:Xpath) + [CODE] + call RunInNewVim(test, verify) +endfunc + +"------------------------------------------------------------------------------- +" Test 21: :finally for :try after :continue/:break/:return/:finish {{{1 +" +" If a :try conditional stays inactive due to a preceding :continue, +" :break, :return, or :finish, its :finally clause should not be +" executed. +"------------------------------------------------------------------------------- + +func Test_finally_after_loop_ctrl_statement() + let test =<< trim [CODE] + func F() + let loops = 2 + while loops > 0 + XloopNEXT + let loops = loops - 1 + try + if loops == 1 + Xloop 'a' + continue + call assert_report('should not get here') + elseif loops == 0 + Xloop 'b' + break + call assert_report('should not get here') + endif + + try " inactive + call assert_report('should not get here') + finally + call assert_report('should not get here') + endtry + finally + Xloop 'c' + endtry + call assert_report('should not get here') + endwhile + + try + Xpath 'd' + return + call assert_report('should not get here') + try " inactive + call assert_report('should not get here') + finally + call assert_report('should not get here') + endtry + finally + Xpath 'e' + endtry + call assert_report('should not get here') + endfunc + + try + Xpath 'f' + call F() + Xpath 'g' + finish + call assert_report('should not get here') + try " inactive + call assert_report('should not get here') + finally + call assert_report('should not get here') + endtry + finally + Xpath 'h' + endtry + call assert_report('should not get here') + [CODE] + let verify =<< trim [CODE] + call assert_equal('fa2c2b3c3degh', g:Xpath) + [CODE] + call RunInNewVim(test, verify) +endfunc + +"------------------------------------------------------------------------------- +" Test 22: :finally for a :try after an error/interrupt/:throw {{{1 +" +" If a :try conditional stays inactive due to a preceding error or +" interrupt or :throw, its :finally clause should not be executed. +"------------------------------------------------------------------------------- + +func Test_finally_after_error_in_func() + let test =<< trim [CODE] + func Error() + try + Xpath 'b' + asdf " aborting error, triggering error exception + call assert_report('should not get here') + endtry + call assert_report('should not get here') + endfunc + + Xpath 'a' + call Error() + call assert_report('should not get here') + + if 1 " not active due to error + try " not active since :if inactive + call assert_report('should not get here') + finally + call assert_report('should not get here') + endtry + endif + + try " not active due to error + call assert_report('should not get here') + finally + call assert_report('should not get here') + endtry + [CODE] + let verify =<< trim [CODE] + call assert_equal('ab', g:Xpath) + [CODE] + call RunInNewVim(test, verify) +endfunc + +func Test_finally_after_interrupt() + let test =<< trim [CODE] + func Interrupt() + try + Xpath 'a' + call interrupt() " triggering interrupt exception + call assert_report('should not get here') + endtry + endfunc + + Xpath 'b' + try + call Interrupt() + catch /^Vim:Interrupt$/ + Xpath 'c' + finish + endtry + call assert_report('should not get here') + + if 1 " not active due to interrupt + try " not active since :if inactive + call assert_report('should not get here') + finally + call assert_report('should not get here') + endtry + endif + + try " not active due to interrupt + call assert_report('should not get here') + finally + call assert_report('should not get here') + endtry + [CODE] + let verify =<< trim [CODE] + call assert_equal('bac', g:Xpath) + [CODE] + call RunInNewVim(test, verify) +endfunc + +func Test_finally_after_throw() + let test =<< trim [CODE] + func Throw() + Xpath 'a' + throw 'xyz' + endfunc + + Xpath 'b' + call Throw() + call assert_report('should not get here') + + if 1 " not active due to :throw + try " not active since :if inactive + call assert_report('should not get here') + finally + call assert_report('should not get here') + endtry + endif + + try " not active due to :throw + call assert_report('should not get here') + finally + call assert_report('should not get here') + endtry + [CODE] + let verify =<< trim [CODE] + call assert_equal('ba', g:Xpath) + [CODE] + call RunInNewVim(test, verify) +endfunc + +"------------------------------------------------------------------------------- +" Test 23: :catch clauses for a :try after a :throw {{{1 +" +" If a :try conditional stays inactive due to a preceding :throw, +" none of its :catch clauses should be executed. +"------------------------------------------------------------------------------- + +func Test_catch_after_throw() + let test =<< trim [CODE] + try + Xpath 'a' + throw "xyz" + call assert_report('should not get here') + + if 1 " not active due to :throw + try " not active since :if inactive + call assert_report('should not get here') + catch /xyz/ + call assert_report('should not get here') + endtry + endif + catch /xyz/ + Xpath 'b' + endtry + + Xpath 'c' + throw "abc" + call assert_report('should not get here') + + try " not active due to :throw + call assert_report('should not get here') + catch /abc/ + call assert_report('should not get here') + endtry + [CODE] + let verify =<< trim [CODE] + call assert_equal('abc', g:Xpath) + [CODE] + call RunInNewVim(test, verify) +endfunc + +"------------------------------------------------------------------------------- +" Test 24: :endtry for a :try after a :throw {{{1 +" +" If a :try conditional stays inactive due to a preceding :throw, +" its :endtry should not rethrow the exception to the next surrounding +" active :try conditional. +"------------------------------------------------------------------------------- + +func Test_endtry_after_throw() + let test =<< trim [CODE] + try " try 1 + try " try 2 + Xpath 'a' + throw "xyz" " makes try 2 inactive + call assert_report('should not get here') + + try " try 3 + call assert_report('should not get here') + endtry " no rethrow to try 1 + catch /xyz/ " should catch although try 2 inactive + Xpath 'b' + endtry + catch /xyz/ " try 1 active, but exception already caught + call assert_report('should not get here') + endtry + Xpath 'c' + [CODE] + let verify =<< trim [CODE] + call assert_equal('abc', g:Xpath) + [CODE] + call RunInNewVim(test, verify) +endfunc + +"------------------------------------------------------------------------------- +" Test 27: Executing :finally clauses after :return {{{1 +" +" For a :return command dynamically enclosed in a :try/:endtry region, +" :finally clauses are executed and the called function is ended. +"------------------------------------------------------------------------------- + +func T27_F() + try + Xpath 'a' + try + Xpath 'b' + return + call assert_report('should not get here') + finally + Xpath 'c' + endtry + Xpath 'd' + finally + Xpath 'e' + endtry + call assert_report('should not get here') +endfunc + +func T27_G() + try + Xpath 'f' + return + call assert_report('should not get here') + finally + Xpath 'g' + call T27_F() + Xpath 'h' + endtry + call assert_report('should not get here') +endfunc + +func T27_H() + try + Xpath 'i' + call T27_G() + Xpath 'j' + finally + Xpath 'k' + return + call assert_report('should not get here') + endtry + call assert_report('should not get here') +endfunction + +func Test_finally_after_return() + XpathINIT + try + Xpath 'l' + call T27_H() + Xpath 'm' + finally + Xpath 'n' + endtry + call assert_equal('lifgabcehjkmn', g:Xpath) +endfunc + +"------------------------------------------------------------------------------- +" Test 28: Executing :finally clauses after :finish {{{1 +" +" For a :finish command dynamically enclosed in a :try/:endtry region, +" :finally clauses are executed and the sourced file is finished. +" +" This test executes the bodies of the functions F, G, and H from the +" previous test as script files (:return replaced by :finish). +"------------------------------------------------------------------------------- + +func Test_finally_after_finish() + XpathINIT + + let scriptF = MakeScript("T27_F") + let scriptG = MakeScript("T27_G", scriptF) + let scriptH = MakeScript("T27_H", scriptG) + + try + Xpath 'A' + exec "source" scriptH + Xpath 'B' + finally + Xpath 'C' + endtry + Xpath 'D' + call assert_equal('AifgabcehjkBCD', g:Xpath) + call delete(scriptF) + call delete(scriptG) + call delete(scriptH) +endfunc + +"------------------------------------------------------------------------------- +" Test 29: Executing :finally clauses on errors {{{1 +" +" After an error in a command dynamically enclosed in a :try/:endtry +" region, :finally clauses are executed and the script processing is +" terminated. +"------------------------------------------------------------------------------- + +func Test_finally_after_error_1() + let test =<< trim [CODE] + func F() + while 1 + try + Xpath 'a' + while 1 + try + Xpath 'b' + asdf " error + call assert_report('should not get here') + finally + Xpath 'c' + endtry | call assert_report('should not get here') + call assert_report('should not get here') + break + endwhile + call assert_report('should not get here') + finally + Xpath 'd' + endtry | call assert_report('should not get here') + call assert_report('should not get here') + break + endwhile + call assert_report('should not get here') + endfunc + + while 1 + try + Xpath 'e' + while 1 + call F() + call assert_report('should not get here') + break + endwhile | call assert_report('should not get here') + call assert_report('should not get here') + finally + Xpath 'f' + endtry | call assert_report('should not get here') + endwhile | call assert_report('should not get here') + call assert_report('should not get here') + [CODE] + let verify =<< trim [CODE] + call assert_equal('eabcdf', g:Xpath) + [CODE] + call RunInNewVim(test, verify) +endfunc + +func Test_finally_after_error_2() + let test =<< trim [CODE] + func G() abort + if 1 + try + Xpath 'a' + asdf " error + call assert_report('should not get here') + finally + Xpath 'b' + endtry | Xpath 'c' + endif | Xpath 'd' + call assert_report('should not get here') + endfunc + + if 1 + try + Xpath 'e' + call G() + call assert_report('should not get here') + finally + Xpath 'f' + endtry | call assert_report('should not get here') + endif | call assert_report('should not get here') + call assert_report('should not get here') + [CODE] + let verify =<< trim [CODE] + call assert_equal('eabf', g:Xpath) + [CODE] + call RunInNewVim(test, verify) +endfunc + +"------------------------------------------------------------------------------- +" Test 30: Executing :finally clauses on interrupt {{{1 +" +" After an interrupt in a command dynamically enclosed in +" a :try/:endtry region, :finally clauses are executed and the +" script processing is terminated. +"------------------------------------------------------------------------------- + +func Test_finally_on_interrupt() + let test =<< trim [CODE] + func F() + try + Xloop 'a' + call interrupt() + call assert_report('should not get here') + finally + Xloop 'b' + endtry + call assert_report('should not get here') + endfunc + + try + try + Xpath 'c' + try + Xpath 'd' + call interrupt() + call assert_report('should not get here') + finally + Xpath 'e' + try + Xpath 'f' + try + Xpath 'g' + finally + Xpath 'h' + try + Xpath 'i' + call interrupt() + call assert_report('should not get here') + endtry + call assert_report('should not get here') + endtry + call assert_report('should not get here') + endtry + call assert_report('should not get here') + endtry + call assert_report('should not get here') + finally + Xpath 'j' + try + Xpath 'k' + call F() + call assert_report('should not get here') + finally + Xpath 'l' + try + Xpath 'm' + XloopNEXT + ExecAsScript F + call assert_report('should not get here') + finally + Xpath 'n' + endtry + call assert_report('should not get here') + endtry + call assert_report('should not get here') + endtry + call assert_report('should not get here') + catch /^Vim:Interrupt$/ + Xpath 'o' + endtry + [CODE] + let verify =<< trim [CODE] + call assert_equal('cdefghijka1b1lma2b2no', g:Xpath) + [CODE] + call RunInNewVim(test, verify) +endfunc + +"------------------------------------------------------------------------------- +" Test 31: Executing :finally clauses after :throw {{{1 +" +" After a :throw dynamically enclosed in a :try/:endtry region, +" :finally clauses are executed and the script processing is +" terminated. +"------------------------------------------------------------------------------- + +func Test_finally_after_throw_2() + let test =<< trim [CODE] + func F() + try + Xloop 'a' + throw "exception" + call assert_report('should not get here') + finally + Xloop 'b' + endtry + call assert_report('should not get here') + endfunc + + try + Xpath 'c' + try + Xpath 'd' + throw "exception" + call assert_report('should not get here') + finally + Xpath 'e' + try + Xpath 'f' + try + Xpath 'g' + finally + Xpath 'h' + try + Xpath 'i' + throw "exception" + call assert_report('should not get here') + endtry + call assert_report('should not get here') + endtry + call assert_report('should not get here') + endtry + call assert_report('should not get here') + endtry + call assert_report('should not get here') + finally + Xpath 'j' + try + Xpath 'k' + call F() + call assert_report('should not get here') + finally + Xpath 'l' + try + Xpath 'm' + XloopNEXT + ExecAsScript F + call assert_report('should not get here') + finally + Xpath 'n' + endtry + call assert_report('should not get here') + endtry + call assert_report('should not get here') + endtry + call assert_report('should not get here') + [CODE] + let verify =<< trim [CODE] + call assert_equal('cdefghijka1b1lma2b2n', g:Xpath) + [CODE] + call RunInNewVim(test, verify) +endfunc + +"------------------------------------------------------------------------------- +" Test 34: :finally reason discarded by :continue {{{1 +" +" When a :finally clause is executed due to a :continue, :break, +" :return, :finish, error, interrupt or :throw, the jump reason is +" discarded by a :continue in the finally clause. +"------------------------------------------------------------------------------- + +func Test_finally_after_continue() + let test =<< trim [CODE] + func C(jump) + XloopNEXT + let loop = 0 + while loop < 2 + let loop = loop + 1 + if loop == 1 + try + if a:jump == "continue" + continue + elseif a:jump == "break" + break + elseif a:jump == "return" || a:jump == "finish" + return + elseif a:jump == "error" + asdf + elseif a:jump == "interrupt" + call interrupt() + let dummy = 0 + elseif a:jump == "throw" + throw "abc" + endif + finally + continue " discards jump that caused the :finally + call assert_report('should not get here') + endtry + call assert_report('should not get here') + elseif loop == 2 + Xloop 'a' + endif + endwhile + endfunc + + call C("continue") + Xpath 'b' + call C("break") + Xpath 'c' + call C("return") + Xpath 'd' + let g:jump = "finish" + ExecAsScript C + unlet g:jump + Xpath 'e' + try + call C("error") + Xpath 'f' + finally + Xpath 'g' + try + call C("interrupt") + Xpath 'h' + finally + Xpath 'i' + call C("throw") + Xpath 'j' + endtry + endtry + Xpath 'k' + [CODE] + let verify =<< trim [CODE] + call assert_equal('a2ba3ca4da5ea6fga7hia8jk', g:Xpath) + [CODE] + call RunInNewVim(test, verify) +endfunc + +"------------------------------------------------------------------------------- +" Test 35: :finally reason discarded by :break {{{1 +" +" When a :finally clause is executed due to a :continue, :break, +" :return, :finish, error, interrupt or :throw, the jump reason is +" discarded by a :break in the finally clause. +"------------------------------------------------------------------------------- + +func Test_finally_discard_by_break() + let test =<< trim [CODE] + func B(jump) + XloopNEXT + let loop = 0 + while loop < 2 + let loop = loop + 1 + if loop == 1 + try + if a:jump == "continue" + continue + elseif a:jump == "break" + break + elseif a:jump == "return" || a:jump == "finish" + return + elseif a:jump == "error" + asdf + elseif a:jump == "interrupt" + call interrupt() + let dummy = 0 + elseif a:jump == "throw" + throw "abc" + endif + finally + break " discards jump that caused the :finally + call assert_report('should not get here') + endtry + elseif loop == 2 + call assert_report('should not get here') + endif + endwhile + Xloop 'a' + endfunc + + call B("continue") + Xpath 'b' + call B("break") + Xpath 'c' + call B("return") + Xpath 'd' + let g:jump = "finish" + ExecAsScript B + unlet g:jump + Xpath 'e' + try + call B("error") + Xpath 'f' + finally + Xpath 'g' + try + call B("interrupt") + Xpath 'h' + finally + Xpath 'i' + call B("throw") + Xpath 'j' + endtry + endtry + Xpath 'k' + [CODE] + let verify =<< trim [CODE] + call assert_equal('a2ba3ca4da5ea6fga7hia8jk', g:Xpath) + [CODE] + call RunInNewVim(test, verify) +endfunc + +"------------------------------------------------------------------------------- +" Test 36: :finally reason discarded by :return {{{1 +" +" When a :finally clause is executed due to a :continue, :break, +" :return, :finish, error, interrupt or :throw, the jump reason is +" discarded by a :return in the finally clause. +"------------------------------------------------------------------------------- + +func Test_finally_discard_by_return() + let test =<< trim [CODE] + func R(jump, retval) abort + let loop = 0 + while loop < 2 + let loop = loop + 1 + if loop == 1 + try + if a:jump == "continue" + continue + elseif a:jump == "break" + break + elseif a:jump == "return" + return + elseif a:jump == "error" + asdf + elseif a:jump == "interrupt" + call interrupt() + let dummy = 0 + elseif a:jump == "throw" + throw "abc" + endif + finally + return a:retval " discards jump that caused the :finally + call assert_report('should not get here') + endtry + elseif loop == 2 + call assert_report('should not get here') + endif + endwhile + call assert_report('should not get here') + endfunc + + let sum = -R("continue", -8) + Xpath 'a' + let sum = sum - R("break", -16) + Xpath 'b' + let sum = sum - R("return", -32) + Xpath 'c' + try + let sum = sum - R("error", -64) + Xpath 'd' + finally + Xpath 'e' + try + let sum = sum - R("interrupt", -128) + Xpath 'f' + finally + Xpath 'g' + let sum = sum - R("throw", -256) + Xpath 'h' + endtry + endtry + Xpath 'i' + + let expected = 8 + 16 + 32 + 64 + 128 + 256 + call assert_equal(sum, expected) + [CODE] + let verify =<< trim [CODE] + call assert_equal('abcdefghi', g:Xpath) + [CODE] + call RunInNewVim(test, verify) +endfunc + +"------------------------------------------------------------------------------- +" Test 37: :finally reason discarded by :finish {{{1 +" +" When a :finally clause is executed due to a :continue, :break, +" :return, :finish, error, interrupt or :throw, the jump reason is +" discarded by a :finish in the finally clause. +"------------------------------------------------------------------------------- + +func Test_finally_discard_by_finish() + let test =<< trim [CODE] + func F(jump) " not executed as function, transformed to a script + let loop = 0 + while loop < 2 + let loop = loop + 1 + if loop == 1 + try + if a:jump == "continue" + continue + elseif a:jump == "break" + break + elseif a:jump == "finish" + finish + elseif a:jump == "error" + asdf + elseif a:jump == "interrupt" + call interrupt() + let dummy = 0 + elseif a:jump == "throw" + throw "abc" + endif + finally + finish " discards jump that caused the :finally + call assert_report('should not get here') + endtry + elseif loop == 2 + call assert_report('should not get here') + endif + endwhile + call assert_report('should not get here') + endfunc + + let scriptF = MakeScript("F") + delfunction F + + let g:jump = "continue" + exec "source" scriptF + Xpath 'a' + let g:jump = "break" + exec "source" scriptF + Xpath 'b' + let g:jump = "finish" + exec "source" scriptF + Xpath 'c' + try + let g:jump = "error" + exec "source" scriptF + Xpath 'd' + finally + Xpath 'e' + try + let g:jump = "interrupt" + exec "source" scriptF + Xpath 'f' + finally + Xpath 'g' + try + let g:jump = "throw" + exec "source" scriptF + Xpath 'h' + finally + Xpath 'i' + endtry + endtry + endtry + unlet g:jump + call delete(scriptF) + [CODE] + let verify =<< trim [CODE] + call assert_equal('abcdefghi', g:Xpath) + [CODE] + call RunInNewVim(test, verify) +endfunc + +"------------------------------------------------------------------------------- +" Test 38: :finally reason discarded by an error {{{1 +" +" When a :finally clause is executed due to a :continue, :break, +" :return, :finish, error, interrupt or :throw, the jump reason is +" discarded by an error in the finally clause. +"------------------------------------------------------------------------------- + +func Test_finally_discard_by_error() + let test =<< trim [CODE] + func E(jump) + let loop = 0 + while loop < 2 + let loop = loop + 1 + if loop == 1 + try + if a:jump == "continue" + continue + elseif a:jump == "break" + break + elseif a:jump == "return" || a:jump == "finish" + return + elseif a:jump == "error" + asdf + elseif a:jump == "interrupt" + call interrupt() + let dummy = 0 + elseif a:jump == "throw" + throw "abc" + endif + finally + asdf " error; discards jump that caused the :finally + endtry + elseif loop == 2 + call assert_report('should not get here') + endif + endwhile + call assert_report('should not get here') + endfunc + + try + Xpath 'a' + call E("continue") + call assert_report('should not get here') + finally + try + Xpath 'b' + call E("break") + call assert_report('should not get here') + finally + try + Xpath 'c' + call E("return") + call assert_report('should not get here') + finally + try + Xpath 'd' + let g:jump = "finish" + ExecAsScript E + call assert_report('should not get here') + finally + unlet g:jump + try + Xpath 'e' + call E("error") + call assert_report('should not get here') + finally + try + Xpath 'f' + call E("interrupt") + call assert_report('should not get here') + finally + try + Xpath 'g' + call E("throw") + call assert_report('should not get here') + finally + Xpath 'h' + delfunction E + endtry + endtry + endtry + endtry + endtry + endtry + endtry + call assert_report('should not get here') + [CODE] + let verify =<< trim [CODE] + call assert_equal('abcdefgh', g:Xpath) + [CODE] + call RunInNewVim(test, verify) +endfunc + +"------------------------------------------------------------------------------- +" Test 39: :finally reason discarded by an interrupt {{{1 +" +" When a :finally clause is executed due to a :continue, :break, +" :return, :finish, error, interrupt or :throw, the jump reason is +" discarded by an interrupt in the finally clause. +"------------------------------------------------------------------------------- + +func Test_finally_discarded_by_interrupt() + let test =<< trim [CODE] + func I(jump) + let loop = 0 + while loop < 2 + let loop = loop + 1 + if loop == 1 + try + if a:jump == "continue" + continue + elseif a:jump == "break" + break + elseif a:jump == "return" || a:jump == "finish" + return + elseif a:jump == "error" + asdf + elseif a:jump == "interrupt" + call interrupt() + let dummy = 0 + elseif a:jump == "throw" + throw "abc" + endif + finally + call interrupt() + let dummy = 0 + endtry + elseif loop == 2 + call assert_report('should not get here') + endif + endwhile + call assert_report('should not get here') + endfunc + + try + try + Xpath 'a' + call I("continue") + call assert_report('should not get here') + finally + try + Xpath 'b' + call I("break") + call assert_report('should not get here') + finally + try + Xpath 'c' + call I("return") + call assert_report('should not get here') + finally + try + Xpath 'd' + let g:jump = "finish" + ExecAsScript I + call assert_report('should not get here') + finally + unlet g:jump + try + Xpath 'e' + call I("error") + call assert_report('should not get here') + finally + try + Xpath 'f' + call I("interrupt") + call assert_report('should not get here') + finally + try + Xpath 'g' + call I("throw") + call assert_report('should not get here') + finally + Xpath 'h' + delfunction I + endtry + endtry + endtry + endtry + endtry + endtry + endtry + call assert_report('should not get here') + catch /^Vim:Interrupt$/ + Xpath 'A' + endtry + [CODE] + let verify =<< trim [CODE] + call assert_equal('abcdefghA', g:Xpath) + [CODE] + call RunInNewVim(test, verify) +endfunc + +"------------------------------------------------------------------------------- +" Test 40: :finally reason discarded by :throw {{{1 +" +" When a :finally clause is executed due to a :continue, :break, +" :return, :finish, error, interrupt or :throw, the jump reason is +" discarded by a :throw in the finally clause. +"------------------------------------------------------------------------------- + +func Test_finally_discard_by_throw() + let test =<< trim [CODE] + func T(jump) + let loop = 0 + while loop < 2 + let loop = loop + 1 + if loop == 1 + try + if a:jump == "continue" + continue + elseif a:jump == "break" + break + elseif a:jump == "return" || a:jump == "finish" + return + elseif a:jump == "error" + asdf + elseif a:jump == "interrupt" + call interrupt() + let dummy = 0 + elseif a:jump == "throw" + throw "abc" + endif + finally + throw "xyz" " discards jump that caused the :finally + endtry + elseif loop == 2 + call assert_report('should not get here') + endif + endwhile + call assert_report('should not get here') + endfunc + + try + Xpath 'a' + call T("continue") + call assert_report('should not get here') + finally + try + Xpath 'b' + call T("break") + call assert_report('should not get here') + finally + try + Xpath 'c' + call T("return") + call assert_report('should not get here') + finally + try + Xpath 'd' + let g:jump = "finish" + ExecAsScript T + call assert_report('should not get here') + finally + unlet g:jump + try + Xpath 'e' + call T("error") + call assert_report('should not get here') + finally + try + Xpath 'f' + call T("interrupt") + call assert_report('should not get here') + finally + try + Xpath 'g' + call T("throw") + call assert_report('should not get here') + finally + Xpath 'h' + delfunction T + endtry + endtry + endtry + endtry + endtry + endtry + endtry + call assert_report('should not get here') + [CODE] + let verify =<< trim [CODE] + call assert_equal('abcdefgh', g:Xpath) + [CODE] + call RunInNewVim(test, verify) +endfunc + +"------------------------------------------------------------------------------- +" Test 49: Throwing exceptions across functions {{{1 +" +" When an exception is thrown but not caught inside a function, the +" caller is checked for a matching :catch clause. +"------------------------------------------------------------------------------- + +func T49_C() + try + Xpath 'a' + throw "arrgh" + call assert_report('should not get here') + catch /arrgh/ + Xpath 'b' + endtry + Xpath 'c' +endfunc + +func T49_T1() + XloopNEXT + try + Xloop 'd' + throw "arrgh" + call assert_report('should not get here') + finally + Xloop 'e' + endtry + Xloop 'f' +endfunc + +func T49_T2() + try + Xpath 'g' + call T49_T1() + call assert_report('should not get here') + finally + Xpath 'h' + endtry + call assert_report('should not get here') +endfunc + +func Test_throw_exception_across_funcs() + XpathINIT + XloopINIT + try + Xpath 'i' + call T49_C() " throw and catch + Xpath 'j' + catch /.*/ + call assert_report('should not get here') + endtry + + try + Xpath 'k' + call T49_T1() " throw, one level + call assert_report('should not get here') + catch /arrgh/ + Xpath 'l' + catch /.*/ + call assert_report('should not get here') + endtry + + try + Xpath 'm' + call T49_T2() " throw, two levels + call assert_report('should not get here') + catch /arrgh/ + Xpath 'n' + catch /.*/ + call assert_report('should not get here') + endtry + Xpath 'o' + + call assert_equal('iabcjkd2e2lmgd3e3hno', g:Xpath) +endfunc + +"------------------------------------------------------------------------------- +" Test 50: Throwing exceptions across script files {{{1 +" +" When an exception is thrown but not caught inside a script file, +" the sourcing script or function is checked for a matching :catch +" clause. +" +" This test executes the bodies of the functions C, T1, and T2 from +" the previous test as script files (:return replaced by :finish). +"------------------------------------------------------------------------------- + +func T50_F() + try + Xpath 'A' + exec "source" g:scriptC + Xpath 'B' + catch /.*/ + call assert_report('should not get here') + endtry + + try + Xpath 'C' + exec "source" g:scriptT1 + call assert_report('should not get here') + catch /arrgh/ + Xpath 'D' + catch /.*/ + call assert_report('should not get here') + endtry +endfunc + +func Test_throw_across_script() + XpathINIT + XloopINIT + let g:scriptC = MakeScript("T49_C") + let g:scriptT1 = MakeScript("T49_T1") + let scriptT2 = MakeScript("T49_T2", g:scriptT1) + + try + Xpath 'E' + call T50_F() + Xpath 'F' + exec "source" scriptT2 + call assert_report('should not get here') + catch /arrgh/ + Xpath 'G' + catch /.*/ + call assert_report('should not get here') + endtry + Xpath 'H' + call assert_equal('EAabcBCd2e2DFgd3e3hGH', g:Xpath) + + call delete(g:scriptC) + call delete(g:scriptT1) + call delete(scriptT2) + unlet g:scriptC g:scriptT1 scriptT2 +endfunc + "------------------------------------------------------------------------------- " Test 87 using (expr) ? funcref : funcref {{{1 " diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -755,6 +755,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1366, +/**/ 1365, /**/ 1364,