123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509 |
- " Test various aspects of the Vim script language.
- " Most of this was formerly in test49.vim (developed by Servatius Brandt
- " <Servatius.Brandt@fujitsu-siemens.com>)
- source check.vim
- source shared.vim
- source script_util.vim
- "-------------------------------------------------------------------------------
- " Test environment {{{1
- "-------------------------------------------------------------------------------
- " Append a message to the "messages" file
- func Xout(text)
- split messages
- $put =a:text
- wq
- endfunc
- com! -nargs=1 Xout call Xout(<args>)
- " Create a new instance of Vim and run the commands in 'test' and then 'verify'
- " The commands in 'test' are expected to store the test results in the Xtest.out
- " file. If the test passes successfully, then Xtest.out should be empty.
- func RunInNewVim(test, verify)
- let init =<< trim END
- set cpo-=C " support line-continuation in sourced script
- source script_util.vim
- XpathINIT
- XloopINIT
- END
- let cleanup =<< trim END
- call writefile(v:errors, 'Xtest.out')
- qall
- END
- call writefile(init, 'Xtest.vim')
- call writefile(a:test, 'Xtest.vim', 'a')
- call writefile(a:verify, 'Xverify.vim')
- call writefile(cleanup, 'Xverify.vim', 'a')
- call RunVim([], [], "-S Xtest.vim -S Xverify.vim")
- call assert_equal([], readfile('Xtest.out'))
- call delete('Xtest.out')
- call delete('Xtest.vim')
- call delete('Xverify.vim')
- endfunc
- "-------------------------------------------------------------------------------
- " Test 1: :endwhile in function {{{1
- "
- " Detect if a broken loop is (incorrectly) reactivated by the
- " :endwhile. Use a :return to prevent an endless loop, and make
- " this test first to get a meaningful result on an error before other
- " tests will hang.
- "-------------------------------------------------------------------------------
- func T1_F()
- Xpath 'a'
- let first = 1
- while 1
- Xpath 'b'
- if first
- Xpath 'c'
- let first = 0
- break
- else
- Xpath 'd'
- return
- endif
- endwhile
- endfunc
- func T1_G()
- Xpath 'h'
- let first = 1
- while 1
- Xpath 'i'
- if first
- Xpath 'j'
- let first = 0
- break
- else
- Xpath 'k'
- return
- endif
- if 1 " unmatched :if
- endwhile
- endfunc
- func Test_endwhile_function()
- XpathINIT
- call T1_F()
- Xpath 'F'
- try
- call T1_G()
- catch
- " Catch missing :endif
- call assert_true(v:exception =~ 'E171')
- Xpath 'x'
- endtry
- Xpath 'G'
- call assert_equal('abcFhijxG', g:Xpath)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 2: :endwhile in script {{{1
- "
- " Detect if a broken loop is (incorrectly) reactivated by the
- " :endwhile. Use a :finish to prevent an endless loop, and place
- " this test before others that might hang to get a meaningful result
- " on an error.
- "
- " This test executes the bodies of the functions T1_F and T1_G from
- " the previous test as script files (:return replaced by :finish).
- "-------------------------------------------------------------------------------
- func Test_endwhile_script()
- XpathINIT
- ExecAsScript T1_F
- Xpath 'F'
- call DeleteTheScript()
- try
- ExecAsScript T1_G
- catch
- " Catch missing :endif
- call assert_true(v:exception =~ 'E171')
- Xpath 'x'
- endtry
- Xpath 'G'
- call DeleteTheScript()
- call assert_equal('abcFhijxG', g:Xpath)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 3: :if, :elseif, :while, :continue, :break {{{1
- "-------------------------------------------------------------------------------
- func Test_if_while()
- XpathINIT
- if 1
- Xpath 'a'
- let loops = 3
- while loops > -1 " main loop: loops == 3, 2, 1 (which breaks)
- if loops <= 0
- let break_err = 1
- let loops = -1
- else
- Xpath 'b' . loops
- endif
- if (loops == 2)
- while loops == 2 " dummy loop
- Xpath 'c' . loops
- let loops = loops - 1
- continue " stop dummy loop
- Xpath 'd' . loops
- endwhile
- continue " continue main loop
- Xpath 'e' . loops
- elseif (loops == 1)
- let p = 1
- while p " dummy loop
- Xpath 'f' . loops
- let p = 0
- break " break dummy loop
- Xpath 'g' . loops
- endwhile
- Xpath 'h' . loops
- unlet p
- break " break main loop
- Xpath 'i' . loops
- endif
- if (loops > 0)
- Xpath 'j' . loops
- endif
- while loops == 3 " dummy loop
- let loops = loops - 1
- endwhile " end dummy loop
- endwhile " end main loop
- Xpath 'k'
- else
- Xpath 'l'
- endif
- Xpath 'm'
- if exists("break_err")
- Xpath 'm'
- unlet break_err
- endif
- unlet loops
- call assert_equal('ab3j3b2c2b1f1h1km', g:Xpath)
- endfunc
- " Check double quote after skipped "elseif" does not give error E15
- func Test_skipped_elseif()
- if "foo" ==? "foo"
- let result = "first"
- elseif "foo" ==? "foo"
- let result = "second"
- endif
- call assert_equal('first', result)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 4: :return {{{1
- "-------------------------------------------------------------------------------
- func T4_F()
- if 1
- Xpath 'a'
- let loops = 3
- while loops > 0 " 3: 2: 1:
- Xpath 'b' . loops
- if (loops == 2)
- Xpath 'c' . loops
- return
- Xpath 'd' . loops
- endif
- Xpath 'e' . loops
- let loops = loops - 1
- endwhile
- Xpath 'f'
- else
- Xpath 'g'
- endif
- endfunc
- func Test_return()
- XpathINIT
- call T4_F()
- Xpath '4'
- call assert_equal('ab3e3b2c24', g:Xpath)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 5: :finish {{{1
- "
- " This test executes the body of the function T4_F from the previous
- " test as a script file (:return replaced by :finish).
- "-------------------------------------------------------------------------------
- func Test_finish()
- XpathINIT
- ExecAsScript T4_F
- Xpath '5'
- call DeleteTheScript()
- call assert_equal('ab3e3b2c25', g:Xpath)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 6: Defining functions in :while loops {{{1
- "
- " Functions can be defined inside other functions. An inner function
- " gets defined when the outer function is executed. Functions may
- " also be defined inside while loops. Expressions in braces for
- " defining the function name are allowed.
- "
- " The functions are defined when sourcing the script, only the
- " resulting path is checked in the test function.
- "-------------------------------------------------------------------------------
- XpathINIT
- " The command CALL collects the argument of all its invocations in "calls"
- " when used from a function (that is, when the global variable "calls" needs
- " the "g:" prefix). This is to check that the function code is skipped when
- " the function is defined. For inner functions, do so only if the outer
- " function is not being executed.
- "
- let calls = ""
- com! -nargs=1 CALL
- \ if !exists("calls") && !exists("outer") |
- \ let g:calls = g:calls . <args> |
- \ endif
- let i = 0
- while i < 3
- let i = i + 1
- if i == 1
- Xpath 'a'
- function! F1(arg)
- CALL a:arg
- let outer = 1
- let j = 0
- while j < 1
- Xpath 'b'
- let j = j + 1
- function! G1(arg)
- CALL a:arg
- endfunction
- Xpath 'c'
- endwhile
- endfunction
- Xpath 'd'
- continue
- endif
- Xpath 'e' . i
- function! F{i}(i, arg)
- CALL a:arg
- let outer = 1
- if a:i == 3
- Xpath 'f'
- endif
- let k = 0
- while k < 3
- Xpath 'g' . k
- let k = k + 1
- function! G{a:i}{k}(arg)
- CALL a:arg
- endfunction
- Xpath 'h' . k
- endwhile
- endfunction
- Xpath 'i'
- endwhile
- if exists("*G1")
- Xpath 'j'
- endif
- if exists("*F1")
- call F1("F1")
- if exists("*G1")
- call G1("G1")
- endif
- endif
- if exists("G21") || exists("G22") || exists("G23")
- Xpath 'k'
- endif
- if exists("*F2")
- call F2(2, "F2")
- if exists("*G21")
- call G21("G21")
- endif
- if exists("*G22")
- call G22("G22")
- endif
- if exists("*G23")
- call G23("G23")
- endif
- endif
- if exists("G31") || exists("G32") || exists("G33")
- Xpath 'l'
- endif
- if exists("*F3")
- call F3(3, "F3")
- if exists("*G31")
- call G31("G31")
- endif
- if exists("*G32")
- call G32("G32")
- endif
- if exists("*G33")
- call G33("G33")
- endif
- endif
- Xpath 'm'
- let g:test6_result = g:Xpath
- let g:test6_calls = calls
- unlet calls
- delfunction F1
- delfunction G1
- delfunction F2
- delfunction G21
- delfunction G22
- delfunction G23
- delfunction G31
- delfunction G32
- delfunction G33
- func Test_defining_functions()
- call assert_equal('ade2ie3ibcg0h1g1h2g2h3fg0h1g1h2g2h3m', g:test6_result)
- call assert_equal('F1G1F2G21G22G23F3G31G32G33', g:test6_calls)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 7: Continuing on errors outside functions {{{1
- "
- " On an error outside a function, the script processing continues
- " at the line following the outermost :endif or :endwhile. When not
- " inside an :if or :while, the script processing continues at the next
- " line.
- "-------------------------------------------------------------------------------
- XpathINIT
- if 1
- Xpath 'a'
- while 1
- Xpath 'b'
- asdf
- Xpath 'c'
- break
- endwhile | Xpath 'd'
- Xpath 'e'
- endif | Xpath 'f'
- Xpath 'g'
- while 1
- Xpath 'h'
- if 1
- Xpath 'i'
- asdf
- Xpath 'j'
- endif | Xpath 'k'
- Xpath 'l'
- break
- endwhile | Xpath 'm'
- Xpath 'n'
- asdf
- Xpath 'o'
- asdf | Xpath 'p'
- Xpath 'q'
- let g:test7_result = g:Xpath
- func Test_error_in_script()
- call assert_equal('abghinoq', g:test7_result)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 8: Aborting and continuing on errors inside functions {{{1
- "
- " On an error inside a function without the "abort" attribute, the
- " script processing continues at the next line (unless the error was
- " in a :return command). On an error inside a function with the
- " "abort" attribute, the function is aborted and the script processing
- " continues after the function call; the value -1 is returned then.
- "-------------------------------------------------------------------------------
- XpathINIT
- func T8_F()
- if 1
- Xpath 'a'
- while 1
- Xpath 'b'
- asdf
- Xpath 'c'
- asdf | Xpath 'd'
- Xpath 'e'
- break
- endwhile
- Xpath 'f'
- endif | Xpath 'g'
- Xpath 'h'
- while 1
- Xpath 'i'
- if 1
- Xpath 'j'
- asdf
- Xpath 'k'
- asdf | Xpath 'l'
- Xpath 'm'
- endif
- Xpath 'n'
- break
- endwhile | Xpath 'o'
- Xpath 'p'
- return novar " returns (default return value 0)
- Xpath 'q'
- return 1 " not reached
- endfunc
- func T8_G() abort
- if 1
- Xpath 'r'
- while 1
- Xpath 's'
- asdf " returns -1
- Xpath 't'
- break
- endwhile
- Xpath 'v'
- endif | Xpath 'w'
- Xpath 'x'
- return -4 " not reached
- endfunc
- func T8_H() abort
- while 1
- Xpath 'A'
- if 1
- Xpath 'B'
- asdf " returns -1
- Xpath 'C'
- endif
- Xpath 'D'
- break
- endwhile | Xpath 'E'
- Xpath 'F'
- return -4 " not reached
- endfunc
- " Aborted functions (T8_G and T8_H) return -1.
- let g:test8_sum = (T8_F() + 1) - 4 * T8_G() - 8 * T8_H()
- Xpath 'X'
- let g:test8_result = g:Xpath
- func Test_error_in_function()
- call assert_equal(13, g:test8_sum)
- call assert_equal('abcefghijkmnoprsABX', g:test8_result)
- delfunction T8_F
- delfunction T8_G
- delfunction T8_H
- endfunc
- "-------------------------------------------------------------------------------
- " Test 9: Continuing after aborted functions {{{1
- "
- " When a function with the "abort" attribute is aborted due to an
- " error, the next function back in the call hierarchy without an
- " "abort" attribute continues; the value -1 is returned then.
- "-------------------------------------------------------------------------------
- XpathINIT
- func F() abort
- Xpath 'a'
- let result = G() " not aborted
- Xpath 'b'
- if result != 2
- Xpath 'c'
- endif
- return 1
- endfunc
- func G() " no abort attribute
- Xpath 'd'
- if H() != -1 " aborted
- Xpath 'e'
- endif
- Xpath 'f'
- return 2
- endfunc
- func H() abort
- Xpath 'g'
- call I() " aborted
- Xpath 'h'
- return 4
- endfunc
- func I() abort
- Xpath 'i'
- asdf " error
- Xpath 'j'
- return 8
- endfunc
- if F() != 1
- Xpath 'k'
- endif
- let g:test9_result = g:Xpath
- delfunction F
- delfunction G
- delfunction H
- delfunction I
- func Test_func_abort()
- call assert_equal('adgifb', g:test9_result)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 10: :if, :elseif, :while argument parsing {{{1
- "
- " A '"' or '|' in an argument expression must not be mixed up with
- " a comment or a next command after a bar. Parsing errors should
- " be recognized.
- "-------------------------------------------------------------------------------
- XpathINIT
- func MSG(enr, emsg)
- let english = v:lang == "C" || v:lang =~ '^[Ee]n'
- if a:enr == ""
- Xout "TODO: Add message number for:" a:emsg
- let v:errmsg = ":" . v:errmsg
- endif
- let match = 1
- if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
- let match = 0
- if v:errmsg == ""
- Xout "Message missing."
- else
- let v:errmsg = v:errmsg->escape('"')
- Xout "Unexpected message:" v:errmsg
- endif
- endif
- return match
- endfunc
- if 1 || strlen("\"") | Xpath 'a'
- Xpath 'b'
- endif
- Xpath 'c'
- if 0
- elseif 1 || strlen("\"") | Xpath 'd'
- Xpath 'e'
- endif
- Xpath 'f'
- while 1 || strlen("\"") | Xpath 'g'
- Xpath 'h'
- break
- endwhile
- Xpath 'i'
- let v:errmsg = ""
- if 1 ||| strlen("\"") | Xpath 'j'
- Xpath 'k'
- endif
- Xpath 'l'
- if !MSG('E15', "Invalid expression")
- Xpath 'm'
- endif
- let v:errmsg = ""
- if 0
- elseif 1 ||| strlen("\"") | Xpath 'n'
- Xpath 'o'
- endif
- Xpath 'p'
- if !MSG('E15', "Invalid expression")
- Xpath 'q'
- endif
- let v:errmsg = ""
- while 1 ||| strlen("\"") | Xpath 'r'
- Xpath 's'
- break
- endwhile
- Xpath 't'
- if !MSG('E15', "Invalid expression")
- Xpath 'u'
- endif
- let g:test10_result = g:Xpath
- delfunction MSG
- func Test_expr_parsing()
- call assert_equal('abcdefghilpt', g:test10_result)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 11: :if, :elseif, :while argument evaluation after abort {{{1
- "
- " When code is skipped over due to an error, the boolean argument to
- " an :if, :elseif, or :while must not be evaluated.
- "-------------------------------------------------------------------------------
- XpathINIT
- let calls = 0
- func P(num)
- let g:calls = g:calls + a:num " side effect on call
- return 0
- endfunc
- if 1
- Xpath 'a'
- asdf " error
- Xpath 'b'
- if P(1) " should not be called
- Xpath 'c'
- elseif !P(2) " should not be called
- Xpath 'd'
- else
- Xpath 'e'
- endif
- Xpath 'f'
- while P(4) " should not be called
- Xpath 'g'
- endwhile
- Xpath 'h'
- endif
- Xpath 'x'
- let g:test11_calls = calls
- let g:test11_result = g:Xpath
- unlet calls
- delfunction P
- func Test_arg_abort()
- call assert_equal(0, g:test11_calls)
- call assert_equal('ax', g:test11_result)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 12: Expressions in braces in skipped code {{{1
- "
- " In code skipped over due to an error or inactive conditional,
- " an expression in braces as part of a variable or function name
- " should not be evaluated.
- "-------------------------------------------------------------------------------
- XpathINIT
- func NULL()
- Xpath 'a'
- return 0
- endfunc
- func ZERO()
- Xpath 'b'
- return 0
- endfunc
- func! F0()
- Xpath 'c'
- endfunc
- func! F1(arg)
- Xpath 'e'
- endfunc
- let V0 = 1
- Xpath 'f'
- echo 0 ? F{NULL() + V{ZERO()}}() : 1
- Xpath 'g'
- if 0
- Xpath 'h'
- call F{NULL() + V{ZERO()}}()
- endif
- Xpath 'i'
- if 1
- asdf " error
- Xpath 'j'
- call F1(F{NULL() + V{ZERO()}}())
- endif
- Xpath 'k'
- if 1
- asdf " error
- Xpath 'l'
- call F{NULL() + V{ZERO()}}()
- endif
- let g:test12_result = g:Xpath
- func Test_braces_skipped()
- call assert_equal('fgik', g:test12_result)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 13: Failure in argument evaluation for :while {{{1
- "
- " A failure in the expression evaluation for the condition of a :while
- " causes the whole :while loop until the matching :endwhile being
- " ignored. Continuation is at the next following line.
- "-------------------------------------------------------------------------------
- XpathINIT
- Xpath 'a'
- while asdf
- Xpath 'b'
- while 1
- Xpath 'c'
- break
- endwhile
- Xpath 'd'
- break
- endwhile
- Xpath 'e'
- while asdf | Xpath 'f' | endwhile | Xpath 'g'
- Xpath 'h'
- let g:test13_result = g:Xpath
- func Test_while_fail()
- call assert_equal('aeh', g:test13_result)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 14: Failure in argument evaluation for :if {{{1
- "
- " A failure in the expression evaluation for the condition of an :if
- " does not cause the corresponding :else or :endif being matched to
- " a previous :if/:elseif. Neither of both branches of the failed :if
- " are executed.
- "-------------------------------------------------------------------------------
- XpathINIT
- function! F()
- Xpath 'a'
- let x = 0
- if x " false
- Xpath 'b'
- elseif !x " always true
- Xpath 'c'
- let x = 1
- if g:boolvar " possibly undefined
- Xpath 'd'
- else
- Xpath 'e'
- endif
- Xpath 'f'
- elseif x " never executed
- Xpath 'g'
- endif
- Xpath 'h'
- endfunction
- let boolvar = 1
- call F()
- Xpath '-'
- unlet boolvar
- call F()
- let g:test14_result = g:Xpath
- delfunction F
- func Test_if_fail()
- call assert_equal('acdfh-acfh', g:test14_result)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 15: Failure in argument evaluation for :if (bar) {{{1
- "
- " Like previous test, except that the failing :if ... | ... | :endif
- " is in a single line.
- "-------------------------------------------------------------------------------
- XpathINIT
- function! F()
- Xpath 'a'
- let x = 0
- if x " false
- Xpath 'b'
- elseif !x " always true
- Xpath 'c'
- let x = 1
- if g:boolvar | Xpath 'd' | else | Xpath 'e' | endif
- Xpath 'f'
- elseif x " never executed
- Xpath 'g'
- endif
- Xpath 'h'
- endfunction
- let boolvar = 1
- call F()
- Xpath '-'
- unlet boolvar
- call F()
- let g:test15_result = g:Xpath
- delfunction F
- func Test_if_bar_fail()
- call assert_equal('acdfh-acfh', g:test15_result)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 16: Double :else or :elseif after :else {{{1
- "
- " Multiple :elses or an :elseif after an :else are forbidden.
- "-------------------------------------------------------------------------------
- func T16_F() abort
- if 0
- Xpath 'a'
- else
- Xpath 'b'
- else " aborts function
- Xpath 'c'
- endif
- Xpath 'd'
- endfunc
- func T16_G() abort
- if 0
- Xpath 'a'
- else
- Xpath 'b'
- elseif 1 " aborts function
- Xpath 'c'
- else
- Xpath 'd'
- endif
- Xpath 'e'
- endfunc
- func T16_H() abort
- if 0
- Xpath 'a'
- elseif 0
- Xpath 'b'
- else
- Xpath 'c'
- else " aborts function
- Xpath 'd'
- endif
- Xpath 'e'
- endfunc
- func T16_I() abort
- if 0
- Xpath 'a'
- elseif 0
- Xpath 'b'
- else
- Xpath 'c'
- elseif 1 " aborts function
- Xpath 'd'
- else
- Xpath 'e'
- endif
- Xpath 'f'
- endfunc
- func Test_Multi_Else()
- XpathINIT
- try
- call T16_F()
- catch /E583:/
- Xpath 'e'
- endtry
- call assert_equal('be', g:Xpath)
- XpathINIT
- try
- call T16_G()
- catch /E584:/
- Xpath 'f'
- endtry
- call assert_equal('bf', g:Xpath)
- XpathINIT
- try
- call T16_H()
- catch /E583:/
- Xpath 'f'
- endtry
- call assert_equal('cf', g:Xpath)
- XpathINIT
- try
- call T16_I()
- catch /E584:/
- Xpath 'g'
- endtry
- call assert_equal('cg', g:Xpath)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 17: Nesting of unmatched :if or :endif inside a :while {{{1
- "
- " The :while/:endwhile takes precedence in nesting over an unclosed
- " :if or an unopened :endif.
- "-------------------------------------------------------------------------------
- " While loops inside a function are continued on error.
- func T17_F()
- let loops = 3
- while loops > 0
- let loops -= 1
- Xpath 'a' . loops
- if (loops == 1)
- Xpath 'b' . loops
- continue
- elseif (loops == 0)
- Xpath 'c' . loops
- break
- elseif 1
- Xpath 'd' . loops
- " endif missing!
- endwhile " :endwhile after :if 1
- Xpath 'e'
- endfunc
- func T17_G()
- let loops = 2
- while loops > 0
- let loops -= 1
- Xpath 'a' . loops
- if 0
- Xpath 'b' . loops
- " endif missing
- endwhile " :endwhile after :if 0
- endfunc
- func T17_H()
- let loops = 2
- while loops > 0
- let loops -= 1
- Xpath 'a' . loops
- " if missing!
- endif " :endif without :if in while
- Xpath 'b' . loops
- endwhile
- endfunc
- " Error continuation outside a function is at the outermost :endwhile or :endif.
- XpathINIT
- let v:errmsg = ''
- let loops = 2
- while loops > 0
- let loops -= 1
- Xpath 'a' . loops
- if 0
- Xpath 'b' . loops
- " endif missing! Following :endwhile fails.
- endwhile | Xpath 'c'
- Xpath 'd'
- call assert_match('E171:', v:errmsg)
- call assert_equal('a1d', g:Xpath)
- func Test_unmatched_if_in_while()
- XpathINIT
- call assert_fails('call T17_F()', 'E171:')
- call assert_equal('a2d2a1b1a0c0e', g:Xpath)
- XpathINIT
- call assert_fails('call T17_G()', 'E171:')
- call assert_equal('a1a0', g:Xpath)
- XpathINIT
- call assert_fails('call T17_H()', 'E580:')
- call assert_equal('a1b1a0b0', g:Xpath)
- 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 52: Uncaught exceptions {{{1
- "
- " When an exception is thrown but not caught, an error message is
- " displayed when the script is terminated. In case of an interrupt
- " or error exception, the normal interrupt or error message(s) are
- " displayed.
- "-------------------------------------------------------------------------------
- func Test_uncaught_exception_1()
- CheckEnglish
- let test =<< trim [CODE]
- Xpath 'a'
- throw "arrgh"
- call assert_report('should not get here')`
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('E605: Exception not caught: arrgh', v:errmsg)
- call assert_equal('a', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
- endfunc
- func Test_uncaught_exception_2()
- CheckEnglish
- let test =<< trim [CODE]
- try
- Xpath 'a'
- throw "oops"
- call assert_report('should not get here')`
- catch /arrgh/
- call assert_report('should not get here')`
- endtry
- call assert_report('should not get here')`
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('E605: Exception not caught: oops', v:errmsg)
- call assert_equal('a', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
- endfunc
- func Test_uncaught_exception_3()
- CheckEnglish
- let test =<< trim [CODE]
- func T()
- Xpath 'c'
- throw "brrr"
- call assert_report('should not get here')`
- endfunc
- try
- Xpath 'a'
- throw "arrgh"
- call assert_report('should not get here')`
- catch /.*/
- Xpath 'b'
- call T()
- call assert_report('should not get here')`
- endtry
- call assert_report('should not get here')`
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('E605: Exception not caught: brrr', v:errmsg)
- call assert_equal('abc', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
- endfunc
- func Test_uncaught_exception_4()
- CheckEnglish
- let test =<< trim [CODE]
- try
- Xpath 'a'
- throw "arrgh"
- call assert_report('should not get here')`
- finally
- Xpath 'b'
- throw "brrr"
- call assert_report('should not get here')`
- endtry
- call assert_report('should not get here')`
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('E605: Exception not caught: brrr', v:errmsg)
- call assert_equal('ab', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
- endfunc
- func Test_uncaught_exception_5()
- CheckEnglish
- " Need to catch and handle interrupt, otherwise the test will wait for the
- " user to press <Enter> to continue
- 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')
- catch /^Vim:Interrupt$/
- Xpath 'b'
- endtry
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('ab', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
- endfunc
- func Test_uncaught_exception_6()
- CheckEnglish
- let test =<< trim [CODE]
- try
- Xpath 'a'
- let x = novar " error E121; exception: E121
- catch /E15:/ " should not catch
- call assert_report('should not get here')
- endtry
- call assert_report('should not get here')
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('a', g:Xpath)
- call assert_equal('E121: Undefined variable: novar', v:errmsg)
- [CODE]
- call RunInNewVim(test, verify)
- endfunc
- func Test_uncaught_exception_7()
- CheckEnglish
- let test =<< trim [CODE]
- try
- Xpath 'a'
- " error E108/E488; exception: E488
- unlet novar #
- catch /E108:/ " should not catch
- call assert_report('should not get here')
- endtry
- call assert_report('should not get here')
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('a', g:Xpath)
- call assert_equal('E488: Trailing characters: #', v:errmsg)
- [CODE]
- call RunInNewVim(test, verify)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 53: Nesting errors: :endif/:else/:elseif {{{1
- "
- " For nesting errors of :if conditionals the correct error messages
- " should be given.
- "-------------------------------------------------------------------------------
- func Test_nested_if_else_errors()
- CheckEnglish
- " :endif without :if
- let code =<< trim END
- endif
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endif):E580: :endif without :if')
- " :endif without :if
- let code =<< trim END
- while 1
- endif
- endwhile
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endif):E580: :endif without :if')
- " :endif without :if
- let code =<< trim END
- try
- finally
- endif
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endif):E580: :endif without :if')
- " :endif without :if
- let code =<< trim END
- try
- endif
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endif):E580: :endif without :if')
- " :endif without :if
- let code =<< trim END
- try
- throw "a"
- catch /a/
- endif
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endif):E580: :endif without :if')
- " :else without :if
- let code =<< trim END
- else
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(else):E581: :else without :if')
- " :else without :if
- let code =<< trim END
- while 1
- else
- endwhile
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(else):E581: :else without :if')
- " :else without :if
- let code =<< trim END
- try
- finally
- else
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(else):E581: :else without :if')
- " :else without :if
- let code =<< trim END
- try
- else
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(else):E581: :else without :if')
- " :else without :if
- let code =<< trim END
- try
- throw "a"
- catch /a/
- else
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(else):E581: :else without :if')
- " :elseif without :if
- let code =<< trim END
- elseif 1
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(elseif):E582: :elseif without :if')
- " :elseif without :if
- let code =<< trim END
- while 1
- elseif 1
- endwhile
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(elseif):E582: :elseif without :if')
- " :elseif without :if
- let code =<< trim END
- try
- finally
- elseif 1
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(elseif):E582: :elseif without :if')
- " :elseif without :if
- let code =<< trim END
- try
- elseif 1
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(elseif):E582: :elseif without :if')
- " :elseif without :if
- let code =<< trim END
- try
- throw "a"
- catch /a/
- elseif 1
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(elseif):E582: :elseif without :if')
- " multiple :else
- let code =<< trim END
- if 1
- else
- else
- endif
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(else):E583: Multiple :else')
- " :elseif after :else
- let code =<< trim END
- if 1
- else
- elseif 1
- endif
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(elseif):E584: :elseif after :else')
- call delete('Xtest')
- endfunc
- "-------------------------------------------------------------------------------
- " Test 54: Nesting errors: :while/:endwhile {{{1
- "
- " For nesting errors of :while conditionals the correct error messages
- " should be given.
- "
- " This test reuses the function MESSAGES() from the previous test.
- " This function checks the messages in g:msgfile.
- "-------------------------------------------------------------------------------
- func Test_nested_while_error()
- CheckEnglish
- " :endwhile without :while
- let code =<< trim END
- endwhile
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while')
- " :endwhile without :while
- let code =<< trim END
- if 1
- endwhile
- endif
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while')
- " Missing :endif
- let code =<< trim END
- while 1
- if 1
- endwhile
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endwhile):E171: Missing :endif')
- " :endwhile without :while
- let code =<< trim END
- try
- finally
- endwhile
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while')
- " Missing :endtry
- let code =<< trim END
- while 1
- try
- finally
- endwhile
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endwhile):E600: Missing :endtry')
- " Missing :endtry
- let code =<< trim END
- while 1
- if 1
- try
- finally
- endwhile
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endwhile):E600: Missing :endtry')
- " Missing :endif
- let code =<< trim END
- while 1
- try
- finally
- if 1
- endwhile
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endwhile):E171: Missing :endif')
- " :endwhile without :while
- let code =<< trim END
- try
- endwhile
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while')
- " :endwhile without :while
- let code =<< trim END
- while 1
- try
- endwhile
- endtry
- endwhile
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while')
- " :endwhile without :while
- let code =<< trim END
- try
- throw "a"
- catch /a/
- endwhile
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while')
- " :endwhile without :while
- let code =<< trim END
- while 1
- try
- throw "a"
- catch /a/
- endwhile
- endtry
- endwhile
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while')
- call delete('Xtest')
- endfunc
- "-------------------------------------------------------------------------------
- " Test 55: Nesting errors: :continue/:break {{{1
- "
- " For nesting errors of :continue and :break commands the correct
- " error messages should be given.
- "
- " This test reuses the function MESSAGES() from the previous test.
- " This function checks the messages in g:msgfile.
- "-------------------------------------------------------------------------------
- func Test_nested_cont_break_error()
- CheckEnglish
- " :continue without :while
- let code =<< trim END
- continue
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(continue):E586: :continue without :while or :for')
- " :continue without :while
- let code =<< trim END
- if 1
- continue
- endif
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(continue):E586: :continue without :while or :for')
- " :continue without :while
- let code =<< trim END
- try
- finally
- continue
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(continue):E586: :continue without :while or :for')
- " :continue without :while
- let code =<< trim END
- try
- continue
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(continue):E586: :continue without :while or :for')
- " :continue without :while
- let code =<< trim END
- try
- throw "a"
- catch /a/
- continue
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(continue):E586: :continue without :while or :for')
- " :break without :while
- let code =<< trim END
- break
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(break):E587: :break without :while or :for')
- " :break without :while
- let code =<< trim END
- if 1
- break
- endif
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(break):E587: :break without :while or :for')
- " :break without :while
- let code =<< trim END
- try
- finally
- break
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(break):E587: :break without :while or :for')
- " :break without :while
- let code =<< trim END
- try
- break
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(break):E587: :break without :while or :for')
- " :break without :while
- let code =<< trim END
- try
- throw "a"
- catch /a/
- break
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(break):E587: :break without :while or :for')
- call delete('Xtest')
- endfunc
- "-------------------------------------------------------------------------------
- " Test 56: Nesting errors: :endtry {{{1
- "
- " For nesting errors of :try conditionals the correct error messages
- " should be given.
- "
- " This test reuses the function MESSAGES() from the previous test.
- " This function check the messages in g:msgfile.
- "-------------------------------------------------------------------------------
- func Test_nested_endtry_error()
- CheckEnglish
- " :endtry without :try
- let code =<< trim END
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endtry):E602: :endtry without :try')
- " :endtry without :try
- let code =<< trim END
- if 1
- endtry
- endif
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endtry):E602: :endtry without :try')
- " :endtry without :try
- let code =<< trim END
- while 1
- endtry
- endwhile
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endtry):E602: :endtry without :try')
- " Missing :endif
- let code =<< trim END
- try
- if 1
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endtry):E171: Missing :endif')
- " Missing :endwhile
- let code =<< trim END
- try
- while 1
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endtry):E170: Missing :endwhile')
- " Missing :endif
- let code =<< trim END
- try
- finally
- if 1
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endtry):E171: Missing :endif')
- " Missing :endwhile
- let code =<< trim END
- try
- finally
- while 1
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endtry):E170: Missing :endwhile')
- " Missing :endif
- let code =<< trim END
- try
- throw "a"
- catch /a/
- if 1
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endtry):E171: Missing :endif')
- " Missing :endwhile
- let code =<< trim END
- try
- throw "a"
- catch /a/
- while 1
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endtry):E170: Missing :endwhile')
- call delete('Xtest')
- endfunc
- "-------------------------------------------------------------------------------
- " Test 57: v:exception and v:throwpoint for user exceptions {{{1
- "
- " v:exception evaluates to the value of the exception that was caught
- " most recently and is not finished. (A caught exception is finished
- " when the next ":catch", ":finally", or ":endtry" is reached.)
- " v:throwpoint evaluates to the script/function name and line number
- " where that exception has been thrown.
- "-------------------------------------------------------------------------------
- func Test_user_exception_info()
- CheckEnglish
- XpathINIT
- XloopINIT
- func FuncException()
- let g:exception = v:exception
- endfunc
- func FuncThrowpoint()
- let g:throwpoint = v:throwpoint
- endfunc
- let scriptException = MakeScript("FuncException")
- let scriptThrowPoint = MakeScript("FuncThrowpoint")
- command! CmdException let g:exception = v:exception
- command! CmdThrowpoint let g:throwpoint = v:throwpoint
- func T(arg, line)
- if a:line == 2
- throw a:arg " in line 2
- elseif a:line == 4
- throw a:arg " in line 4
- elseif a:line == 6
- throw a:arg " in line 6
- elseif a:line == 8
- throw a:arg " in line 8
- endif
- endfunc
- func G(arg, line)
- call T(a:arg, a:line)
- endfunc
- func F(arg, line)
- call G(a:arg, a:line)
- endfunc
- let scriptT = MakeScript("T")
- let scriptG = MakeScript("G", scriptT)
- let scriptF = MakeScript("F", scriptG)
- try
- Xpath 'a'
- call F("oops", 2)
- catch /.*/
- Xpath 'b'
- let exception = v:exception
- let throwpoint = v:throwpoint
- call assert_equal("oops", v:exception)
- call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint)
- call assert_match('\<2\>', v:throwpoint)
- exec "let exception = v:exception"
- exec "let throwpoint = v:throwpoint"
- call assert_equal("oops", v:exception)
- call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint)
- call assert_match('\<2\>', v:throwpoint)
- CmdException
- CmdThrowpoint
- call assert_equal("oops", v:exception)
- call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint)
- call assert_match('\<2\>', v:throwpoint)
- call FuncException()
- call FuncThrowpoint()
- call assert_equal("oops", v:exception)
- call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint)
- call assert_match('\<2\>', v:throwpoint)
- exec "source" scriptException
- exec "source" scriptThrowPoint
- call assert_equal("oops", v:exception)
- call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint)
- call assert_match('\<2\>', v:throwpoint)
- try
- Xpath 'c'
- call G("arrgh", 4)
- catch /.*/
- Xpath 'd'
- let exception = v:exception
- let throwpoint = v:throwpoint
- call assert_equal("arrgh", v:exception)
- call assert_match('\<G\[1]\.\.T\>', v:throwpoint)
- call assert_match('\<4\>', v:throwpoint)
- try
- Xpath 'e'
- let g:arg = "autsch"
- let g:line = 6
- exec "source" scriptF
- catch /.*/
- Xpath 'f'
- let exception = v:exception
- let throwpoint = v:throwpoint
- call assert_equal("autsch", v:exception)
- call assert_match(fnamemodify(scriptT, ':t'), v:throwpoint)
- call assert_match('\<6\>', v:throwpoint)
- finally
- Xpath 'g'
- let exception = v:exception
- let throwpoint = v:throwpoint
- call assert_equal("arrgh", v:exception)
- call assert_match('\<G\[1]\.\.T\>', v:throwpoint)
- call assert_match('\<4\>', v:throwpoint)
- try
- Xpath 'h'
- let g:arg = "brrrr"
- let g:line = 8
- exec "source" scriptG
- catch /.*/
- Xpath 'i'
- let exception = v:exception
- let throwpoint = v:throwpoint
- " Resolve scriptT for matching it against v:throwpoint.
- call assert_equal("brrrr", v:exception)
- call assert_match(fnamemodify(scriptT, ':t'), v:throwpoint)
- call assert_match('\<8\>', v:throwpoint)
- finally
- Xpath 'j'
- let exception = v:exception
- let throwpoint = v:throwpoint
- call assert_equal("arrgh", v:exception)
- call assert_match('\<G\[1]\.\.T\>', v:throwpoint)
- call assert_match('\<4\>', v:throwpoint)
- endtry
- Xpath 'k'
- let exception = v:exception
- let throwpoint = v:throwpoint
- call assert_equal("arrgh", v:exception)
- call assert_match('\<G\[1]\.\.T\>', v:throwpoint)
- call assert_match('\<4\>', v:throwpoint)
- endtry
- Xpath 'l'
- let exception = v:exception
- let throwpoint = v:throwpoint
- call assert_equal("arrgh", v:exception)
- call assert_match('\<G\[1]\.\.T\>', v:throwpoint)
- call assert_match('\<4\>', v:throwpoint)
- finally
- Xpath 'm'
- let exception = v:exception
- let throwpoint = v:throwpoint
- call assert_equal("oops", v:exception)
- call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint)
- call assert_match('\<2\>', v:throwpoint)
- endtry
- Xpath 'n'
- let exception = v:exception
- let throwpoint = v:throwpoint
- call assert_equal("oops", v:exception)
- call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint)
- call assert_match('\<2\>', v:throwpoint)
- finally
- Xpath 'o'
- let exception = v:exception
- let throwpoint = v:throwpoint
- call assert_equal("", v:exception)
- call assert_match('^$', v:throwpoint)
- call assert_match('^$', v:throwpoint)
- endtry
- call assert_equal('abcdefghijklmno', g:Xpath)
- unlet exception throwpoint
- delfunction FuncException
- delfunction FuncThrowpoint
- call delete(scriptException)
- call delete(scriptThrowPoint)
- unlet scriptException scriptThrowPoint
- delcommand CmdException
- delcommand CmdThrowpoint
- delfunction T
- delfunction G
- delfunction F
- call delete(scriptT)
- call delete(scriptG)
- call delete(scriptF)
- unlet scriptT scriptG scriptF
- endfunc
- "-------------------------------------------------------------------------------
- "
- " Test 58: v:exception and v:throwpoint for error/interrupt exceptions {{{1
- "
- " v:exception and v:throwpoint work also for error and interrupt
- " exceptions.
- "-------------------------------------------------------------------------------
- func Test_exception_info_for_error()
- CheckEnglish
- let test =<< trim [CODE]
- func T(line)
- if a:line == 2
- delfunction T " error (function in use) in line 2
- elseif a:line == 4
- call interrupt()
- endif
- endfunc
- while 1
- try
- Xpath 'a'
- call T(2)
- call assert_report('should not get here')
- catch /.*/
- Xpath 'b'
- if v:exception !~ 'Vim(delfunction):'
- call assert_report('should not get here')
- endif
- if v:throwpoint !~ '\<T\>'
- call assert_report('should not get here')
- endif
- if v:throwpoint !~ '\<2\>'
- call assert_report('should not get here')
- endif
- finally
- Xpath 'c'
- if v:exception != ""
- call assert_report('should not get here')
- endif
- if v:throwpoint != ""
- call assert_report('should not get here')
- endif
- break
- endtry
- endwhile
- Xpath 'd'
- if v:exception != ""
- call assert_report('should not get here')
- endif
- if v:throwpoint != ""
- call assert_report('should not get here')
- endif
- while 1
- try
- Xpath 'e'
- call T(4)
- call assert_report('should not get here')
- catch /.*/
- Xpath 'f'
- if v:exception != 'Vim:Interrupt'
- call assert_report('should not get here')
- endif
- if v:throwpoint !~ 'function T'
- call assert_report('should not get here')
- endif
- if v:throwpoint !~ '\<4\>'
- call assert_report('should not get here')
- endif
- finally
- Xpath 'g'
- if v:exception != ""
- call assert_report('should not get here')
- endif
- if v:throwpoint != ""
- call assert_report('should not get here')
- endif
- break
- endtry
- endwhile
- Xpath 'h'
- if v:exception != ""
- call assert_report('should not get here')
- endif
- if v:throwpoint != ""
- call assert_report('should not get here')
- endif
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('abcdefgh', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
- endfunc
- "-------------------------------------------------------------------------------
- "
- " Test 59: v:exception and v:throwpoint when discarding exceptions {{{1
- "
- " When a :catch clause is left by a ":break" etc or an error or
- " interrupt exception, v:exception and v:throwpoint are reset. They
- " are not affected by an exception that is discarded before being
- " caught.
- "-------------------------------------------------------------------------------
- func Test_exception_info_on_discard()
- CheckEnglish
- let test =<< trim [CODE]
- let sfile = expand("<sfile>")
- while 1
- try
- throw "x1"
- catch /.*/
- break
- endtry
- endwhile
- call assert_equal('', v:exception)
- call assert_equal('', v:throwpoint)
- while 1
- try
- throw "x2"
- catch /.*/
- break
- finally
- call assert_equal('', v:exception)
- call assert_equal('', v:throwpoint)
- endtry
- break
- endwhile
- call assert_equal('', v:exception)
- call assert_equal('', v:throwpoint)
- while 1
- try
- let errcaught = 0
- try
- try
- throw "x3"
- catch /.*/
- let lnum = expand("<sflnum>")
- asdf
- endtry
- catch /.*/
- let errcaught = 1
- call assert_match('Vim:E492: Not an editor command:', v:exception)
- call assert_match('line ' .. (lnum + 1), v:throwpoint)
- endtry
- finally
- call assert_equal(1, errcaught)
- break
- endtry
- endwhile
- call assert_equal('', v:exception)
- call assert_equal('', v:throwpoint)
- Xpath 'a'
- while 1
- try
- let intcaught = 0
- try
- try
- throw "x4"
- catch /.*/
- let lnum = expand("<sflnum>")
- call interrupt()
- endtry
- catch /.*/
- let intcaught = 1
- call assert_match('Vim:Interrupt', v:exception)
- call assert_match('line ' .. (lnum + 1), v:throwpoint)
- endtry
- finally
- call assert_equal(1, intcaught)
- break
- endtry
- endwhile
- call assert_equal('', v:exception)
- call assert_equal('', v:throwpoint)
- Xpath 'b'
- while 1
- try
- let errcaught = 0
- try
- try
- if 1
- let lnum = expand("<sflnum>")
- throw "x5"
- " missing endif
- catch /.*/
- call assert_report('should not get here')
- endtry
- catch /.*/
- let errcaught = 1
- call assert_match('Vim(catch):E171: Missing :endif:', v:exception)
- call assert_match('line ' .. (lnum + 3), v:throwpoint)
- endtry
- finally
- call assert_equal(1, errcaught)
- break
- endtry
- endwhile
- call assert_equal('', v:exception)
- call assert_equal('', v:throwpoint)
- Xpath 'c'
- try
- while 1
- try
- throw "x6"
- finally
- break
- endtry
- break
- endwhile
- catch /.*/
- call assert_report('should not get here')
- endtry
- call assert_equal('', v:exception)
- call assert_equal('', v:throwpoint)
- try
- while 1
- try
- throw "x7"
- finally
- break
- endtry
- break
- endwhile
- catch /.*/
- call assert_report('should not get here')
- finally
- call assert_equal('', v:exception)
- call assert_equal('', v:throwpoint)
- endtry
- call assert_equal('', v:exception)
- call assert_equal('', v:throwpoint)
- while 1
- try
- let errcaught = 0
- try
- try
- throw "x8"
- finally
- let lnum = expand("<sflnum>")
- asdf
- endtry
- catch /.*/
- let errcaught = 1
- call assert_match('Vim:E492: Not an editor command:', v:exception)
- call assert_match('line ' .. (lnum + 1), v:throwpoint)
- endtry
- finally
- call assert_equal(1, errcaught)
- break
- endtry
- endwhile
- call assert_equal('', v:exception)
- call assert_equal('', v:throwpoint)
- Xpath 'd'
- while 1
- try
- let intcaught = 0
- try
- try
- throw "x9"
- finally
- let lnum = expand("<sflnum>")
- call interrupt()
- endtry
- catch /.*/
- let intcaught = 1
- call assert_match('Vim:Interrupt', v:exception)
- call assert_match('line ' .. (lnum + 1), v:throwpoint)
- endtry
- finally
- call assert_equal(1, intcaught)
- break
- endtry
- endwhile
- call assert_equal('', v:exception)
- call assert_equal('', v:throwpoint)
- Xpath 'e'
- while 1
- try
- let errcaught = 0
- try
- try
- if 1
- let lnum = expand("<sflnum>")
- throw "x10"
- " missing endif
- finally
- call assert_equal('', v:exception)
- call assert_equal('', v:throwpoint)
- endtry
- catch /.*/
- let errcaught = 1
- call assert_match('Vim(finally):E171: Missing :endif:', v:exception)
- call assert_match('line ' .. (lnum + 3), v:throwpoint)
- endtry
- finally
- call assert_equal(1, errcaught)
- break
- endtry
- endwhile
- call assert_equal('', v:exception)
- call assert_equal('', v:throwpoint)
- Xpath 'f'
- while 1
- try
- let errcaught = 0
- try
- try
- if 1
- let lnum = expand("<sflnum>")
- throw "x11"
- " missing endif
- endtry
- catch /.*/
- let errcaught = 1
- call assert_match('Vim(endtry):E171: Missing :endif:', v:exception)
- call assert_match('line ' .. (lnum + 3), v:throwpoint)
- endtry
- finally
- call assert_equal(1, errcaught)
- break
- endtry
- endwhile
- call assert_equal('', v:exception)
- call assert_equal('', v:throwpoint)
- Xpath 'g'
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('abcdefg', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
- endfunc
- "-------------------------------------------------------------------------------
- "
- " Test 60: (Re)throwing v:exception; :echoerr. {{{1
- "
- " A user exception can be rethrown after catching by throwing
- " v:exception. An error or interrupt exception cannot be rethrown
- " because Vim exceptions cannot be faked. A Vim exception using the
- " value of v:exception can, however, be triggered by the :echoerr
- " command.
- "-------------------------------------------------------------------------------
- func Test_rethrow_exception_1()
- XpathINIT
- try
- try
- Xpath 'a'
- throw "oops"
- catch /oops/
- Xpath 'b'
- throw v:exception " rethrow user exception
- catch /.*/
- call assert_report('should not get here')
- endtry
- catch /^oops$/ " catches rethrown user exception
- Xpath 'c'
- catch /.*/
- call assert_report('should not get here')
- endtry
- call assert_equal('abc', g:Xpath)
- endfunc
- func Test_rethrow_exception_2()
- XpathINIT
- try
- let caught = 0
- try
- Xpath 'a'
- write /n/o/n/w/r/i/t/a/b/l/e/_/f/i/l/e
- call assert_report('should not get here')
- catch /^Vim(write):/
- let caught = 1
- throw v:exception " throw error: cannot fake Vim exception
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'b'
- call assert_equal(1, caught)
- endtry
- catch /^Vim(throw):/ " catches throw error
- let caught = caught + 1
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'c'
- call assert_equal(2, caught)
- endtry
- call assert_equal('abc', g:Xpath)
- endfunc
- func Test_rethrow_exception_3()
- XpathINIT
- try
- let caught = 0
- try
- Xpath 'a'
- asdf
- catch /^Vim/ " catch error exception
- let caught = 1
- " Trigger Vim error exception with value specified after :echoerr
- let value = substitute(v:exception, '^Vim\((.*)\)\=:', '', "")
- echoerr value
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'b'
- call assert_equal(1, caught)
- endtry
- catch /^Vim(echoerr):/
- let caught = caught + 1
- call assert_match(value, v:exception)
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'c'
- call assert_equal(2, caught)
- endtry
- call assert_equal('abc', g:Xpath)
- endfunc
- func Test_rethrow_exception_3()
- XpathINIT
- try
- let errcaught = 0
- try
- Xpath 'a'
- let intcaught = 0
- call interrupt()
- catch /^Vim:/ " catch interrupt exception
- let intcaught = 1
- " Trigger Vim error exception with value specified after :echoerr
- echoerr substitute(v:exception, '^Vim\((.*)\)\=:', '', "")
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'b'
- call assert_equal(1, intcaught)
- endtry
- catch /^Vim(echoerr):/
- let errcaught = 1
- call assert_match('Interrupt', v:exception)
- finally
- Xpath 'c'
- call assert_equal(1, errcaught)
- endtry
- call assert_equal('abc', g:Xpath)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 61: Catching interrupt exceptions {{{1
- "
- " When an interrupt occurs inside a :try/:endtry region, an
- " interrupt exception is thrown and can be caught. Its value is
- " "Vim:Interrupt". If the interrupt occurs after an error or a :throw
- " but before a matching :catch is reached, all following :catches of
- " that try block are ignored, but the interrupt exception can be
- " caught by the next surrounding try conditional. An interrupt is
- " ignored when there is a previous interrupt that has not been caught
- " or causes a :finally clause to be executed.
- "-------------------------------------------------------------------------------
- func Test_catch_intr_exception()
- let test =<< trim [CODE]
- while 1
- try
- try
- Xpath 'a'
- call interrupt()
- call assert_report('should not get here')
- catch /^Vim:Interrupt$/
- Xpath 'b'
- finally
- Xpath 'c'
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'd'
- break
- endtry
- endwhile
- while 1
- try
- try
- try
- Xpath 'e'
- asdf
- call assert_report('should not get here')
- catch /do_not_catch/
- call assert_report('should not get here')
- catch /.*/
- Xpath 'f'
- call interrupt()
- call assert_report('should not get here')
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'g'
- call interrupt()
- call assert_report('should not get here')
- endtry
- catch /^Vim:Interrupt$/
- Xpath 'h'
- finally
- Xpath 'i'
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'j'
- break
- endtry
- endwhile
- while 1
- try
- try
- try
- Xpath 'k'
- throw "x"
- call assert_report('should not get here')
- catch /do_not_catch/
- call assert_report('should not get here')
- catch /x/
- Xpath 'l'
- call interrupt()
- call assert_report('should not get here')
- catch /.*/
- call assert_report('should not get here')
- endtry
- catch /^Vim:Interrupt$/
- Xpath 'm'
- finally
- Xpath 'n'
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'o'
- break
- endtry
- endwhile
- while 1
- try
- try
- Xpath 'p'
- call interrupt()
- call assert_report('should not get here')
- catch /do_not_catch/
- call interrupt()
- call assert_report('should not get here')
- catch /^Vim:Interrupt$/
- Xpath 'q'
- finally
- Xpath 'r'
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 's'
- break
- endtry
- endwhile
- Xpath 't'
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('abcdefghijklmnopqrst', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 62: Catching error exceptions {{{1
- "
- " An error inside a :try/:endtry region is converted to an exception
- " and can be caught. The error exception has a "Vim(cmdname):" prefix
- " where cmdname is the name of the failing command, or a "Vim:" prefix
- " if no command name is known. The "Vim" prefixes cannot be faked.
- "-------------------------------------------------------------------------------
- func Test_catch_err_exception_1()
- XpathINIT
- while 1
- try
- try
- let caught = 0
- unlet novar
- catch /^Vim(unlet):/
- Xpath 'a'
- let caught = 1
- let v:errmsg = substitute(v:exception, '^Vim(unlet):', '', "")
- finally
- Xpath 'b'
- call assert_equal(1, caught)
- call assert_match('E108: No such variable: "novar"', v:errmsg)
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'c'
- break
- endtry
- call assert_report('should not get here')
- endwhile
- call assert_equal('abc', g:Xpath)
- endfunc
- func Test_catch_err_exception_2()
- XpathINIT
- while 1
- try
- try
- let caught = 0
- throw novar " error in :throw
- catch /^Vim(throw):/
- Xpath 'a'
- let caught = 1
- let v:errmsg = substitute(v:exception, '^Vim(throw):', '', "")
- finally
- Xpath 'b'
- call assert_equal(1, caught)
- call assert_match('E121: Undefined variable: novar', v:errmsg)
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'c'
- break
- endtry
- call assert_report('should not get here')
- endwhile
- call assert_equal('abc', g:Xpath)
- endfunc
- func Test_catch_err_exception_3()
- XpathINIT
- while 1
- try
- try
- let caught = 0
- throw "Vim:faked" " error: cannot fake Vim exception
- catch /^Vim(throw):/
- Xpath 'a'
- let caught = 1
- let v:errmsg = substitute(v:exception, '^Vim(throw):', '', "")
- finally
- Xpath 'b'
- call assert_equal(1, caught)
- call assert_match("E608: Cannot :throw exceptions with 'Vim' prefix",
- \ v:errmsg)
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'c'
- break
- endtry
- call assert_report('should not get here')
- endwhile
- call assert_equal('abc', g:Xpath)
- endfunc
- func Test_catch_err_exception_4()
- XpathINIT
- func F()
- while 1
- " Missing :endwhile
- endfunc
- while 1
- try
- try
- let caught = 0
- call F()
- catch /^Vim(endfunction):/
- Xpath 'a'
- let caught = 1
- let v:errmsg = substitute(v:exception, '^Vim(endfunction):', '', "")
- finally
- Xpath 'b'
- call assert_equal(1, caught)
- call assert_match("E170: Missing :endwhile", v:errmsg)
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'c'
- break
- endtry
- call assert_report('should not get here')
- endwhile
- call assert_equal('abc', g:Xpath)
- delfunc F
- endfunc
- func Test_catch_err_exception_5()
- XpathINIT
- func F()
- while 1
- " Missing :endwhile
- endfunc
- while 1
- try
- try
- let caught = 0
- ExecAsScript F
- catch /^Vim:/
- Xpath 'a'
- let caught = 1
- let v:errmsg = substitute(v:exception, '^Vim:', '', "")
- finally
- Xpath 'b'
- call assert_equal(1, caught)
- call assert_match("E170: Missing :endwhile", v:errmsg)
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'c'
- break
- endtry
- call assert_report('should not get here')
- endwhile
- call assert_equal('abc', g:Xpath)
- delfunc F
- endfunc
- func Test_catch_err_exception_6()
- XpathINIT
- func G()
- call G()
- endfunc
- while 1
- try
- let mfd_save = &mfd
- set mfd=3
- try
- let caught = 0
- call G()
- catch /^Vim(call):/
- Xpath 'a'
- let caught = 1
- let v:errmsg = substitute(v:exception, '^Vim(call):', '', "")
- finally
- Xpath 'b'
- call assert_equal(1, caught)
- call assert_match("E132: Function call depth is higher than 'maxfuncdepth'", v:errmsg)
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'c'
- let &mfd = mfd_save
- break
- endtry
- call assert_report('should not get here')
- endwhile
- call assert_equal('abc', g:Xpath)
- delfunc G
- endfunc
- func Test_catch_err_exception_7()
- XpathINIT
- func H()
- return H()
- endfunc
- while 1
- try
- let mfd_save = &mfd
- set mfd=3
- try
- let caught = 0
- call H()
- catch /^Vim(return):/
- Xpath 'a'
- let caught = 1
- let v:errmsg = substitute(v:exception, '^Vim(return):', '', "")
- finally
- Xpath 'b'
- call assert_equal(1, caught)
- call assert_match("E132: Function call depth is higher than 'maxfuncdepth'", v:errmsg)
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'c'
- let &mfd = mfd_save
- break " discard error for $VIMNOERRTHROW
- endtry
- call assert_report('should not get here')
- endwhile
- call assert_equal('abc', g:Xpath)
- delfunc H
- endfunc
- "-------------------------------------------------------------------------------
- " Test 63: Suppressing error exceptions by :silent!. {{{1
- "
- " A :silent! command inside a :try/:endtry region suppresses the
- " conversion of errors to an exception and the immediate abortion on
- " error. When the commands executed by the :silent! themselves open
- " a new :try/:endtry region, conversion of errors to exception and
- " immediate abortion is switched on again - until the next :silent!
- " etc. The :silent! has the effect of setting v:errmsg to the error
- " message text (without displaying it) and continuing with the next
- " script line.
- "
- " When a command triggering autocommands is executed by :silent!
- " inside a :try/:endtry, the autocommand execution is not suppressed
- " on error.
- "
- " This test reuses the function MSG() from the previous test.
- "-------------------------------------------------------------------------------
- func Test_silent_exception()
- XpathINIT
- XloopINIT
- let g:taken = ""
- func S(n) abort
- XloopNEXT
- let g:taken = g:taken . "E" . a:n
- let v:errmsg = ""
- exec "asdf" . a:n
- " Check that ":silent!" continues:
- Xloop 'a'
- " Check that ":silent!" sets "v:errmsg":
- call assert_match("E492: Not an editor command", v:errmsg)
- endfunc
- func Foo()
- while 1
- try
- try
- let caught = 0
- " This is not silent:
- call S(3)
- catch /^Vim:/
- Xpath 'b'
- let caught = 1
- let errmsg3 = substitute(v:exception, '^Vim:', '', "")
- silent! call S(4)
- finally
- call assert_equal(1, caught)
- Xpath 'c'
- call assert_match("E492: Not an editor command", errmsg3)
- silent! call S(5)
- " Break out of try conditionals that cover ":silent!". This also
- " discards the aborting error when $VIMNOERRTHROW is non-zero.
- break
- endtry
- catch /.*/
- call assert_report('should not get here')
- endtry
- endwhile
- " This is a double ":silent!" (see caller).
- silent! call S(6)
- endfunc
- func Bar()
- try
- silent! call S(2)
- silent! execute "call Foo() | call S(7)"
- silent! call S(8)
- endtry " normal end of try cond that covers ":silent!"
- " This has a ":silent!" from the caller:
- call S(9)
- endfunc
- silent! call S(1)
- silent! call Bar()
- silent! call S(10)
- call assert_equal("E1E2E3E4E5E6E7E8E9E10", g:taken)
- augroup TMP
- au!
- autocmd BufWritePost * Xpath 'd'
- augroup END
- Xpath 'e'
- silent! write /i/m/p/o/s/s/i/b/l/e
- Xpath 'f'
- call assert_equal('a2a3ba5ca6a7a8a9a10a11edf', g:Xpath)
- augroup TMP
- au!
- augroup END
- augroup! TMP
- delfunction S
- delfunction Foo
- delfunction Bar
- endfunc
- "-------------------------------------------------------------------------------
- " Test 64: Error exceptions after error, interrupt or :throw {{{1
- "
- " When an error occurs after an interrupt or a :throw but before
- " a matching :catch is reached, all following :catches of that try
- " block are ignored, but the error exception can be caught by the next
- " surrounding try conditional. Any previous error exception is
- " discarded. An error is ignored when there is a previous error that
- " has not been caught.
- "-------------------------------------------------------------------------------
- func Test_exception_after_error_1()
- XpathINIT
- while 1
- try
- try
- Xpath 'a'
- let caught = 0
- while 1
- if 1
- " Missing :endif
- endwhile " throw error exception
- catch /^Vim(/
- Xpath 'b'
- let caught = 1
- finally
- Xpath 'c'
- call assert_equal(1, caught)
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'd'
- break
- endtry
- call assert_report('should not get here')
- endwhile
- call assert_equal('abcd', g:Xpath)
- endfunc
- func Test_exception_after_error_2()
- XpathINIT
- while 1
- try
- try
- Xpath 'a'
- let caught = 0
- try
- if 1
- " Missing :endif
- catch /.*/ " throw error exception
- call assert_report('should not get here')
- catch /.*/
- call assert_report('should not get here')
- endtry
- catch /^Vim(/
- Xpath 'b'
- let caught = 1
- finally
- Xpath 'c'
- call assert_equal(1, caught)
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'd'
- break
- endtry
- call assert_report('should not get here')
- endwhile
- call assert_equal('abcd', g:Xpath)
- endfunc
- func Test_exception_after_error_3()
- XpathINIT
- while 1
- try
- try
- let caught = 0
- try
- Xpath 'a'
- call interrupt()
- catch /do_not_catch/
- call assert_report('should not get here')
- if 1
- " Missing :endif
- catch /.*/ " throw error exception
- call assert_report('should not get here')
- catch /.*/
- call assert_report('should not get here')
- endtry
- catch /^Vim(/
- Xpath 'b'
- let caught = 1
- finally
- Xpath 'c'
- call assert_equal(1, caught)
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'd'
- break
- endtry
- call assert_report('should not get here')
- endwhile
- call assert_equal('abcd', g:Xpath)
- endfunc
- func Test_exception_after_error_4()
- XpathINIT
- while 1
- try
- try
- let caught = 0
- try
- Xpath 'a'
- throw "x"
- catch /do_not_catch/
- call assert_report('should not get here')
- if 1
- " Missing :endif
- catch /x/ " throw error exception
- call assert_report('should not get here')
- catch /.*/
- call assert_report('should not get here')
- endtry
- catch /^Vim(/
- Xpath 'b'
- let caught = 1
- finally
- Xpath 'c'
- call assert_equal(1, caught)
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'd'
- break
- endtry
- call assert_report('should not get here')
- endwhile
- call assert_equal('abcd', g:Xpath)
- endfunc
- func Test_exception_after_error_5()
- XpathINIT
- while 1
- try
- try
- let caught = 0
- Xpath 'a'
- endif " :endif without :if; throw error exception
- if 1
- " Missing :endif
- catch /do_not_catch/ " ignore new error
- call assert_report('should not get here')
- catch /^Vim(endif):/
- Xpath 'b'
- let caught = 1
- catch /^Vim(/
- call assert_report('should not get here')
- finally
- Xpath 'c'
- call assert_equal(1, caught)
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'd'
- break
- endtry
- call assert_report('should not get here')
- endwhile
- call assert_equal('abcd', g:Xpath)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 65: Errors in the /pattern/ argument of a :catch {{{1
- "
- " On an error in the /pattern/ argument of a :catch, the :catch does
- " not match. Any following :catches of the same :try/:endtry don't
- " match either. Finally clauses are executed.
- "-------------------------------------------------------------------------------
- func Test_catch_pattern_error()
- CheckEnglish
- XpathINIT
- try
- try
- Xpath 'a'
- throw "oops"
- catch /^oops$/
- Xpath 'b'
- catch /\)/ " not checked; exception has already been caught
- call assert_report('should not get here')
- endtry
- Xpath 'c'
- catch /.*/
- call assert_report('should not get here')
- endtry
- call assert_equal('abc', g:Xpath)
- XpathINIT
- func F()
- try
- try
- try
- Xpath 'a'
- throw "ab"
- catch /abc/ " does not catch
- call assert_report('should not get here')
- catch /\)/ " error; discards exception
- call assert_report('should not get here')
- catch /.*/ " not checked
- call assert_report('should not get here')
- finally
- Xpath 'b'
- endtry
- call assert_report('should not get here')
- catch /^ab$/ " checked, but original exception is discarded
- call assert_report('should not get here')
- catch /^Vim(catch):/
- Xpath 'c'
- call assert_match('Vim(catch):E475: Invalid argument:', v:exception)
- finally
- Xpath 'd'
- endtry
- Xpath 'e'
- catch /.*/
- call assert_report('should not get here')
- endtry
- Xpath 'f'
- endfunc
- call F()
- call assert_equal('abcdef', g:Xpath)
- delfunc F
- endfunc
- "-------------------------------------------------------------------------------
- " Test 66: Stop range :call on error, interrupt, or :throw {{{1
- "
- " When a function which is multiply called for a range since it
- " doesn't handle the range itself has an error in a command
- " dynamically enclosed by :try/:endtry or gets an interrupt or
- " executes a :throw, no more calls for the remaining lines in the
- " range are made. On an error in a command not dynamically enclosed
- " by :try/:endtry, the function is executed again for the remaining
- " lines in the range.
- "-------------------------------------------------------------------------------
- func Test_stop_range_on_error()
- let test =<< trim [CODE]
- let file = tempname()
- exec "edit" file
- call setline(1, ['line 1', 'line 2', 'line 3'])
- let taken = ""
- let expected = "G1EF1E(1)F1E(2)F1E(3)G2EF2E(1)G3IF3I(1)G4TF4T(1)G5AF5A(1)"
- func F(reason, n) abort
- let g:taken = g:taken .. "F" .. a:n ..
- \ substitute(a:reason, '\(\l\).*', '\u\1', "") ..
- \ "(" .. line(".") .. ")"
- if a:reason == "error"
- asdf
- elseif a:reason == "interrupt"
- call interrupt()
- elseif a:reason == "throw"
- throw "xyz"
- elseif a:reason == "aborting error"
- XloopNEXT
- call assert_equal(g:taken, g:expected)
- try
- bwipeout!
- call delete(g:file)
- asdf
- endtry
- endif
- endfunc
- func G(reason, n)
- let g:taken = g:taken .. "G" .. a:n ..
- \ substitute(a:reason, '\(\l\).*', '\u\1', "")
- 1,3call F(a:reason, a:n)
- endfunc
- Xpath 'a'
- call G("error", 1)
- try
- Xpath 'b'
- try
- call G("error", 2)
- call assert_report('should not get here')
- finally
- Xpath 'c'
- try
- call G("interrupt", 3)
- call assert_report('should not get here')
- finally
- Xpath 'd'
- try
- call G("throw", 4)
- call assert_report('should not get here')
- endtry
- endtry
- endtry
- catch /xyz/
- Xpath 'e'
- catch /.*/
- call assert_report('should not get here')
- endtry
- Xpath 'f'
- call G("aborting error", 5)
- call assert_report('should not get here')
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('abcdef', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 67: :throw across :call command {{{1
- "
- " On a call command, an exception might be thrown when evaluating the
- " function name, during evaluation of the arguments, or when the
- " function is being executed. The exception can be caught by the
- " caller.
- "-------------------------------------------------------------------------------
- func THROW(x, n)
- if a:n == 1
- Xpath 'A'
- elseif a:n == 2
- Xpath 'B'
- elseif a:n == 3
- Xpath 'C'
- endif
- throw a:x
- endfunc
- func NAME(x, n)
- if a:n == 1
- call assert_report('should not get here')
- elseif a:n == 2
- Xpath 'D'
- elseif a:n == 3
- Xpath 'E'
- elseif a:n == 4
- Xpath 'F'
- endif
- return a:x
- endfunc
- func ARG(x, n)
- if a:n == 1
- call assert_report('should not get here')
- elseif a:n == 2
- call assert_report('should not get here')
- elseif a:n == 3
- Xpath 'G'
- elseif a:n == 4
- Xpath 'I'
- endif
- return a:x
- endfunc
- func Test_throw_across_call_cmd()
- XpathINIT
- func F(x, n)
- if a:n == 2
- call assert_report('should not get here')
- elseif a:n == 4
- Xpath 'a'
- endif
- endfunc
- while 1
- try
- let v:errmsg = ""
- while 1
- try
- Xpath 'b'
- call {NAME(THROW("name", 1), 1)}(ARG(4711, 1), 1)
- call assert_report('should not get here')
- catch /^name$/
- Xpath 'c'
- catch /.*/
- call assert_report('should not get here')
- finally
- call assert_equal("", v:errmsg)
- let v:errmsg = ""
- break
- endtry
- endwhile
- while 1
- try
- Xpath 'd'
- call {NAME("F", 2)}(ARG(THROW("arg", 2), 2), 2)
- call assert_report('should not get here')
- catch /^arg$/
- Xpath 'e'
- catch /.*/
- call assert_report('should not get here')
- finally
- call assert_equal("", v:errmsg)
- let v:errmsg = ""
- break
- endtry
- endwhile
- while 1
- try
- Xpath 'f'
- call {NAME("THROW", 3)}(ARG("call", 3), 3)
- call assert_report('should not get here')
- catch /^call$/
- Xpath 'g'
- catch /^0$/ " default return value
- call assert_report('should not get here')
- catch /.*/
- call assert_report('should not get here')
- finally
- call assert_equal("", v:errmsg)
- let v:errmsg = ""
- break
- endtry
- endwhile
- while 1
- try
- Xpath 'h'
- call {NAME("F", 4)}(ARG(4711, 4), 4)
- Xpath 'i'
- catch /.*/
- call assert_report('should not get here')
- finally
- call assert_equal("", v:errmsg)
- let v:errmsg = ""
- break
- endtry
- endwhile
- catch /^0$/ " default return value
- call assert_report('should not get here')
- catch /.*/
- call assert_report('should not get here')
- finally
- call assert_equal("", v:errmsg)
- let v:errmsg = ""
- break
- endtry
- endwhile
- call assert_equal('bAcdDBefEGCghFIai', g:Xpath)
- delfunction F
- endfunc
- "-------------------------------------------------------------------------------
- " Test 68: :throw across function calls in expressions {{{1
- "
- " On a function call within an expression, an exception might be
- " thrown when evaluating the function name, during evaluation of the
- " arguments, or when the function is being executed. The exception
- " can be caught by the caller.
- "
- " This test reuses the functions THROW(), NAME(), and ARG() from the
- " previous test.
- "-------------------------------------------------------------------------------
- func Test_throw_across_call_expr()
- XpathINIT
- func F(x, n)
- if a:n == 2
- call assert_report('should not get here')
- elseif a:n == 4
- Xpath 'a'
- endif
- return a:x
- endfunction
- while 1
- try
- let error = 0
- let v:errmsg = ""
- while 1
- try
- Xpath 'b'
- let var1 = {NAME(THROW("name", 1), 1)}(ARG(4711, 1), 1)
- call assert_report('should not get here')
- catch /^name$/
- Xpath 'c'
- catch /.*/
- call assert_report('should not get here')
- finally
- call assert_equal("", v:errmsg)
- let v:errmsg = ""
- break
- endtry
- endwhile
- call assert_true(!exists('var1'))
- while 1
- try
- Xpath 'd'
- let var2 = {NAME("F", 2)}(ARG(THROW("arg", 2), 2), 2)
- call assert_report('should not get here')
- catch /^arg$/
- Xpath 'e'
- catch /.*/
- call assert_report('should not get here')
- finally
- call assert_equal("", v:errmsg)
- let v:errmsg = ""
- break
- endtry
- endwhile
- call assert_true(!exists('var2'))
- while 1
- try
- Xpath 'f'
- let var3 = {NAME("THROW", 3)}(ARG("call", 3), 3)
- call assert_report('should not get here')
- catch /^call$/
- Xpath 'g'
- catch /^0$/ " default return value
- call assert_report('should not get here')
- catch /.*/
- call assert_report('should not get here')
- finally
- call assert_equal("", v:errmsg)
- let v:errmsg = ""
- break
- endtry
- endwhile
- call assert_true(!exists('var3'))
- while 1
- try
- Xpath 'h'
- let var4 = {NAME("F", 4)}(ARG(4711, 4), 4)
- Xpath 'i'
- catch /.*/
- call assert_report('should not get here')
- finally
- call assert_equal("", v:errmsg)
- let v:errmsg = ""
- break
- endtry
- endwhile
- call assert_true(exists('var4') && var4 == 4711)
- catch /^0$/ " default return value
- call assert_report('should not get here')
- catch /.*/
- call assert_report('should not get here')
- finally
- call assert_equal("", v:errmsg)
- break
- endtry
- endwhile
- call assert_equal('bAcdDBefEGCghFIai', g:Xpath)
- delfunc F
- endfunc
- "-------------------------------------------------------------------------------
- " Test 76: Errors, interrupts, :throw during expression evaluation {{{1
- "
- " When a function call made during expression evaluation is aborted
- " due to an error inside a :try/:endtry region or due to an interrupt
- " or a :throw, the expression evaluation is aborted as well. No
- " message is displayed for the cancelled expression evaluation. On an
- " error not inside :try/:endtry, the expression evaluation continues.
- "-------------------------------------------------------------------------------
- func Test_expr_eval_error()
- let test =<< trim [CODE]
- let taken = ""
- func ERR(n)
- let g:taken = g:taken .. "E" .. a:n
- asdf
- endfunc
- func ERRabort(n) abort
- let g:taken = g:taken .. "A" .. a:n
- asdf
- endfunc " returns -1; may cause follow-up msg for illegal var/func name
- func WRAP(n, arg)
- let g:taken = g:taken .. "W" .. a:n
- let g:saved_errmsg = v:errmsg
- return arg
- endfunc
- func INT(n)
- let g:taken = g:taken .. "I" .. a:n
- call interrupt()
- endfunc
- func THR(n)
- let g:taken = g:taken .. "T" .. a:n
- throw "should not be caught"
- endfunc
- func CONT(n)
- let g:taken = g:taken .. "C" .. a:n
- endfunc
- func MSG(n)
- let g:taken = g:taken .. "M" .. a:n
- let errmsg = (a:n >= 37 && a:n <= 44) ? g:saved_errmsg : v:errmsg
- let msgptn = (a:n >= 10 && a:n <= 27) ? "^$" : "asdf"
- call assert_match(msgptn, errmsg)
- let v:errmsg = ""
- let g:saved_errmsg = ""
- endfunc
- let v:errmsg = ""
- try
- let t = 1
- while t <= 9
- Xloop 'a'
- try
- if t == 1
- let v{ERR(t) + CONT(t)} = 0
- elseif t == 2
- let v{ERR(t) + CONT(t)}
- elseif t == 3
- let var = exists('v{ERR(t) + CONT(t)}')
- elseif t == 4
- unlet v{ERR(t) + CONT(t)}
- elseif t == 5
- function F{ERR(t) + CONT(t)}()
- endfunction
- elseif t == 6
- function F{ERR(t) + CONT(t)}
- elseif t == 7
- let var = exists('*F{ERR(t) + CONT(t)}')
- elseif t == 8
- delfunction F{ERR(t) + CONT(t)}
- elseif t == 9
- let var = ERR(t) + CONT(t)
- endif
- catch /asdf/
- " v:errmsg is not set when the error message is converted to an
- " exception. Set it to the original error message.
- let v:errmsg = substitute(v:exception, '^Vim:', '', "")
- catch /^Vim\((\a\+)\)\=:/
- " An error exception has been thrown after the original error.
- let v:errmsg = ""
- finally
- call MSG(t)
- let t = t + 1
- XloopNEXT
- continue " discard an aborting error
- endtry
- endwhile
- catch /.*/
- call assert_report('should not get here')
- endtry
- try
- let t = 10
- while t <= 18
- Xloop 'b'
- try
- if t == 10
- let v{INT(t) + CONT(t)} = 0
- elseif t == 11
- let v{INT(t) + CONT(t)}
- elseif t == 12
- let var = exists('v{INT(t) + CONT(t)}')
- elseif t == 13
- unlet v{INT(t) + CONT(t)}
- elseif t == 14
- function F{INT(t) + CONT(t)}()
- endfunction
- elseif t == 15
- function F{INT(t) + CONT(t)}
- elseif t == 16
- let var = exists('*F{INT(t) + CONT(t)}')
- elseif t == 17
- delfunction F{INT(t) + CONT(t)}
- elseif t == 18
- let var = INT(t) + CONT(t)
- endif
- catch /^Vim\((\a\+)\)\=:\(Interrupt\)\@!/
- " An error exception has been triggered after the interrupt.
- let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
- finally
- call MSG(t)
- let t = t + 1
- XloopNEXT
- continue " discard interrupt
- endtry
- endwhile
- catch /.*/
- call assert_report('should not get here')
- endtry
- try
- let t = 19
- while t <= 27
- Xloop 'c'
- try
- if t == 19
- let v{THR(t) + CONT(t)} = 0
- elseif t == 20
- let v{THR(t) + CONT(t)}
- elseif t == 21
- let var = exists('v{THR(t) + CONT(t)}')
- elseif t == 22
- unlet v{THR(t) + CONT(t)}
- elseif t == 23
- function F{THR(t) + CONT(t)}()
- endfunction
- elseif t == 24
- function F{THR(t) + CONT(t)}
- elseif t == 25
- let var = exists('*F{THR(t) + CONT(t)}')
- elseif t == 26
- delfunction F{THR(t) + CONT(t)}
- elseif t == 27
- let var = THR(t) + CONT(t)
- endif
- catch /^Vim\((\a\+)\)\=:/
- " An error exception has been triggered after the :throw.
- let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
- finally
- call MSG(t)
- let t = t + 1
- XloopNEXT
- continue " discard exception
- endtry
- endwhile
- catch /.*/
- call assert_report('should not get here')
- endtry
- let v{ERR(28) + CONT(28)} = 0
- call MSG(28)
- let v{ERR(29) + CONT(29)}
- call MSG(29)
- let var = exists('v{ERR(30) + CONT(30)}')
- call MSG(30)
- unlet v{ERR(31) + CONT(31)}
- call MSG(31)
- function F{ERR(32) + CONT(32)}()
- endfunction
- call MSG(32)
- function F{ERR(33) + CONT(33)}
- call MSG(33)
- let var = exists('*F{ERR(34) + CONT(34)}')
- call MSG(34)
- delfunction F{ERR(35) + CONT(35)}
- call MSG(35)
- let var = ERR(36) + CONT(36)
- call MSG(36)
- let saved_errmsg = ""
- let v{WRAP(37, ERRabort(37)) + CONT(37)} = 0
- call MSG(37)
- let v{WRAP(38, ERRabort(38)) + CONT(38)}
- call MSG(38)
- let var = exists('v{WRAP(39, ERRabort(39)) + CONT(39)}')
- call MSG(39)
- unlet v{WRAP(40, ERRabort(40)) + CONT(40)}
- call MSG(40)
- function F{WRAP(41, ERRabort(41)) + CONT(41)}()
- endfunction
- call MSG(41)
- function F{WRAP(42, ERRabort(42)) + CONT(42)}
- call MSG(42)
- let var = exists('*F{WRAP(43, ERRabort(43)) + CONT(43)}')
- call MSG(43)
- delfunction F{WRAP(44, ERRabort(44)) + CONT(44)}
- call MSG(44)
- let var = ERRabort(45) + CONT(45)
- call MSG(45)
- Xpath 'd'
- let expected = ""
- \ .. "E1M1E2M2E3M3E4M4E5M5E6M6E7M7E8M8E9M9"
- \ .. "I10M10I11M11I12M12I13M13I14M14I15M15I16M16I17M17I18M18"
- \ .. "T19M19T20M20T21M21T22M22T23M23T24M24T25M25T26M26T27M27"
- \ .. "E28C28M28E29C29M29E30C30M30E31C31M31E32C32M32E33C33M33"
- \ .. "E34C34M34E35C35M35E36C36M36"
- \ .. "A37W37C37M37A38W38C38M38A39W39C39M39A40W40C40M40A41W41C41M41"
- \ .. "A42W42C42M42A43W43C43M43A44W44C44M44A45C45M45"
- call assert_equal(expected, taken)
- [CODE]
- let verify =<< trim [CODE]
- let expected = "a1a2a3a4a5a6a7a8a9"
- \ .. "b10b11b12b13b14b15b16b17b18"
- \ .. "c19c20c21c22c23c24c25c26c27d"
- call assert_equal(expected, g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 77: Errors, interrupts, :throw in name{brace-expression} {{{1
- "
- " When a function call made during evaluation of an expression in
- " braces as part of a function name after ":function" is aborted due
- " to an error inside a :try/:endtry region or due to an interrupt or
- " a :throw, the expression evaluation is aborted as well, and the
- " function definition is ignored, skipping all commands to the
- " ":endfunction". On an error not inside :try/:endtry, the expression
- " evaluation continues and the function gets defined, and can be
- " called and deleted.
- "-------------------------------------------------------------------------------
- func Test_brace_expr_error()
- let test =<< trim [CODE]
- func ERR() abort
- Xloop 'a'
- asdf
- endfunc " returns -1
- func OK()
- Xloop 'b'
- let v:errmsg = ""
- return 0
- endfunc
- let v:errmsg = ""
- Xpath 'c'
- func F{1 + ERR() + OK()}(arg)
- " F0 should be defined.
- if exists("a:arg") && a:arg == "calling"
- Xpath 'd'
- else
- call assert_report('should not get here')
- endif
- endfunction
- call assert_equal("", v:errmsg)
- XloopNEXT
- Xpath 'e'
- call F{1 + ERR() + OK()}("calling")
- call assert_equal("", v:errmsg)
- XloopNEXT
- Xpath 'f'
- delfunction F{1 + ERR() + OK()}
- call assert_equal("", v:errmsg)
- XloopNEXT
- try
- while 1
- try
- Xpath 'g'
- func G{1 + ERR() + OK()}(arg)
- " G0 should not be defined, and the function body should be
- " skipped.
- call assert_report('should not get here')
- " Use an unmatched ":finally" to check whether the body is
- " skipped when an error occurs in ERR(). This works whether or
- " not the exception is converted to an exception.
- finally
- call assert_report('should not get here')
- endtry
- try
- call assert_report('should not get here')
- endfunction
- call assert_report('should not get here')
- catch /asdf/
- " Jumped to when the function is not defined and the body is
- " skipped.
- Xpath 'h'
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'i'
- break
- endtry " jumped to when the body is not skipped
- endwhile
- catch /.*/
- call assert_report('should not get here')
- endtry
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('ca1b1ea2b2dfa3b3ga4hi', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 78: Messages on parsing errors in expression evaluation {{{1
- "
- " When an expression evaluation detects a parsing error, an error
- " message is given and converted to an exception, and the expression
- " evaluation is aborted.
- "-------------------------------------------------------------------------------
- func Test_expr_eval_error_msg()
- CheckEnglish
- let test =<< trim [CODE]
- let taken = ""
- func F(n)
- let g:taken = g:taken . "F" . a:n
- endfunc
- func MSG(n, enr, emsg)
- let g:taken = g:taken . "M" . a:n
- call assert_match('^' .. a:enr .. ':', v:errmsg)
- call assert_match(a:emsg, v:errmsg)
- endfunc
- func CONT(n)
- let g:taken = g:taken . "C" . a:n
- endfunc
- let v:errmsg = ""
- try
- let t = 1
- while t <= 14
- let g:taken = g:taken . "T" . t
- let v:errmsg = ""
- try
- if t == 1
- let v{novar + CONT(t)} = 0
- elseif t == 2
- let v{novar + CONT(t)}
- elseif t == 3
- let var = exists('v{novar + CONT(t)}')
- elseif t == 4
- unlet v{novar + CONT(t)}
- elseif t == 5
- function F{novar + CONT(t)}()
- endfunction
- elseif t == 6
- function F{novar + CONT(t)}
- elseif t == 7
- let var = exists('*F{novar + CONT(t)}')
- elseif t == 8
- delfunction F{novar + CONT(t)}
- elseif t == 9
- echo novar + CONT(t)
- elseif t == 10
- echo v{novar + CONT(t)}
- elseif t == 11
- echo F{novar + CONT(t)}
- elseif t == 12
- let var = novar + CONT(t)
- elseif t == 13
- let var = v{novar + CONT(t)}
- elseif t == 14
- let var = F{novar + CONT(t)}()
- endif
- catch /^Vim\((\a\+)\)\=:/
- Xloop 'a'
- " v:errmsg is not set when the error message is converted to an
- " exception. Set it to the original error message.
- let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
- finally
- Xloop 'b'
- if t <= 8 && t != 3 && t != 7
- call MSG(t, 'E475', 'Invalid argument\>')
- else
- call MSG(t, 'E121', "Undefined variable")
- endif
- let t = t + 1
- XloopNEXT
- continue " discard an aborting error
- endtry
- endwhile
- catch /.*/
- call assert_report('should not get here')
- endtry
- func T(n, expr, enr, emsg)
- try
- let g:taken = g:taken . "T" . a:n
- let v:errmsg = ""
- try
- execute "let var = " . a:expr
- catch /^Vim\((\a\+)\)\=:/
- Xloop 'c'
- " v:errmsg is not set when the error message is converted to an
- " exception. Set it to the original error message.
- let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
- finally
- Xloop 'd'
- call MSG(a:n, a:enr, a:emsg)
- XloopNEXT
- " Discard an aborting error:
- return
- endtry
- catch /.*/
- call assert_report('should not get here')
- endtry
- endfunc
- call T(15, 'Nofunc() + CONT(15)', 'E117', "Unknown function")
- call T(16, 'F(1 2 + CONT(16))', 'E116', "Invalid arguments")
- call T(17, 'F(1, 2) + CONT(17)', 'E118', "Too many arguments")
- call T(18, 'F() + CONT(18)', 'E119', "Not enough arguments")
- call T(19, '{(1} + CONT(19)', 'E110', "Missing ')'")
- call T(20, '("abc"[1) + CONT(20)', 'E111', "Missing ']'")
- call T(21, '(1 +) + CONT(21)', 'E15', "Invalid expression")
- call T(22, '1 2 + CONT(22)', 'E488', "Trailing characters: 2 +")
- call T(23, '(1 ? 2) + CONT(23)', 'E109', "Missing ':' after '?'")
- call T(24, '("abc) + CONT(24)', 'E114', "Missing quote")
- call T(25, "('abc) + CONT(25)", 'E115', "Missing quote")
- call T(26, '& + CONT(26)', 'E112', "Option name missing")
- call T(27, '&asdf + CONT(27)', 'E113', "Unknown option")
- let expected = ""
- \ .. "T1M1T2M2T3M3T4M4T5M5T6M6T7M7T8M8T9M9T10M10T11M11T12M12T13M13T14M14"
- \ .. "T15M15T16M16T17M17T18M18T19M19T20M20T21M21T22M22T23M23T24M24T25M25"
- \ .. "T26M26T27M27"
- call assert_equal(expected, taken)
- [CODE]
- let verify =<< trim [CODE]
- let expected = "a1b1a2b2a3b3a4b4a5b5a6b6a7b7a8b8a9b9a10b10a11b11a12b12"
- \ .. "a13b13a14b14c15d15c16d16c17d17c18d18c19d19c20d20"
- \ .. "c21d21c22d22c23d23c24d24c25d25c26d26c27d27"
- call assert_equal(expected, g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 79: Throwing one of several errors for the same command {{{1
- "
- " When several errors appear in a row (for instance during expression
- " evaluation), the first as the most specific one is used when
- " throwing an error exception. If, however, a syntax error is
- " detected afterwards, this one is used for the error exception.
- " On a syntax error, the next command is not executed, on a normal
- " error, however, it is (relevant only in a function without the
- " "abort" flag). v:errmsg is not set.
- "
- " If throwing error exceptions is configured off, v:errmsg is always
- " set to the latest error message, that is, to the more general
- " message or the syntax error, respectively.
- "-------------------------------------------------------------------------------
- func Test_throw_multi_error()
- CheckEnglish
- let test =<< trim [CODE]
- func NEXT(cmd)
- exec a:cmd . " | Xloop 'a'"
- endfun
- call NEXT('echo novar') " (checks nextcmd)
- XloopNEXT
- call NEXT('let novar #') " (skips nextcmd)
- XloopNEXT
- call NEXT('unlet novar #') " (skips nextcmd)
- XloopNEXT
- call NEXT('let {novar}') " (skips nextcmd)
- XloopNEXT
- call NEXT('unlet{ novar}') " (skips nextcmd)
- call assert_equal('a1', g:Xpath)
- XpathINIT
- XloopINIT
- func EXEC(cmd)
- exec a:cmd
- endfunc
- try
- while 1 " dummy loop
- try
- let v:errmsg = ""
- call EXEC('echo novar') " normal error
- catch /^Vim\((\a\+)\)\=:/
- Xpath 'b'
- call assert_match('E121: Undefined variable: novar', v:exception)
- finally
- Xpath 'c'
- call assert_equal("", v:errmsg)
- break
- endtry
- endwhile
- Xpath 'd'
- let cmd = "let"
- while cmd != ""
- try
- let v:errmsg = ""
- call EXEC(cmd . ' novar #') " normal plus syntax error
- catch /^Vim\((\a\+)\)\=:/
- Xloop 'e'
- call assert_match('E488: Trailing characters', v:exception)
- finally
- Xloop 'f'
- call assert_equal("", v:errmsg)
- if cmd == "let"
- let cmd = "unlet"
- else
- let cmd = ""
- endif
- XloopNEXT
- continue
- endtry
- endwhile
- Xpath 'g'
- let cmd = "let"
- while cmd != ""
- try
- let v:errmsg = ""
- call EXEC(cmd . ' {novar}') " normal plus syntax error
- catch /^Vim\((\a\+)\)\=:/
- Xloop 'h'
- call assert_match('E475: Invalid argument: {novar}', v:exception)
- finally
- Xloop 'i'
- call assert_equal("", v:errmsg)
- if cmd == "let"
- let cmd = "unlet"
- else
- let cmd = ""
- endif
- XloopNEXT
- continue
- endtry
- endwhile
- catch /.*/
- call assert_report('should not get here')
- endtry
- Xpath 'j'
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('bcde1f1e2f2gh3i3h4i4j', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 80: Syntax error in expression for illegal :elseif {{{1
- "
- " If there is a syntax error in the expression after an illegal
- " :elseif, an error message is given (or an error exception thrown)
- " for the illegal :elseif rather than the expression error.
- "-------------------------------------------------------------------------------
- func Test_if_syntax_error()
- CheckEnglish
- let test =<< trim [CODE]
- let v:errmsg = ""
- if 0
- else
- elseif 1 ||| 2
- endif
- Xpath 'a'
- call assert_match('E584: :elseif after :else', v:errmsg)
- let v:errmsg = ""
- if 1
- else
- elseif 1 ||| 2
- endif
- Xpath 'b'
- call assert_match('E584: :elseif after :else', v:errmsg)
- let v:errmsg = ""
- elseif 1 ||| 2
- Xpath 'c'
- call assert_match('E582: :elseif without :if', v:errmsg)
- let v:errmsg = ""
- while 1
- elseif 1 ||| 2
- endwhile
- Xpath 'd'
- call assert_match('E582: :elseif without :if', v:errmsg)
- while 1
- try
- try
- let v:errmsg = ""
- if 0
- else
- elseif 1 ||| 2
- endif
- catch /^Vim\((\a\+)\)\=:/
- Xpath 'e'
- call assert_match('E584: :elseif after :else', v:exception)
- finally
- Xpath 'f'
- call assert_equal("", v:errmsg)
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'g'
- break
- endtry
- endwhile
- while 1
- try
- try
- let v:errmsg = ""
- if 1
- else
- elseif 1 ||| 2
- endif
- catch /^Vim\((\a\+)\)\=:/
- Xpath 'h'
- call assert_match('E584: :elseif after :else', v:exception)
- finally
- Xpath 'i'
- call assert_equal("", v:errmsg)
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'j'
- break
- endtry
- endwhile
- while 1
- try
- try
- let v:errmsg = ""
- elseif 1 ||| 2
- catch /^Vim\((\a\+)\)\=:/
- Xpath 'k'
- call assert_match('E582: :elseif without :if', v:exception)
- finally
- Xpath 'l'
- call assert_equal("", v:errmsg)
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'm'
- break
- endtry
- endwhile
- while 1
- try
- try
- let v:errmsg = ""
- while 1
- elseif 1 ||| 2
- endwhile
- catch /^Vim\((\a\+)\)\=:/
- Xpath 'n'
- call assert_match('E582: :elseif without :if', v:exception)
- finally
- Xpath 'o'
- call assert_equal("", v:errmsg)
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'p'
- break
- endtry
- endwhile
- Xpath 'q'
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('abcdefghijklmnopq', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 81: Discarding exceptions after an error or interrupt {{{1
- "
- " When an exception is thrown from inside a :try conditional without
- " :catch and :finally clauses and an error or interrupt occurs before
- " the :endtry is reached, the exception is discarded.
- "-------------------------------------------------------------------------------
- func Test_discard_exception_after_error_1()
- let test =<< trim [CODE]
- try
- Xpath 'a'
- try
- Xpath 'b'
- throw "arrgh"
- call assert_report('should not get here')
- if 1
- call assert_report('should not get here')
- " error after :throw: missing :endif
- endtry
- call assert_report('should not get here')
- catch /arrgh/
- call assert_report('should not get here')
- endtry
- call assert_report('should not get here')
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('ab', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
- endfunc
- " interrupt the code before the endtry is invoked
- func Test_discard_exception_after_error_2()
- XpathINIT
- let lines =<< trim [CODE]
- try
- Xpath 'a'
- try
- Xpath 'b'
- throw "arrgh"
- call assert_report('should not get here')
- endtry " interrupt here
- call assert_report('should not get here')
- catch /arrgh/
- call assert_report('should not get here')
- endtry
- call assert_report('should not get here')
- [CODE]
- call writefile(lines, 'Xscript')
- breakadd file 7 Xscript
- try
- let caught_intr = 0
- debuggreedy
- call feedkeys(":source Xscript\<CR>quit\<CR>", "xt")
- catch /^Vim:Interrupt$/
- call assert_match('Xscript, line 7', v:throwpoint)
- let caught_intr = 1
- endtry
- 0debuggreedy
- call assert_equal(1, caught_intr)
- call assert_equal('ab', g:Xpath)
- breakdel *
- call delete('Xscript')
- endfunc
- "-------------------------------------------------------------------------------
- " Test 82: Ignoring :catch clauses after an error or interrupt {{{1
- "
- " When an exception is thrown and an error or interrupt occurs before
- " the matching :catch clause is reached, the exception is discarded
- " and the :catch clause is ignored (also for the error or interrupt
- " exception being thrown then).
- "-------------------------------------------------------------------------------
- func Test_ignore_catch_after_error_1()
- let test =<< trim [CODE]
- try
- try
- Xpath 'a'
- throw "arrgh"
- call assert_report('should not get here')
- if 1
- call assert_report('should not get here')
- " error after :throw: missing :endif
- catch /.*/
- call assert_report('should not get here')
- catch /.*/
- call assert_report('should not get here')
- endtry
- call assert_report('should not get here')
- catch /arrgh/
- call assert_report('should not get here')
- endtry
- 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_ignore_catch_after_error_2()
- let test =<< trim [CODE]
- func E()
- try
- try
- Xpath 'a'
- throw "arrgh"
- call assert_report('should not get here')
- if 1
- call assert_report('should not get here')
- " error after :throw: missing :endif
- catch /.*/
- call assert_report('should not get here')
- catch /.*/
- call assert_report('should not get here')
- endtry
- call assert_report('should not get here')
- catch /arrgh/
- call assert_report('should not get here')
- endtry
- endfunc
- call E()
- call assert_report('should not get here')
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('a', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
- endfunc
- " interrupt right before a catch is invoked in a script
- func Test_ignore_catch_after_intr_1()
- " for unknown reasons this test sometimes fails on MS-Windows.
- let g:test_is_flaky = 1
- XpathINIT
- let lines =<< trim [CODE]
- try
- try
- Xpath 'a'
- throw "arrgh"
- call assert_report('should not get here')
- catch /.*/ " interrupt here
- call assert_report('should not get here')
- catch /.*/
- call assert_report('should not get here')
- endtry
- call assert_report('should not get here')
- catch /arrgh/
- call assert_report('should not get here')
- endtry
- call assert_report('should not get here')
- [CODE]
- call writefile(lines, 'Xscript')
- breakadd file 6 Xscript
- try
- let caught_intr = 0
- debuggreedy
- call feedkeys(":source Xscript\<CR>quit\<CR>", "xt")
- catch /^Vim:Interrupt$/
- call assert_match('Xscript, line 6', v:throwpoint)
- let caught_intr = 1
- endtry
- 0debuggreedy
- call assert_equal(1, caught_intr)
- call assert_equal('a', g:Xpath)
- breakdel *
- call delete('Xscript')
- endfunc
- " interrupt right before a catch is invoked inside a function.
- func Test_ignore_catch_after_intr_2()
- " for unknown reasons this test sometimes fails on MS-Windows.
- let g:test_is_flaky = 1
- XpathINIT
- func F()
- try
- try
- Xpath 'a'
- throw "arrgh"
- call assert_report('should not get here')
- catch /.*/ " interrupt here
- call assert_report('should not get here')
- catch /.*/
- call assert_report('should not get here')
- endtry
- call assert_report('should not get here')
- catch /arrgh/
- call assert_report('should not get here')
- endtry
- call assert_report('should not get here')
- endfunc
- breakadd func 6 F
- try
- let caught_intr = 0
- debuggreedy
- call feedkeys(":call F()\<CR>quit\<CR>", "xt")
- catch /^Vim:Interrupt$/
- call assert_match('\.F, line 6', v:throwpoint)
- let caught_intr = 1
- endtry
- 0debuggreedy
- call assert_equal(1, caught_intr)
- call assert_equal('a', g:Xpath)
- breakdel *
- delfunc F
- endfunc
- "-------------------------------------------------------------------------------
- " Test 83: Executing :finally clauses after an error or interrupt {{{1
- "
- " When an exception is thrown and an error or interrupt occurs before
- " the :finally of the innermost :try is reached, the exception is
- " discarded and the :finally clause is executed.
- "-------------------------------------------------------------------------------
- func Test_finally_after_error()
- let test =<< trim [CODE]
- try
- Xpath 'a'
- try
- Xpath 'b'
- throw "arrgh"
- call assert_report('should not get here')
- if 1
- call assert_report('should not get here')
- " error after :throw: missing :endif
- finally
- Xpath 'c'
- endtry
- call assert_report('should not get here')
- catch /arrgh/
- call assert_report('should not get here')
- endtry
- call assert_report('should not get here')
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('abc', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
- endfunc
- " interrupt the code right before the finally is invoked
- func Test_finally_after_intr()
- XpathINIT
- let lines =<< trim [CODE]
- try
- Xpath 'a'
- try
- Xpath 'b'
- throw "arrgh"
- call assert_report('should not get here')
- finally " interrupt here
- Xpath 'c'
- endtry
- call assert_report('should not get here')
- catch /arrgh/
- call assert_report('should not get here')
- endtry
- call assert_report('should not get here')
- [CODE]
- call writefile(lines, 'Xscript')
- breakadd file 7 Xscript
- try
- let caught_intr = 0
- debuggreedy
- call feedkeys(":source Xscript\<CR>quit\<CR>", "xt")
- catch /^Vim:Interrupt$/
- call assert_match('Xscript, line 7', v:throwpoint)
- let caught_intr = 1
- endtry
- 0debuggreedy
- call assert_equal(1, caught_intr)
- call assert_equal('abc', g:Xpath)
- breakdel *
- call delete('Xscript')
- endfunc
- "-------------------------------------------------------------------------------
- " Test 84: Exceptions in autocommand sequences. {{{1
- "
- " When an exception occurs in a sequence of autocommands for
- " a specific event, the rest of the sequence is not executed. The
- " command that triggered the autocommand execution aborts, and the
- " exception is propagated to the caller.
- "
- " For the FuncUndefined event under a function call expression or
- " :call command, the function is not executed, even when it has
- " been defined by the autocommands before the exception occurred.
- "-------------------------------------------------------------------------------
- func Test_autocmd_exception()
- let test =<< trim [CODE]
- func INT()
- call interrupt()
- endfunc
- aug TMP
- autocmd!
- autocmd User x1 Xpath 'a'
- autocmd User x1 throw "x1"
- autocmd User x1 call assert_report('should not get here')
- autocmd User x2 Xpath 'b'
- autocmd User x2 asdf
- autocmd User x2 call assert_report('should not get here')
- autocmd User x3 Xpath 'c'
- autocmd User x3 call INT()
- autocmd User x3 call assert_report('should not get here')
- autocmd FuncUndefined U1 func U1()
- autocmd FuncUndefined U1 call assert_report('should not get here')
- autocmd FuncUndefined U1 endfunc
- autocmd FuncUndefined U1 Xpath 'd'
- autocmd FuncUndefined U1 throw "U1"
- autocmd FuncUndefined U1 call assert_report('should not get here')
- autocmd FuncUndefined U2 func U2()
- autocmd FuncUndefined U2 call assert_report('should not get here')
- autocmd FuncUndefined U2 endfunc
- autocmd FuncUndefined U2 Xpath 'e'
- autocmd FuncUndefined U2 ASDF
- autocmd FuncUndefined U2 call assert_report('should not get here')
- autocmd FuncUndefined U3 func U3()
- autocmd FuncUndefined U3 call assert_report('should not get here')
- autocmd FuncUndefined U3 endfunc
- autocmd FuncUndefined U3 Xpath 'f'
- autocmd FuncUndefined U3 call INT()
- autocmd FuncUndefined U3 call assert_report('should not get here')
- aug END
- try
- try
- Xpath 'g'
- doautocmd User x1
- catch /x1/
- Xpath 'h'
- endtry
- while 1
- try
- Xpath 'i'
- doautocmd User x2
- catch /asdf/
- Xpath 'j'
- finally
- Xpath 'k'
- break
- endtry
- endwhile
- while 1
- try
- Xpath 'l'
- doautocmd User x3
- catch /Vim:Interrupt/
- Xpath 'm'
- finally
- Xpath 'n'
- " ... but break loop for caught interrupt exception,
- " or discard interrupt and break loop if $VIMNOINTTHROW
- break
- endtry
- endwhile
- if exists("*U1") | delfunction U1 | endif
- if exists("*U2") | delfunction U2 | endif
- if exists("*U3") | delfunction U3 | endif
- try
- Xpath 'o'
- call U1()
- catch /U1/
- Xpath 'p'
- endtry
- while 1
- try
- Xpath 'q'
- call U2()
- catch /ASDF/
- Xpath 'r'
- finally
- Xpath 's'
- " ... but break loop for caught error exception,
- " or discard error and break loop if $VIMNOERRTHROW
- break
- endtry
- endwhile
- while 1
- try
- Xpath 't'
- call U3()
- catch /Vim:Interrupt/
- Xpath 'u'
- finally
- Xpath 'v'
- " ... but break loop for caught interrupt exception,
- " or discard interrupt and break loop if $VIMNOINTTHROW
- break
- endtry
- endwhile
- catch /.*/
- call assert_report('should not get here')
- endtry
- Xpath 'w'
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('gahibjklcmnodpqerstfuvw', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 85: Error exceptions in autocommands for I/O command events {{{1
- "
- " When an I/O command is inside :try/:endtry, autocommands to be
- " executed after it should be skipped on an error (exception) in the
- " command itself or in autocommands to be executed before the command.
- " In the latter case, the I/O command should not be executed either.
- " Example 1: BufWritePre, :write, BufWritePost
- " Example 2: FileReadPre, :read, FileReadPost.
- "-------------------------------------------------------------------------------
- func Test_autocmd_error_io_exception()
- let test =<< trim [CODE]
- " Remove the autocommands for the events specified as arguments in all used
- " autogroups.
- func Delete_autocommands(...)
- let augfile = tempname()
- while 1
- try
- exec "redir >" . augfile
- aug
- redir END
- exec "edit" augfile
- g/^$/d
- norm G$
- let wrap = "w"
- while search('\%( \|^\)\@<=.\{-}\%( \)\@=', wrap) > 0
- let wrap = "W"
- exec "norm y/ \n"
- let argno = 1
- while argno <= a:0
- exec "au!" escape(@", " ") a:{argno}
- let argno = argno + 1
- endwhile
- endwhile
- catch /.*/
- finally
- bwipeout!
- call delete(augfile)
- break
- endtry
- endwhile
- endfunc
- call Delete_autocommands("BufWritePre", "BufWritePost")
- while 1
- try
- try
- let post = 0
- aug TMP
- au! BufWritePost * let post = 1
- aug END
- write /n/o/n/e/x/i/s/t/e/n/t
- catch /^Vim(write):/
- Xpath 'a'
- call assert_match("E212: Can't open file for writing", v:exception)
- finally
- Xpath 'b'
- call assert_equal(0, post)
- au! TMP
- aug! TMP
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'c'
- break
- endtry
- endwhile
- while 1
- try
- try
- let post = 0
- aug TMP
- au! BufWritePre * asdf
- au! BufWritePost * let post = 1
- aug END
- let tmpfile = tempname()
- exec "write" tmpfile
- catch /^Vim\((write)\)\=:/
- Xpath 'd'
- call assert_match('E492: Not an editor command', v:exception)
- finally
- Xpath 'e'
- if filereadable(tmpfile)
- call assert_report('should not get here')
- endif
- call assert_equal(0, post)
- au! TMP
- aug! TMP
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'f'
- break
- endtry
- endwhile
- call delete(tmpfile)
- call Delete_autocommands("BufWritePre", "BufWritePost",
- \ "BufReadPre", "BufReadPost", "FileReadPre", "FileReadPost")
- while 1
- try
- try
- let post = 0
- aug TMP
- au! FileReadPost * let post = 1
- aug END
- let caught = 0
- read /n/o/n/e/x/i/s/t/e/n/t
- catch /^Vim(read):/
- Xpath 'g'
- call assert_match("E484: Can't open file", v:exception)
- finally
- Xpath 'h'
- call assert_equal(0, post)
- au! TMP
- aug! TMP
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'i'
- break
- endtry
- endwhile
- while 1
- try
- let infile = tempname()
- let tmpfile = tempname()
- call writefile(["XYZ"], infile)
- exec "edit" tmpfile
- try
- Xpath 'j'
- try
- let post = 0
- aug TMP
- au! FileReadPre * asdf
- au! FileReadPost * let post = 1
- aug END
- exec "0read" infile
- catch /^Vim\((read)\)\=:/
- Xpath 'k'
- call assert_match('E492: Not an editor command', v:exception)
- finally
- Xpath 'l'
- if getline("1") == "XYZ"
- call assert_report('should not get here')
- endif
- call assert_equal(0, post)
- au! TMP
- aug! TMP
- endtry
- finally
- Xpath 'm'
- bwipeout!
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'n'
- break
- endtry
- endwhile
- call delete(infile)
- call delete(tmpfile)
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('abcdefghijklmn', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
- endfunc
- "-------------------------------------------------------------------------------
- " Test 87 using (expr) ? funcref : funcref {{{1
- "
- " Vim needs to correctly parse the funcref and even when it does
- " not execute the funcref, it needs to consume the trailing ()
- "-------------------------------------------------------------------------------
- func Add2(x1, x2)
- return a:x1 + a:x2
- endfu
- func GetStr()
- return "abcdefghijklmnopqrstuvwxyp"
- endfu
- func Test_funcref_with_condexpr()
- call assert_equal(5, function('Add2')(2,3))
- call assert_equal(3, 1 ? function('Add2')(1,2) : function('Add2')(2,3))
- call assert_equal(5, 0 ? function('Add2')(1,2) : function('Add2')(2,3))
- " Make sure, GetStr() still works.
- call assert_equal('abcdefghijk', GetStr()[0:10])
- endfunc
- "-------------------------------------------------------------------------------
- " Test 90: Recognizing {} in variable name. {{{1
- "-------------------------------------------------------------------------------
- func Test_curlies()
- let s:var = 66
- let ns = 's'
- call assert_equal(66, {ns}:var)
- let g:a = {}
- let g:b = 't'
- let g:a[g:b] = 77
- call assert_equal(77, g:a['t'])
- endfunc
- "-------------------------------------------------------------------------------
- " Test 91: using type(). {{{1
- "-------------------------------------------------------------------------------
- func Test_type()
- call assert_equal(0, type(0))
- call assert_equal(1, type(""))
- call assert_equal(2, type(function("tr")))
- call assert_equal(2, type(function("tr", [8])))
- call assert_equal(3, type([]))
- call assert_equal(4, type({}))
- if has('float')
- call assert_equal(5, type(0.0))
- endif
- call assert_equal(6, type(v:false))
- call assert_equal(6, type(v:true))
- " call assert_equal(7, type(v:none))
- call assert_equal(7, type(v:null))
- call assert_equal(v:t_number, type(0))
- call assert_equal(v:t_string, type(""))
- call assert_equal(v:t_func, type(function("tr")))
- call assert_equal(v:t_func, type(function("tr", [8])))
- call assert_equal(v:t_list, type([]))
- call assert_equal(v:t_dict, type({}))
- if has('float')
- call assert_equal(v:t_float, type(0.0))
- endif
- call assert_equal(v:t_bool, type(v:false))
- call assert_equal(v:t_bool, type(v:true))
- " call assert_equal(v:t_none, type(v:none))
- " call assert_equal(v:t_none, type(v:null))
- call assert_equal(v:t_string, type(v:_null_string))
- call assert_equal(v:t_list, type(v:_null_list))
- call assert_equal(v:t_dict, type(v:_null_dict))
- if has('job')
- call assert_equal(v:t_job, type(test_null_job()))
- endif
- if has('channel')
- call assert_equal(v:t_channel, type(test_null_channel()))
- endif
- call assert_equal(v:t_blob, type(v:_null_blob))
- call assert_equal(0, 0 + v:false)
- call assert_equal(1, 0 + v:true)
- " call assert_equal(0, 0 + v:none)
- call assert_equal(0, 0 + v:null)
- call assert_equal('v:false', '' . v:false)
- call assert_equal('v:true', '' . v:true)
- " call assert_equal('v:none', '' . v:none)
- call assert_equal('v:null', '' . v:null)
- call assert_true(v:false == 0)
- call assert_false(v:false != 0)
- call assert_true(v:true == 1)
- call assert_false(v:true != 1)
- call assert_false(v:true == v:false)
- call assert_true(v:true != v:false)
- call assert_true(v:null == 0)
- call assert_false(v:null != 0)
- " call assert_true(v:none == 0)
- " call assert_false(v:none != 0)
- call assert_true(v:false is v:false)
- call assert_true(v:true is v:true)
- " call assert_true(v:none is v:none)
- call assert_true(v:null is v:null)
- call assert_false(v:false isnot v:false)
- call assert_false(v:true isnot v:true)
- " call assert_false(v:none isnot v:none)
- call assert_false(v:null isnot v:null)
- call assert_false(v:false is 0)
- call assert_false(v:true is 1)
- call assert_false(v:true is v:false)
- " call assert_false(v:none is 0)
- call assert_false(v:null is 0)
- " call assert_false(v:null is v:none)
- call assert_true(v:false isnot 0)
- call assert_true(v:true isnot 1)
- call assert_true(v:true isnot v:false)
- " call assert_true(v:none isnot 0)
- call assert_true(v:null isnot 0)
- " call assert_true(v:null isnot v:none)
- call assert_equal(v:false, eval(string(v:false)))
- call assert_equal(v:true, eval(string(v:true)))
- " call assert_equal(v:none, eval(string(v:none)))
- call assert_equal(v:null, eval(string(v:null)))
- call assert_equal(v:false, copy(v:false))
- call assert_equal(v:true, copy(v:true))
- " call assert_equal(v:none, copy(v:none))
- call assert_equal(v:null, copy(v:null))
- call assert_equal([v:false], deepcopy([v:false]))
- call assert_equal([v:true], deepcopy([v:true]))
- " call assert_equal([v:none], deepcopy([v:none]))
- call assert_equal([v:null], deepcopy([v:null]))
- call assert_true(empty(v:false))
- call assert_false(empty(v:true))
- call assert_true(empty(v:null))
- " call assert_true(empty(v:none))
- func ChangeYourMind()
- try
- return v:true
- finally
- return 'something else'
- endtry
- endfunc
- call ChangeYourMind()
- endfunc
- "-------------------------------------------------------------------------------
- " Test 92: skipping code {{{1
- "-------------------------------------------------------------------------------
- func Test_skip()
- let Fn = function('Test_type')
- call assert_false(0 && Fn[1])
- call assert_false(0 && string(Fn))
- call assert_false(0 && len(Fn))
- let l = []
- call assert_false(0 && l[1])
- call assert_false(0 && string(l))
- call assert_false(0 && len(l))
- let f = 1.0
- call assert_false(0 && f[1])
- call assert_false(0 && string(f))
- call assert_false(0 && len(f))
- let sp = v:null
- call assert_false(0 && sp[1])
- call assert_false(0 && string(sp))
- call assert_false(0 && len(sp))
- endfunc
- "-------------------------------------------------------------------------------
- " Test 93: :echo and string() {{{1
- "-------------------------------------------------------------------------------
- func Test_echo_and_string()
- " String
- let a = 'foo bar'
- redir => result
- echo a
- echo string(a)
- redir END
- let l = split(result, "\n")
- call assert_equal(["foo bar",
- \ "'foo bar'"], l)
- " Float
- if has('float')
- let a = -1.2e0
- redir => result
- echo a
- echo string(a)
- redir END
- let l = split(result, "\n")
- call assert_equal(["-1.2",
- \ "-1.2"], l)
- endif
- " Funcref
- redir => result
- echo function('string')
- echo string(function('string'))
- redir END
- let l = split(result, "\n")
- call assert_equal(["string",
- \ "function('string')"], l)
- " Empty dictionaries in a list
- let a = {}
- redir => result
- echo [a, a, a]
- echo string([a, a, a])
- redir END
- let l = split(result, "\n")
- call assert_equal(["[{}, {}, {}]",
- \ "[{}, {}, {}]"], l)
- " Empty dictionaries in a dictionary
- let a = {}
- let b = {"a": a, "b": a}
- redir => result
- echo b
- echo string(b)
- redir END
- let l = split(result, "\n")
- call assert_equal(["{'a': {}, 'b': {}}",
- \ "{'a': {}, 'b': {}}"], l)
- " Empty lists in a list
- let a = []
- redir => result
- echo [a, a, a]
- echo string([a, a, a])
- redir END
- let l = split(result, "\n")
- call assert_equal(["[[], [], []]",
- \ "[[], [], []]"], l)
- " Empty lists in a dictionary
- let a = []
- let b = {"a": a, "b": a}
- redir => result
- echo b
- echo string(b)
- redir END
- let l = split(result, "\n")
- call assert_equal(["{'a': [], 'b': []}",
- \ "{'a': [], 'b': []}"], l)
- call assert_fails('echo &:', 'E112:')
- call assert_fails('echo &g:', 'E112:')
- call assert_fails('echo &l:', 'E112:')
- endfunc
- "-------------------------------------------------------------------------------
- " Test 94: 64-bit Numbers {{{1
- "-------------------------------------------------------------------------------
- func Test_num64()
- call assert_notequal( 4294967296, 0)
- call assert_notequal(-4294967296, 0)
- call assert_equal( 4294967296, 0xFFFFffff + 1)
- call assert_equal(-4294967296, -0xFFFFffff - 1)
- call assert_equal( 9223372036854775807, 1 / 0)
- call assert_equal(-9223372036854775807, -1 / 0)
- call assert_equal(-9223372036854775807 - 1, 0 / 0)
- if has('float')
- call assert_equal( 0x7FFFffffFFFFffff, float2nr( 1.0e150))
- call assert_equal(-0x7FFFffffFFFFffff, float2nr(-1.0e150))
- endif
- let rng = range(0xFFFFffff, 0x100000001)
- call assert_equal([0xFFFFffff, 0x100000000, 0x100000001], rng)
- call assert_equal(0x100000001, max(rng))
- call assert_equal(0xFFFFffff, min(rng))
- call assert_equal(rng, sort(range(0x100000001, 0xFFFFffff, -1), 'N'))
- endfunc
- "-------------------------------------------------------------------------------
- " Test 95: lines of :append, :change, :insert {{{1
- "-------------------------------------------------------------------------------
- func DefineFunction(name, body)
- let func = join(['function! ' . a:name . '()'] + a:body + ['endfunction'], "\n")
- exec func
- endfunc
- func Test_script_lines()
- " :append
- try
- call DefineFunction('T_Append', [
- \ 'append',
- \ 'py <<EOS',
- \ '.',
- \ ])
- catch
- call assert_report("Can't define function")
- endtry
- try
- call DefineFunction('T_Append', [
- \ 'append',
- \ 'abc',
- \ ])
- call assert_report("Shouldn't be able to define function")
- catch
- call assert_exception('Vim(function):E1145: Missing heredoc end marker: .')
- endtry
- " :change
- try
- call DefineFunction('T_Change', [
- \ 'change',
- \ 'py <<EOS',
- \ '.',
- \ ])
- catch
- call assert_report("Can't define function")
- endtry
- try
- call DefineFunction('T_Change', [
- \ 'change',
- \ 'abc',
- \ ])
- call assert_report("Shouldn't be able to define function")
- catch
- call assert_exception('Vim(function):E1145: Missing heredoc end marker: .')
- endtry
- " :insert
- try
- call DefineFunction('T_Insert', [
- \ 'insert',
- \ 'py <<EOS',
- \ '.',
- \ ])
- catch
- call assert_report("Can't define function")
- endtry
- try
- call DefineFunction('T_Insert', [
- \ 'insert',
- \ 'abc',
- \ ])
- call assert_report("Shouldn't be able to define function")
- catch
- call assert_exception('Vim(function):E1145: Missing heredoc end marker: .')
- endtry
- endfunc
- "-------------------------------------------------------------------------------
- " Test 96: line continuation {{{1
- "
- " Undefined behavior was detected by ubsan with line continuation
- " after an empty line.
- "-------------------------------------------------------------------------------
- func Test_script_empty_line_continuation()
- \
- endfunc
- "-------------------------------------------------------------------------------
- " Test 97: bitwise functions {{{1
- "-------------------------------------------------------------------------------
- func Test_bitwise_functions()
- " and
- call assert_equal(127, and(127, 127))
- call assert_equal(16, and(127, 16))
- eval 127->and(16)->assert_equal(16)
- call assert_equal(0, and(127, 128))
- call assert_fails("call and([], 1)", 'E745:')
- call assert_fails("call and({}, 1)", 'E728:')
- if has('float')
- call assert_fails("call and(1.0, 1)", 'E805:')
- call assert_fails("call and(1, 1.0)", 'E805:')
- endif
- call assert_fails("call and(1, [])", 'E745:')
- call assert_fails("call and(1, {})", 'E728:')
- " or
- call assert_equal(23, or(16, 7))
- call assert_equal(15, or(8, 7))
- eval 8->or(7)->assert_equal(15)
- call assert_equal(123, or(0, 123))
- call assert_fails("call or([], 1)", 'E745:')
- call assert_fails("call or({}, 1)", 'E728:')
- if has('float')
- call assert_fails("call or(1.0, 1)", 'E805:')
- call assert_fails("call or(1, 1.0)", 'E805:')
- endif
- call assert_fails("call or(1, [])", 'E745:')
- call assert_fails("call or(1, {})", 'E728:')
- " xor
- call assert_equal(0, xor(127, 127))
- call assert_equal(111, xor(127, 16))
- eval 127->xor(16)->assert_equal(111)
- call assert_equal(255, xor(127, 128))
- if has('float')
- call assert_fails("call xor(1.0, 1)", 'E805:')
- call assert_fails("call xor(1, 1.0)", 'E805:')
- endif
- call assert_fails("call xor([], 1)", 'E745:')
- call assert_fails("call xor({}, 1)", 'E728:')
- call assert_fails("call xor(1, [])", 'E745:')
- call assert_fails("call xor(1, {})", 'E728:')
- " invert
- call assert_equal(65408, and(invert(127), 65535))
- eval 127->invert()->and(65535)->assert_equal(65408)
- call assert_equal(65519, and(invert(16), 65535))
- call assert_equal(65407, and(invert(128), 65535))
- if has('float')
- call assert_fails("call invert(1.0)", 'E805:')
- endif
- call assert_fails("call invert([])", 'E745:')
- call assert_fails("call invert({})", 'E728:')
- endfunc
- " Test using bang after user command {{{1
- func Test_user_command_with_bang()
- command -bang Nieuw let nieuw = 1
- Ni!
- call assert_equal(1, nieuw)
- unlet nieuw
- delcommand Nieuw
- endfunc
- func Test_script_expand_sfile()
- let lines =<< trim END
- func s:snr()
- return expand('<sfile>')
- endfunc
- let g:result = s:snr()
- END
- call writefile(lines, 'Xexpand')
- source Xexpand
- call assert_match('<SNR>\d\+_snr', g:result)
- source Xexpand
- call assert_match('<SNR>\d\+_snr', g:result)
- call delete('Xexpand')
- unlet g:result
- endfunc
- func Test_compound_assignment_operators()
- " Test for number
- let x = 1
- let x += 10
- call assert_equal(11, x)
- let x -= 5
- call assert_equal(6, x)
- let x *= 4
- call assert_equal(24, x)
- let x /= 3
- call assert_equal(8, x)
- let x %= 3
- call assert_equal(2, x)
- let x .= 'n'
- call assert_equal('2n', x)
- " Test special cases: division or modulus with 0.
- let x = 1
- let x /= 0
- call assert_equal(0x7FFFFFFFFFFFFFFF, x)
- let x = -1
- let x /= 0
- call assert_equal(-0x7FFFFFFFFFFFFFFF, x)
- let x = 0
- let x /= 0
- call assert_equal(-0x7FFFFFFFFFFFFFFF - 1, x)
- let x = 1
- let x %= 0
- call assert_equal(0, x)
- let x = -1
- let x %= 0
- call assert_equal(0, x)
- let x = 0
- let x %= 0
- call assert_equal(0, x)
- " Test for string
- let x = 'str'
- let x .= 'ing'
- call assert_equal('string', x)
- let x += 1
- call assert_equal(1, x)
- if has('float')
- " Test for float
- let x -= 1.5
- call assert_equal(-0.5, x)
- let x = 0.5
- let x += 4.5
- call assert_equal(5.0, x)
- let x -= 1.5
- call assert_equal(3.5, x)
- let x *= 3.0
- call assert_equal(10.5, x)
- let x /= 2.5
- call assert_equal(4.2, x)
- call assert_fails('let x %= 0.5', 'E734')
- call assert_fails('let x .= "f"', 'E734')
- let x = !3.14
- call assert_equal(0.0, x)
- " integer and float operations
- let x = 1
- let x *= 2.1
- call assert_equal(2.1, x)
- let x = 1
- let x /= 0.25
- call assert_equal(4.0, x)
- let x = 1
- call assert_fails('let x %= 0.25', 'E734:')
- let x = 1
- call assert_fails('let x .= 0.25', 'E734:')
- let x = 1.0
- call assert_fails('let x += [1.1]', 'E734:')
- endif
- " Test for environment variable
- let $FOO = 1
- call assert_fails('let $FOO += 1', 'E734')
- call assert_fails('let $FOO -= 1', 'E734')
- call assert_fails('let $FOO *= 1', 'E734')
- call assert_fails('let $FOO /= 1', 'E734')
- call assert_fails('let $FOO %= 1', 'E734')
- let $FOO .= 's'
- call assert_equal('1s', $FOO)
- unlet $FOO
- " Test for option variable (type: number)
- let &scrolljump = 1
- let &scrolljump += 5
- call assert_equal(6, &scrolljump)
- let &scrolljump -= 2
- call assert_equal(4, &scrolljump)
- let &scrolljump *= 3
- call assert_equal(12, &scrolljump)
- let &scrolljump /= 2
- call assert_equal(6, &scrolljump)
- let &scrolljump %= 5
- call assert_equal(1, &scrolljump)
- call assert_fails('let &scrolljump .= "j"', ['E734:', 'E734:'])
- set scrolljump&vim
- let &foldlevelstart = 2
- let &foldlevelstart -= 1
- call assert_equal(1, &foldlevelstart)
- let &foldlevelstart -= 1
- call assert_equal(0, &foldlevelstart)
- let &foldlevelstart = 2
- let &foldlevelstart -= 2
- call assert_equal(0, &foldlevelstart)
- " Test for register
- let @/ = 1
- call assert_fails('let @/ += 1', 'E734:')
- call assert_fails('let @/ -= 1', 'E734:')
- call assert_fails('let @/ *= 1', 'E734:')
- call assert_fails('let @/ /= 1', 'E734:')
- call assert_fails('let @/ %= 1', 'E734:')
- let @/ .= 's'
- call assert_equal('1s', @/)
- let @/ = ''
- endfunc
- func Test_unlet_env()
- let $TESTVAR = 'yes'
- call assert_equal('yes', $TESTVAR)
- call assert_fails('lockvar $TESTVAR', 'E940')
- call assert_fails('unlockvar $TESTVAR', 'E940')
- call assert_equal('yes', $TESTVAR)
- if 0
- unlet $TESTVAR
- endif
- call assert_equal('yes', $TESTVAR)
- unlet $TESTVAR
- call assert_equal('', $TESTVAR)
- endfunc
- func Test_refcount()
- throw 'Skipped: Nvim does not support test_refcount()'
- " Immediate values
- call assert_equal(-1, test_refcount(1))
- call assert_equal(-1, test_refcount('s'))
- call assert_equal(-1, test_refcount(v:true))
- call assert_equal(0, test_refcount([]))
- call assert_equal(0, test_refcount({}))
- call assert_equal(0, test_refcount(0zff))
- call assert_equal(0, test_refcount({-> line('.')}))
- call assert_equal(-1, test_refcount(0.1))
- if has('job')
- call assert_equal(0, test_refcount(job_start([&shell, &shellcmdflag, 'echo .'])))
- endif
- " No refcount types
- let x = 1
- call assert_equal(-1, test_refcount(x))
- let x = 's'
- call assert_equal(-1, test_refcount(x))
- let x = v:true
- call assert_equal(-1, test_refcount(x))
- let x = 0.1
- call assert_equal(-1, test_refcount(x))
- " Check refcount
- let x = []
- call assert_equal(1, test_refcount(x))
- let x = {}
- call assert_equal(1, x->test_refcount())
- let x = 0zff
- call assert_equal(1, test_refcount(x))
- let X = {-> line('.')}
- call assert_equal(1, test_refcount(X))
- let Y = X
- call assert_equal(2, test_refcount(X))
- if has('job')
- let job = job_start([&shell, &shellcmdflag, 'echo .'])
- call assert_equal(1, test_refcount(job))
- call assert_equal(1, test_refcount(job_getchannel(job)))
- call assert_equal(1, test_refcount(job))
- endif
- " Function arguments, copying and unassigning
- func ExprCheck(x, i)
- let i = a:i + 1
- call assert_equal(i, test_refcount(a:x))
- let Y = a:x
- call assert_equal(i + 1, test_refcount(a:x))
- call assert_equal(test_refcount(a:x), test_refcount(Y))
- let Y = 0
- call assert_equal(i, test_refcount(a:x))
- endfunc
- call ExprCheck([], 0)
- call ExprCheck({}, 0)
- call ExprCheck(0zff, 0)
- call ExprCheck({-> line('.')}, 0)
- if has('job')
- call ExprCheck(job, 1)
- call ExprCheck(job_getchannel(job), 1)
- call job_stop(job)
- endif
- delfunc ExprCheck
- " Regarding function
- func Func(x) abort
- call assert_equal(2, test_refcount(function('Func')))
- call assert_equal(0, test_refcount(funcref('Func')))
- endfunc
- call assert_equal(1, test_refcount(function('Func')))
- call assert_equal(0, test_refcount(function('Func', [1])))
- call assert_equal(0, test_refcount(funcref('Func')))
- call assert_equal(0, test_refcount(funcref('Func', [1])))
- let X = function('Func')
- let Y = X
- call assert_equal(1, test_refcount(X))
- let X = function('Func', [1])
- let Y = X
- call assert_equal(2, test_refcount(X))
- let X = funcref('Func')
- let Y = X
- call assert_equal(2, test_refcount(X))
- let X = funcref('Func', [1])
- let Y = X
- call assert_equal(2, test_refcount(X))
- unlet X
- unlet Y
- call Func(1)
- delfunc Func
- " Function with dict
- func DictFunc() dict
- call assert_equal(3, test_refcount(self))
- endfunc
- let d = {'Func': function('DictFunc')}
- call assert_equal(1, test_refcount(d))
- call assert_equal(0, test_refcount(d.Func))
- call d.Func()
- unlet d
- delfunc DictFunc
- if has('channel')
- call assert_equal(-1, test_refcount(test_null_job()))
- call assert_equal(-1, test_refcount(test_null_channel()))
- endif
- call assert_equal(-1, test_refcount(test_null_function()))
- call assert_equal(-1, test_refcount(test_null_partial()))
- call assert_equal(-1, test_refcount(test_null_blob()))
- call assert_equal(-1, test_refcount(test_null_list()))
- call assert_equal(-1, test_refcount(test_null_dict()))
- endfunc
- " Test for missing :endif, :endfor, :endwhile and :endtry {{{1
- func Test_missing_end()
- call writefile(['if 2 > 1', 'echo ">"'], 'Xscript')
- call assert_fails('source Xscript', 'E171:')
- call writefile(['for i in range(5)', 'echo i'], 'Xscript')
- call assert_fails('source Xscript', 'E170:')
- call writefile(['while v:true', 'echo "."'], 'Xscript')
- call assert_fails('source Xscript', 'E170:')
- call writefile(['try', 'echo "."'], 'Xscript')
- call assert_fails('source Xscript', 'E600:')
- call delete('Xscript')
- " Using endfor with :while
- let caught_e732 = 0
- try
- while v:true
- endfor
- catch /E732:/
- let caught_e732 = 1
- endtry
- call assert_equal(1, caught_e732)
- " Using endwhile with :for
- let caught_e733 = 0
- try
- for i in range(1)
- endwhile
- catch /E733:/
- let caught_e733 = 1
- endtry
- call assert_equal(1, caught_e733)
- " Using endfunc with :if
- call assert_fails('exe "if 1 | endfunc | endif"', 'E193:')
- " Missing 'in' in a :for statement
- call assert_fails('for i range(1) | endfor', 'E690:')
- " Incorrect number of variables in for
- call assert_fails('for [i,] in range(3) | endfor', 'E475:')
- endfunc
- " Test for deep nesting of if/for/while/try statements {{{1
- func Test_deep_nest()
- CheckRunVimInTerminal
- let lines =<< trim [SCRIPT]
- " Deep nesting of if ... endif
- func Test1()
- let @a = join(repeat(['if v:true'], 51), "\n")
- let @a ..= "\n"
- let @a ..= join(repeat(['endif'], 51), "\n")
- @a
- let @a = ''
- endfunc
- " Deep nesting of for ... endfor
- func Test2()
- let @a = join(repeat(['for i in [1]'], 51), "\n")
- let @a ..= "\n"
- let @a ..= join(repeat(['endfor'], 51), "\n")
- @a
- let @a = ''
- endfunc
- " Deep nesting of while ... endwhile
- func Test3()
- let @a = join(repeat(['while v:true'], 51), "\n")
- let @a ..= "\n"
- let @a ..= join(repeat(['endwhile'], 51), "\n")
- @a
- let @a = ''
- endfunc
- " Deep nesting of try ... endtry
- func Test4()
- let @a = join(repeat(['try'], 51), "\n")
- let @a ..= "\necho v:true\n"
- let @a ..= join(repeat(['endtry'], 51), "\n")
- @a
- let @a = ''
- endfunc
- " Deep nesting of function ... endfunction
- func Test5()
- let @a = join(repeat(['function X()'], 51), "\n")
- let @a ..= "\necho v:true\n"
- let @a ..= join(repeat(['endfunction'], 51), "\n")
- @a
- let @a = ''
- endfunc
- [SCRIPT]
- call writefile(lines, 'Xscript')
- let buf = RunVimInTerminal('-S Xscript', {'rows': 6})
- " Deep nesting of if ... endif
- call term_sendkeys(buf, ":call Test1()\n")
- call TermWait(buf)
- call WaitForAssert({-> assert_match('^E579:', term_getline(buf, 5))})
- " Deep nesting of for ... endfor
- call term_sendkeys(buf, ":call Test2()\n")
- call TermWait(buf)
- call WaitForAssert({-> assert_match('^E585:', term_getline(buf, 5))})
- " Deep nesting of while ... endwhile
- call term_sendkeys(buf, ":call Test3()\n")
- call TermWait(buf)
- call WaitForAssert({-> assert_match('^E585:', term_getline(buf, 5))})
- " Deep nesting of try ... endtry
- call term_sendkeys(buf, ":call Test4()\n")
- call TermWait(buf)
- call WaitForAssert({-> assert_match('^E601:', term_getline(buf, 5))})
- " Deep nesting of function ... endfunction
- call term_sendkeys(buf, ":call Test5()\n")
- call TermWait(buf)
- call WaitForAssert({-> assert_match('^E1058:', term_getline(buf, 4))})
- call term_sendkeys(buf, "\<C-C>\n")
- call TermWait(buf)
- "let l = ''
- "for i in range(1, 6)
- " let l ..= term_getline(buf, i) . "\n"
- "endfor
- "call assert_report(l)
- call StopVimInTerminal(buf)
- call delete('Xscript')
- endfunc
- " Test for errors in converting to float from various types {{{1
- func Test_float_conversion_errors()
- if has('float')
- call assert_fails('let x = 4.0 % 2.0', 'E804')
- call assert_fails('echo 1.1[0]', 'E806')
- call assert_fails('echo sort([function("min"), 1], "f")', 'E891:')
- call assert_fails('echo 3.2 == "vim"', 'E892:')
- call assert_fails('echo sort([[], 1], "f")', 'E893:')
- call assert_fails('echo sort([{}, 1], "f")', 'E894:')
- call assert_fails('echo 3.2 == v:true', 'E362:')
- " call assert_fails('echo 3.2 == v:none', 'E907:')
- endif
- endfunc
- " invalid function names {{{1
- func Test_invalid_function_names()
- " function name not starting with capital
- let caught_e128 = 0
- try
- func! g:test()
- echo "test"
- endfunc
- catch /E128:/
- let caught_e128 = 1
- endtry
- call assert_equal(1, caught_e128)
- " function name includes a colon
- let caught_e884 = 0
- try
- func! b:test()
- echo "test"
- endfunc
- catch /E884:/
- let caught_e884 = 1
- endtry
- call assert_equal(1, caught_e884)
- " function name followed by #
- let caught_e128 = 0
- try
- func! test2() "#
- echo "test2"
- endfunc
- catch /E128:/
- let caught_e128 = 1
- endtry
- call assert_equal(1, caught_e128)
- " function name starting with/without "g:", buffer-local funcref.
- function! g:Foo(n)
- return 'called Foo(' . a:n . ')'
- endfunction
- let b:my_func = function('Foo')
- call assert_equal('called Foo(1)', b:my_func(1))
- call assert_equal('called Foo(2)', g:Foo(2))
- call assert_equal('called Foo(3)', Foo(3))
- delfunc g:Foo
- " script-local function used in Funcref must exist.
- let lines =<< trim END
- func s:Testje()
- return "foo"
- endfunc
- let Bar = function('s:Testje')
- call assert_equal(0, exists('s:Testje'))
- call assert_equal(1, exists('*s:Testje'))
- call assert_equal(1, exists('Bar'))
- call assert_equal(1, exists('*Bar'))
- END
- call writefile(lines, 'Xscript')
- source Xscript
- call delete('Xscript')
- endfunc
- " substring and variable name {{{1
- func Test_substring_var()
- let str = 'abcdef'
- let n = 3
- call assert_equal('def', str[n:])
- call assert_equal('abcd', str[:n])
- call assert_equal('d', str[n:n])
- unlet n
- let nn = 3
- call assert_equal('def', str[nn:])
- call assert_equal('abcd', str[:nn])
- call assert_equal('d', str[nn:nn])
- unlet nn
- let b:nn = 4
- call assert_equal('ef', str[b:nn:])
- call assert_equal('abcde', str[:b:nn])
- call assert_equal('e', str[b:nn:b:nn])
- unlet b:nn
- endfunc
- " Test using s: with a typed command {{{1
- func Test_typed_script_var()
- CheckRunVimInTerminal
- let buf = RunVimInTerminal('', {'rows': 6})
- " Deep nesting of if ... endif
- call term_sendkeys(buf, ":echo get(s:, 'foo', 'x')\n")
- call TermWait(buf)
- call WaitForAssert({-> assert_match('^E116:', term_getline(buf, 5))})
- call StopVimInTerminal(buf)
- endfunc
- " Test for issue6776 {{{1
- func Test_ternary_expression()
- try
- call eval('0 ? 0')
- catch
- endtry
- " previous failure should not cause next expression to fail
- call assert_equal(v:false, eval(string(v:false)))
- try
- call eval('0 ? "burp')
- catch
- endtry
- " previous failure should not cause next expression to fail
- call assert_equal(v:false, eval(string(v:false)))
- try
- call eval('1 ? 0 : "burp')
- catch
- endtry
- " previous failure should not cause next expression to fail
- call assert_equal(v:false, eval(string(v:false)))
- endfunction
- func Test_for_over_string()
- let res = ''
- for c in 'aéc̀d'
- let res ..= c .. '-'
- endfor
- call assert_equal('a-é-c̀-d-', res)
- let res = ''
- for c in ''
- let res ..= c .. '-'
- endfor
- call assert_equal('', res)
- let res = ''
- for c in v:_null_string
- let res ..= c .. '-'
- endfor
- call assert_equal('', res)
- " Test for using "_" as the loop variable
- let i = 0
- let s = 'abc'
- for _ in s
- call assert_equal(s[i], _)
- let i += 1
- endfor
- endfunc
- " Test for deeply nested :source command {{{1
- func Test_deeply_nested_source()
- throw 'Skipped: Vim9 script is N/A'
- let lines =<< trim END
- so
- sil 0scr
- delete
- so
- 0
- END
- call writefile(["vim9 silent! @0 \n/"] + lines, 'Xnested.vim', 'D')
- " this must not crash
- let cmd = GetVimCommand() .. " -e -s -S Xnested.vim -c qa!"
- call system(cmd)
- endfunc
- func Test_exception_silent()
- XpathINIT
- let lines =<< trim END
- func Throw()
- Xpath 'a'
- throw "Uncaught"
- " This line is not executed.
- Xpath 'b'
- endfunc
- " The exception is suppressed due to the presence of silent!.
- silent! call Throw()
- try
- call DoesNotExist()
- catch /E117:/
- Xpath 'c'
- endtry
- Xpath 'd'
- END
- let verify =<< trim END
- call assert_equal('acd', g:Xpath)
- END
- call RunInNewVim(lines, verify)
- endfunc
- "-------------------------------------------------------------------------------
- " Modelines {{{1
- " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
- "-------------------------------------------------------------------------------
|