12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390 |
- " Test try-catch-finally exception handling
- " Most of this was formerly in test49.
- source check.vim
- source shared.vim
- source vim9.vim
- "-------------------------------------------------------------------------------
- " Test environment {{{1
- "-------------------------------------------------------------------------------
- com! XpathINIT let g:Xpath = ''
- com! -nargs=1 -bar Xpath let g:Xpath = g:Xpath . <args>
- " Test 25: Executing :finally clauses on normal control flow {{{1
- "
- " Control flow in a :try conditional should always fall through to its
- " :finally clause. A :finally clause of a :try conditional inside an
- " inactive conditional should never be executed.
- "-------------------------------------------------------------------------------
- func T25_F()
- let loops = 3
- while loops > 0
- Xpath 'a' . loops
- if loops >= 2
- try
- Xpath 'b' . loops
- if loops == 2
- try
- Xpath 'c' . loops
- finally
- Xpath 'd' . loops
- endtry
- endif
- finally
- Xpath 'e' . loops
- if loops == 2
- try
- Xpath 'f' . loops
- final
- Xpath 'g' . loops
- endtry
- endif
- endtry
- endif
- Xpath 'h' . loops
- let loops = loops - 1
- endwhile
- Xpath 'i'
- endfunc
- " Also try using "fina" and "final" and "finall" as abbreviations.
- func T25_G()
- if 1
- try
- Xpath 'A'
- call T25_F()
- Xpath 'B'
- fina
- Xpath 'C'
- endtry
- else
- try
- Xpath 'D'
- finall
- Xpath 'E'
- endtry
- endif
- endfunc
- func Test_finally()
- XpathINIT
- call T25_G()
- call assert_equal('Aa3b3e3h3a2b2c2d2e2f2g2h2a1h1iBC', g:Xpath)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 26: Executing :finally clauses after :continue or :break {{{1
- "
- " For a :continue or :break dynamically enclosed in a :try/:endtry
- " region inside the next surrounding :while/:endwhile, if the
- " :continue/:break is before the :finally, the :finally clause is
- " executed first. If the :continue/:break is after the :finally, the
- " :finally clause is broken (like an :if/:endif region).
- "-------------------------------------------------------------------------------
- func T26_F()
- try
- let loops = 3
- while loops > 0
- try
- try
- if loops == 2
- Xpath 'a' . loops
- let loops = loops - 1
- continue
- elseif loops == 1
- Xpath 'b' . loops
- break
- finish
- endif
- Xpath 'c' . loops
- endtry
- finally
- Xpath 'd' . loops
- endtry
- Xpath 'e' . loops
- let loops = loops - 1
- endwhile
- Xpath 'f'
- finally
- Xpath 'g'
- let loops = 3
- while loops > 0
- try
- finally
- try
- if loops == 2
- Xpath 'h' . loops
- let loops = loops - 1
- continue
- elseif loops == 1
- Xpath 'i' . loops
- break
- finish
- endif
- endtry
- Xpath 'j' . loops
- endtry
- Xpath 'k' . loops
- let loops = loops - 1
- endwhile
- Xpath 'l'
- endtry
- Xpath 'm'
- endfunc
- func Test_finally_after_continue()
- XpathINIT
- call T26_F()
- call assert_equal('c3d3e3a2d1b1d1fgj3k3h2i1lm', g:Xpath)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 32: Remembering the :return value on :finally {{{1
- "
- " If a :finally clause is executed due to a :return specifying
- " a value, this is the value visible to the caller if not overwritten
- " by a new :return in the :finally clause. A :return without a value
- " in the :finally clause overwrites with value 0.
- "-------------------------------------------------------------------------------
- func T32_F()
- try
- Xpath 'a'
- try
- Xpath 'b'
- return "ABCD"
- Xpath 'c'
- finally
- Xpath 'd'
- endtry
- Xpath 'e'
- finally
- Xpath 'f'
- endtry
- Xpath 'g'
- endfunc
- func T32_G()
- try
- Xpath 'h'
- return 8
- Xpath 'i'
- finally
- Xpath 'j'
- return 16 + strlen(T32_F())
- Xpath 'k'
- endtry
- Xpath 'l'
- endfunc
- func T32_H()
- try
- Xpath 'm'
- return 32
- Xpath 'n'
- finally
- Xpath 'o'
- return
- Xpath 'p'
- endtry
- Xpath 'q'
- endfunc
- func T32_I()
- try
- Xpath 'r'
- finally
- Xpath 's'
- return T32_G() + T32_H() + 64
- Xpath 't'
- endtry
- Xpath 'u'
- endfunc
- func Test_finally_return()
- XpathINIT
- call assert_equal(84, T32_I())
- call assert_equal('rshjabdfmo', g:Xpath)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 33: :return under :execute or user command and :finally {{{1
- "
- " A :return command may be executed under an ":execute" or from
- " a user command. Executing of :finally clauses and passing through
- " the return code works also then.
- "-------------------------------------------------------------------------------
- func T33_F()
- try
- RETURN 10
- Xpath 'a'
- finally
- Xpath 'b'
- endtry
- Xpath 'c'
- endfunc
- func T33_G()
- try
- RETURN 20
- Xpath 'd'
- finally
- Xpath 'e'
- RETURN 30
- Xpath 'f'
- endtry
- Xpath 'g'
- endfunc
- func T33_H()
- try
- execute "try | return 40 | finally | return 50 | endtry"
- Xpath 'h'
- finally
- Xpath 'i'
- endtry
- Xpath 'j'
- endfunc
- func T33_I()
- try
- execute "try | return 60 | finally | return 70 | endtry"
- Xpath 'k'
- finally
- Xpath 'l'
- execute "try | return 80 | finally | return 90 | endtry"
- Xpath 'm'
- endtry
- Xpath 'n'
- endfunc
- func T33_J()
- try
- RETURN 100
- Xpath 'o'
- finally
- Xpath 'p'
- return
- Xpath 'q'
- endtry
- Xpath 'r'
- endfunc
- func T33_K()
- try
- execute "try | return 110 | finally | return 120 | endtry"
- Xpath 's'
- finally
- Xpath 't'
- execute "try | return 130 | finally | return | endtry"
- Xpath 'u'
- endtry
- Xpath 'v'
- endfunc
- func T33_L()
- try
- return
- Xpath 'w'
- finally
- Xpath 'x'
- RETURN 140
- Xpath 'y'
- endtry
- Xpath 'z'
- endfunc
- func T33_M()
- try
- return
- Xpath 'A'
- finally
- Xpath 'B'
- execute "try | return 150 | finally | return 160 | endtry"
- Xpath 'C'
- endtry
- Xpath 'D'
- endfunc
- func T33_N()
- RETURN 170
- endfunc
- func T33_O()
- execute "try | return 180 | finally | return 190 | endtry"
- endfunc
- func Test_finally_cmd_return()
- command! -nargs=? RETURN
- \ try | return <args> | finally | return <args> * 2 | endtry
- XpathINIT
- call assert_equal(20, T33_F())
- call assert_equal(60, T33_G())
- call assert_equal(50, T33_H())
- call assert_equal(90, T33_I())
- call assert_equal(0, T33_J())
- call assert_equal(0, T33_K())
- call assert_equal(280, T33_L())
- call assert_equal(160, T33_M())
- call assert_equal(340, T33_N())
- call assert_equal(190, T33_O())
- call assert_equal('beilptxB', g:Xpath)
- delcommand RETURN
- endfunc
- "-------------------------------------------------------------------------------
- " Test 41: Skipped :throw finding next command {{{1
- "
- " A :throw in an inactive conditional must not hide a following
- " command.
- "-------------------------------------------------------------------------------
- func T41_F()
- Xpath 'a'
- if 0 | throw 'never' | endif | Xpath 'b'
- Xpath 'c'
- endfunc
- func T41_G()
- Xpath 'd'
- while 0 | throw 'never' | endwhile | Xpath 'e'
- Xpath 'f'
- endfunc
- func T41_H()
- Xpath 'g'
- if 0 | try | throw 'never' | endtry | endif | Xpath 'h'
- Xpath 'i'
- endfunc
- func Test_throw_inactive_cond()
- XpathINIT
- try
- Xpath 'j'
- call T41_F()
- Xpath 'k'
- catch /.*/
- Xpath 'l'
- call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
- endtry
- try
- Xpath 'm'
- call T41_G()
- Xpath 'n'
- catch /.*/
- Xpath 'o'
- call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
- endtry
- try
- Xpath 'p'
- call T41_H()
- Xpath 'q'
- catch /.*/
- Xpath 'r'
- call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
- endtry
- call assert_equal('jabckmdefnpghiq', g:Xpath)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 42: Catching number and string exceptions {{{1
- "
- " When a number is thrown, it is converted to a string exception.
- " Numbers and strings may be caught by specifying a regular exception
- " as argument to the :catch command.
- "-------------------------------------------------------------------------------
- func T42_F()
- try
- try
- Xpath 'a'
- throw 4711
- Xpath 'b'
- catch /4711/
- Xpath 'c'
- endtry
- try
- Xpath 'd'
- throw 4711
- Xpath 'e'
- catch /^4711$/
- Xpath 'f'
- endtry
- try
- Xpath 'g'
- throw 4711
- Xpath 'h'
- catch /\d/
- Xpath 'i'
- endtry
- try
- Xpath 'j'
- throw 4711
- Xpath 'k'
- catch /^\d\+$/
- Xpath 'l'
- endtry
- try
- Xpath 'm'
- throw "arrgh"
- Xpath 'n'
- catch /arrgh/
- Xpath 'o'
- endtry
- try
- Xpath 'p'
- throw "arrgh"
- Xpath 'q'
- catch /^arrgh$/
- Xpath 'r'
- endtry
- try
- Xpath 's'
- throw "arrgh"
- Xpath 't'
- catch /\l/
- Xpath 'u'
- endtry
- try
- Xpath 'v'
- throw "arrgh"
- Xpath 'w'
- catch /^\l\+$/
- Xpath 'x'
- endtry
- try
- try
- Xpath 'y'
- throw "ARRGH"
- Xpath 'z'
- catch /^arrgh$/
- Xpath 'A'
- endtry
- catch /^\carrgh$/
- Xpath 'B'
- endtry
- try
- Xpath 'C'
- throw ""
- Xpath 'D'
- catch /^$/
- Xpath 'E'
- endtry
- catch /.*/
- Xpath 'F'
- call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
- endtry
- endfunc
- func Test_catch_number_string()
- XpathINIT
- call T42_F()
- call assert_equal('acdfgijlmoprsuvxyBCE', g:Xpath)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 43: Selecting the correct :catch clause {{{1
- "
- " When an exception is thrown and there are multiple :catch clauses,
- " the first matching one is taken.
- "-------------------------------------------------------------------------------
- func T43_F()
- let loops = 3
- while loops > 0
- try
- if loops == 3
- Xpath 'a' . loops
- throw "a"
- Xpath 'b' . loops
- elseif loops == 2
- Xpath 'c' . loops
- throw "ab"
- Xpath 'd' . loops
- elseif loops == 1
- Xpath 'e' . loops
- throw "abc"
- Xpath 'f' . loops
- endif
- catch /abc/
- Xpath 'g' . loops
- catch /ab/
- Xpath 'h' . loops
- catch /.*/
- Xpath 'i' . loops
- catch /a/
- Xpath 'j' . loops
- endtry
- let loops = loops - 1
- endwhile
- Xpath 'k'
- endfunc
- func Test_multi_catch()
- XpathINIT
- call T43_F()
- call assert_equal('a3i3c2h2e1g1k', g:Xpath)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 44: Missing or empty :catch patterns {{{1
- "
- " A missing or empty :catch pattern means the same as /.*/, that is,
- " catches everything. To catch only empty exceptions, /^$/ must be
- " used. A :catch with missing, empty, or /.*/ argument also works
- " when followed by another command separated by a bar on the same
- " line. :catch patterns cannot be specified between ||. But other
- " pattern separators can be used instead of //.
- "-------------------------------------------------------------------------------
- func T44_F()
- try
- try
- Xpath 'a'
- throw ""
- catch /^$/
- Xpath 'b'
- endtry
- try
- Xpath 'c'
- throw ""
- catch /.*/
- Xpath 'd'
- endtry
- try
- Xpath 'e'
- throw ""
- catch //
- Xpath 'f'
- endtry
- try
- Xpath 'g'
- throw ""
- catch
- Xpath 'h'
- endtry
- try
- Xpath 'i'
- throw "oops"
- catch /^$/
- Xpath 'j'
- catch /.*/
- Xpath 'k'
- endtry
- try
- Xpath 'l'
- throw "arrgh"
- catch /^$/
- Xpath 'm'
- catch //
- Xpath 'n'
- endtry
- try
- Xpath 'o'
- throw "brrr"
- catch /^$/
- Xpath 'p'
- catch
- Xpath 'q'
- endtry
- try | Xpath 'r' | throw "x" | catch /.*/ | Xpath 's' | endtry
- try | Xpath 't' | throw "y" | catch // | Xpath 'u' | endtry
- while 1
- try
- let caught = 0
- let v:errmsg = ""
- " Extra try level: if ":catch" without arguments below raises
- " a syntax error because it misinterprets the "Xpath" as a pattern,
- " let it be caught by the ":catch /.*/" below.
- try
- try | Xpath 'v' | throw "z" | catch | Xpath 'w' | :
- endtry
- endtry
- catch /.*/
- let caught = 1
- call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
- finally
- if $VIMNOERRTHROW && v:errmsg != ""
- call assert_report(v:errmsg)
- endif
- if caught || $VIMNOERRTHROW && v:errmsg != ""
- Xpath 'x'
- endif
- break " discard error for $VIMNOERRTHROW
- endtry
- endwhile
- let cologne = 4711
- try
- try
- Xpath 'y'
- throw "throw cologne"
- " Next lines catches all and throws 4711:
- catch |throw cologne|
- Xpath 'z'
- endtry
- catch /4711/
- Xpath 'A'
- endtry
- try
- Xpath 'B'
- throw "plus"
- catch +plus+
- Xpath 'C'
- endtry
- Xpath 'D'
- catch /.*/
- Xpath 'E'
- call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
- endtry
- endfunc
- func Test_empty_catch()
- XpathINIT
- call T44_F()
- call assert_equal('abcdefghiklnoqrstuvwyABCD', g:Xpath)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 45: Catching exceptions from nested :try blocks {{{1
- "
- " When :try blocks are nested, an exception is caught by the innermost
- " try conditional that has a matching :catch clause.
- "-------------------------------------------------------------------------------
- func T45_F()
- let loops = 3
- while loops > 0
- try
- try
- try
- try
- if loops == 3
- Xpath 'a' . loops
- throw "a"
- Xpath 'b' . loops
- elseif loops == 2
- Xpath 'c' . loops
- throw "ab"
- Xpath 'd' . loops
- elseif loops == 1
- Xpath 'e' . loops
- throw "abc"
- Xpath 'f' . loops
- endif
- catch /abc/
- Xpath 'g' . loops
- endtry
- catch /ab/
- Xpath 'h' . loops
- endtry
- catch /.*/
- Xpath 'i' . loops
- endtry
- catch /a/
- Xpath 'j' . loops
- endtry
- let loops = loops - 1
- endwhile
- Xpath 'k'
- endfunc
- func Test_catch_from_nested_try()
- XpathINIT
- call T45_F()
- call assert_equal('a3i3c2h2e1g1k', g:Xpath)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 46: Executing :finally after a :throw in nested :try {{{1
- "
- " When an exception is thrown from within nested :try blocks, the
- " :finally clauses of the non-catching try conditionals should be
- " executed before the matching :catch of the next surrounding :try
- " gets the control. If this also has a :finally clause, it is
- " executed afterwards.
- "-------------------------------------------------------------------------------
- func T46_F()
- let sum = 0
- try
- Xpath 'a'
- try
- Xpath 'b'
- try
- Xpath 'c'
- try
- Xpath 'd'
- throw "ABC"
- Xpath 'e'
- catch /xyz/
- Xpath 'f'
- finally
- Xpath 'g'
- if sum != 0
- Xpath 'h'
- endif
- let sum = sum + 1
- endtry
- Xpath 'i'
- catch /123/
- Xpath 'j'
- catch /321/
- Xpath 'k'
- finally
- Xpath 'l'
- if sum != 1
- Xpath 'm'
- endif
- let sum = sum + 2
- endtry
- Xpath 'n'
- finally
- Xpath 'o'
- if sum != 3
- Xpath 'p'
- endif
- let sum = sum + 4
- endtry
- Xpath 'q'
- catch /ABC/
- Xpath 'r'
- if sum != 7
- Xpath 's'
- endif
- let sum = sum + 8
- finally
- Xpath 't'
- if sum != 15
- Xpath 'u'
- endif
- let sum = sum + 16
- endtry
- Xpath 'v'
- if sum != 31
- Xpath 'w'
- endif
- endfunc
- func Test_finally_after_throw()
- XpathINIT
- call T46_F()
- call assert_equal('abcdglortv', g:Xpath)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 47: Throwing exceptions from a :catch clause {{{1
- "
- " When an exception is thrown from a :catch clause, it should not be
- " caught by a :catch of the same :try conditional. After executing
- " the :finally clause (if present), surrounding try conditionals
- " should be checked for a matching :catch.
- "-------------------------------------------------------------------------------
- func T47_F()
- Xpath 'a'
- try
- Xpath 'b'
- try
- Xpath 'c'
- try
- Xpath 'd'
- throw "x1"
- Xpath 'e'
- catch /x1/
- Xpath 'f'
- try
- Xpath 'g'
- throw "x2"
- Xpath 'h'
- catch /x1/
- Xpath 'i'
- catch /x2/
- Xpath 'j'
- try
- Xpath 'k'
- throw "x3"
- Xpath 'l'
- catch /x1/
- Xpath 'm'
- catch /x2/
- Xpath 'n'
- finally
- Xpath 'o'
- endtry
- Xpath 'p'
- catch /x3/
- Xpath 'q'
- endtry
- Xpath 'r'
- catch /x1/
- Xpath 's'
- catch /x2/
- Xpath 't'
- catch /x3/
- Xpath 'u'
- finally
- Xpath 'v'
- endtry
- Xpath 'w'
- catch /x1/
- Xpath 'x'
- catch /x2/
- Xpath 'y'
- catch /x3/
- Xpath 'z'
- endtry
- Xpath 'A'
- catch /.*/
- Xpath 'B'
- call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
- endtry
- Xpath 'C'
- endfunc
- func Test_throw_from_catch()
- XpathINIT
- call T47_F()
- call assert_equal('abcdfgjkovzAC', g:Xpath)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 48: Throwing exceptions from a :finally clause {{{1
- "
- " When an exception is thrown from a :finally clause, it should not be
- " caught by a :catch of the same :try conditional. Surrounding try
- " conditionals should be checked for a matching :catch. A previously
- " thrown exception is discarded.
- "-------------------------------------------------------------------------------
- func T48_F()
- try
- try
- try
- Xpath 'a'
- catch /x1/
- Xpath 'b'
- finally
- Xpath 'c'
- throw "x1"
- Xpath 'd'
- endtry
- Xpath 'e'
- catch /x1/
- Xpath 'f'
- endtry
- Xpath 'g'
- try
- try
- Xpath 'h'
- throw "x2"
- Xpath 'i'
- catch /x2/
- Xpath 'j'
- catch /x3/
- Xpath 'k'
- finally
- Xpath 'l'
- throw "x3"
- Xpath 'm'
- endtry
- Xpath 'n'
- catch /x2/
- Xpath 'o'
- catch /x3/
- Xpath 'p'
- endtry
- Xpath 'q'
- try
- try
- try
- Xpath 'r'
- throw "x4"
- Xpath 's'
- catch /x5/
- Xpath 't'
- finally
- Xpath 'u'
- throw "x5" " discards 'x4'
- Xpath 'v'
- endtry
- Xpath 'w'
- catch /x4/
- Xpath 'x'
- finally
- Xpath 'y'
- endtry
- Xpath 'z'
- catch /x5/
- Xpath 'A'
- endtry
- Xpath 'B'
- catch /.*/
- Xpath 'C'
- call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
- endtry
- Xpath 'D'
- endfunc
- func Test_throw_from_finally()
- XpathINIT
- call T48_F()
- call assert_equal('acfghjlpqruyABD', g:Xpath)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 51: Throwing exceptions across :execute and user commands {{{1
- "
- " A :throw command may be executed under an ":execute" or from
- " a user command.
- "-------------------------------------------------------------------------------
- func T51_F()
- command! -nargs=? THROW1 throw <args> | throw 1
- command! -nargs=? THROW2 try | throw <args> | endtry | throw 2
- command! -nargs=? THROW3 try | throw 3 | catch /3/ | throw <args> | endtry
- command! -nargs=? THROW4 try | throw 4 | finally | throw <args> | endtry
- try
- try
- try
- Xpath 'a'
- THROW1 "A"
- catch /A/
- Xpath 'b'
- endtry
- catch /1/
- Xpath 'c'
- endtry
- try
- try
- Xpath 'd'
- THROW2 "B"
- catch /B/
- Xpath 'e'
- endtry
- catch /2/
- Xpath 'f'
- endtry
- try
- try
- Xpath 'g'
- THROW3 "C"
- catch /C/
- Xpath 'h'
- endtry
- catch /3/
- Xpath 'i'
- endtry
- try
- try
- Xpath 'j'
- THROW4 "D"
- catch /D/
- Xpath 'k'
- endtry
- catch /4/
- Xpath 'l'
- endtry
- try
- try
- Xpath 'm'
- execute 'throw "E" | throw 5'
- catch /E/
- Xpath 'n'
- endtry
- catch /5/
- Xpath 'o'
- endtry
- try
- try
- Xpath 'p'
- execute 'try | throw "F" | endtry | throw 6'
- catch /F/
- Xpath 'q'
- endtry
- catch /6/
- Xpath 'r'
- endtry
- try
- try
- Xpath 's'
- execute'try | throw 7 | catch /7/ | throw "G" | endtry'
- catch /G/
- Xpath 't'
- endtry
- catch /7/
- Xpath 'u'
- endtry
- try
- try
- Xpath 'v'
- execute 'try | throw 8 | finally | throw "H" | endtry'
- catch /H/
- Xpath 'w'
- endtry
- catch /8/
- Xpath 'x'
- endtry
- catch /.*/
- Xpath 'y'
- call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
- endtry
- Xpath 'z'
- delcommand THROW1
- delcommand THROW2
- delcommand THROW3
- delcommand THROW4
- endfunc
- func Test_throw_across_commands()
- XpathINIT
- call T51_F()
- call assert_equal('abdeghjkmnpqstvwz', g:Xpath)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 69: :throw across :if, :elseif, :while {{{1
- "
- " On an :if, :elseif, or :while command, an exception might be thrown
- " during evaluation of the expression to test. The exception can be
- " caught by the script.
- "-------------------------------------------------------------------------------
- func T69_throw(x)
- Xpath 'x'
- throw a:x
- endfunc
- func Test_throw_ifelsewhile()
- XpathINIT
- try
- try
- Xpath 'a'
- if 111 == T69_throw("if") + 111
- Xpath 'b'
- else
- Xpath 'c'
- endif
- Xpath 'd'
- catch /^if$/
- Xpath 'e'
- catch /.*/
- Xpath 'f'
- call assert_report("if: " . v:exception . " in " . v:throwpoint)
- endtry
- try
- Xpath 'g'
- if v:false
- Xpath 'h'
- elseif 222 == T69_throw("elseif") + 222
- Xpath 'i'
- else
- Xpath 'j'
- endif
- Xpath 'k'
- catch /^elseif$/
- Xpath 'l'
- catch /.*/
- Xpath 'm'
- call assert_report("elseif: " . v:exception . " in " . v:throwpoint)
- endtry
- try
- Xpath 'n'
- while 333 == T69_throw("while") + 333
- Xpath 'o'
- break
- endwhile
- Xpath 'p'
- catch /^while$/
- Xpath 'q'
- catch /.*/
- Xpath 'r'
- call assert_report("while: " .. v:exception .. " in " .. v:throwpoint)
- endtry
- catch /^0$/ " default return value
- Xpath 's'
- call assert_report(v:throwpoint)
- catch /.*/
- call assert_report(v:exception .. " in " .. v:throwpoint)
- Xpath 't'
- endtry
- call assert_equal('axegxlnxq', g:Xpath)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 70: :throw across :return or :throw {{{1
- "
- " On a :return or :throw command, an exception might be thrown during
- " evaluation of the expression to return or throw, respectively. The
- " exception can be caught by the script.
- "-------------------------------------------------------------------------------
- let T70_taken = ""
- func T70_throw(x, n)
- let g:T70_taken = g:T70_taken . "T" . a:n
- throw a:x
- endfunc
- func T70_F(x, y, n)
- let g:T70_taken = g:T70_taken . "F" . a:n
- return a:x + T70_throw(a:y, a:n)
- endfunc
- func T70_G(x, y, n)
- let g:T70_taken = g:T70_taken . "G" . a:n
- throw a:x . T70_throw(a:y, a:n)
- return a:x
- endfunc
- func Test_throwreturn()
- XpathINIT
- try
- try
- Xpath 'a'
- call T70_F(4711, "return", 1)
- Xpath 'b'
- catch /^return$/
- Xpath 'c'
- catch /.*/
- Xpath 'd'
- call assert_report("return: " .. v:exception .. " in " .. v:throwpoint)
- endtry
- try
- Xpath 'e'
- let var = T70_F(4712, "return-var", 2)
- Xpath 'f'
- catch /^return-var$/
- Xpath 'g'
- catch /.*/
- Xpath 'h'
- call assert_report("return-var: " . v:exception . " in " . v:throwpoint)
- finally
- unlet! var
- endtry
- try
- Xpath 'i'
- throw "except1" . T70_throw("throw1", 3)
- Xpath 'j'
- catch /^except1/
- Xpath 'k'
- catch /^throw1$/
- Xpath 'l'
- catch /.*/
- Xpath 'm'
- call assert_report("throw1: " .. v:exception .. " in " .. v:throwpoint)
- endtry
- try
- Xpath 'n'
- call T70_G("except2", "throw2", 4)
- Xpath 'o'
- catch /^except2/
- Xpath 'p'
- catch /^throw2$/
- Xpath 'q'
- catch /.*/
- Xpath 'r'
- call assert_report("throw2: " .. v:exception .. " in " .. v:throwpoint)
- endtry
- try
- Xpath 's'
- let var = T70_G("except3", "throw3", 5)
- Xpath 't'
- catch /^except3/
- Xpath 'u'
- catch /^throw3$/
- Xpath 'v'
- catch /.*/
- Xpath 'w'
- call assert_report("throw3: " .. v:exception .. " in " .. v:throwpoint)
- finally
- unlet! var
- endtry
- call assert_equal('F1T1F2T2T3G4T4G5T5', g:T70_taken)
- Xpath 'x'
- catch /^0$/ " default return value
- Xpath 'y'
- call assert_report(v:throwpoint)
- catch /.*/
- Xpath 'z'
- call assert_report('Caught' .. v:exception .. ' in ' .. v:throwpoint)
- endtry
- call assert_equal('acegilnqsvx', g:Xpath)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 71: :throw across :echo variants and :execute {{{1
- "
- " On an :echo, :echon, :echomsg, :echoerr, or :execute command, an
- " exception might be thrown during evaluation of the arguments to
- " be displayed or executed as a command, respectively. Any following
- " arguments are not evaluated, then. The exception can be caught by
- " the script.
- "-------------------------------------------------------------------------------
- let T71_taken = ""
- func T71_throw(x, n)
- let g:T71_taken = g:T71_taken . "T" . a:n
- throw a:x
- endfunc
- func T71_F(n)
- let g:T71_taken = g:T71_taken . "F" . a:n
- return "F" . a:n
- endfunc
- func Test_throw_echo()
- XpathINIT
- try
- try
- Xpath 'a'
- echo 'echo ' . T71_throw("echo-except", 1) . T71_F(1)
- Xpath 'b'
- catch /^echo-except$/
- Xpath 'c'
- catch /.*/
- Xpath 'd'
- call assert_report("echo: " .. v:exception .. " in " .. v:throwpoint)
- endtry
- try
- Xpath 'e'
- echon "echon " . T71_throw("echon-except", 2) . T71_F(2)
- Xpath 'f'
- catch /^echon-except$/
- Xpath 'g'
- catch /.*/
- Xpath 'h'
- call assert_report('echon: ' . v:exception . ' in ' . v:throwpoint)
- endtry
- try
- Xpath 'i'
- echomsg "echomsg " . T71_throw("echomsg-except", 3) . T71_F(3)
- Xpath 'j'
- catch /^echomsg-except$/
- Xpath 'k'
- catch /.*/
- Xpath 'l'
- call assert_report('echomsg: ' . v:exception . ' in ' . v:throwpoint)
- endtry
- try
- Xpath 'm'
- echoerr "echoerr " . T71_throw("echoerr-except", 4) . T71_F(4)
- Xpath 'n'
- catch /^echoerr-except$/
- Xpath 'o'
- catch /Vim/
- Xpath 'p'
- catch /echoerr/
- Xpath 'q'
- catch /.*/
- Xpath 'r'
- call assert_report('echoerr: ' . v:exception . ' in ' . v:throwpoint)
- endtry
- try
- Xpath 's'
- execute "echo 'execute " . T71_throw("execute-except", 5) . T71_F(5) "'"
- Xpath 't'
- catch /^execute-except$/
- Xpath 'u'
- catch /.*/
- Xpath 'v'
- call assert_report('execute: ' . v:exception . ' in ' . v:throwpoint)
- endtry
- call assert_equal('T1T2T3T4T5', g:T71_taken)
- Xpath 'w'
- catch /^0$/ " default return value
- Xpath 'x'
- call assert_report(v:throwpoint)
- catch /.*/
- Xpath 'y'
- call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
- endtry
- call assert_equal('acegikmosuw', g:Xpath)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 72: :throw across :let or :unlet {{{1
- "
- " On a :let command, an exception might be thrown during evaluation
- " of the expression to assign. On an :let or :unlet command, the
- " evaluation of the name of the variable to be assigned or list or
- " deleted, respectively, may throw an exception. Any following
- " arguments are not evaluated, then. The exception can be caught by
- " the script.
- "-------------------------------------------------------------------------------
- let throwcount = 0
- func T72_throw(x)
- let g:throwcount = g:throwcount + 1
- throw a:x
- endfunc
- let T72_addpath = ''
- func T72_addpath(p)
- let g:T72_addpath = g:T72_addpath . a:p
- endfunc
- func Test_throw_let()
- XpathINIT
- try
- try
- let $VAR = 'old_value'
- Xpath 'a'
- let $VAR = 'let(' . T72_throw('var') . ')'
- Xpath 'b'
- catch /^var$/
- Xpath 'c'
- finally
- call assert_equal('old_value', $VAR)
- endtry
- try
- let @a = 'old_value'
- Xpath 'd'
- let @a = 'let(' . T72_throw('reg') . ')'
- Xpath 'e'
- catch /^reg$/
- try
- Xpath 'f'
- let @A = 'let(' . T72_throw('REG') . ')'
- Xpath 'g'
- catch /^REG$/
- Xpath 'h'
- endtry
- finally
- call assert_equal('old_value', @a)
- call assert_equal('old_value', @A)
- endtry
- try
- let saved_gpath = &g:path
- let saved_lpath = &l:path
- Xpath 'i'
- let &path = 'let(' . T72_throw('opt') . ')'
- Xpath 'j'
- catch /^opt$/
- try
- Xpath 'k'
- let &g:path = 'let(' . T72_throw('gopt') . ')'
- Xpath 'l'
- catch /^gopt$/
- try
- Xpath 'm'
- let &l:path = 'let(' . T72_throw('lopt') . ')'
- Xpath 'n'
- catch /^lopt$/
- Xpath 'o'
- endtry
- endtry
- finally
- call assert_equal(saved_gpath, &g:path)
- call assert_equal(saved_lpath, &l:path)
- let &g:path = saved_gpath
- let &l:path = saved_lpath
- endtry
- unlet! var1 var2 var3
- try
- Xpath 'p'
- let var1 = 'let(' . T72_throw('var1') . ')'
- Xpath 'q'
- catch /^var1$/
- Xpath 'r'
- finally
- call assert_true(!exists('var1'))
- endtry
- try
- let var2 = 'old_value'
- Xpath 's'
- let var2 = 'let(' . T72_throw('var2'). ')'
- Xpath 't'
- catch /^var2$/
- Xpath 'u'
- finally
- call assert_equal('old_value', var2)
- endtry
- try
- Xpath 'v'
- let var{T72_throw('var3')} = 4711
- Xpath 'w'
- catch /^var3$/
- Xpath 'x'
- endtry
- try
- call T72_addpath('T1')
- let var{T72_throw('var4')} var{T72_addpath('T2')} | call T72_addpath('T3')
- call T72_addpath('T4')
- catch /^var4$/
- call T72_addpath('T5')
- endtry
- try
- call T72_addpath('T6')
- unlet var{T72_throw('var5')} var{T72_addpath('T7')}
- \ | call T72_addpath('T8')
- call T72_addpath('T9')
- catch /^var5$/
- call T72_addpath('T10')
- endtry
- call assert_equal('T1T5T6T10', g:T72_addpath)
- call assert_equal(11, g:throwcount)
- catch /.*/
- call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
- endtry
- call assert_equal('acdfhikmoprsuvx', g:Xpath)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 73: :throw across :function, :delfunction {{{1
- "
- " The :function and :delfunction commands may cause an expression
- " specified in braces to be evaluated. During evaluation, an
- " exception might be thrown. The exception can be caught by the
- " script.
- "-------------------------------------------------------------------------------
- let T73_taken = ''
- func T73_throw(x, n)
- let g:T73_taken = g:T73_taken . 'T' . a:n
- throw a:x
- endfunc
- func T73_expr(x, n)
- let g:T73_taken = g:T73_taken . 'E' . a:n
- if a:n % 2 == 0
- call T73_throw(a:x, a:n)
- endif
- return 2 - a:n % 2
- endfunc
- func Test_throw_func()
- XpathINIT
- try
- try
- " Define function.
- Xpath 'a'
- function! F0()
- endfunction
- Xpath 'b'
- function! F{T73_expr('function-def-ok', 1)}()
- endfunction
- Xpath 'c'
- function! F{T73_expr('function-def', 2)}()
- endfunction
- Xpath 'd'
- catch /^function-def-ok$/
- Xpath 'e'
- catch /^function-def$/
- Xpath 'f'
- catch /.*/
- call assert_report('def: ' . v:exception . ' in ' . v:throwpoint)
- endtry
- try
- " List function.
- Xpath 'g'
- function F0
- Xpath 'h'
- function F{T73_expr('function-lst-ok', 3)}
- Xpath 'i'
- function F{T73_expr('function-lst', 4)}
- Xpath 'j'
- catch /^function-lst-ok$/
- Xpath 'k'
- catch /^function-lst$/
- Xpath 'l'
- catch /.*/
- call assert_report('lst: ' . v:exception . ' in ' . v:throwpoint)
- endtry
- try
- " Delete function
- Xpath 'm'
- delfunction F0
- Xpath 'n'
- delfunction F{T73_expr('function-del-ok', 5)}
- Xpath 'o'
- delfunction F{T73_expr('function-del', 6)}
- Xpath 'p'
- catch /^function-del-ok$/
- Xpath 'q'
- catch /^function-del$/
- Xpath 'r'
- catch /.*/
- call assert_report('del: ' . v:exception . ' in ' . v:throwpoint)
- endtry
- call assert_equal('E1E2T2E3E4T4E5E6T6', g:T73_taken)
- catch /.*/
- call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
- endtry
- call assert_equal('abcfghilmnor', g:Xpath)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 74: :throw across builtin functions and commands {{{1
- "
- " Some functions like exists(), searchpair() take expression
- " arguments, other functions or commands like substitute() or
- " :substitute cause an expression (specified in the regular
- " expression) to be evaluated. During evaluation an exception
- " might be thrown. The exception can be caught by the script.
- "-------------------------------------------------------------------------------
- let T74_taken = ""
- func T74_throw(x, n)
- let g:T74_taken = g:T74_taken . "T" . a:n
- throw a:x
- endfunc
- func T74_expr(x, n)
- let g:T74_taken = g:T74_taken . "E" . a:n
- call T74_throw(a:x . a:n, a:n)
- return "EXPR"
- endfunc
- func T74_skip(x, n)
- let g:T74_taken = g:T74_taken . "S" . a:n . "(" . line(".")
- let theline = getline(".")
- if theline =~ "skip"
- let g:T74_taken = g:T74_taken . "s)"
- return 1
- elseif theline =~ "throw"
- let g:T74_taken = g:T74_taken . "t)"
- call T74_throw(a:x . a:n, a:n)
- else
- let g:T74_taken = g:T74_taken . ")"
- return 0
- endif
- endfunc
- func T74_subst(x, n)
- let g:T74_taken = g:T74_taken . "U" . a:n . "(" . line(".")
- let theline = getline(".")
- if theline =~ "not" " T74_subst() should not be called for this line
- let g:T74_taken = g:T74_taken . "n)"
- call T74_throw(a:x . a:n, a:n)
- elseif theline =~ "throw"
- let g:T74_taken = g:T74_taken . "t)"
- call T74_throw(a:x . a:n, a:n)
- else
- let g:T74_taken = g:T74_taken . ")"
- return "replaced"
- endif
- endfunc
- func Test_throw_builtin_func()
- XpathINIT
- try
- try
- Xpath 'a'
- let result = exists('*{T74_expr("exists", 1)}')
- Xpath 'b'
- catch /^exists1$/
- Xpath 'c'
- try
- let result = exists('{T74_expr("exists", 2)}')
- Xpath 'd'
- catch /^exists2$/
- Xpath 'e'
- catch /.*/
- call assert_report('exists2: ' . v:exception . ' in ' . v:throwpoint)
- endtry
- catch /.*/
- call assert_report('exists1: ' . v:exception . ' in ' . v:throwpoint)
- endtry
- try
- let file = tempname()
- exec "edit" file
- call append(0, [
- \ 'begin',
- \ 'xx',
- \ 'middle 3',
- \ 'xx',
- \ 'middle 5 skip',
- \ 'xx',
- \ 'middle 7 throw',
- \ 'xx',
- \ 'end'])
- normal! gg
- Xpath 'f'
- let result = searchpair("begin", "middle", "end", '',
- \ 'T74_skip("searchpair", 3)')
- Xpath 'g'
- let result = searchpair("begin", "middle", "end", '',
- \ 'T74_skip("searchpair", 4)')
- Xpath 'h'
- let result = searchpair("begin", "middle", "end", '',
- \ 'T74_skip("searchpair", 5)')
- Xpath 'i'
- catch /^searchpair[35]$/
- Xpath 'j'
- catch /^searchpair4$/
- Xpath 'k'
- catch /.*/
- call assert_report('searchpair: ' . v:exception . ' in ' . v:throwpoint)
- finally
- bwipeout!
- call delete(file)
- endtry
- try
- let file = tempname()
- exec "edit" file
- call append(0, [
- \ 'subst 1',
- \ 'subst 2',
- \ 'not',
- \ 'subst 4',
- \ 'subst throw',
- \ 'subst 6'])
- normal! gg
- Xpath 'l'
- 1,2substitute/subst/\=T74_subst("substitute", 6)/
- try
- Xpath 'm'
- try
- let v:errmsg = ""
- 3substitute/subst/\=T74_subst("substitute", 7)/
- finally
- if v:errmsg != ""
- " If exceptions are not thrown on errors, fake the error
- " exception in order to get the same execution path.
- throw "faked Vim(substitute)"
- endif
- endtry
- catch /Vim(substitute)/ " Pattern not found ('e' flag missing)
- Xpath 'n'
- 3substitute/subst/\=T74_subst("substitute", 8)/e
- Xpath 'o'
- endtry
- Xpath 'p'
- 4,6substitute/subst/\=T74_subst("substitute", 9)/
- Xpath 'q'
- catch /^substitute[678]/
- Xpath 'r'
- catch /^substitute9/
- Xpath 's'
- finally
- bwipeout!
- call delete(file)
- endtry
- try
- Xpath 't'
- let var = substitute("sub", "sub", '\=T74_throw("substitute()y", 10)', '')
- Xpath 'u'
- catch /substitute()y/
- Xpath 'v'
- catch /.*/
- call assert_report('substitute()y: ' . v:exception . ' in '
- \ . v:throwpoint)
- endtry
- try
- Xpath 'w'
- let var = substitute("not", "sub", '\=T74_throw("substitute()n", 11)', '')
- Xpath 'x'
- catch /substitute()n/
- Xpath 'y'
- catch /.*/
- call assert_report('substitute()n: ' . v:exception . ' in '
- \ . v:throwpoint)
- endtry
- call assert_equal('E1T1E2T2S3(3)S4(5s)S4(7t)T4U6(1)U6(2)U9(4)U9(5t)T9T10',
- \ g:T74_taken)
- catch /.*/
- call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
- endtry
- call assert_equal('acefgklmnopstvwx', g:Xpath)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 75: Errors in builtin functions. {{{1
- "
- " On an error in a builtin function called inside a :try/:endtry
- " region, the evaluation of the expression calling that function and
- " the command containing that expression are abandoned. The error can
- " be caught as an exception.
- "
- " A simple :call of the builtin function is a trivial case. If the
- " builtin function is called in the argument list of another function,
- " no further arguments are evaluated, and the other function is not
- " executed. If the builtin function is called from the argument of
- " a :return command, the :return command is not executed. If the
- " builtin function is called from the argument of a :throw command,
- " the :throw command is not executed. The evaluation of the
- " expression calling the builtin function is abandoned.
- "-------------------------------------------------------------------------------
- func T75_F1(arg1)
- Xpath 'a'
- endfunc
- func T75_F2(arg1, arg2)
- Xpath 'b'
- endfunc
- func T75_G()
- Xpath 'c'
- endfunc
- func T75_H()
- Xpath 'd'
- endfunc
- func T75_R()
- while 1
- try
- let caught = 0
- let v:errmsg = ""
- Xpath 'e'
- return append(1, "s")
- catch /E21/
- let caught = 1
- catch /.*/
- Xpath 'f'
- finally
- Xpath 'g'
- if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
- Xpath 'h'
- endif
- break " discard error for $VIMNOERRTHROW
- endtry
- endwhile
- Xpath 'i'
- endfunc
- func Test_builtin_func_error()
- XpathINIT
- try
- set noma " let append() fail with "E21"
- while 1
- try
- let caught = 0
- let v:errmsg = ""
- Xpath 'j'
- call append(1, "s")
- catch /E21/
- let caught = 1
- catch /.*/
- Xpath 'k'
- finally
- Xpath 'l'
- if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
- Xpath 'm'
- endif
- break " discard error for $VIMNOERRTHROW
- endtry
- endwhile
- while 1
- try
- let caught = 0
- let v:errmsg = ""
- Xpath 'n'
- call T75_F1('x' . append(1, "s"))
- catch /E21/
- let caught = 1
- catch /.*/
- Xpath 'o'
- finally
- Xpath 'p'
- if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
- Xpath 'q'
- endif
- break " discard error for $VIMNOERRTHROW
- endtry
- endwhile
- while 1
- try
- let caught = 0
- let v:errmsg = ""
- Xpath 'r'
- call T75_F2('x' . append(1, "s"), T75_G())
- catch /E21/
- let caught = 1
- catch /.*/
- Xpath 's'
- finally
- Xpath 't'
- if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
- Xpath 'u'
- endif
- break " discard error for $VIMNOERRTHROW
- endtry
- endwhile
- call T75_R()
- while 1
- try
- let caught = 0
- let v:errmsg = ""
- Xpath 'v'
- throw "T" . append(1, "s")
- catch /E21/
- let caught = 1
- catch /^T.*/
- Xpath 'w'
- catch /.*/
- Xpath 'x'
- finally
- Xpath 'y'
- if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
- Xpath 'z'
- endif
- break " discard error for $VIMNOERRTHROW
- endtry
- endwhile
- while 1
- try
- let caught = 0
- let v:errmsg = ""
- Xpath 'A'
- let x = "a"
- let x = x . "b" . append(1, "s") . T75_H()
- catch /E21/
- let caught = 1
- catch /.*/
- Xpath 'B'
- finally
- Xpath 'C'
- if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
- Xpath 'D'
- endif
- call assert_equal('a', x)
- break " discard error for $VIMNOERRTHROW
- endtry
- endwhile
- catch /.*/
- call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
- finally
- set ma&
- endtry
- call assert_equal('jlmnpqrtueghivyzACD', g:Xpath)
- endfunc
- func Test_reload_in_try_catch()
- call writefile(['x'], 'Xreload')
- set autoread
- edit Xreload
- tabnew
- call writefile(['xx'], 'Xreload')
- augroup ReLoad
- au FileReadPost Xreload let x = doesnotexist
- au BufReadPost Xreload let x = doesnotexist
- augroup END
- try
- edit Xreload
- catch
- endtry
- tabnew
- tabclose
- tabclose
- autocmd! ReLoad
- set noautoread
- bwipe! Xreload
- call delete('Xreload')
- endfunc
- " Test for errors with :catch, :throw, :finally {{{1
- func Test_try_catch_errors()
- call assert_fails('throw |', 'E471:')
- call assert_fails("throw \n ", 'E471:')
- call assert_fails('catch abc', 'E654:')
- call assert_fails('try | let i = 1| finally | catch | endtry', 'E604:')
- call assert_fails('finally', 'E606:')
- call assert_fails('try | finally | finally | endtry', 'E607:')
- call assert_fails('try | for i in range(5) | endif | endtry', 'E580:')
- call assert_fails('try | while v:true | endtry', 'E170:')
- call assert_fails('try | if v:true | endtry', 'E171:')
- " this was using a negative index in cstack[]
- let lines =<< trim END
- try
- for
- if
- endwhile
- if
- finally
- END
- call CheckScriptFailure(lines, 'E690:')
- let lines =<< trim END
- try
- for
- if
- endwhile
- if
- endtry
- END
- call CheckScriptFailure(lines, 'E690:')
- endfunc
- " Test for verbose messages with :try :catch, and :finally {{{1
- func Test_try_catch_verbose()
- " This test works only when the language is English
- CheckEnglish
- set verbose=14
- " Test for verbose messages displayed when an exception is caught
- redir => msg
- try
- echo i
- catch /E121:/
- finally
- endtry
- redir END
- let expected = [
- \ 'Exception thrown: Vim(echo):E121: Undefined variable: i', '',
- \ 'Exception caught: Vim(echo):E121: Undefined variable: i', '',
- \ 'Exception finished: Vim(echo):E121: Undefined variable: i']
- call assert_equal(expected, split(msg, "\n"))
- " Test for verbose messages displayed when an exception is discarded
- redir => msg
- try
- try
- throw 'abc'
- finally
- throw 'xyz'
- endtry
- catch
- endtry
- redir END
- let expected = [
- \ 'Exception thrown: abc', '',
- \ 'Exception made pending: abc', '',
- \ 'Exception thrown: xyz', '',
- \ 'Exception discarded: abc', '',
- \ 'Exception caught: xyz', '',
- \ 'Exception finished: xyz']
- call assert_equal(expected, split(msg, "\n"))
- " Test for messages displayed when :throw is resumed after :finally
- redir => msg
- try
- try
- throw 'abc'
- finally
- endtry
- catch
- endtry
- redir END
- let expected = [
- \ 'Exception thrown: abc', '',
- \ 'Exception made pending: abc', '',
- \ 'Exception resumed: abc', '',
- \ 'Exception caught: abc', '',
- \ 'Exception finished: abc']
- call assert_equal(expected, split(msg, "\n"))
- " Test for messages displayed when :break is resumed after :finally
- redir => msg
- for i in range(1)
- try
- break
- finally
- endtry
- endfor
- redir END
- let expected = [':break made pending', '', ':break resumed']
- call assert_equal(expected, split(msg, "\n"))
- " Test for messages displayed when :continue is resumed after :finally
- redir => msg
- for i in range(1)
- try
- continue
- finally
- endtry
- endfor
- redir END
- let expected = [':continue made pending', '', ':continue resumed']
- call assert_equal(expected, split(msg, "\n"))
- " Test for messages displayed when :return is resumed after :finally
- func Xtest()
- try
- return 'vim'
- finally
- endtry
- endfunc
- redir => msg
- call Xtest()
- redir END
- let expected = [
- \ 'calling Xtest()', '',
- \ ':return vim made pending', '',
- \ ':return vim resumed', '',
- \ 'Xtest returning ''vim''', '',
- \ 'continuing in Test_try_catch_verbose']
- call assert_equal(expected, split(msg, "\n"))
- delfunc Xtest
- " Test for messages displayed when :finish is resumed after :finally
- call writefile(['try', 'finish', 'finally', 'endtry'], 'Xscript')
- redir => msg
- source Xscript
- redir END
- let expected = [
- \ ':finish made pending', '',
- \ ':finish resumed', '',
- \ 'finished sourcing Xscript',
- \ 'continuing in Test_try_catch_verbose']
- call assert_equal(expected, split(msg, "\n")[1:])
- call delete('Xscript')
- " Test for messages displayed when a pending :continue is discarded by an
- " exception in a finally handler
- redir => msg
- try
- for i in range(1)
- try
- continue
- finally
- throw 'abc'
- endtry
- endfor
- catch
- endtry
- redir END
- let expected = [
- \ ':continue made pending', '',
- \ 'Exception thrown: abc', '',
- \ ':continue discarded', '',
- \ 'Exception caught: abc', '',
- \ 'Exception finished: abc']
- call assert_equal(expected, split(msg, "\n"))
- set verbose&
- endfunc
- " Test for throwing an exception from a BufEnter autocmd {{{1
- func Test_BufEnter_exception()
- augroup bufenter_exception
- au!
- autocmd BufEnter Xfile1 throw 'abc'
- augroup END
- let caught_abc = 0
- try
- sp Xfile1
- catch /^abc/
- let caught_abc = 1
- endtry
- call assert_equal(1, caught_abc)
- call assert_equal(1, winnr('$'))
- augroup bufenter_exception
- au!
- augroup END
- augroup! bufenter_exception
- %bwipe!
- " Test for recursively throwing exceptions in autocmds
- augroup bufenter_exception
- au!
- autocmd BufEnter Xfile1 throw 'bufenter'
- autocmd BufLeave Xfile1 throw 'bufleave'
- augroup END
- let ex_count = 0
- try
- try
- sp Xfile1
- catch /^bufenter/
- let ex_count += 1
- endtry
- catch /^bufleave/
- let ex_count += 10
- endtry
- call assert_equal(10, ex_count)
- call assert_equal(2, winnr('$'))
- augroup bufenter_exception
- au!
- augroup END
- augroup! bufenter_exception
- %bwipe!
- endfunc
- " Test for using try/catch when lines are joined by "|" or "\n" {{{1
- func Test_try_catch_nextcmd()
- func Throw()
- throw "Failure"
- endfunc
- let lines =<< trim END
- try
- let s:x = Throw()
- catch
- let g:caught = 1
- endtry
- END
- let g:caught = 0
- call execute(lines)
- call assert_equal(1, g:caught)
- let g:caught = 0
- call execute(join(lines, '|'))
- call assert_equal(1, g:caught)
- let g:caught = 0
- call execute(join(lines, "\n"))
- call assert_equal(1, g:caught)
- unlet g:caught
- delfunc Throw
- endfunc
- " Test for using try/catch in a user command with a failing expression {{{1
- func Test_user_command_try_catch()
- let lines =<< trim END
- function s:throw() abort
- throw 'error'
- endfunction
- command! Execute
- \ try
- \ | let s:x = s:throw()
- \ | catch
- \ | let g:caught = 'caught'
- \ | endtry
- let g:caught = 'no'
- Execute
- call assert_equal('caught', g:caught)
- END
- call writefile(lines, 'XtestTryCatch')
- source XtestTryCatch
- call delete('XtestTryCatch')
- unlet g:caught
- endfunc
- " Test for using throw in a called function with following error {{{1
- func Test_user_command_throw_in_function_call()
- let lines =<< trim END
- function s:get_dict() abort
- throw 'my_error'
- endfunction
- try
- call s:get_dict().foo()
- catch /my_error/
- let caught = 'yes'
- catch
- let caught = v:exception
- endtry
- call assert_equal('yes', caught)
- END
- call writefile(lines, 'XtestThrow')
- source XtestThrow
- call delete('XtestThrow')
- unlet g:caught
- endfunc
- " Test that after reporting an uncaught exception there is no error for a
- " missing :endif
- func Test_after_exception_no_endif_error()
- function Throw()
- throw "Failure"
- endfunction
- function Foo()
- if 1
- call Throw()
- endif
- endfunction
- call assert_fails('call Foo()', ['E605:', 'E605:'])
- delfunc Throw
- delfunc Foo
- endfunc
- " Test for using throw in a called function with following endtry {{{1
- func Test_user_command_function_call_with_endtry()
- let lines =<< trim END
- funct s:throw(msg) abort
- throw a:msg
- endfunc
- func s:main() abort
- try
- try
- throw 'err1'
- catch
- call s:throw('err2') | endtry
- catch
- let s:caught = 'yes'
- endtry
- endfunc
- call s:main()
- call assert_equal('yes', s:caught)
- END
- call writefile(lines, 'XtestThrow')
- source XtestThrow
- call delete('XtestThrow')
- endfunc
- func ThisWillFail()
- endfunc
- " This was crashing prior to the fix in 8.2.3478.
- func Test_error_in_catch_and_finally()
- let lines =<< trim END
- try
- echo x
- catch
- for l in []
- finally
- END
- call writefile(lines, 'XtestCatchAndFinally')
- try
- source XtestCatchAndFinally
- catch /E600:/
- endtry
- call delete('XtestCatchAndFinally')
- endfunc
- " This was causing an illegal memory access
- func Test_leave_block_in_endtry_not_called()
- let lines =<< trim END
- " vim9script
- " try #
- try "
- for x in []
- if
- endwhile
- if
- endtry
- END
- call writefile(lines, 'XtestEndtry')
- try
- source XtestEndtry
- catch /E171:/
- endtry
- call delete('XtestEndtry')
- endfunc
- " Modeline {{{1
- " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
|