blob: 4e57f742f6f9d9147dbcd73850d5000e1cea4e84 [file] [log] [blame]
Bram Moolenaard8448622022-01-07 21:39:52 +00001" Test import/export of the Vim9 script language.
2
3source check.vim
4source term_util.vim
5source vim9.vim
6
7let s:export_script_lines =<< trim END
8 vim9script
9 var name: string = 'bob'
10 def Concat(arg: string): string
11 return name .. arg
12 enddef
13 g:result = Concat('bie')
14 g:localname = name
15
16 export const CONST = 1234
17 export var exported = 9876
18 export var exp_name = 'John'
19 export def Exported(): string
20 return 'Exported'
21 enddef
22 export def ExportedValue(): number
23 return exported
24 enddef
25 export def ExportedInc()
26 exported += 5
27 enddef
28 export final theList = [1]
29END
30
31def Undo_export_script_lines()
32 unlet g:result
33 unlet g:localname
34enddef
35
36def Test_vim9_import_export()
37 writefile(s:export_script_lines, 'Xexport.vim')
38 var import_script_lines =<< trim END
39 vim9script
40 var dir = './'
41 var ext = ".vim"
42 import dir .. 'Xexport' .. ext as expo
43
44 g:exported1 = expo.exported
45 expo.exported += 3
46 g:exported2 = expo.exported
47 g:exported3 = expo.ExportedValue()
48
49 expo.ExportedInc()
50 g:exported_i1 = expo.exported
51 g:exported_i2 = expo.ExportedValue()
52
53 expo.exported = 11
54 g:exported_s1 = expo.exported
55 g:exported_s2 = expo.ExportedValue()
56
57 g:imported_func = expo.Exported()
58
59 def GetExported(): string
60 var local_dict = {ref: expo.Exported}
61 return local_dict.ref()
62 enddef
63 g:funcref_result = GetExported()
64
65 g:imported_name = expo.exp_name
66 expo.exp_name ..= ' Doe'
67 g:imported_name_appended = expo.exp_name
68 g:exported_later = expo.exported
69
70 expo.theList->add(2)
71 assert_equal([1, 2], expo.theList)
72 END
73 writefile(import_script_lines, 'Ximport.vim')
74 source Ximport.vim
75
76 assert_equal('bobbie', g:result)
77 assert_equal('bob', g:localname)
78 assert_equal(9876, g:exported1)
79 assert_equal(9879, g:exported2)
80 assert_equal(9879, g:exported3)
81
82 assert_equal(9884, g:exported_i1)
83 assert_equal(9884, g:exported_i2)
84
85 assert_equal(11, g:exported_s1)
86 assert_equal(11, g:exported_s2)
87 assert_equal(11, g:exported_later)
88
89 assert_equal('Exported', g:imported_func)
90 assert_equal('Exported', g:funcref_result)
91 assert_equal('John', g:imported_name)
92 assert_equal('John Doe', g:imported_name_appended)
93 assert_false(exists('g:name'))
94
95 Undo_export_script_lines()
96 unlet g:exported1
97 unlet g:exported2
98 unlet g:exported3
99 unlet g:exported_i1
100 unlet g:exported_i2
101 unlet g:exported_later
102 unlet g:imported_func
103 unlet g:imported_name g:imported_name_appended
104 delete('Ximport.vim')
105
106 # similar, with line breaks
107 var import_line_break_script_lines =<< trim END
108 vim9script
109 import './Xexport.vim'
110 as expo
111 g:exported = expo.exported
112 expo.exported += 7
113 g:exported_added = expo.exported
114 g:imported_func = expo.Exported()
115 END
116 writefile(import_line_break_script_lines, 'Ximport_lbr.vim')
117 source Ximport_lbr.vim
118
119 assert_equal(11, g:exported)
120 assert_equal(18, g:exported_added)
121 assert_equal('Exported', g:imported_func)
122
123 # exported script not sourced again
124 assert_false(exists('g:result'))
125 unlet g:exported
126 unlet g:exported_added
127 unlet g:imported_func
128 delete('Ximport_lbr.vim')
129
130 var line_break_before_dot =<< trim END
131 vim9script
132 import './Xexport.vim' as expo
133 g:exported = expo
134 .exported
135 END
136 writefile(line_break_before_dot, 'Ximport_lbr_before_dot.vim')
137 assert_fails('source Ximport_lbr_before_dot.vim', 'E1060:', '', 3)
138 delete('Ximport_lbr_before_dot.vim')
139
140 var line_break_after_dot =<< trim END
141 vim9script
142 import './Xexport.vim' as expo
143 g:exported = expo.
144 exported
145 END
146 writefile(line_break_after_dot, 'Ximport_lbr_after_dot.vim')
147 assert_fails('source Ximport_lbr_after_dot.vim', 'E1074:', '', 3)
148 delete('Ximport_lbr_after_dot.vim')
149
150 var import_star_as_lines =<< trim END
151 vim9script
152 import './Xexport.vim' as Export
153 def UseExport()
154 g:exported_def = Export.exported
155 enddef
156 g:exported_script = Export.exported
157 assert_equal(1, exists('Export.exported'))
158 assert_equal(0, exists('Export.notexported'))
159 UseExport()
160 END
161 writefile(import_star_as_lines, 'Ximport.vim')
162 source Ximport.vim
163
164 assert_equal(18, g:exported_def)
165 assert_equal(18, g:exported_script)
166 unlet g:exported_def
167 unlet g:exported_script
168
169 var import_star_as_lines_no_dot =<< trim END
170 vim9script
171 import './Xexport.vim' as Export
172 def Func()
173 var dummy = 1
174 var imported = Export + dummy
175 enddef
176 defcompile
177 END
178 writefile(import_star_as_lines_no_dot, 'Ximport.vim')
179 assert_fails('source Ximport.vim', 'E1060:', '', 2, 'Func')
180
181 var import_star_as_lines_dot_space =<< trim END
182 vim9script
183 import './Xexport.vim' as Export
184 def Func()
185 var imported = Export . exported
186 enddef
187 defcompile
188 END
189 writefile(import_star_as_lines_dot_space, 'Ximport.vim')
190 assert_fails('source Ximport.vim', 'E1074:', '', 1, 'Func')
191
Bram Moolenaar7c24dfd2022-01-08 17:03:55 +0000192 writefile(s:export_script_lines, 'Xexport2.vim')
193 var import_as_duplicated =<< trim END
Bram Moolenaard8448622022-01-07 21:39:52 +0000194 vim9script
195 import './Xexport.vim' as expo
Bram Moolenaar7c24dfd2022-01-08 17:03:55 +0000196 import './Xexport2.vim' as expo
Bram Moolenaard8448622022-01-07 21:39:52 +0000197 END
Bram Moolenaar7c24dfd2022-01-08 17:03:55 +0000198 writefile(import_as_duplicated, 'Ximport.vim')
Bram Moolenaard8448622022-01-07 21:39:52 +0000199 assert_fails('source Ximport.vim', 'E1073:', '', 3, 'Ximport.vim')
Bram Moolenaar7c24dfd2022-01-08 17:03:55 +0000200 delete('Xexport2.vim')
Bram Moolenaard8448622022-01-07 21:39:52 +0000201
202 var import_star_as_lines_script_no_dot =<< trim END
203 vim9script
204 import './Xexport.vim' as Export
205 g:imported_script = Export exported
206 END
207 writefile(import_star_as_lines_script_no_dot, 'Ximport.vim')
208 assert_fails('source Ximport.vim', 'E1060: Expected dot after name: Export exported')
209
210 var import_star_as_lines_script_space_after_dot =<< trim END
211 vim9script
212 import './Xexport.vim' as Export
213 g:imported_script = Export. exported
214 END
215 writefile(import_star_as_lines_script_space_after_dot, 'Ximport.vim')
216 assert_fails('source Ximport.vim', 'E1074:')
217
218 var import_star_as_lines_missing_name =<< trim END
219 vim9script
220 import './Xexport.vim' as Export
221 def Func()
222 var imported = Export.
223 enddef
224 defcompile
225 END
226 writefile(import_star_as_lines_missing_name, 'Ximport.vim')
227 assert_fails('source Ximport.vim', 'E1048:', '', 1, 'Func')
228
229 var import_star_as_lbr_lines =<< trim END
230 vim9script
231 import './Xexport.vim'
232 as Export
233 def UseExport()
234 g:exported = Export.exported
235 enddef
236 UseExport()
237 END
238 writefile(import_star_as_lbr_lines, 'Ximport.vim')
239 source Ximport.vim
240 assert_equal(18, g:exported)
241 unlet g:exported
242
243 # try to use something that exists but is not exported
244 var import_not_exported_lines =<< trim END
245 vim9script
246 import './Xexport.vim' as expo
247 echo expo.name
248 END
249 writefile(import_not_exported_lines, 'Ximport.vim')
250 assert_fails('source Ximport.vim', 'E1049:', '', 3, 'Ximport.vim')
251
252 # try to import something that is already defined
253 var import_already_defined =<< trim END
254 vim9script
255 var exported = 'something'
256 import './Xexport.vim' as exported
257 END
258 writefile(import_already_defined, 'Ximport.vim')
259 assert_fails('source Ximport.vim', 'E1054:', '', 3, 'Ximport.vim')
260
261 # try changing an imported const
262 var import_assign_to_const =<< trim END
263 vim9script
264 import './Xexport.vim' as expo
265 def Assign()
266 expo.CONST = 987
267 enddef
268 defcompile
269 END
270 writefile(import_assign_to_const, 'Ximport.vim')
271 assert_fails('source Ximport.vim', 'E46:', '', 1, '_Assign')
272
273 # try changing an imported final
274 var import_assign_to_final =<< trim END
275 vim9script
276 import './Xexport.vim' as expo
277 def Assign()
278 expo.theList = [2]
279 enddef
280 defcompile
281 END
282 writefile(import_assign_to_final, 'Ximport.vim')
283 assert_fails('source Ximport.vim', 'E46:', '', 1, '_Assign')
284
285 var import_no_as_lines =<< trim END
286 vim9script
287 import './Xexport.vim' name
288 END
289 writefile(import_no_as_lines, 'Ximport.vim')
290 assert_fails('source Ximport.vim', 'E488:', '', 2, 'Ximport.vim')
291
292 var import_invalid_string_lines =<< trim END
293 vim9script
294 import Xexport.vim
295 END
296 writefile(import_invalid_string_lines, 'Ximport.vim')
297 assert_fails('source Ximport.vim', 'E121:', '', 2, 'Ximport.vim')
298
299 var import_wrong_name_lines =<< trim END
300 vim9script
301 import './XnoExport.vim'
302 END
303 writefile(import_wrong_name_lines, 'Ximport.vim')
304 assert_fails('source Ximport.vim', 'E1053:', '', 2, 'Ximport.vim')
305
306 var import_redefining_lines =<< trim END
307 vim9script
308 import './Xexport.vim' as exported
309 var exported = 5
310 END
311 writefile(import_redefining_lines, 'Ximport.vim')
312 assert_fails('source Ximport.vim', 'E1213: Redefining imported item "exported"', '', 3)
313
314 var import_assign_wrong_type_lines =<< trim END
315 vim9script
316 import './Xexport.vim' as expo
317 expo.exported = 'xxx'
318 END
319 writefile(import_assign_wrong_type_lines, 'Ximport.vim')
320 assert_fails('source Ximport.vim', 'E1012: Type mismatch; expected number but got string', '', 3)
321
322 var import_assign_const_lines =<< trim END
323 vim9script
324 import './Xexport.vim' as expo
325 expo.CONST = 4321
326 END
327 writefile(import_assign_const_lines, 'Ximport.vim')
328 assert_fails('source Ximport.vim', 'E46: Cannot change read-only variable "CONST"', '', 3)
329
330 delete('Ximport.vim')
331 delete('Ximport3.vim')
332 delete('Xexport.vim')
333
334 # Check that in a Vim9 script 'cpo' is set to the Vim default.
335 # Flags added or removed are also applied to the restored value.
336 set cpo=abcd
337 var lines =<< trim END
338 vim9script
339 g:cpo_in_vim9script = &cpo
340 set cpo+=f
341 set cpo-=c
342 g:cpo_after_vim9script = &cpo
343 END
344 writefile(lines, 'Xvim9_script')
345 source Xvim9_script
346 assert_equal('fabd', &cpo)
347 set cpo&vim
348 assert_equal(&cpo, g:cpo_in_vim9script)
349 var newcpo = substitute(&cpo, 'c', '', '') .. 'f'
350 assert_equal(newcpo, g:cpo_after_vim9script)
351
352 delete('Xvim9_script')
353enddef
354
355def Test_import_funcref()
356 var lines =<< trim END
357 vim9script
358 export def F(): number
359 return 42
360 enddef
361 export const G = F
362 END
363 writefile(lines, 'Xlib.vim')
364
365 lines =<< trim END
366 vim9script
367 import './Xlib.vim' as lib
368 const Foo = lib.G()
369 assert_equal(42, Foo)
370
371 def DoTest()
372 const Goo = lib.G()
373 assert_equal(42, Goo)
374 enddef
375 DoTest()
376 END
377 CheckScriptSuccess(lines)
378
379 delete('Xlib.vim')
380enddef
381
382def Test_import_fails()
383 writefile([], 'Xfoo.vim')
384 var lines =<< trim END
385 import './Xfoo.vim' as foo
386 foo = 'bar'
387 END
388 CheckDefAndScriptFailure(lines, ['E1094:', 'E1236: Cannot use foo itself'])
389 lines =<< trim END
390 vim9script
391 import './Xfoo.vim' as foo
392 var that = foo
393 END
394 CheckScriptFailure(lines, 'E1060: Expected dot after name: foo')
395
396 lines =<< trim END
397 vim9script
398 import './Xfoo.vim' as 9foo
399 END
400 CheckScriptFailure(lines, 'E1047:')
401 lines =<< trim END
402 vim9script
403 import './Xfoo.vim' as the#foo
404 END
405 CheckScriptFailure(lines, 'E1047:')
406 lines =<< trim END
407 vim9script
408 import './Xfoo.vim' as g:foo
409 END
410 CheckScriptFailure(lines, 'E1047:')
411
412 delete('Xfoo.vim')
413
414 lines =<< trim END
415 vim9script
416 def TheFunc()
417 echo 'the func'
418 enddef
419 export var Ref = TheFunc
420 END
421 writefile([], 'Xthat.vim')
Bram Moolenaar7c24dfd2022-01-08 17:03:55 +0000422
Bram Moolenaard8448622022-01-07 21:39:52 +0000423 lines =<< trim END
424 import './Xthat.vim' as That
425 That()
426 END
427 CheckDefAndScriptFailure(lines, ['E1094:', 'E1236: Cannot use That itself'])
Bram Moolenaar7c24dfd2022-01-08 17:03:55 +0000428
429 lines =<< trim END
430 import './Xthat.vim' as one
431 import './Xthat.vim' as two
432 END
433 CheckScriptFailure(lines, 'E1262:')
434
435 delete('Xthat.vim')
Bram Moolenaard8448622022-01-07 21:39:52 +0000436
437 mkdir('Ximport')
438
439 writefile(['vim9script'], 'Ximport/.vim')
440 lines =<< trim END
441 vim9script
442 import './Ximport/.vim'
443 END
444 CheckScriptFailure(lines, 'E1261: Cannot import .vim without using "as"')
445 lines =<< trim END
446 vim9script
447 import './Ximport/.vim' as vim
448 END
449 CheckScriptSuccess(lines)
450
451 writefile(['vim9script'], 'Ximport/.vimrc')
452 lines =<< trim END
453 vim9script
454 import './Ximport/.vimrc'
455 END
456 CheckScriptFailure(lines, 'E1257: Imported script must use "as" or end in .vim')
457 lines =<< trim END
458 vim9script
459 import './Ximport/.vimrc' as vimrc
460 END
461 CheckScriptSuccess(lines)
462
463 delete('Ximport', 'rf')
464enddef
465
466func g:Trigger()
467 source Ximport.vim
468 return "echo 'yes'\<CR>"
469endfunc
470
471def Test_import_export_expr_map()
472 # check that :import and :export work when buffer is locked
473 var export_lines =<< trim END
474 vim9script
475 export def That(): string
476 return 'yes'
477 enddef
478 END
479 writefile(export_lines, 'Xexport_that.vim')
480
481 var import_lines =<< trim END
482 vim9script
483 import './Xexport_that.vim' as that
484 assert_equal('yes', that.That())
485 END
486 writefile(import_lines, 'Ximport.vim')
487
488 nnoremap <expr> trigger g:Trigger()
489 feedkeys('trigger', "xt")
490
491 delete('Xexport_that.vim')
492 delete('Ximport.vim')
493 nunmap trigger
494enddef
495
496def Test_import_in_filetype()
497 # check that :import works when the buffer is locked
498 mkdir('ftplugin', 'p')
499 var export_lines =<< trim END
500 vim9script
501 export var That = 'yes'
502 END
503 writefile(export_lines, 'ftplugin/Xexport_ft.vim')
504
505 var import_lines =<< trim END
506 vim9script
507 import './Xexport_ft.vim' as ft
508 assert_equal('yes', ft.That)
509 g:did_load_mytpe = 1
510 END
511 writefile(import_lines, 'ftplugin/qf.vim')
512
513 var save_rtp = &rtp
514 &rtp = getcwd() .. ',' .. &rtp
515
516 filetype plugin on
517 copen
518 assert_equal(1, g:did_load_mytpe)
519
520 quit!
521 delete('Xexport_ft.vim')
522 delete('ftplugin', 'rf')
523 &rtp = save_rtp
524enddef
525
526def Test_use_import_in_mapping()
527 var lines =<< trim END
528 vim9script
529 export def Funcx()
530 g:result = 42
531 enddef
532 END
533 writefile(lines, 'XsomeExport.vim')
534 lines =<< trim END
535 vim9script
536 import './XsomeExport.vim' as some
537 var Funcy = some.Funcx
538 nnoremap <F3> :call <sid>Funcy()<cr>
539 END
540 writefile(lines, 'Xmapscript.vim')
541
542 source Xmapscript.vim
543 feedkeys("\<F3>", "xt")
544 assert_equal(42, g:result)
545
546 unlet g:result
547 delete('XsomeExport.vim')
548 delete('Xmapscript.vim')
549 nunmap <F3>
550enddef
551
552def Test_export_fails()
553 CheckScriptFailure(['export var some = 123'], 'E1042:')
554 CheckScriptFailure(['vim9script', 'export var g:some'], 'E1022:')
555 CheckScriptFailure(['vim9script', 'export echo 134'], 'E1043:')
556
557 assert_fails('export something', 'E1043:')
558enddef
559
560func Test_import_fails_without_script()
561 CheckRunVimInTerminal
562
563 " call indirectly to avoid compilation error for missing functions
564 call Run_Test_import_fails_on_command_line()
565endfunc
566
567def Run_Test_import_fails_on_command_line()
568 var export =<< trim END
569 vim9script
570 export def Foo(): number
571 return 0
572 enddef
573 END
574 writefile(export, 'XexportCmd.vim')
575
576 var buf = RunVimInTerminal('-c "import Foo from ''./XexportCmd.vim''"', {
577 rows: 6, wait_for_ruler: 0})
578 WaitForAssert(() => assert_match('^E1094:', term_getline(buf, 5)))
579
580 delete('XexportCmd.vim')
581 StopVimInTerminal(buf)
582enddef
583
584def Test_vim9_reload_noclear()
585 var lines =<< trim END
586 vim9script
587 export var exported = 'thexport'
588
589 export def TheFunc(x = 0)
590 enddef
591 END
592 writefile(lines, 'XExportReload')
593 lines =<< trim END
594 vim9script noclear
595 g:loadCount += 1
596 var s:reloaded = 'init'
597 import './XExportReload' as exp
598
599 def Again(): string
600 return 'again'
601 enddef
602
603 exp.TheFunc()
604
605 if exists('s:loaded') | finish | endif
606 var s:loaded = true
607
608 var s:notReloaded = 'yes'
609 s:reloaded = 'first'
610 def g:Values(): list<string>
611 return [s:reloaded, s:notReloaded, Again(), Once(), exp.exported]
612 enddef
613
614 def Once(): string
615 return 'once'
616 enddef
617 END
618 writefile(lines, 'XReloaded')
619 g:loadCount = 0
620 source XReloaded
621 assert_equal(1, g:loadCount)
622 assert_equal(['first', 'yes', 'again', 'once', 'thexport'], g:Values())
623 source XReloaded
624 assert_equal(2, g:loadCount)
625 assert_equal(['init', 'yes', 'again', 'once', 'thexport'], g:Values())
626 source XReloaded
627 assert_equal(3, g:loadCount)
628 assert_equal(['init', 'yes', 'again', 'once', 'thexport'], g:Values())
629
630 delete('XReloaded')
631 delete('XExportReload')
632 delfunc g:Values
633 unlet g:loadCount
634
635 lines =<< trim END
636 vim9script
637 def Inner()
638 enddef
639 END
640 lines->writefile('XreloadScript.vim')
641 source XreloadScript.vim
642
643 lines =<< trim END
644 vim9script
645 def Outer()
646 def Inner()
647 enddef
648 enddef
649 defcompile
650 END
651 lines->writefile('XreloadScript.vim')
652 source XreloadScript.vim
653
654 delete('XreloadScript.vim')
655enddef
656
657def Test_vim9_reload_import()
658 var lines =<< trim END
659 vim9script
660 const var = ''
661 var valone = 1234
662 def MyFunc(arg: string)
663 valone = 5678
664 enddef
665 END
666 var morelines =<< trim END
667 var valtwo = 222
668 export def GetValtwo(): number
669 return valtwo
670 enddef
671 END
672 writefile(lines + morelines, 'Xreload.vim')
673 source Xreload.vim
674 source Xreload.vim
675 source Xreload.vim
676
677 # cannot declare a var twice
678 lines =<< trim END
679 vim9script
680 var valone = 1234
681 var valone = 5678
682 END
683 writefile(lines, 'Xreload.vim')
684 assert_fails('source Xreload.vim', 'E1041:', '', 3, 'Xreload.vim')
685
686 delete('Xreload.vim')
687 delete('Ximport.vim')
688enddef
689
690" if a script is reloaded with a script-local variable that changed its type, a
691" compiled function using that variable must fail.
692def Test_script_reload_change_type()
693 var lines =<< trim END
694 vim9script noclear
695 var str = 'string'
696 def g:GetStr(): string
697 return str .. 'xxx'
698 enddef
699 END
700 writefile(lines, 'Xreload.vim')
701 source Xreload.vim
702 echo g:GetStr()
703
704 lines =<< trim END
705 vim9script noclear
706 var str = 1234
707 END
708 writefile(lines, 'Xreload.vim')
709 source Xreload.vim
710 assert_fails('echo g:GetStr()', 'E1150:')
711
712 delfunc g:GetStr
713 delete('Xreload.vim')
714enddef
715
716" Define CallFunc so that the test can be compiled
717command CallFunc echo 'nop'
718
719def Test_script_reload_from_function()
720 var lines =<< trim END
721 vim9script
722
723 if exists('g:loaded')
724 finish
725 endif
726 g:loaded = 1
727 delcommand CallFunc
728 command CallFunc Func()
729 def Func()
730 so XreloadFunc.vim
731 g:didTheFunc = 1
732 enddef
733 END
734 writefile(lines, 'XreloadFunc.vim')
735 source XreloadFunc.vim
736 CallFunc
737 assert_equal(1, g:didTheFunc)
738
739 delete('XreloadFunc.vim')
740 delcommand CallFunc
741 unlet g:loaded
742 unlet g:didTheFunc
743enddef
744
745def s:RetSome(): string
746 return 'some'
747enddef
748
749" Not exported function that is referenced needs to be accessed by the
750" script-local name.
751def Test_vim9_funcref()
752 var sortlines =<< trim END
753 vim9script
754 def Compare(i1: number, i2: number): number
755 return i2 - i1
756 enddef
757
758 export def FastSort(): list<number>
759 return range(5)->sort(Compare)
760 enddef
761
762 export def GetString(arg: string): string
763 return arg
764 enddef
765 END
766 writefile(sortlines, 'Xsort.vim')
767
768 var lines =<< trim END
769 vim9script
770 import './Xsort.vim'
771 def Test()
772 g:result = Xsort.FastSort()
773 enddef
774 Test()
Bram Moolenaar7c24dfd2022-01-08 17:03:55 +0000775 END
776 writefile(lines, 'Xscript.vim')
777 source Xscript.vim
778 assert_equal([4, 3, 2, 1, 0], g:result)
779 unlet g:result
Bram Moolenaard8448622022-01-07 21:39:52 +0000780
Bram Moolenaar7c24dfd2022-01-08 17:03:55 +0000781 lines =<< trim END
782 vim9script
Bram Moolenaard8448622022-01-07 21:39:52 +0000783 # using a function imported with "as"
784 import './Xsort.vim' as anAlias
785 assert_equal('yes', anAlias.GetString('yes'))
786
787 # using the function from a compiled function
788 def TestMore(): string
789 var s = s:anAlias.GetString('foo')
790 return s .. anAlias.GetString('bar')
791 enddef
792 assert_equal('foobar', TestMore())
793
794 # error when using a function that isn't exported
795 assert_fails('anAlias.Compare(1, 2)', 'E1049:')
796 END
797 writefile(lines, 'Xscript.vim')
798
Bram Moolenaard8448622022-01-07 21:39:52 +0000799 delete('Xsort.vim')
800 delete('Xscript.vim')
801
802 var Funcref = function('s:RetSome')
803 assert_equal('some', Funcref())
804enddef
805
806" Check that when searching for "FilterFunc" it finds the import in the
807" script where FastFilter() is called from, both as a string and as a direct
808" function reference.
809def Test_vim9_funcref_other_script()
810 var filterLines =<< trim END
811 vim9script
812 export def FilterFunc(idx: number, val: number): bool
813 return idx % 2 == 1
814 enddef
815 export def FastFilter(): list<number>
816 return range(10)->filter('FilterFunc(v:key, v:val)')
817 enddef
818 export def FastFilterDirect(): list<number>
819 return range(10)->filter(FilterFunc)
820 enddef
821 END
822 writefile(filterLines, 'Xfilter.vim')
823
824 var lines =<< trim END
825 vim9script
826 import './Xfilter.vim' as filter
827 def Test()
828 var x: list<number> = filter.FastFilter()
829 enddef
830 Test()
831 def TestDirect()
832 var x: list<number> = filter.FastFilterDirect()
833 enddef
834 TestDirect()
835 END
836 CheckScriptSuccess(lines)
837 delete('Xfilter.vim')
838enddef
839
840def Test_import_absolute()
841 var import_lines = [
842 'vim9script',
843 'import "' .. escape(getcwd(), '\') .. '/Xexport_abs.vim" as abs',
844 'def UseExported()',
845 ' g:imported_abs = abs.exported',
846 ' abs.exported = 8888',
847 ' g:imported_after = abs.exported',
848 'enddef',
849 'UseExported()',
850 'g:import_disassembled = execute("disass UseExported")',
851 ]
852 writefile(import_lines, 'Ximport_abs.vim')
853 writefile(s:export_script_lines, 'Xexport_abs.vim')
854
855 source Ximport_abs.vim
856
857 assert_equal(9876, g:imported_abs)
858 assert_equal(8888, g:imported_after)
859 assert_match('<SNR>\d\+_UseExported\_s*' ..
860 'g:imported_abs = abs.exported\_s*' ..
861 '0 LOADSCRIPT exported-2 from .*Xexport_abs.vim\_s*' ..
862 '1 STOREG g:imported_abs\_s*' ..
863 'abs.exported = 8888\_s*' ..
864 '2 PUSHNR 8888\_s*' ..
865 '3 STORESCRIPT exported-2 in .*Xexport_abs.vim\_s*' ..
866 'g:imported_after = abs.exported\_s*' ..
867 '4 LOADSCRIPT exported-2 from .*Xexport_abs.vim\_s*' ..
868 '5 STOREG g:imported_after',
869 g:import_disassembled)
870
871 Undo_export_script_lines()
872 unlet g:imported_abs
873 unlet g:import_disassembled
874
875 delete('Ximport_abs.vim')
876 delete('Xexport_abs.vim')
877enddef
878
879def Test_import_rtp()
880 var import_lines = [
881 'vim9script',
882 'import "Xexport_rtp.vim" as rtp',
883 'g:imported_rtp = rtp.exported',
884 ]
885 writefile(import_lines, 'Ximport_rtp.vim')
886 mkdir('import', 'p')
887 writefile(s:export_script_lines, 'import/Xexport_rtp.vim')
888
889 var save_rtp = &rtp
890 &rtp = getcwd()
891 source Ximport_rtp.vim
892 &rtp = save_rtp
893
894 assert_equal(9876, g:imported_rtp)
895
896 Undo_export_script_lines()
897 unlet g:imported_rtp
898 delete('Ximport_rtp.vim')
899 delete('import', 'rf')
900enddef
901
902def Test_import_compile_error()
903 var export_lines = [
904 'vim9script',
905 'export def ExpFunc(): string',
906 ' return notDefined',
907 'enddef',
908 ]
909 writefile(export_lines, 'Xexported.vim')
910
911 var import_lines = [
912 'vim9script',
913 'import "./Xexported.vim" as expo',
914 'def ImpFunc()',
915 ' echo expo.ExpFunc()',
916 'enddef',
917 'defcompile',
918 ]
919 writefile(import_lines, 'Ximport.vim')
920
921 try
922 source Ximport.vim
923 catch /E1001/
924 # Error should be before the Xexported.vim file.
925 assert_match('E1001: Variable not found: notDefined', v:exception)
926 assert_match('function <SNR>\d\+_ImpFunc\[1\]..<SNR>\d\+_ExpFunc, line 1', v:throwpoint)
927 endtry
928
929 delete('Xexported.vim')
930 delete('Ximport.vim')
931enddef
932
933def Test_func_overrules_import_fails()
934 var export_lines =<< trim END
935 vim9script
936 export def Func()
937 echo 'imported'
938 enddef
939 END
940 writefile(export_lines, 'XexportedFunc.vim')
941
942 var lines =<< trim END
943 vim9script
944 import './XexportedFunc.vim' as Func
945 def Func()
946 echo 'local to function'
947 enddef
948 END
949 CheckScriptFailure(lines, 'E1236:')
950
951 lines =<< trim END
952 vim9script
953 import './XexportedFunc.vim' as Func
954 def Outer()
955 def Func()
956 echo 'local to function'
957 enddef
958 enddef
959 defcompile
960 END
961 CheckScriptFailure(lines, 'E1236:')
962
963 delete('XexportedFunc.vim')
964enddef
965
966def Test_source_vim9_from_legacy()
967 var vim9_lines =<< trim END
968 vim9script
969 var local = 'local'
970 g:global = 'global'
971 export var exported = 'exported'
972 export def GetText(): string
973 return 'text'
974 enddef
975 END
976 writefile(vim9_lines, 'Xvim9_script.vim')
977
978 var legacy_lines =<< trim END
979 source Xvim9_script.vim
980
981 call assert_false(exists('local'))
982 call assert_false(exists('exported'))
983 call assert_false(exists('s:exported'))
984 call assert_equal('global', global)
985 call assert_equal('global', g:global)
986
987 "" imported variable becomes script-local
988 "import exported from './Xvim9_script.vim'
989 "call assert_equal('exported', s:exported)
990 "call assert_false(exists('exported'))
991
992 "" imported function becomes script-local
993 "import GetText from './Xvim9_script.vim'
994 "call assert_equal('text', s:GetText())
995 "call assert_false(exists('*GetText'))
996 END
997 writefile(legacy_lines, 'Xlegacy_script.vim')
998
999 source Xlegacy_script.vim
1000 assert_equal('global', g:global)
1001 unlet g:global
1002
1003 delete('Xlegacy_script.vim')
1004 delete('Xvim9_script.vim')
1005enddef
1006
1007def Test_cmdline_win()
1008 # if the Vim syntax highlighting uses Vim9 constructs they can be used from
1009 # the command line window.
1010 mkdir('rtp/syntax', 'p')
1011 var export_lines =<< trim END
1012 vim9script
1013 export var That = 'yes'
1014 END
1015 writefile(export_lines, 'rtp/syntax/Xexport.vim')
1016 var import_lines =<< trim END
1017 vim9script
1018 import './Xexport.vim' as exp
1019 echo exp.That
1020 END
1021 writefile(import_lines, 'rtp/syntax/vim.vim')
1022 var save_rtp = &rtp
1023 &rtp = getcwd() .. '/rtp' .. ',' .. &rtp
1024 syntax on
1025 augroup CmdWin
1026 autocmd CmdwinEnter * g:got_there = 'yes'
1027 augroup END
1028 # this will open and also close the cmdline window
1029 feedkeys('q:', 'xt')
1030 assert_equal('yes', g:got_there)
1031
1032 augroup CmdWin
1033 au!
1034 augroup END
1035 &rtp = save_rtp
1036 delete('rtp', 'rf')
1037enddef
1038
1039def Test_import_gone_when_sourced_twice()
1040 var exportlines =<< trim END
1041 vim9script
1042 if exists('g:guard')
1043 finish
1044 endif
1045 g:guard = 1
1046 export var name = 'someName'
1047 END
1048 writefile(exportlines, 'XexportScript.vim')
1049
1050 var lines =<< trim END
1051 vim9script
1052 import './XexportScript.vim' as expo
1053 def g:GetName(): string
1054 return expo.name
1055 enddef
1056 END
1057 writefile(lines, 'XscriptImport.vim')
1058 so XscriptImport.vim
1059 assert_equal('someName', g:GetName())
1060
1061 so XexportScript.vim
1062 assert_fails('call g:GetName()', 'E1149:')
1063
1064 delfunc g:GetName
1065 delete('XexportScript.vim')
1066 delete('XscriptImport.vim')
1067 unlet g:guard
1068enddef
1069
1070
1071" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker