Mercurial > vim
comparison src/testdir/test_trycatch.vim @ 18504:ece46bd3c9af v8.1.2246
patch 8.1.2246: some tests are still in old style
Commit: https://github.com/vim/vim/commit/1f068233c101ecf5966e6df14853fe68f08175a7
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Nov 3 16:17:26 2019 +0100
patch 8.1.2246: some tests are still in old style
Problem: Some tests are still in old style.
Solution: Change a few tests to new style. (Yegappan Lakshmanan)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 03 Nov 2019 16:30:03 +0100 |
parents | |
children | 050f5eaa9e50 |
comparison
equal
deleted
inserted
replaced
18503:d946c71f8b4c | 18504:ece46bd3c9af |
---|---|
1 " Test try-catch-finally exception handling | |
2 " Most of this was formerly in test49. | |
3 | |
4 source check.vim | |
5 source shared.vim | |
6 | |
7 "------------------------------------------------------------------------------- | |
8 " Test environment {{{1 | |
9 "------------------------------------------------------------------------------- | |
10 | |
11 com! XpathINIT let g:Xpath = '' | |
12 com! -nargs=1 -bar Xpath let g:Xpath = g:Xpath . <args> | |
13 | |
14 " Test 25: Executing :finally clauses on normal control flow {{{1 | |
15 " | |
16 " Control flow in a :try conditional should always fall through to its | |
17 " :finally clause. A :finally clause of a :try conditional inside an | |
18 " inactive conditional should never be executed. | |
19 "------------------------------------------------------------------------------- | |
20 | |
21 func T25_F() | |
22 let loops = 3 | |
23 while loops > 0 | |
24 Xpath 'a' . loops | |
25 if loops >= 2 | |
26 try | |
27 Xpath 'b' . loops | |
28 if loops == 2 | |
29 try | |
30 Xpath 'c' . loops | |
31 finally | |
32 Xpath 'd' . loops | |
33 endtry | |
34 endif | |
35 finally | |
36 Xpath 'e' . loops | |
37 if loops == 2 | |
38 try | |
39 Xpath 'f' . loops | |
40 finally | |
41 Xpath 'g' . loops | |
42 endtry | |
43 endif | |
44 endtry | |
45 endif | |
46 Xpath 'h' . loops | |
47 let loops = loops - 1 | |
48 endwhile | |
49 Xpath 'i' | |
50 endfunc | |
51 | |
52 func T25_G() | |
53 if 1 | |
54 try | |
55 Xpath 'A' | |
56 call T25_F() | |
57 Xpath 'B' | |
58 finally | |
59 Xpath 'C' | |
60 endtry | |
61 else | |
62 try | |
63 Xpath 'D' | |
64 finally | |
65 Xpath 'E' | |
66 endtry | |
67 endif | |
68 endfunc | |
69 | |
70 func Test_finally() | |
71 XpathINIT | |
72 call T25_G() | |
73 call assert_equal('Aa3b3e3h3a2b2c2d2e2f2g2h2a1h1iBC', g:Xpath) | |
74 endfunc | |
75 | |
76 | |
77 "------------------------------------------------------------------------------- | |
78 " Test 26: Executing :finally clauses after :continue or :break {{{1 | |
79 " | |
80 " For a :continue or :break dynamically enclosed in a :try/:endtry | |
81 " region inside the next surrounding :while/:endwhile, if the | |
82 " :continue/:break is before the :finally, the :finally clause is | |
83 " executed first. If the :continue/:break is after the :finally, the | |
84 " :finally clause is broken (like an :if/:endif region). | |
85 "------------------------------------------------------------------------------- | |
86 | |
87 func T26_F() | |
88 try | |
89 let loops = 3 | |
90 while loops > 0 | |
91 try | |
92 try | |
93 if loops == 2 | |
94 Xpath 'a' . loops | |
95 let loops = loops - 1 | |
96 continue | |
97 elseif loops == 1 | |
98 Xpath 'b' . loops | |
99 break | |
100 finish | |
101 endif | |
102 Xpath 'c' . loops | |
103 endtry | |
104 finally | |
105 Xpath 'd' . loops | |
106 endtry | |
107 Xpath 'e' . loops | |
108 let loops = loops - 1 | |
109 endwhile | |
110 Xpath 'f' | |
111 finally | |
112 Xpath 'g' | |
113 let loops = 3 | |
114 while loops > 0 | |
115 try | |
116 finally | |
117 try | |
118 if loops == 2 | |
119 Xpath 'h' . loops | |
120 let loops = loops - 1 | |
121 continue | |
122 elseif loops == 1 | |
123 Xpath 'i' . loops | |
124 break | |
125 finish | |
126 endif | |
127 endtry | |
128 Xpath 'j' . loops | |
129 endtry | |
130 Xpath 'k' . loops | |
131 let loops = loops - 1 | |
132 endwhile | |
133 Xpath 'l' | |
134 endtry | |
135 Xpath 'm' | |
136 endfunc | |
137 | |
138 func Test_finally_after_continue() | |
139 XpathINIT | |
140 call T26_F() | |
141 call assert_equal('c3d3e3a2d1b1d1fgj3k3h2i1lm', g:Xpath) | |
142 endfunc | |
143 | |
144 | |
145 "------------------------------------------------------------------------------- | |
146 " Test 32: Remembering the :return value on :finally {{{1 | |
147 " | |
148 " If a :finally clause is executed due to a :return specifying | |
149 " a value, this is the value visible to the caller if not overwritten | |
150 " by a new :return in the :finally clause. A :return without a value | |
151 " in the :finally clause overwrites with value 0. | |
152 "------------------------------------------------------------------------------- | |
153 | |
154 func T32_F() | |
155 try | |
156 Xpath 'a' | |
157 try | |
158 Xpath 'b' | |
159 return "ABCD" | |
160 Xpath 'c' | |
161 finally | |
162 Xpath 'd' | |
163 endtry | |
164 Xpath 'e' | |
165 finally | |
166 Xpath 'f' | |
167 endtry | |
168 Xpath 'g' | |
169 endfunc | |
170 | |
171 func T32_G() | |
172 try | |
173 Xpath 'h' | |
174 return 8 | |
175 Xpath 'i' | |
176 finally | |
177 Xpath 'j' | |
178 return 16 + strlen(T32_F()) | |
179 Xpath 'k' | |
180 endtry | |
181 Xpath 'l' | |
182 endfunc | |
183 | |
184 func T32_H() | |
185 try | |
186 Xpath 'm' | |
187 return 32 | |
188 Xpath 'n' | |
189 finally | |
190 Xpath 'o' | |
191 return | |
192 Xpath 'p' | |
193 endtry | |
194 Xpath 'q' | |
195 endfunc | |
196 | |
197 func T32_I() | |
198 try | |
199 Xpath 'r' | |
200 finally | |
201 Xpath 's' | |
202 return T32_G() + T32_H() + 64 | |
203 Xpath 't' | |
204 endtry | |
205 Xpath 'u' | |
206 endfunc | |
207 | |
208 func Test_finally_return() | |
209 XpathINIT | |
210 call assert_equal(84, T32_I()) | |
211 call assert_equal('rshjabdfmo', g:Xpath) | |
212 endfunc | |
213 | |
214 "------------------------------------------------------------------------------- | |
215 " Test 33: :return under :execute or user command and :finally {{{1 | |
216 " | |
217 " A :return command may be executed under an ":execute" or from | |
218 " a user command. Executing of :finally clauses and passing through | |
219 " the return code works also then. | |
220 "------------------------------------------------------------------------------- | |
221 | |
222 func T33_F() | |
223 try | |
224 RETURN 10 | |
225 Xpath 'a' | |
226 finally | |
227 Xpath 'b' | |
228 endtry | |
229 Xpath 'c' | |
230 endfunc | |
231 | |
232 func T33_G() | |
233 try | |
234 RETURN 20 | |
235 Xpath 'd' | |
236 finally | |
237 Xpath 'e' | |
238 RETURN 30 | |
239 Xpath 'f' | |
240 endtry | |
241 Xpath 'g' | |
242 endfunc | |
243 | |
244 func T33_H() | |
245 try | |
246 execute "try | return 40 | finally | return 50 | endtry" | |
247 Xpath 'h' | |
248 finally | |
249 Xpath 'i' | |
250 endtry | |
251 Xpath 'j' | |
252 endfunc | |
253 | |
254 func T33_I() | |
255 try | |
256 execute "try | return 60 | finally | return 70 | endtry" | |
257 Xpath 'k' | |
258 finally | |
259 Xpath 'l' | |
260 execute "try | return 80 | finally | return 90 | endtry" | |
261 Xpath 'm' | |
262 endtry | |
263 Xpath 'n' | |
264 endfunc | |
265 | |
266 func T33_J() | |
267 try | |
268 RETURN 100 | |
269 Xpath 'o' | |
270 finally | |
271 Xpath 'p' | |
272 return | |
273 Xpath 'q' | |
274 endtry | |
275 Xpath 'r' | |
276 endfunc | |
277 | |
278 func T33_K() | |
279 try | |
280 execute "try | return 110 | finally | return 120 | endtry" | |
281 Xpath 's' | |
282 finally | |
283 Xpath 't' | |
284 execute "try | return 130 | finally | return | endtry" | |
285 Xpath 'u' | |
286 endtry | |
287 Xpath 'v' | |
288 endfunc | |
289 | |
290 func T33_L() | |
291 try | |
292 return | |
293 Xpath 'w' | |
294 finally | |
295 Xpath 'x' | |
296 RETURN 140 | |
297 Xpath 'y' | |
298 endtry | |
299 Xpath 'z' | |
300 endfunc | |
301 | |
302 func T33_M() | |
303 try | |
304 return | |
305 Xpath 'A' | |
306 finally | |
307 Xpath 'B' | |
308 execute "try | return 150 | finally | return 160 | endtry" | |
309 Xpath 'C' | |
310 endtry | |
311 Xpath 'D' | |
312 endfunc | |
313 | |
314 func T33_N() | |
315 RETURN 170 | |
316 endfunc | |
317 | |
318 func T33_O() | |
319 execute "try | return 180 | finally | return 190 | endtry" | |
320 endfunc | |
321 | |
322 func Test_finally_cmd_return() | |
323 command! -nargs=? RETURN | |
324 \ try | return <args> | finally | return <args> * 2 | endtry | |
325 XpathINIT | |
326 call assert_equal(20, T33_F()) | |
327 call assert_equal(60, T33_G()) | |
328 call assert_equal(50, T33_H()) | |
329 call assert_equal(90, T33_I()) | |
330 call assert_equal(0, T33_J()) | |
331 call assert_equal(0, T33_K()) | |
332 call assert_equal(280, T33_L()) | |
333 call assert_equal(160, T33_M()) | |
334 call assert_equal(340, T33_N()) | |
335 call assert_equal(190, T33_O()) | |
336 call assert_equal('beilptxB', g:Xpath) | |
337 delcommand RETURN | |
338 endfunc | |
339 | |
340 | |
341 "------------------------------------------------------------------------------- | |
342 " Test 41: Skipped :throw finding next command {{{1 | |
343 " | |
344 " A :throw in an inactive conditional must not hide a following | |
345 " command. | |
346 "------------------------------------------------------------------------------- | |
347 | |
348 func T41_F() | |
349 Xpath 'a' | |
350 if 0 | throw 'never' | endif | Xpath 'b' | |
351 Xpath 'c' | |
352 endfunc | |
353 | |
354 func T41_G() | |
355 Xpath 'd' | |
356 while 0 | throw 'never' | endwhile | Xpath 'e' | |
357 Xpath 'f' | |
358 endfunc | |
359 | |
360 func T41_H() | |
361 Xpath 'g' | |
362 if 0 | try | throw 'never' | endtry | endif | Xpath 'h' | |
363 Xpath 'i' | |
364 endfunc | |
365 | |
366 func Test_throw_inactive_cond() | |
367 XpathINIT | |
368 try | |
369 Xpath 'j' | |
370 call T41_F() | |
371 Xpath 'k' | |
372 catch /.*/ | |
373 Xpath 'l' | |
374 call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint) | |
375 endtry | |
376 | |
377 try | |
378 Xpath 'm' | |
379 call T41_G() | |
380 Xpath 'n' | |
381 catch /.*/ | |
382 Xpath 'o' | |
383 call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint) | |
384 endtry | |
385 | |
386 try | |
387 Xpath 'p' | |
388 call T41_H() | |
389 Xpath 'q' | |
390 catch /.*/ | |
391 Xpath 'r' | |
392 call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint) | |
393 endtry | |
394 | |
395 call assert_equal('jabckmdefnpghiq', g:Xpath) | |
396 endfunc | |
397 | |
398 | |
399 "------------------------------------------------------------------------------- | |
400 " Test 42: Catching number and string exceptions {{{1 | |
401 " | |
402 " When a number is thrown, it is converted to a string exception. | |
403 " Numbers and strings may be caught by specifying a regular exception | |
404 " as argument to the :catch command. | |
405 "------------------------------------------------------------------------------- | |
406 | |
407 | |
408 func T42_F() | |
409 try | |
410 | |
411 try | |
412 Xpath 'a' | |
413 throw 4711 | |
414 Xpath 'b' | |
415 catch /4711/ | |
416 Xpath 'c' | |
417 endtry | |
418 | |
419 try | |
420 Xpath 'd' | |
421 throw 4711 | |
422 Xpath 'e' | |
423 catch /^4711$/ | |
424 Xpath 'f' | |
425 endtry | |
426 | |
427 try | |
428 Xpath 'g' | |
429 throw 4711 | |
430 Xpath 'h' | |
431 catch /\d/ | |
432 Xpath 'i' | |
433 endtry | |
434 | |
435 try | |
436 Xpath 'j' | |
437 throw 4711 | |
438 Xpath 'k' | |
439 catch /^\d\+$/ | |
440 Xpath 'l' | |
441 endtry | |
442 | |
443 try | |
444 Xpath 'm' | |
445 throw "arrgh" | |
446 Xpath 'n' | |
447 catch /arrgh/ | |
448 Xpath 'o' | |
449 endtry | |
450 | |
451 try | |
452 Xpath 'p' | |
453 throw "arrgh" | |
454 Xpath 'q' | |
455 catch /^arrgh$/ | |
456 Xpath 'r' | |
457 endtry | |
458 | |
459 try | |
460 Xpath 's' | |
461 throw "arrgh" | |
462 Xpath 't' | |
463 catch /\l/ | |
464 Xpath 'u' | |
465 endtry | |
466 | |
467 try | |
468 Xpath 'v' | |
469 throw "arrgh" | |
470 Xpath 'w' | |
471 catch /^\l\+$/ | |
472 Xpath 'x' | |
473 endtry | |
474 | |
475 try | |
476 try | |
477 Xpath 'y' | |
478 throw "ARRGH" | |
479 Xpath 'z' | |
480 catch /^arrgh$/ | |
481 Xpath 'A' | |
482 endtry | |
483 catch /^\carrgh$/ | |
484 Xpath 'B' | |
485 endtry | |
486 | |
487 try | |
488 Xpath 'C' | |
489 throw "" | |
490 Xpath 'D' | |
491 catch /^$/ | |
492 Xpath 'E' | |
493 endtry | |
494 | |
495 catch /.*/ | |
496 Xpath 'F' | |
497 call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint) | |
498 endtry | |
499 endfunc | |
500 | |
501 func Test_catch_number_string() | |
502 XpathINIT | |
503 call T42_F() | |
504 call assert_equal('acdfgijlmoprsuvxyBCE', g:Xpath) | |
505 endfunc | |
506 | |
507 | |
508 "------------------------------------------------------------------------------- | |
509 " Test 43: Selecting the correct :catch clause {{{1 | |
510 " | |
511 " When an exception is thrown and there are multiple :catch clauses, | |
512 " the first matching one is taken. | |
513 "------------------------------------------------------------------------------- | |
514 | |
515 func T43_F() | |
516 let loops = 3 | |
517 while loops > 0 | |
518 try | |
519 if loops == 3 | |
520 Xpath 'a' . loops | |
521 throw "a" | |
522 Xpath 'b' . loops | |
523 elseif loops == 2 | |
524 Xpath 'c' . loops | |
525 throw "ab" | |
526 Xpath 'd' . loops | |
527 elseif loops == 1 | |
528 Xpath 'e' . loops | |
529 throw "abc" | |
530 Xpath 'f' . loops | |
531 endif | |
532 catch /abc/ | |
533 Xpath 'g' . loops | |
534 catch /ab/ | |
535 Xpath 'h' . loops | |
536 catch /.*/ | |
537 Xpath 'i' . loops | |
538 catch /a/ | |
539 Xpath 'j' . loops | |
540 endtry | |
541 | |
542 let loops = loops - 1 | |
543 endwhile | |
544 Xpath 'k' | |
545 endfunc | |
546 | |
547 func Test_multi_catch() | |
548 XpathINIT | |
549 call T43_F() | |
550 call assert_equal('a3i3c2h2e1g1k', g:Xpath) | |
551 endfunc | |
552 | |
553 | |
554 "------------------------------------------------------------------------------- | |
555 " Test 44: Missing or empty :catch patterns {{{1 | |
556 " | |
557 " A missing or empty :catch pattern means the same as /.*/, that is, | |
558 " catches everything. To catch only empty exceptions, /^$/ must be | |
559 " used. A :catch with missing, empty, or /.*/ argument also works | |
560 " when followed by another command separated by a bar on the same | |
561 " line. :catch patterns cannot be specified between ||. But other | |
562 " pattern separators can be used instead of //. | |
563 "------------------------------------------------------------------------------- | |
564 | |
565 func T44_F() | |
566 try | |
567 try | |
568 Xpath 'a' | |
569 throw "" | |
570 catch /^$/ | |
571 Xpath 'b' | |
572 endtry | |
573 | |
574 try | |
575 Xpath 'c' | |
576 throw "" | |
577 catch /.*/ | |
578 Xpath 'd' | |
579 endtry | |
580 | |
581 try | |
582 Xpath 'e' | |
583 throw "" | |
584 catch // | |
585 Xpath 'f' | |
586 endtry | |
587 | |
588 try | |
589 Xpath 'g' | |
590 throw "" | |
591 catch | |
592 Xpath 'h' | |
593 endtry | |
594 | |
595 try | |
596 Xpath 'i' | |
597 throw "oops" | |
598 catch /^$/ | |
599 Xpath 'j' | |
600 catch /.*/ | |
601 Xpath 'k' | |
602 endtry | |
603 | |
604 try | |
605 Xpath 'l' | |
606 throw "arrgh" | |
607 catch /^$/ | |
608 Xpath 'm' | |
609 catch // | |
610 Xpath 'n' | |
611 endtry | |
612 | |
613 try | |
614 Xpath 'o' | |
615 throw "brrr" | |
616 catch /^$/ | |
617 Xpath 'p' | |
618 catch | |
619 Xpath 'q' | |
620 endtry | |
621 | |
622 try | Xpath 'r' | throw "x" | catch /.*/ | Xpath 's' | endtry | |
623 | |
624 try | Xpath 't' | throw "y" | catch // | Xpath 'u' | endtry | |
625 | |
626 while 1 | |
627 try | |
628 let caught = 0 | |
629 let v:errmsg = "" | |
630 " Extra try level: if ":catch" without arguments below raises | |
631 " a syntax error because it misinterprets the "Xpath" as a pattern, | |
632 " let it be caught by the ":catch /.*/" below. | |
633 try | |
634 try | Xpath 'v' | throw "z" | catch | Xpath 'w' | : | |
635 endtry | |
636 endtry | |
637 catch /.*/ | |
638 let caught = 1 | |
639 call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint) | |
640 finally | |
641 if $VIMNOERRTHROW && v:errmsg != "" | |
642 call assert_report(v:errmsg) | |
643 endif | |
644 if caught || $VIMNOERRTHROW && v:errmsg != "" | |
645 Xpath 'x' | |
646 endif | |
647 break " discard error for $VIMNOERRTHROW | |
648 endtry | |
649 endwhile | |
650 | |
651 let cologne = 4711 | |
652 try | |
653 try | |
654 Xpath 'y' | |
655 throw "throw cologne" | |
656 " Next lines catches all and throws 4711: | |
657 catch |throw cologne| | |
658 Xpath 'z' | |
659 endtry | |
660 catch /4711/ | |
661 Xpath 'A' | |
662 endtry | |
663 | |
664 try | |
665 Xpath 'B' | |
666 throw "plus" | |
667 catch +plus+ | |
668 Xpath 'C' | |
669 endtry | |
670 | |
671 Xpath 'D' | |
672 catch /.*/ | |
673 Xpath 'E' | |
674 call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint) | |
675 endtry | |
676 endfunc | |
677 | |
678 func Test_empty_catch() | |
679 XpathINIT | |
680 call T44_F() | |
681 call assert_equal('abcdefghiklnoqrstuvwyABCD', g:Xpath) | |
682 endfunc | |
683 | |
684 | |
685 "------------------------------------------------------------------------------- | |
686 " Test 45: Catching exceptions from nested :try blocks {{{1 | |
687 " | |
688 " When :try blocks are nested, an exception is caught by the innermost | |
689 " try conditional that has a matching :catch clause. | |
690 "------------------------------------------------------------------------------- | |
691 | |
692 func T45_F() | |
693 let loops = 3 | |
694 while loops > 0 | |
695 try | |
696 try | |
697 try | |
698 try | |
699 if loops == 3 | |
700 Xpath 'a' . loops | |
701 throw "a" | |
702 Xpath 'b' . loops | |
703 elseif loops == 2 | |
704 Xpath 'c' . loops | |
705 throw "ab" | |
706 Xpath 'd' . loops | |
707 elseif loops == 1 | |
708 Xpath 'e' . loops | |
709 throw "abc" | |
710 Xpath 'f' . loops | |
711 endif | |
712 catch /abc/ | |
713 Xpath 'g' . loops | |
714 endtry | |
715 catch /ab/ | |
716 Xpath 'h' . loops | |
717 endtry | |
718 catch /.*/ | |
719 Xpath 'i' . loops | |
720 endtry | |
721 catch /a/ | |
722 Xpath 'j' . loops | |
723 endtry | |
724 | |
725 let loops = loops - 1 | |
726 endwhile | |
727 Xpath 'k' | |
728 endfunc | |
729 | |
730 func Test_catch_from_nested_try() | |
731 XpathINIT | |
732 call T45_F() | |
733 call assert_equal('a3i3c2h2e1g1k', g:Xpath) | |
734 endfunc | |
735 | |
736 | |
737 "------------------------------------------------------------------------------- | |
738 " Test 46: Executing :finally after a :throw in nested :try {{{1 | |
739 " | |
740 " When an exception is thrown from within nested :try blocks, the | |
741 " :finally clauses of the non-catching try conditionals should be | |
742 " executed before the matching :catch of the next surrounding :try | |
743 " gets the control. If this also has a :finally clause, it is | |
744 " executed afterwards. | |
745 "------------------------------------------------------------------------------- | |
746 | |
747 func T46_F() | |
748 let sum = 0 | |
749 | |
750 try | |
751 Xpath 'a' | |
752 try | |
753 Xpath 'b' | |
754 try | |
755 Xpath 'c' | |
756 try | |
757 Xpath 'd' | |
758 throw "ABC" | |
759 Xpath 'e' | |
760 catch /xyz/ | |
761 Xpath 'f' | |
762 finally | |
763 Xpath 'g' | |
764 if sum != 0 | |
765 Xpath 'h' | |
766 endif | |
767 let sum = sum + 1 | |
768 endtry | |
769 Xpath 'i' | |
770 catch /123/ | |
771 Xpath 'j' | |
772 catch /321/ | |
773 Xpath 'k' | |
774 finally | |
775 Xpath 'l' | |
776 if sum != 1 | |
777 Xpath 'm' | |
778 endif | |
779 let sum = sum + 2 | |
780 endtry | |
781 Xpath 'n' | |
782 finally | |
783 Xpath 'o' | |
784 if sum != 3 | |
785 Xpath 'p' | |
786 endif | |
787 let sum = sum + 4 | |
788 endtry | |
789 Xpath 'q' | |
790 catch /ABC/ | |
791 Xpath 'r' | |
792 if sum != 7 | |
793 Xpath 's' | |
794 endif | |
795 let sum = sum + 8 | |
796 finally | |
797 Xpath 't' | |
798 if sum != 15 | |
799 Xpath 'u' | |
800 endif | |
801 let sum = sum + 16 | |
802 endtry | |
803 Xpath 'v' | |
804 if sum != 31 | |
805 Xpath 'w' | |
806 endif | |
807 endfunc | |
808 | |
809 func Test_finally_after_throw() | |
810 XpathINIT | |
811 call T46_F() | |
812 call assert_equal('abcdglortv', g:Xpath) | |
813 endfunc | |
814 | |
815 | |
816 "------------------------------------------------------------------------------- | |
817 " Test 47: Throwing exceptions from a :catch clause {{{1 | |
818 " | |
819 " When an exception is thrown from a :catch clause, it should not be | |
820 " caught by a :catch of the same :try conditional. After executing | |
821 " the :finally clause (if present), surrounding try conditionals | |
822 " should be checked for a matching :catch. | |
823 "------------------------------------------------------------------------------- | |
824 | |
825 func T47_F() | |
826 Xpath 'a' | |
827 try | |
828 Xpath 'b' | |
829 try | |
830 Xpath 'c' | |
831 try | |
832 Xpath 'd' | |
833 throw "x1" | |
834 Xpath 'e' | |
835 catch /x1/ | |
836 Xpath 'f' | |
837 try | |
838 Xpath 'g' | |
839 throw "x2" | |
840 Xpath 'h' | |
841 catch /x1/ | |
842 Xpath 'i' | |
843 catch /x2/ | |
844 Xpath 'j' | |
845 try | |
846 Xpath 'k' | |
847 throw "x3" | |
848 Xpath 'l' | |
849 catch /x1/ | |
850 Xpath 'm' | |
851 catch /x2/ | |
852 Xpath 'n' | |
853 finally | |
854 Xpath 'o' | |
855 endtry | |
856 Xpath 'p' | |
857 catch /x3/ | |
858 Xpath 'q' | |
859 endtry | |
860 Xpath 'r' | |
861 catch /x1/ | |
862 Xpath 's' | |
863 catch /x2/ | |
864 Xpath 't' | |
865 catch /x3/ | |
866 Xpath 'u' | |
867 finally | |
868 Xpath 'v' | |
869 endtry | |
870 Xpath 'w' | |
871 catch /x1/ | |
872 Xpath 'x' | |
873 catch /x2/ | |
874 Xpath 'y' | |
875 catch /x3/ | |
876 Xpath 'z' | |
877 endtry | |
878 Xpath 'A' | |
879 catch /.*/ | |
880 Xpath 'B' | |
881 call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint) | |
882 endtry | |
883 Xpath 'C' | |
884 endfunc | |
885 | |
886 func Test_throw_from_catch() | |
887 XpathINIT | |
888 call T47_F() | |
889 call assert_equal('abcdfgjkovzAC', g:Xpath) | |
890 endfunc | |
891 | |
892 | |
893 "------------------------------------------------------------------------------- | |
894 " Test 48: Throwing exceptions from a :finally clause {{{1 | |
895 " | |
896 " When an exception is thrown from a :finally clause, it should not be | |
897 " caught by a :catch of the same :try conditional. Surrounding try | |
898 " conditionals should be checked for a matching :catch. A previously | |
899 " thrown exception is discarded. | |
900 "------------------------------------------------------------------------------- | |
901 | |
902 func T48_F() | |
903 try | |
904 | |
905 try | |
906 try | |
907 Xpath 'a' | |
908 catch /x1/ | |
909 Xpath 'b' | |
910 finally | |
911 Xpath 'c' | |
912 throw "x1" | |
913 Xpath 'd' | |
914 endtry | |
915 Xpath 'e' | |
916 catch /x1/ | |
917 Xpath 'f' | |
918 endtry | |
919 Xpath 'g' | |
920 | |
921 try | |
922 try | |
923 Xpath 'h' | |
924 throw "x2" | |
925 Xpath 'i' | |
926 catch /x2/ | |
927 Xpath 'j' | |
928 catch /x3/ | |
929 Xpath 'k' | |
930 finally | |
931 Xpath 'l' | |
932 throw "x3" | |
933 Xpath 'm' | |
934 endtry | |
935 Xpath 'n' | |
936 catch /x2/ | |
937 Xpath 'o' | |
938 catch /x3/ | |
939 Xpath 'p' | |
940 endtry | |
941 Xpath 'q' | |
942 | |
943 try | |
944 try | |
945 try | |
946 Xpath 'r' | |
947 throw "x4" | |
948 Xpath 's' | |
949 catch /x5/ | |
950 Xpath 't' | |
951 finally | |
952 Xpath 'u' | |
953 throw "x5" " discards 'x4' | |
954 Xpath 'v' | |
955 endtry | |
956 Xpath 'w' | |
957 catch /x4/ | |
958 Xpath 'x' | |
959 finally | |
960 Xpath 'y' | |
961 endtry | |
962 Xpath 'z' | |
963 catch /x5/ | |
964 Xpath 'A' | |
965 endtry | |
966 Xpath 'B' | |
967 | |
968 catch /.*/ | |
969 Xpath 'C' | |
970 call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint) | |
971 endtry | |
972 Xpath 'D' | |
973 endfunc | |
974 | |
975 func Test_throw_from_finally() | |
976 XpathINIT | |
977 call T48_F() | |
978 call assert_equal('acfghjlpqruyABD', g:Xpath) | |
979 endfunc | |
980 | |
981 | |
982 "------------------------------------------------------------------------------- | |
983 " Test 51: Throwing exceptions across :execute and user commands {{{1 | |
984 " | |
985 " A :throw command may be executed under an ":execute" or from | |
986 " a user command. | |
987 "------------------------------------------------------------------------------- | |
988 | |
989 func T51_F() | |
990 command! -nargs=? THROW1 throw <args> | throw 1 | |
991 command! -nargs=? THROW2 try | throw <args> | endtry | throw 2 | |
992 command! -nargs=? THROW3 try | throw 3 | catch /3/ | throw <args> | endtry | |
993 command! -nargs=? THROW4 try | throw 4 | finally | throw <args> | endtry | |
994 | |
995 try | |
996 | |
997 try | |
998 try | |
999 Xpath 'a' | |
1000 THROW1 "A" | |
1001 catch /A/ | |
1002 Xpath 'b' | |
1003 endtry | |
1004 catch /1/ | |
1005 Xpath 'c' | |
1006 endtry | |
1007 | |
1008 try | |
1009 try | |
1010 Xpath 'd' | |
1011 THROW2 "B" | |
1012 catch /B/ | |
1013 Xpath 'e' | |
1014 endtry | |
1015 catch /2/ | |
1016 Xpath 'f' | |
1017 endtry | |
1018 | |
1019 try | |
1020 try | |
1021 Xpath 'g' | |
1022 THROW3 "C" | |
1023 catch /C/ | |
1024 Xpath 'h' | |
1025 endtry | |
1026 catch /3/ | |
1027 Xpath 'i' | |
1028 endtry | |
1029 | |
1030 try | |
1031 try | |
1032 Xpath 'j' | |
1033 THROW4 "D" | |
1034 catch /D/ | |
1035 Xpath 'k' | |
1036 endtry | |
1037 catch /4/ | |
1038 Xpath 'l' | |
1039 endtry | |
1040 | |
1041 try | |
1042 try | |
1043 Xpath 'm' | |
1044 execute 'throw "E" | throw 5' | |
1045 catch /E/ | |
1046 Xpath 'n' | |
1047 endtry | |
1048 catch /5/ | |
1049 Xpath 'o' | |
1050 endtry | |
1051 | |
1052 try | |
1053 try | |
1054 Xpath 'p' | |
1055 execute 'try | throw "F" | endtry | throw 6' | |
1056 catch /F/ | |
1057 Xpath 'q' | |
1058 endtry | |
1059 catch /6/ | |
1060 Xpath 'r' | |
1061 endtry | |
1062 | |
1063 try | |
1064 try | |
1065 Xpath 's' | |
1066 execute'try | throw 7 | catch /7/ | throw "G" | endtry' | |
1067 catch /G/ | |
1068 Xpath 't' | |
1069 endtry | |
1070 catch /7/ | |
1071 Xpath 'u' | |
1072 endtry | |
1073 | |
1074 try | |
1075 try | |
1076 Xpath 'v' | |
1077 execute 'try | throw 8 | finally | throw "H" | endtry' | |
1078 catch /H/ | |
1079 Xpath 'w' | |
1080 endtry | |
1081 catch /8/ | |
1082 Xpath 'x' | |
1083 endtry | |
1084 | |
1085 catch /.*/ | |
1086 Xpath 'y' | |
1087 call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint) | |
1088 endtry | |
1089 | |
1090 Xpath 'z' | |
1091 | |
1092 delcommand THROW1 | |
1093 delcommand THROW2 | |
1094 delcommand THROW3 | |
1095 delcommand THROW4 | |
1096 endfunc | |
1097 | |
1098 func Test_throw_across_commands() | |
1099 XpathINIT | |
1100 call T51_F() | |
1101 call assert_equal('abdeghjkmnpqstvwz', g:Xpath) | |
1102 endfunc | |
1103 | |
1104 | |
1105 | |
1106 "------------------------------------------------------------------------------- | |
1107 " Test 69: :throw across :if, :elseif, :while {{{1 | |
1108 " | |
1109 " On an :if, :elseif, or :while command, an exception might be thrown | |
1110 " during evaluation of the expression to test. The exception can be | |
1111 " caught by the script. | |
1112 "------------------------------------------------------------------------------- | |
1113 | |
1114 func T69_throw(x) | |
1115 Xpath 'x' | |
1116 throw a:x | |
1117 endfunc | |
1118 | |
1119 func Test_throw_ifelsewhile() | |
1120 XpathINIT | |
1121 | |
1122 try | |
1123 try | |
1124 Xpath 'a' | |
1125 if 111 == T69_throw("if") + 111 | |
1126 Xpath 'b' | |
1127 else | |
1128 Xpath 'c' | |
1129 endif | |
1130 Xpath 'd' | |
1131 catch /^if$/ | |
1132 Xpath 'e' | |
1133 catch /.*/ | |
1134 Xpath 'f' | |
1135 call assert_report("if: " . v:exception . " in " . v:throwpoint) | |
1136 endtry | |
1137 | |
1138 try | |
1139 Xpath 'g' | |
1140 if v:false | |
1141 Xpath 'h' | |
1142 elseif 222 == T69_throw("elseif") + 222 | |
1143 Xpath 'i' | |
1144 else | |
1145 Xpath 'j' | |
1146 endif | |
1147 Xpath 'k' | |
1148 catch /^elseif$/ | |
1149 Xpath 'l' | |
1150 catch /.*/ | |
1151 Xpath 'm' | |
1152 call assert_report("elseif: " . v:exception . " in " . v:throwpoint) | |
1153 endtry | |
1154 | |
1155 try | |
1156 Xpath 'n' | |
1157 while 333 == T69_throw("while") + 333 | |
1158 Xpath 'o' | |
1159 break | |
1160 endwhile | |
1161 Xpath 'p' | |
1162 catch /^while$/ | |
1163 Xpath 'q' | |
1164 catch /.*/ | |
1165 Xpath 'r' | |
1166 call assert_report("while: " .. v:exception .. " in " .. v:throwpoint) | |
1167 endtry | |
1168 catch /^0$/ " default return value | |
1169 Xpath 's' | |
1170 call assert_report(v:throwpoint) | |
1171 catch /.*/ | |
1172 call assert_report(v:exception .. " in " .. v:throwpoint) | |
1173 Xpath 't' | |
1174 endtry | |
1175 | |
1176 call assert_equal('axegxlnxq', g:Xpath) | |
1177 endfunc | |
1178 | |
1179 | |
1180 "------------------------------------------------------------------------------- | |
1181 " Test 70: :throw across :return or :throw {{{1 | |
1182 " | |
1183 " On a :return or :throw command, an exception might be thrown during | |
1184 " evaluation of the expression to return or throw, respectively. The | |
1185 " exception can be caught by the script. | |
1186 "------------------------------------------------------------------------------- | |
1187 | |
1188 let T70_taken = "" | |
1189 | |
1190 func T70_throw(x, n) | |
1191 let g:T70_taken = g:T70_taken . "T" . a:n | |
1192 throw a:x | |
1193 endfunc | |
1194 | |
1195 func T70_F(x, y, n) | |
1196 let g:T70_taken = g:T70_taken . "F" . a:n | |
1197 return a:x + T70_throw(a:y, a:n) | |
1198 endfunc | |
1199 | |
1200 func T70_G(x, y, n) | |
1201 let g:T70_taken = g:T70_taken . "G" . a:n | |
1202 throw a:x . T70_throw(a:y, a:n) | |
1203 return a:x | |
1204 endfunc | |
1205 | |
1206 func Test_throwreturn() | |
1207 XpathINIT | |
1208 | |
1209 try | |
1210 try | |
1211 Xpath 'a' | |
1212 call T70_F(4711, "return", 1) | |
1213 Xpath 'b' | |
1214 catch /^return$/ | |
1215 Xpath 'c' | |
1216 catch /.*/ | |
1217 Xpath 'd' | |
1218 call assert_report("return: " .. v:exception .. " in " .. v:throwpoint) | |
1219 endtry | |
1220 | |
1221 try | |
1222 Xpath 'e' | |
1223 let var = T70_F(4712, "return-var", 2) | |
1224 Xpath 'f' | |
1225 catch /^return-var$/ | |
1226 Xpath 'g' | |
1227 catch /.*/ | |
1228 Xpath 'h' | |
1229 call assert_report("return-var: " . v:exception . " in " . v:throwpoint) | |
1230 finally | |
1231 unlet! var | |
1232 endtry | |
1233 | |
1234 try | |
1235 Xpath 'i' | |
1236 throw "except1" . T70_throw("throw1", 3) | |
1237 Xpath 'j' | |
1238 catch /^except1/ | |
1239 Xpath 'k' | |
1240 catch /^throw1$/ | |
1241 Xpath 'l' | |
1242 catch /.*/ | |
1243 Xpath 'm' | |
1244 call assert_report("throw1: " .. v:exception .. " in " .. v:throwpoint) | |
1245 endtry | |
1246 | |
1247 try | |
1248 Xpath 'n' | |
1249 call T70_G("except2", "throw2", 4) | |
1250 Xpath 'o' | |
1251 catch /^except2/ | |
1252 Xpath 'p' | |
1253 catch /^throw2$/ | |
1254 Xpath 'q' | |
1255 catch /.*/ | |
1256 Xpath 'r' | |
1257 call assert_report("throw2: " .. v:exception .. " in " .. v:throwpoint) | |
1258 endtry | |
1259 | |
1260 try | |
1261 Xpath 's' | |
1262 let var = T70_G("except3", "throw3", 5) | |
1263 Xpath 't' | |
1264 catch /^except3/ | |
1265 Xpath 'u' | |
1266 catch /^throw3$/ | |
1267 Xpath 'v' | |
1268 catch /.*/ | |
1269 Xpath 'w' | |
1270 call assert_report("throw3: " .. v:exception .. " in " .. v:throwpoint) | |
1271 finally | |
1272 unlet! var | |
1273 endtry | |
1274 | |
1275 call assert_equal('F1T1F2T2T3G4T4G5T5', g:T70_taken) | |
1276 Xpath 'x' | |
1277 catch /^0$/ " default return value | |
1278 Xpath 'y' | |
1279 call assert_report(v:throwpoint) | |
1280 catch /.*/ | |
1281 Xpath 'z' | |
1282 call assert_report('Caught' .. v:exception .. ' in ' .. v:throwpoint) | |
1283 endtry | |
1284 | |
1285 call assert_equal('acegilnqsvx', g:Xpath) | |
1286 endfunc | |
1287 | |
1288 "------------------------------------------------------------------------------- | |
1289 " Test 71: :throw across :echo variants and :execute {{{1 | |
1290 " | |
1291 " On an :echo, :echon, :echomsg, :echoerr, or :execute command, an | |
1292 " exception might be thrown during evaluation of the arguments to | |
1293 " be displayed or executed as a command, respectively. Any following | |
1294 " arguments are not evaluated, then. The exception can be caught by | |
1295 " the script. | |
1296 "------------------------------------------------------------------------------- | |
1297 | |
1298 let T71_taken = "" | |
1299 | |
1300 func T71_throw(x, n) | |
1301 let g:T71_taken = g:T71_taken . "T" . a:n | |
1302 throw a:x | |
1303 endfunc | |
1304 | |
1305 func T71_F(n) | |
1306 let g:T71_taken = g:T71_taken . "F" . a:n | |
1307 return "F" . a:n | |
1308 endfunc | |
1309 | |
1310 func Test_throw_echo() | |
1311 XpathINIT | |
1312 | |
1313 try | |
1314 try | |
1315 Xpath 'a' | |
1316 echo 'echo ' . T71_throw("echo-except", 1) . T71_F(1) | |
1317 Xpath 'b' | |
1318 catch /^echo-except$/ | |
1319 Xpath 'c' | |
1320 catch /.*/ | |
1321 Xpath 'd' | |
1322 call assert_report("echo: " .. v:exception .. " in " .. v:throwpoint) | |
1323 endtry | |
1324 | |
1325 try | |
1326 Xpath 'e' | |
1327 echon "echon " . T71_throw("echon-except", 2) . T71_F(2) | |
1328 Xpath 'f' | |
1329 catch /^echon-except$/ | |
1330 Xpath 'g' | |
1331 catch /.*/ | |
1332 Xpath 'h' | |
1333 call assert_report('echon: ' . v:exception . ' in ' . v:throwpoint) | |
1334 endtry | |
1335 | |
1336 try | |
1337 Xpath 'i' | |
1338 echomsg "echomsg " . T71_throw("echomsg-except", 3) . T71_F(3) | |
1339 Xpath 'j' | |
1340 catch /^echomsg-except$/ | |
1341 Xpath 'k' | |
1342 catch /.*/ | |
1343 Xpath 'l' | |
1344 call assert_report('echomsg: ' . v:exception . ' in ' . v:throwpoint) | |
1345 endtry | |
1346 | |
1347 try | |
1348 Xpath 'm' | |
1349 echoerr "echoerr " . T71_throw("echoerr-except", 4) . T71_F(4) | |
1350 Xpath 'n' | |
1351 catch /^echoerr-except$/ | |
1352 Xpath 'o' | |
1353 catch /Vim/ | |
1354 Xpath 'p' | |
1355 catch /echoerr/ | |
1356 Xpath 'q' | |
1357 catch /.*/ | |
1358 Xpath 'r' | |
1359 call assert_report('echoerr: ' . v:exception . ' in ' . v:throwpoint) | |
1360 endtry | |
1361 | |
1362 try | |
1363 Xpath 's' | |
1364 execute "echo 'execute " . T71_throw("execute-except", 5) . T71_F(5) "'" | |
1365 Xpath 't' | |
1366 catch /^execute-except$/ | |
1367 Xpath 'u' | |
1368 catch /.*/ | |
1369 Xpath 'v' | |
1370 call assert_report('execute: ' . v:exception . ' in ' . v:throwpoint) | |
1371 endtry | |
1372 | |
1373 call assert_equal('T1T2T3T4T5', g:T71_taken) | |
1374 Xpath 'w' | |
1375 catch /^0$/ " default return value | |
1376 Xpath 'x' | |
1377 call assert_report(v:throwpoint) | |
1378 catch /.*/ | |
1379 Xpath 'y' | |
1380 call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint) | |
1381 endtry | |
1382 | |
1383 call assert_equal('acegikmosuw', g:Xpath) | |
1384 endfunc | |
1385 | |
1386 | |
1387 "------------------------------------------------------------------------------- | |
1388 " Test 72: :throw across :let or :unlet {{{1 | |
1389 " | |
1390 " On a :let command, an exception might be thrown during evaluation | |
1391 " of the expression to assign. On an :let or :unlet command, the | |
1392 " evaluation of the name of the variable to be assigned or list or | |
1393 " deleted, respectively, may throw an exception. Any following | |
1394 " arguments are not evaluated, then. The exception can be caught by | |
1395 " the script. | |
1396 "------------------------------------------------------------------------------- | |
1397 | |
1398 let throwcount = 0 | |
1399 | |
1400 func T72_throw(x) | |
1401 let g:throwcount = g:throwcount + 1 | |
1402 throw a:x | |
1403 endfunc | |
1404 | |
1405 let T72_addpath = '' | |
1406 | |
1407 func T72_addpath(p) | |
1408 let g:T72_addpath = g:T72_addpath . a:p | |
1409 endfunc | |
1410 | |
1411 func Test_throw_let() | |
1412 XpathINIT | |
1413 | |
1414 try | |
1415 try | |
1416 let $VAR = 'old_value' | |
1417 Xpath 'a' | |
1418 let $VAR = 'let(' . T72_throw('var') . ')' | |
1419 Xpath 'b' | |
1420 catch /^var$/ | |
1421 Xpath 'c' | |
1422 finally | |
1423 call assert_equal('old_value', $VAR) | |
1424 endtry | |
1425 | |
1426 try | |
1427 let @a = 'old_value' | |
1428 Xpath 'd' | |
1429 let @a = 'let(' . T72_throw('reg') . ')' | |
1430 Xpath 'e' | |
1431 catch /^reg$/ | |
1432 try | |
1433 Xpath 'f' | |
1434 let @A = 'let(' . T72_throw('REG') . ')' | |
1435 Xpath 'g' | |
1436 catch /^REG$/ | |
1437 Xpath 'h' | |
1438 endtry | |
1439 finally | |
1440 call assert_equal('old_value', @a) | |
1441 call assert_equal('old_value', @A) | |
1442 endtry | |
1443 | |
1444 try | |
1445 let saved_gpath = &g:path | |
1446 let saved_lpath = &l:path | |
1447 Xpath 'i' | |
1448 let &path = 'let(' . T72_throw('opt') . ')' | |
1449 Xpath 'j' | |
1450 catch /^opt$/ | |
1451 try | |
1452 Xpath 'k' | |
1453 let &g:path = 'let(' . T72_throw('gopt') . ')' | |
1454 Xpath 'l' | |
1455 catch /^gopt$/ | |
1456 try | |
1457 Xpath 'm' | |
1458 let &l:path = 'let(' . T72_throw('lopt') . ')' | |
1459 Xpath 'n' | |
1460 catch /^lopt$/ | |
1461 Xpath 'o' | |
1462 endtry | |
1463 endtry | |
1464 finally | |
1465 call assert_equal(saved_gpath, &g:path) | |
1466 call assert_equal(saved_lpath, &l:path) | |
1467 let &g:path = saved_gpath | |
1468 let &l:path = saved_lpath | |
1469 endtry | |
1470 | |
1471 unlet! var1 var2 var3 | |
1472 | |
1473 try | |
1474 Xpath 'p' | |
1475 let var1 = 'let(' . T72_throw('var1') . ')' | |
1476 Xpath 'q' | |
1477 catch /^var1$/ | |
1478 Xpath 'r' | |
1479 finally | |
1480 call assert_true(!exists('var1')) | |
1481 endtry | |
1482 | |
1483 try | |
1484 let var2 = 'old_value' | |
1485 Xpath 's' | |
1486 let var2 = 'let(' . T72_throw('var2'). ')' | |
1487 Xpath 't' | |
1488 catch /^var2$/ | |
1489 Xpath 'u' | |
1490 finally | |
1491 call assert_equal('old_value', var2) | |
1492 endtry | |
1493 | |
1494 try | |
1495 Xpath 'v' | |
1496 let var{T72_throw('var3')} = 4711 | |
1497 Xpath 'w' | |
1498 catch /^var3$/ | |
1499 Xpath 'x' | |
1500 endtry | |
1501 | |
1502 try | |
1503 call T72_addpath('T1') | |
1504 let var{T72_throw('var4')} var{T72_addpath('T2')} | call T72_addpath('T3') | |
1505 call T72_addpath('T4') | |
1506 catch /^var4$/ | |
1507 call T72_addpath('T5') | |
1508 endtry | |
1509 | |
1510 try | |
1511 call T72_addpath('T6') | |
1512 unlet var{T72_throw('var5')} var{T72_addpath('T7')} | |
1513 \ | call T72_addpath('T8') | |
1514 call T72_addpath('T9') | |
1515 catch /^var5$/ | |
1516 call T72_addpath('T10') | |
1517 endtry | |
1518 | |
1519 call assert_equal('T1T5T6T10', g:T72_addpath) | |
1520 call assert_equal(11, g:throwcount) | |
1521 catch /.*/ | |
1522 call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint) | |
1523 endtry | |
1524 | |
1525 call assert_equal('acdfhikmoprsuvx', g:Xpath) | |
1526 endfunc | |
1527 | |
1528 | |
1529 "------------------------------------------------------------------------------- | |
1530 " Test 73: :throw across :function, :delfunction {{{1 | |
1531 " | |
1532 " The :function and :delfunction commands may cause an expression | |
1533 " specified in braces to be evaluated. During evaluation, an | |
1534 " exception might be thrown. The exception can be caught by the | |
1535 " script. | |
1536 "------------------------------------------------------------------------------- | |
1537 | |
1538 let T73_taken = '' | |
1539 | |
1540 func T73_throw(x, n) | |
1541 let g:T73_taken = g:T73_taken . 'T' . a:n | |
1542 throw a:x | |
1543 endfunc | |
1544 | |
1545 func T73_expr(x, n) | |
1546 let g:T73_taken = g:T73_taken . 'E' . a:n | |
1547 if a:n % 2 == 0 | |
1548 call T73_throw(a:x, a:n) | |
1549 endif | |
1550 return 2 - a:n % 2 | |
1551 endfunc | |
1552 | |
1553 func Test_throw_func() | |
1554 XpathINIT | |
1555 | |
1556 try | |
1557 try | |
1558 " Define function. | |
1559 Xpath 'a' | |
1560 function! F0() | |
1561 endfunction | |
1562 Xpath 'b' | |
1563 function! F{T73_expr('function-def-ok', 1)}() | |
1564 endfunction | |
1565 Xpath 'c' | |
1566 function! F{T73_expr('function-def', 2)}() | |
1567 endfunction | |
1568 Xpath 'd' | |
1569 catch /^function-def-ok$/ | |
1570 Xpath 'e' | |
1571 catch /^function-def$/ | |
1572 Xpath 'f' | |
1573 catch /.*/ | |
1574 call assert_report('def: ' . v:exception . ' in ' . v:throwpoint) | |
1575 endtry | |
1576 | |
1577 try | |
1578 " List function. | |
1579 Xpath 'g' | |
1580 function F0 | |
1581 Xpath 'h' | |
1582 function F{T73_expr('function-lst-ok', 3)} | |
1583 Xpath 'i' | |
1584 function F{T73_expr('function-lst', 4)} | |
1585 Xpath 'j' | |
1586 catch /^function-lst-ok$/ | |
1587 Xpath 'k' | |
1588 catch /^function-lst$/ | |
1589 Xpath 'l' | |
1590 catch /.*/ | |
1591 call assert_report('lst: ' . v:exception . ' in ' . v:throwpoint) | |
1592 endtry | |
1593 | |
1594 try | |
1595 " Delete function | |
1596 Xpath 'm' | |
1597 delfunction F0 | |
1598 Xpath 'n' | |
1599 delfunction F{T73_expr('function-del-ok', 5)} | |
1600 Xpath 'o' | |
1601 delfunction F{T73_expr('function-del', 6)} | |
1602 Xpath 'p' | |
1603 catch /^function-del-ok$/ | |
1604 Xpath 'q' | |
1605 catch /^function-del$/ | |
1606 Xpath 'r' | |
1607 catch /.*/ | |
1608 call assert_report('del: ' . v:exception . ' in ' . v:throwpoint) | |
1609 endtry | |
1610 call assert_equal('E1E2T2E3E4T4E5E6T6', g:T73_taken) | |
1611 catch /.*/ | |
1612 call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint) | |
1613 endtry | |
1614 | |
1615 call assert_equal('abcfghilmnor', g:Xpath) | |
1616 endfunc | |
1617 | |
1618 | |
1619 "------------------------------------------------------------------------------- | |
1620 " Test 74: :throw across builtin functions and commands {{{1 | |
1621 " | |
1622 " Some functions like exists(), searchpair() take expression | |
1623 " arguments, other functions or commands like substitute() or | |
1624 " :substitute cause an expression (specified in the regular | |
1625 " expression) to be evaluated. During evaluation an exception | |
1626 " might be thrown. The exception can be caught by the script. | |
1627 "------------------------------------------------------------------------------- | |
1628 | |
1629 let T74_taken = "" | |
1630 | |
1631 func T74_throw(x, n) | |
1632 let g:T74_taken = g:T74_taken . "T" . a:n | |
1633 throw a:x | |
1634 endfunc | |
1635 | |
1636 func T74_expr(x, n) | |
1637 let g:T74_taken = g:T74_taken . "E" . a:n | |
1638 call T74_throw(a:x . a:n, a:n) | |
1639 return "EXPR" | |
1640 endfunc | |
1641 | |
1642 func T74_skip(x, n) | |
1643 let g:T74_taken = g:T74_taken . "S" . a:n . "(" . line(".") | |
1644 let theline = getline(".") | |
1645 if theline =~ "skip" | |
1646 let g:T74_taken = g:T74_taken . "s)" | |
1647 return 1 | |
1648 elseif theline =~ "throw" | |
1649 let g:T74_taken = g:T74_taken . "t)" | |
1650 call T74_throw(a:x . a:n, a:n) | |
1651 else | |
1652 let g:T74_taken = g:T74_taken . ")" | |
1653 return 0 | |
1654 endif | |
1655 endfunc | |
1656 | |
1657 func T74_subst(x, n) | |
1658 let g:T74_taken = g:T74_taken . "U" . a:n . "(" . line(".") | |
1659 let theline = getline(".") | |
1660 if theline =~ "not" " T74_subst() should not be called for this line | |
1661 let g:T74_taken = g:T74_taken . "n)" | |
1662 call T74_throw(a:x . a:n, a:n) | |
1663 elseif theline =~ "throw" | |
1664 let g:T74_taken = g:T74_taken . "t)" | |
1665 call T74_throw(a:x . a:n, a:n) | |
1666 else | |
1667 let g:T74_taken = g:T74_taken . ")" | |
1668 return "replaced" | |
1669 endif | |
1670 endfunc | |
1671 | |
1672 func Test_throw_builtin_func() | |
1673 XpathINIT | |
1674 | |
1675 try | |
1676 try | |
1677 Xpath 'a' | |
1678 let result = exists('*{T74_expr("exists", 1)}') | |
1679 Xpath 'b' | |
1680 catch /^exists1$/ | |
1681 Xpath 'c' | |
1682 try | |
1683 let result = exists('{T74_expr("exists", 2)}') | |
1684 Xpath 'd' | |
1685 catch /^exists2$/ | |
1686 Xpath 'e' | |
1687 catch /.*/ | |
1688 call assert_report('exists2: ' . v:exception . ' in ' . v:throwpoint) | |
1689 endtry | |
1690 catch /.*/ | |
1691 call assert_report('exists1: ' . v:exception . ' in ' . v:throwpoint) | |
1692 endtry | |
1693 | |
1694 try | |
1695 let file = tempname() | |
1696 exec "edit" file | |
1697 call append(0, [ | |
1698 \ 'begin', | |
1699 \ 'xx', | |
1700 \ 'middle 3', | |
1701 \ 'xx', | |
1702 \ 'middle 5 skip', | |
1703 \ 'xx', | |
1704 \ 'middle 7 throw', | |
1705 \ 'xx', | |
1706 \ 'end']) | |
1707 normal! gg | |
1708 Xpath 'f' | |
1709 let result = searchpair("begin", "middle", "end", '', | |
1710 \ 'T74_skip("searchpair", 3)') | |
1711 Xpath 'g' | |
1712 let result = searchpair("begin", "middle", "end", '', | |
1713 \ 'T74_skip("searchpair", 4)') | |
1714 Xpath 'h' | |
1715 let result = searchpair("begin", "middle", "end", '', | |
1716 \ 'T74_skip("searchpair", 5)') | |
1717 Xpath 'i' | |
1718 catch /^searchpair[35]$/ | |
1719 Xpath 'j' | |
1720 catch /^searchpair4$/ | |
1721 Xpath 'k' | |
1722 catch /.*/ | |
1723 call assert_report('searchpair: ' . v:exception . ' in ' . v:throwpoint) | |
1724 finally | |
1725 bwipeout! | |
1726 call delete(file) | |
1727 endtry | |
1728 | |
1729 try | |
1730 let file = tempname() | |
1731 exec "edit" file | |
1732 call append(0, [ | |
1733 \ 'subst 1', | |
1734 \ 'subst 2', | |
1735 \ 'not', | |
1736 \ 'subst 4', | |
1737 \ 'subst throw', | |
1738 \ 'subst 6']) | |
1739 normal! gg | |
1740 Xpath 'l' | |
1741 1,2substitute/subst/\=T74_subst("substitute", 6)/ | |
1742 try | |
1743 Xpath 'm' | |
1744 try | |
1745 let v:errmsg = "" | |
1746 3substitute/subst/\=T74_subst("substitute", 7)/ | |
1747 finally | |
1748 if v:errmsg != "" | |
1749 " If exceptions are not thrown on errors, fake the error | |
1750 " exception in order to get the same execution path. | |
1751 throw "faked Vim(substitute)" | |
1752 endif | |
1753 endtry | |
1754 catch /Vim(substitute)/ " Pattern not found ('e' flag missing) | |
1755 Xpath 'n' | |
1756 3substitute/subst/\=T74_subst("substitute", 8)/e | |
1757 Xpath 'o' | |
1758 endtry | |
1759 Xpath 'p' | |
1760 4,6substitute/subst/\=T74_subst("substitute", 9)/ | |
1761 Xpath 'q' | |
1762 catch /^substitute[678]/ | |
1763 Xpath 'r' | |
1764 catch /^substitute9/ | |
1765 Xpath 's' | |
1766 finally | |
1767 bwipeout! | |
1768 call delete(file) | |
1769 endtry | |
1770 | |
1771 try | |
1772 Xpath 't' | |
1773 let var = substitute("sub", "sub", '\=T74_throw("substitute()y", 10)', '') | |
1774 Xpath 'u' | |
1775 catch /substitute()y/ | |
1776 Xpath 'v' | |
1777 catch /.*/ | |
1778 call assert_report('substitute()y: ' . v:exception . ' in ' | |
1779 \ . v:throwpoint) | |
1780 endtry | |
1781 | |
1782 try | |
1783 Xpath 'w' | |
1784 let var = substitute("not", "sub", '\=T74_throw("substitute()n", 11)', '') | |
1785 Xpath 'x' | |
1786 catch /substitute()n/ | |
1787 Xpath 'y' | |
1788 catch /.*/ | |
1789 call assert_report('substitute()n: ' . v:exception . ' in ' | |
1790 \ . v:throwpoint) | |
1791 endtry | |
1792 | |
1793 call assert_equal('E1T1E2T2S3(3)S4(5s)S4(7t)T4U6(1)U6(2)U9(4)U9(5t)T9T10', | |
1794 \ g:T74_taken) | |
1795 | |
1796 catch /.*/ | |
1797 call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint) | |
1798 endtry | |
1799 | |
1800 call assert_equal('acefgklmnopstvwx', g:Xpath) | |
1801 endfunc | |
1802 | |
1803 | |
1804 "------------------------------------------------------------------------------- | |
1805 " Test 75: Errors in builtin functions. {{{1 | |
1806 " | |
1807 " On an error in a builtin function called inside a :try/:endtry | |
1808 " region, the evaluation of the expression calling that function and | |
1809 " the command containing that expression are abandoned. The error can | |
1810 " be caught as an exception. | |
1811 " | |
1812 " A simple :call of the builtin function is a trivial case. If the | |
1813 " builtin function is called in the argument list of another function, | |
1814 " no further arguments are evaluated, and the other function is not | |
1815 " executed. If the builtin function is called from the argument of | |
1816 " a :return command, the :return command is not executed. If the | |
1817 " builtin function is called from the argument of a :throw command, | |
1818 " the :throw command is not executed. The evaluation of the | |
1819 " expression calling the builtin function is abandoned. | |
1820 "------------------------------------------------------------------------------- | |
1821 | |
1822 func T75_F1(arg1) | |
1823 Xpath 'a' | |
1824 endfunc | |
1825 | |
1826 func T75_F2(arg1, arg2) | |
1827 Xpath 'b' | |
1828 endfunc | |
1829 | |
1830 func T75_G() | |
1831 Xpath 'c' | |
1832 endfunc | |
1833 | |
1834 func T75_H() | |
1835 Xpath 'd' | |
1836 endfunc | |
1837 | |
1838 func T75_R() | |
1839 while 1 | |
1840 try | |
1841 let caught = 0 | |
1842 let v:errmsg = "" | |
1843 Xpath 'e' | |
1844 return append(1, "s") | |
1845 catch /E21/ | |
1846 let caught = 1 | |
1847 catch /.*/ | |
1848 Xpath 'f' | |
1849 finally | |
1850 Xpath 'g' | |
1851 if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21' | |
1852 Xpath 'h' | |
1853 endif | |
1854 break " discard error for $VIMNOERRTHROW | |
1855 endtry | |
1856 endwhile | |
1857 Xpath 'i' | |
1858 endfunc | |
1859 | |
1860 func Test_builtin_func_error() | |
1861 XpathINIT | |
1862 | |
1863 try | |
1864 set noma " let append() fail with "E21" | |
1865 | |
1866 while 1 | |
1867 try | |
1868 let caught = 0 | |
1869 let v:errmsg = "" | |
1870 Xpath 'j' | |
1871 call append(1, "s") | |
1872 catch /E21/ | |
1873 let caught = 1 | |
1874 catch /.*/ | |
1875 Xpath 'k' | |
1876 finally | |
1877 Xpath 'l' | |
1878 if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21' | |
1879 Xpath 'm' | |
1880 endif | |
1881 break " discard error for $VIMNOERRTHROW | |
1882 endtry | |
1883 endwhile | |
1884 | |
1885 while 1 | |
1886 try | |
1887 let caught = 0 | |
1888 let v:errmsg = "" | |
1889 Xpath 'n' | |
1890 call T75_F1('x' . append(1, "s")) | |
1891 catch /E21/ | |
1892 let caught = 1 | |
1893 catch /.*/ | |
1894 Xpath 'o' | |
1895 finally | |
1896 Xpath 'p' | |
1897 if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21' | |
1898 Xpath 'q' | |
1899 endif | |
1900 break " discard error for $VIMNOERRTHROW | |
1901 endtry | |
1902 endwhile | |
1903 | |
1904 while 1 | |
1905 try | |
1906 let caught = 0 | |
1907 let v:errmsg = "" | |
1908 Xpath 'r' | |
1909 call T75_F2('x' . append(1, "s"), T75_G()) | |
1910 catch /E21/ | |
1911 let caught = 1 | |
1912 catch /.*/ | |
1913 Xpath 's' | |
1914 finally | |
1915 Xpath 't' | |
1916 if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21' | |
1917 Xpath 'u' | |
1918 endif | |
1919 break " discard error for $VIMNOERRTHROW | |
1920 endtry | |
1921 endwhile | |
1922 | |
1923 call T75_R() | |
1924 | |
1925 while 1 | |
1926 try | |
1927 let caught = 0 | |
1928 let v:errmsg = "" | |
1929 Xpath 'v' | |
1930 throw "T" . append(1, "s") | |
1931 catch /E21/ | |
1932 let caught = 1 | |
1933 catch /^T.*/ | |
1934 Xpath 'w' | |
1935 catch /.*/ | |
1936 Xpath 'x' | |
1937 finally | |
1938 Xpath 'y' | |
1939 if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21' | |
1940 Xpath 'z' | |
1941 endif | |
1942 break " discard error for $VIMNOERRTHROW | |
1943 endtry | |
1944 endwhile | |
1945 | |
1946 while 1 | |
1947 try | |
1948 let caught = 0 | |
1949 let v:errmsg = "" | |
1950 Xpath 'A' | |
1951 let x = "a" | |
1952 let x = x . "b" . append(1, "s") . T75_H() | |
1953 catch /E21/ | |
1954 let caught = 1 | |
1955 catch /.*/ | |
1956 Xpath 'B' | |
1957 finally | |
1958 Xpath 'C' | |
1959 if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21' | |
1960 Xpath 'D' | |
1961 endif | |
1962 call assert_equal('a', x) | |
1963 break " discard error for $VIMNOERRTHROW | |
1964 endtry | |
1965 endwhile | |
1966 catch /.*/ | |
1967 call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint) | |
1968 finally | |
1969 set ma& | |
1970 endtry | |
1971 | |
1972 call assert_equal('jlmnpqrtueghivyzACD', g:Xpath) | |
1973 endfunc | |
1974 | |
1975 " Modelines {{{1 | |
1976 " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker | |
1977 "------------------------------------------------------------------------------- |