To: vim_dev@googlegroups.com Subject: Patch 8.2.4036 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.4036 Problem: Vim9: script test file is getting too long. Solution: Split the import/export functionality to a separate file. Files: src/testdir/test_vim9_script.vim src/testdir/test_vim9_import.vim, src/testdir/Make_all.mak *** ../vim-8.2.4035/src/testdir/test_vim9_script.vim 2022-01-07 18:20:48.374967088 +0000 --- src/testdir/test_vim9_script.vim 2022-01-07 21:33:06.440079483 +0000 *************** *** 2,11 **** source check.vim source term_util.vim - source view_util.vim source vim9.vim - source shared.vim source screendump.vim def Test_vim9script_feature() # example from the help, here the feature is always present --- 2,10 ---- source check.vim source term_util.vim source vim9.vim source screendump.vim + source shared.vim def Test_vim9script_feature() # example from the help, here the feature is always present *************** *** 1142,1693 **** endfunc endif - let s:export_script_lines =<< trim END - vim9script - var name: string = 'bob' - def Concat(arg: string): string - return name .. arg - enddef - g:result = Concat('bie') - g:localname = name - - export const CONST = 1234 - export var exported = 9876 - export var exp_name = 'John' - export def Exported(): string - return 'Exported' - enddef - export def ExportedValue(): number - return exported - enddef - export def ExportedInc() - exported += 5 - enddef - export final theList = [1] - END - - def Undo_export_script_lines() - unlet g:result - unlet g:localname - enddef - - def Test_vim9_import_export() - writefile(s:export_script_lines, 'Xexport.vim') - var import_script_lines =<< trim END - vim9script - var dir = './' - var ext = ".vim" - import dir .. 'Xexport' .. ext as expo - - g:exported1 = expo.exported - expo.exported += 3 - g:exported2 = expo.exported - g:exported3 = expo.ExportedValue() - - expo.ExportedInc() - g:exported_i1 = expo.exported - g:exported_i2 = expo.ExportedValue() - - expo.exported = 11 - g:exported_s1 = expo.exported - g:exported_s2 = expo.ExportedValue() - - g:imported_func = expo.Exported() - - def GetExported(): string - var local_dict = {ref: expo.Exported} - return local_dict.ref() - enddef - g:funcref_result = GetExported() - - g:imported_name = expo.exp_name - expo.exp_name ..= ' Doe' - g:imported_name_appended = expo.exp_name - g:exported_later = expo.exported - - expo.theList->add(2) - assert_equal([1, 2], expo.theList) - END - writefile(import_script_lines, 'Ximport.vim') - source Ximport.vim - - assert_equal('bobbie', g:result) - assert_equal('bob', g:localname) - assert_equal(9876, g:exported1) - assert_equal(9879, g:exported2) - assert_equal(9879, g:exported3) - - assert_equal(9884, g:exported_i1) - assert_equal(9884, g:exported_i2) - - assert_equal(11, g:exported_s1) - assert_equal(11, g:exported_s2) - assert_equal(11, g:exported_later) - - assert_equal('Exported', g:imported_func) - assert_equal('Exported', g:funcref_result) - assert_equal('John', g:imported_name) - assert_equal('John Doe', g:imported_name_appended) - assert_false(exists('g:name')) - - Undo_export_script_lines() - unlet g:exported1 - unlet g:exported2 - unlet g:exported3 - unlet g:exported_i1 - unlet g:exported_i2 - unlet g:exported_later - unlet g:imported_func - unlet g:imported_name g:imported_name_appended - delete('Ximport.vim') - - # similar, with line breaks - var import_line_break_script_lines =<< trim END - vim9script - import './Xexport.vim' - as expo - g:exported = expo.exported - expo.exported += 7 - g:exported_added = expo.exported - g:imported_func = expo.Exported() - END - writefile(import_line_break_script_lines, 'Ximport_lbr.vim') - source Ximport_lbr.vim - - assert_equal(11, g:exported) - assert_equal(18, g:exported_added) - assert_equal('Exported', g:imported_func) - - # exported script not sourced again - assert_false(exists('g:result')) - unlet g:exported - unlet g:exported_added - unlet g:imported_func - delete('Ximport_lbr.vim') - - var line_break_before_dot =<< trim END - vim9script - import './Xexport.vim' as expo - g:exported = expo - .exported - END - writefile(line_break_before_dot, 'Ximport_lbr_before_dot.vim') - assert_fails('source Ximport_lbr_before_dot.vim', 'E1060:', '', 3) - delete('Ximport_lbr_before_dot.vim') - - var line_break_after_dot =<< trim END - vim9script - import './Xexport.vim' as expo - g:exported = expo. - exported - END - writefile(line_break_after_dot, 'Ximport_lbr_after_dot.vim') - assert_fails('source Ximport_lbr_after_dot.vim', 'E1074:', '', 3) - delete('Ximport_lbr_after_dot.vim') - - var import_star_as_lines =<< trim END - vim9script - import './Xexport.vim' as Export - def UseExport() - g:exported_def = Export.exported - enddef - g:exported_script = Export.exported - assert_equal(1, exists('Export.exported')) - assert_equal(0, exists('Export.notexported')) - UseExport() - END - writefile(import_star_as_lines, 'Ximport.vim') - source Ximport.vim - - assert_equal(18, g:exported_def) - assert_equal(18, g:exported_script) - unlet g:exported_def - unlet g:exported_script - - var import_star_as_lines_no_dot =<< trim END - vim9script - import './Xexport.vim' as Export - def Func() - var dummy = 1 - var imported = Export + dummy - enddef - defcompile - END - writefile(import_star_as_lines_no_dot, 'Ximport.vim') - assert_fails('source Ximport.vim', 'E1060:', '', 2, 'Func') - - var import_star_as_lines_dot_space =<< trim END - vim9script - import './Xexport.vim' as Export - def Func() - var imported = Export . exported - enddef - defcompile - END - writefile(import_star_as_lines_dot_space, 'Ximport.vim') - assert_fails('source Ximport.vim', 'E1074:', '', 1, 'Func') - - var import_func_duplicated =<< trim END - vim9script - import './Xexport.vim' as expo - import './Xexport.vim' as expo - - ExportedInc() - END - writefile(import_func_duplicated, 'Ximport.vim') - assert_fails('source Ximport.vim', 'E1073:', '', 3, 'Ximport.vim') - - var import_star_as_duplicated =<< trim END - vim9script - import './Xexport.vim' as Export - var some = 'other' - import './Xexport.vim' as Export - defcompile - END - writefile(import_star_as_duplicated, 'Ximport.vim') - assert_fails('source Ximport.vim', 'E1073:', '', 4, 'Ximport.vim') - - var import_star_as_lines_script_no_dot =<< trim END - vim9script - import './Xexport.vim' as Export - g:imported_script = Export exported - END - writefile(import_star_as_lines_script_no_dot, 'Ximport.vim') - assert_fails('source Ximport.vim', 'E1060: Expected dot after name: Export exported') - - var import_star_as_lines_script_space_after_dot =<< trim END - vim9script - import './Xexport.vim' as Export - g:imported_script = Export. exported - END - writefile(import_star_as_lines_script_space_after_dot, 'Ximport.vim') - assert_fails('source Ximport.vim', 'E1074:') - - var import_star_as_lines_missing_name =<< trim END - vim9script - import './Xexport.vim' as Export - def Func() - var imported = Export. - enddef - defcompile - END - writefile(import_star_as_lines_missing_name, 'Ximport.vim') - assert_fails('source Ximport.vim', 'E1048:', '', 1, 'Func') - - var import_star_as_lbr_lines =<< trim END - vim9script - import './Xexport.vim' - as Export - def UseExport() - g:exported = Export.exported - enddef - UseExport() - END - writefile(import_star_as_lbr_lines, 'Ximport.vim') - source Ximport.vim - assert_equal(18, g:exported) - unlet g:exported - - # try to use something that exists but is not exported - var import_not_exported_lines =<< trim END - vim9script - import './Xexport.vim' as expo - echo expo.name - END - writefile(import_not_exported_lines, 'Ximport.vim') - assert_fails('source Ximport.vim', 'E1049:', '', 3, 'Ximport.vim') - - # try to import something that is already defined - var import_already_defined =<< trim END - vim9script - var exported = 'something' - import './Xexport.vim' as exported - END - writefile(import_already_defined, 'Ximport.vim') - assert_fails('source Ximport.vim', 'E1054:', '', 3, 'Ximport.vim') - - # try changing an imported const - var import_assign_to_const =<< trim END - vim9script - import './Xexport.vim' as expo - def Assign() - expo.CONST = 987 - enddef - defcompile - END - writefile(import_assign_to_const, 'Ximport.vim') - assert_fails('source Ximport.vim', 'E46:', '', 1, '_Assign') - - # try changing an imported final - var import_assign_to_final =<< trim END - vim9script - import './Xexport.vim' as expo - def Assign() - expo.theList = [2] - enddef - defcompile - END - writefile(import_assign_to_final, 'Ximport.vim') - assert_fails('source Ximport.vim', 'E46:', '', 1, '_Assign') - - var import_no_as_lines =<< trim END - vim9script - import './Xexport.vim' name - END - writefile(import_no_as_lines, 'Ximport.vim') - assert_fails('source Ximport.vim', 'E488:', '', 2, 'Ximport.vim') - - var import_invalid_string_lines =<< trim END - vim9script - import Xexport.vim - END - writefile(import_invalid_string_lines, 'Ximport.vim') - assert_fails('source Ximport.vim', 'E121:', '', 2, 'Ximport.vim') - - var import_wrong_name_lines =<< trim END - vim9script - import './XnoExport.vim' - END - writefile(import_wrong_name_lines, 'Ximport.vim') - assert_fails('source Ximport.vim', 'E1053:', '', 2, 'Ximport.vim') - - var import_redefining_lines =<< trim END - vim9script - import './Xexport.vim' as exported - var exported = 5 - END - writefile(import_redefining_lines, 'Ximport.vim') - assert_fails('source Ximport.vim', 'E1213: Redefining imported item "exported"', '', 3) - - var import_assign_wrong_type_lines =<< trim END - vim9script - import './Xexport.vim' as expo - expo.exported = 'xxx' - END - writefile(import_assign_wrong_type_lines, 'Ximport.vim') - assert_fails('source Ximport.vim', 'E1012: Type mismatch; expected number but got string', '', 3) - - var import_assign_const_lines =<< trim END - vim9script - import './Xexport.vim' as expo - expo.CONST = 4321 - END - writefile(import_assign_const_lines, 'Ximport.vim') - assert_fails('source Ximport.vim', 'E46: Cannot change read-only variable "CONST"', '', 3) - - delete('Ximport.vim') - delete('Ximport3.vim') - delete('Xexport.vim') - - # Check that in a Vim9 script 'cpo' is set to the Vim default. - # Flags added or removed are also applied to the restored value. - set cpo=abcd - var lines =<< trim END - vim9script - g:cpo_in_vim9script = &cpo - set cpo+=f - set cpo-=c - g:cpo_after_vim9script = &cpo - END - writefile(lines, 'Xvim9_script') - source Xvim9_script - assert_equal('fabd', &cpo) - set cpo&vim - assert_equal(&cpo, g:cpo_in_vim9script) - var newcpo = substitute(&cpo, 'c', '', '') .. 'f' - assert_equal(newcpo, g:cpo_after_vim9script) - - delete('Xvim9_script') - enddef - - def Test_import_funcref() - var lines =<< trim END - vim9script - export def F(): number - return 42 - enddef - export const G = F - END - writefile(lines, 'Xlib.vim') - - lines =<< trim END - vim9script - import './Xlib.vim' as lib - const Foo = lib.G() - assert_equal(42, Foo) - - def DoTest() - const Goo = lib.G() - assert_equal(42, Goo) - enddef - DoTest() - END - CheckScriptSuccess(lines) - - delete('Xlib.vim') - enddef - - def Test_import_fails() - writefile([], 'Xfoo.vim') - var lines =<< trim END - import './Xfoo.vim' as foo - foo = 'bar' - END - CheckDefAndScriptFailure(lines, ['E1094:', 'E1236: Cannot use foo itself']) - lines =<< trim END - vim9script - import './Xfoo.vim' as foo - var that = foo - END - CheckScriptFailure(lines, 'E1060: Expected dot after name: foo') - - lines =<< trim END - vim9script - import './Xfoo.vim' as 9foo - END - CheckScriptFailure(lines, 'E1047:') - lines =<< trim END - vim9script - import './Xfoo.vim' as the#foo - END - CheckScriptFailure(lines, 'E1047:') - lines =<< trim END - vim9script - import './Xfoo.vim' as g:foo - END - CheckScriptFailure(lines, 'E1047:') - - delete('Xfoo.vim') - - lines =<< trim END - vim9script - def TheFunc() - echo 'the func' - enddef - export var Ref = TheFunc - END - writefile([], 'Xthat.vim') - lines =<< trim END - import './Xthat.vim' as That - That() - END - CheckDefAndScriptFailure(lines, ['E1094:', 'E1236: Cannot use That itself']) - - mkdir('Ximport') - - writefile(['vim9script'], 'Ximport/.vim') - lines =<< trim END - vim9script - import './Ximport/.vim' - END - CheckScriptFailure(lines, 'E1261: Cannot import .vim without using "as"') - lines =<< trim END - vim9script - import './Ximport/.vim' as vim - END - CheckScriptSuccess(lines) - - writefile(['vim9script'], 'Ximport/.vimrc') - lines =<< trim END - vim9script - import './Ximport/.vimrc' - END - CheckScriptFailure(lines, 'E1257: Imported script must use "as" or end in .vim') - lines =<< trim END - vim9script - import './Ximport/.vimrc' as vimrc - END - CheckScriptSuccess(lines) - - delete('Ximport', 'rf') - enddef - - func g:Trigger() - source Ximport.vim - return "echo 'yes'\" - endfunc - - def Test_import_export_expr_map() - # check that :import and :export work when buffer is locked - var export_lines =<< trim END - vim9script - export def That(): string - return 'yes' - enddef - END - writefile(export_lines, 'Xexport_that.vim') - - var import_lines =<< trim END - vim9script - import './Xexport_that.vim' as that - assert_equal('yes', that.That()) - END - writefile(import_lines, 'Ximport.vim') - - nnoremap trigger g:Trigger() - feedkeys('trigger', "xt") - - delete('Xexport_that.vim') - delete('Ximport.vim') - nunmap trigger - enddef - - def Test_import_in_filetype() - # check that :import works when the buffer is locked - mkdir('ftplugin', 'p') - var export_lines =<< trim END - vim9script - export var That = 'yes' - END - writefile(export_lines, 'ftplugin/Xexport_ft.vim') - - var import_lines =<< trim END - vim9script - import './Xexport_ft.vim' as ft - assert_equal('yes', ft.That) - g:did_load_mytpe = 1 - END - writefile(import_lines, 'ftplugin/qf.vim') - - var save_rtp = &rtp - &rtp = getcwd() .. ',' .. &rtp - - filetype plugin on - copen - assert_equal(1, g:did_load_mytpe) - - quit! - delete('Xexport_ft.vim') - delete('ftplugin', 'rf') - &rtp = save_rtp - enddef - - def Test_use_import_in_mapping() - var lines =<< trim END - vim9script - export def Funcx() - g:result = 42 - enddef - END - writefile(lines, 'XsomeExport.vim') - lines =<< trim END - vim9script - import './XsomeExport.vim' as some - var Funcy = some.Funcx - nnoremap :call Funcy() - END - writefile(lines, 'Xmapscript.vim') - - source Xmapscript.vim - feedkeys("\", "xt") - assert_equal(42, g:result) - - unlet g:result - delete('XsomeExport.vim') - delete('Xmapscript.vim') - nunmap - enddef - def Test_vim9script_mix() var lines =<< trim END if has(g:feature) --- 1141,1146 ---- *************** *** 1712,1911 **** def Test_vim9script_fails() CheckScriptFailure(['scriptversion 2', 'vim9script'], 'E1039:') CheckScriptFailure(['vim9script', 'scriptversion 2'], 'E1040:') - CheckScriptFailure(['export var some = 123'], 'E1042:') - CheckScriptFailure(['vim9script', 'export var g:some'], 'E1022:') - CheckScriptFailure(['vim9script', 'export echo 134'], 'E1043:') CheckScriptFailure(['vim9script', 'var str: string', 'str = 1234'], 'E1012:') CheckScriptFailure(['vim9script', 'const str = "asdf"', 'str = "xxx"'], 'E46:') assert_fails('vim9script', 'E1038:') - assert_fails('export something', 'E1043:') - enddef - - func Test_import_fails_without_script() - CheckRunVimInTerminal - - " call indirectly to avoid compilation error for missing functions - call Run_Test_import_fails_on_command_line() - endfunc - - def Run_Test_import_fails_on_command_line() - var export =<< trim END - vim9script - export def Foo(): number - return 0 - enddef - END - writefile(export, 'XexportCmd.vim') - - var buf = RunVimInTerminal('-c "import Foo from ''./XexportCmd.vim''"', { - rows: 6, wait_for_ruler: 0}) - WaitForAssert(() => assert_match('^E1094:', term_getline(buf, 5))) - - delete('XexportCmd.vim') - StopVimInTerminal(buf) - enddef - - def Test_vim9script_reload_noclear() - var lines =<< trim END - vim9script - export var exported = 'thexport' - - export def TheFunc(x = 0) - enddef - END - writefile(lines, 'XExportReload') - lines =<< trim END - vim9script noclear - g:loadCount += 1 - var s:reloaded = 'init' - import './XExportReload' as exp - - def Again(): string - return 'again' - enddef - - exp.TheFunc() - - if exists('s:loaded') | finish | endif - var s:loaded = true - - var s:notReloaded = 'yes' - s:reloaded = 'first' - def g:Values(): list - return [s:reloaded, s:notReloaded, Again(), Once(), exp.exported] - enddef - - def Once(): string - return 'once' - enddef - END - writefile(lines, 'XReloaded') - g:loadCount = 0 - source XReloaded - assert_equal(1, g:loadCount) - assert_equal(['first', 'yes', 'again', 'once', 'thexport'], g:Values()) - source XReloaded - assert_equal(2, g:loadCount) - assert_equal(['init', 'yes', 'again', 'once', 'thexport'], g:Values()) - source XReloaded - assert_equal(3, g:loadCount) - assert_equal(['init', 'yes', 'again', 'once', 'thexport'], g:Values()) - - delete('XReloaded') - delete('XExportReload') - delfunc g:Values - unlet g:loadCount - - lines =<< trim END - vim9script - def Inner() - enddef - END - lines->writefile('XreloadScript.vim') - source XreloadScript.vim - - lines =<< trim END - vim9script - def Outer() - def Inner() - enddef - enddef - defcompile - END - lines->writefile('XreloadScript.vim') - source XreloadScript.vim - - delete('XreloadScript.vim') - enddef - - def Test_vim9script_reload_import() - var lines =<< trim END - vim9script - const var = '' - var valone = 1234 - def MyFunc(arg: string) - valone = 5678 - enddef - END - var morelines =<< trim END - var valtwo = 222 - export def GetValtwo(): number - return valtwo - enddef - END - writefile(lines + morelines, 'Xreload.vim') - source Xreload.vim - source Xreload.vim - source Xreload.vim - - # cannot declare a var twice - lines =<< trim END - vim9script - var valone = 1234 - var valone = 5678 - END - writefile(lines, 'Xreload.vim') - assert_fails('source Xreload.vim', 'E1041:', '', 3, 'Xreload.vim') - - delete('Xreload.vim') - delete('Ximport.vim') - enddef - - " if a script is reloaded with a script-local variable that changed its type, a - " compiled function using that variable must fail. - def Test_script_reload_change_type() - var lines =<< trim END - vim9script noclear - var str = 'string' - def g:GetStr(): string - return str .. 'xxx' - enddef - END - writefile(lines, 'Xreload.vim') - source Xreload.vim - echo g:GetStr() - - lines =<< trim END - vim9script noclear - var str = 1234 - END - writefile(lines, 'Xreload.vim') - source Xreload.vim - assert_fails('echo g:GetStr()', 'E1150:') - - delfunc g:GetStr - delete('Xreload.vim') - enddef - - " Define CallFunc so that the test can be compiled - command CallFunc echo 'nop' - - def Test_script_reload_from_function() - var lines =<< trim END - vim9script - - if exists('g:loaded') - finish - endif - g:loaded = 1 - delcommand CallFunc - command CallFunc Func() - def Func() - so XreloadFunc.vim - g:didTheFunc = 1 - enddef - END - writefile(lines, 'XreloadFunc.vim') - source XreloadFunc.vim - CallFunc - assert_equal(1, g:didTheFunc) - - delete('XreloadFunc.vim') - delcommand CallFunc - unlet g:loaded - unlet g:didTheFunc enddef def Test_script_var_shadows_function() --- 1165,1175 ---- *************** *** 1954,2051 **** CheckScriptFailure(lines, 'E1085:') enddef - def s:RetSome(): string - return 'some' - enddef - - " Not exported function that is referenced needs to be accessed by the - " script-local name. - def Test_vim9script_funcref() - var sortlines =<< trim END - vim9script - def Compare(i1: number, i2: number): number - return i2 - i1 - enddef - - export def FastSort(): list - return range(5)->sort(Compare) - enddef - - export def GetString(arg: string): string - return arg - enddef - END - writefile(sortlines, 'Xsort.vim') - - var lines =<< trim END - vim9script - import './Xsort.vim' - def Test() - g:result = Xsort.FastSort() - enddef - Test() - - # using a function imported with "as" - import './Xsort.vim' as anAlias - assert_equal('yes', anAlias.GetString('yes')) - - # using the function from a compiled function - def TestMore(): string - var s = s:anAlias.GetString('foo') - return s .. anAlias.GetString('bar') - enddef - assert_equal('foobar', TestMore()) - - # error when using a function that isn't exported - assert_fails('anAlias.Compare(1, 2)', 'E1049:') - END - writefile(lines, 'Xscript.vim') - - source Xscript.vim - assert_equal([4, 3, 2, 1, 0], g:result) - - unlet g:result - delete('Xsort.vim') - delete('Xscript.vim') - - var Funcref = function('s:RetSome') - assert_equal('some', Funcref()) - enddef - - " Check that when searching for "FilterFunc" it finds the import in the - " script where FastFilter() is called from, both as a string and as a direct - " function reference. - def Test_vim9script_funcref_other_script() - var filterLines =<< trim END - vim9script - export def FilterFunc(idx: number, val: number): bool - return idx % 2 == 1 - enddef - export def FastFilter(): list - return range(10)->filter('FilterFunc(v:key, v:val)') - enddef - export def FastFilterDirect(): list - return range(10)->filter(FilterFunc) - enddef - END - writefile(filterLines, 'Xfilter.vim') - - var lines =<< trim END - vim9script - import './Xfilter.vim' as filter - def Test() - var x: list = filter.FastFilter() - enddef - Test() - def TestDirect() - var x: list = filter.FastFilterDirect() - enddef - TestDirect() - END - CheckScriptSuccess(lines) - delete('Xfilter.vim') - enddef - def Test_vim9script_reload_delfunc() var first_lines =<< trim END vim9script --- 1218,1223 ---- *************** *** 2109,2207 **** delete('XreloadVar.vim') enddef - def Test_import_absolute() - var import_lines = [ - 'vim9script', - 'import "' .. escape(getcwd(), '\') .. '/Xexport_abs.vim" as abs', - 'def UseExported()', - ' g:imported_abs = abs.exported', - ' abs.exported = 8888', - ' g:imported_after = abs.exported', - 'enddef', - 'UseExported()', - 'g:import_disassembled = execute("disass UseExported")', - ] - writefile(import_lines, 'Ximport_abs.vim') - writefile(s:export_script_lines, 'Xexport_abs.vim') - - source Ximport_abs.vim - - assert_equal(9876, g:imported_abs) - assert_equal(8888, g:imported_after) - assert_match('\d\+_UseExported\_s*' .. - 'g:imported_abs = abs.exported\_s*' .. - '0 LOADSCRIPT exported-2 from .*Xexport_abs.vim\_s*' .. - '1 STOREG g:imported_abs\_s*' .. - 'abs.exported = 8888\_s*' .. - '2 PUSHNR 8888\_s*' .. - '3 STORESCRIPT exported-2 in .*Xexport_abs.vim\_s*' .. - 'g:imported_after = abs.exported\_s*' .. - '4 LOADSCRIPT exported-2 from .*Xexport_abs.vim\_s*' .. - '5 STOREG g:imported_after', - g:import_disassembled) - - Undo_export_script_lines() - unlet g:imported_abs - unlet g:import_disassembled - - delete('Ximport_abs.vim') - delete('Xexport_abs.vim') - enddef - - def Test_import_rtp() - var import_lines = [ - 'vim9script', - 'import "Xexport_rtp.vim" as rtp', - 'g:imported_rtp = rtp.exported', - ] - writefile(import_lines, 'Ximport_rtp.vim') - mkdir('import', 'p') - writefile(s:export_script_lines, 'import/Xexport_rtp.vim') - - var save_rtp = &rtp - &rtp = getcwd() - source Ximport_rtp.vim - &rtp = save_rtp - - assert_equal(9876, g:imported_rtp) - - Undo_export_script_lines() - unlet g:imported_rtp - delete('Ximport_rtp.vim') - delete('import', 'rf') - enddef - - def Test_import_compile_error() - var export_lines = [ - 'vim9script', - 'export def ExpFunc(): string', - ' return notDefined', - 'enddef', - ] - writefile(export_lines, 'Xexported.vim') - - var import_lines = [ - 'vim9script', - 'import "./Xexported.vim" as expo', - 'def ImpFunc()', - ' echo expo.ExpFunc()', - 'enddef', - 'defcompile', - ] - writefile(import_lines, 'Ximport.vim') - - try - source Ximport.vim - catch /E1001/ - # Error should be before the Xexported.vim file. - assert_match('E1001: Variable not found: notDefined', v:exception) - assert_match('function \d\+_ImpFunc\[1\]..\d\+_ExpFunc, line 1', v:throwpoint) - endtry - - delete('Xexported.vim') - delete('Ximport.vim') - enddef - def Test_func_redefine_error() var lines = [ 'vim9script', --- 1281,1286 ---- *************** *** 2225,2263 **** delete('Xtestscript.vim') enddef - def Test_func_overrules_import_fails() - var export_lines =<< trim END - vim9script - export def Func() - echo 'imported' - enddef - END - writefile(export_lines, 'XexportedFunc.vim') - - var lines =<< trim END - vim9script - import './XexportedFunc.vim' as Func - def Func() - echo 'local to function' - enddef - END - CheckScriptFailure(lines, 'E1236:') - - lines =<< trim END - vim9script - import './XexportedFunc.vim' as Func - def Outer() - def Func() - echo 'local to function' - enddef - enddef - defcompile - END - CheckScriptFailure(lines, 'E1236:') - - delete('XexportedFunc.vim') - enddef - def Test_func_redefine_fails() var lines =<< trim END vim9script --- 1304,1309 ---- *************** *** 3877,3923 **** delete('Xforward') enddef - def Test_source_vim9_from_legacy() - var vim9_lines =<< trim END - vim9script - var local = 'local' - g:global = 'global' - export var exported = 'exported' - export def GetText(): string - return 'text' - enddef - END - writefile(vim9_lines, 'Xvim9_script.vim') - - var legacy_lines =<< trim END - source Xvim9_script.vim - - call assert_false(exists('local')) - call assert_false(exists('exported')) - call assert_false(exists('s:exported')) - call assert_equal('global', global) - call assert_equal('global', g:global) - - "" imported variable becomes script-local - "import exported from './Xvim9_script.vim' - "call assert_equal('exported', s:exported) - "call assert_false(exists('exported')) - - "" imported function becomes script-local - "import GetText from './Xvim9_script.vim' - "call assert_equal('text', s:GetText()) - "call assert_false(exists('*GetText')) - END - writefile(legacy_lines, 'Xlegacy_script.vim') - - source Xlegacy_script.vim - assert_equal('global', g:global) - unlet g:global - - delete('Xlegacy_script.vim') - delete('Xvim9_script.vim') - enddef - def Test_declare_script_in_func() var lines =<< trim END vim9script --- 2923,2928 ---- *************** *** 4194,4231 **** delete(dir, 'rf') enddef - def Test_cmdline_win() - # if the Vim syntax highlighting uses Vim9 constructs they can be used from - # the command line window. - mkdir('rtp/syntax', 'p') - var export_lines =<< trim END - vim9script - export var That = 'yes' - END - writefile(export_lines, 'rtp/syntax/Xexport.vim') - var import_lines =<< trim END - vim9script - import './Xexport.vim' as exp - echo exp.That - END - writefile(import_lines, 'rtp/syntax/vim.vim') - var save_rtp = &rtp - &rtp = getcwd() .. '/rtp' .. ',' .. &rtp - syntax on - augroup CmdWin - autocmd CmdwinEnter * g:got_there = 'yes' - augroup END - # this will open and also close the cmdline window - feedkeys('q:', 'xt') - assert_equal('yes', g:got_there) - - augroup CmdWin - au! - augroup END - &rtp = save_rtp - delete('rtp', 'rf') - enddef - def Test_invalid_sid() assert_fails('func 1234_func', 'E123:') --- 3199,3204 ---- *************** *** 4552,4588 **** unlet g:guard enddef - "def Test_import_gone_when_sourced_twice() - " var exportlines =<< trim END - " vim9script - " if exists('g:guard') - " finish - " endif - " g:guard = 1 - " export var name = 'someName' - " END - " writefile(exportlines, 'XexportScript.vim') - " - " var lines =<< trim END - " vim9script - " import name from './XexportScript.vim' - " def g:GetName(): string - " return name - " enddef - " END - " writefile(lines, 'XscriptImport.vim') - " so XscriptImport.vim - " assert_equal('someName', g:GetName()) - " - " so XexportScript.vim - " assert_fails('call g:GetName()', 'E1149:') - " - " delfunc g:GetName - " delete('XexportScript.vim') - " delete('XscriptImport.vim') - " unlet g:guard - "enddef - def Test_unsupported_commands() var lines =<< trim END ka --- 3525,3530 ---- *** ../vim-8.2.4035/src/testdir/test_vim9_import.vim 2022-01-07 21:38:24.203472398 +0000 --- src/testdir/test_vim9_import.vim 2022-01-07 21:38:01.615515852 +0000 *************** *** 0 **** --- 1,1069 ---- + " Test import/export of the Vim9 script language. + + source check.vim + source term_util.vim + source vim9.vim + + let s:export_script_lines =<< trim END + vim9script + var name: string = 'bob' + def Concat(arg: string): string + return name .. arg + enddef + g:result = Concat('bie') + g:localname = name + + export const CONST = 1234 + export var exported = 9876 + export var exp_name = 'John' + export def Exported(): string + return 'Exported' + enddef + export def ExportedValue(): number + return exported + enddef + export def ExportedInc() + exported += 5 + enddef + export final theList = [1] + END + + def Undo_export_script_lines() + unlet g:result + unlet g:localname + enddef + + def Test_vim9_import_export() + writefile(s:export_script_lines, 'Xexport.vim') + var import_script_lines =<< trim END + vim9script + var dir = './' + var ext = ".vim" + import dir .. 'Xexport' .. ext as expo + + g:exported1 = expo.exported + expo.exported += 3 + g:exported2 = expo.exported + g:exported3 = expo.ExportedValue() + + expo.ExportedInc() + g:exported_i1 = expo.exported + g:exported_i2 = expo.ExportedValue() + + expo.exported = 11 + g:exported_s1 = expo.exported + g:exported_s2 = expo.ExportedValue() + + g:imported_func = expo.Exported() + + def GetExported(): string + var local_dict = {ref: expo.Exported} + return local_dict.ref() + enddef + g:funcref_result = GetExported() + + g:imported_name = expo.exp_name + expo.exp_name ..= ' Doe' + g:imported_name_appended = expo.exp_name + g:exported_later = expo.exported + + expo.theList->add(2) + assert_equal([1, 2], expo.theList) + END + writefile(import_script_lines, 'Ximport.vim') + source Ximport.vim + + assert_equal('bobbie', g:result) + assert_equal('bob', g:localname) + assert_equal(9876, g:exported1) + assert_equal(9879, g:exported2) + assert_equal(9879, g:exported3) + + assert_equal(9884, g:exported_i1) + assert_equal(9884, g:exported_i2) + + assert_equal(11, g:exported_s1) + assert_equal(11, g:exported_s2) + assert_equal(11, g:exported_later) + + assert_equal('Exported', g:imported_func) + assert_equal('Exported', g:funcref_result) + assert_equal('John', g:imported_name) + assert_equal('John Doe', g:imported_name_appended) + assert_false(exists('g:name')) + + Undo_export_script_lines() + unlet g:exported1 + unlet g:exported2 + unlet g:exported3 + unlet g:exported_i1 + unlet g:exported_i2 + unlet g:exported_later + unlet g:imported_func + unlet g:imported_name g:imported_name_appended + delete('Ximport.vim') + + # similar, with line breaks + var import_line_break_script_lines =<< trim END + vim9script + import './Xexport.vim' + as expo + g:exported = expo.exported + expo.exported += 7 + g:exported_added = expo.exported + g:imported_func = expo.Exported() + END + writefile(import_line_break_script_lines, 'Ximport_lbr.vim') + source Ximport_lbr.vim + + assert_equal(11, g:exported) + assert_equal(18, g:exported_added) + assert_equal('Exported', g:imported_func) + + # exported script not sourced again + assert_false(exists('g:result')) + unlet g:exported + unlet g:exported_added + unlet g:imported_func + delete('Ximport_lbr.vim') + + var line_break_before_dot =<< trim END + vim9script + import './Xexport.vim' as expo + g:exported = expo + .exported + END + writefile(line_break_before_dot, 'Ximport_lbr_before_dot.vim') + assert_fails('source Ximport_lbr_before_dot.vim', 'E1060:', '', 3) + delete('Ximport_lbr_before_dot.vim') + + var line_break_after_dot =<< trim END + vim9script + import './Xexport.vim' as expo + g:exported = expo. + exported + END + writefile(line_break_after_dot, 'Ximport_lbr_after_dot.vim') + assert_fails('source Ximport_lbr_after_dot.vim', 'E1074:', '', 3) + delete('Ximport_lbr_after_dot.vim') + + var import_star_as_lines =<< trim END + vim9script + import './Xexport.vim' as Export + def UseExport() + g:exported_def = Export.exported + enddef + g:exported_script = Export.exported + assert_equal(1, exists('Export.exported')) + assert_equal(0, exists('Export.notexported')) + UseExport() + END + writefile(import_star_as_lines, 'Ximport.vim') + source Ximport.vim + + assert_equal(18, g:exported_def) + assert_equal(18, g:exported_script) + unlet g:exported_def + unlet g:exported_script + + var import_star_as_lines_no_dot =<< trim END + vim9script + import './Xexport.vim' as Export + def Func() + var dummy = 1 + var imported = Export + dummy + enddef + defcompile + END + writefile(import_star_as_lines_no_dot, 'Ximport.vim') + assert_fails('source Ximport.vim', 'E1060:', '', 2, 'Func') + + var import_star_as_lines_dot_space =<< trim END + vim9script + import './Xexport.vim' as Export + def Func() + var imported = Export . exported + enddef + defcompile + END + writefile(import_star_as_lines_dot_space, 'Ximport.vim') + assert_fails('source Ximport.vim', 'E1074:', '', 1, 'Func') + + var import_func_duplicated =<< trim END + vim9script + import './Xexport.vim' as expo + import './Xexport.vim' as expo + + ExportedInc() + END + writefile(import_func_duplicated, 'Ximport.vim') + assert_fails('source Ximport.vim', 'E1073:', '', 3, 'Ximport.vim') + + var import_star_as_duplicated =<< trim END + vim9script + import './Xexport.vim' as Export + var some = 'other' + import './Xexport.vim' as Export + defcompile + END + writefile(import_star_as_duplicated, 'Ximport.vim') + assert_fails('source Ximport.vim', 'E1073:', '', 4, 'Ximport.vim') + + var import_star_as_lines_script_no_dot =<< trim END + vim9script + import './Xexport.vim' as Export + g:imported_script = Export exported + END + writefile(import_star_as_lines_script_no_dot, 'Ximport.vim') + assert_fails('source Ximport.vim', 'E1060: Expected dot after name: Export exported') + + var import_star_as_lines_script_space_after_dot =<< trim END + vim9script + import './Xexport.vim' as Export + g:imported_script = Export. exported + END + writefile(import_star_as_lines_script_space_after_dot, 'Ximport.vim') + assert_fails('source Ximport.vim', 'E1074:') + + var import_star_as_lines_missing_name =<< trim END + vim9script + import './Xexport.vim' as Export + def Func() + var imported = Export. + enddef + defcompile + END + writefile(import_star_as_lines_missing_name, 'Ximport.vim') + assert_fails('source Ximport.vim', 'E1048:', '', 1, 'Func') + + var import_star_as_lbr_lines =<< trim END + vim9script + import './Xexport.vim' + as Export + def UseExport() + g:exported = Export.exported + enddef + UseExport() + END + writefile(import_star_as_lbr_lines, 'Ximport.vim') + source Ximport.vim + assert_equal(18, g:exported) + unlet g:exported + + # try to use something that exists but is not exported + var import_not_exported_lines =<< trim END + vim9script + import './Xexport.vim' as expo + echo expo.name + END + writefile(import_not_exported_lines, 'Ximport.vim') + assert_fails('source Ximport.vim', 'E1049:', '', 3, 'Ximport.vim') + + # try to import something that is already defined + var import_already_defined =<< trim END + vim9script + var exported = 'something' + import './Xexport.vim' as exported + END + writefile(import_already_defined, 'Ximport.vim') + assert_fails('source Ximport.vim', 'E1054:', '', 3, 'Ximport.vim') + + # try changing an imported const + var import_assign_to_const =<< trim END + vim9script + import './Xexport.vim' as expo + def Assign() + expo.CONST = 987 + enddef + defcompile + END + writefile(import_assign_to_const, 'Ximport.vim') + assert_fails('source Ximport.vim', 'E46:', '', 1, '_Assign') + + # try changing an imported final + var import_assign_to_final =<< trim END + vim9script + import './Xexport.vim' as expo + def Assign() + expo.theList = [2] + enddef + defcompile + END + writefile(import_assign_to_final, 'Ximport.vim') + assert_fails('source Ximport.vim', 'E46:', '', 1, '_Assign') + + var import_no_as_lines =<< trim END + vim9script + import './Xexport.vim' name + END + writefile(import_no_as_lines, 'Ximport.vim') + assert_fails('source Ximport.vim', 'E488:', '', 2, 'Ximport.vim') + + var import_invalid_string_lines =<< trim END + vim9script + import Xexport.vim + END + writefile(import_invalid_string_lines, 'Ximport.vim') + assert_fails('source Ximport.vim', 'E121:', '', 2, 'Ximport.vim') + + var import_wrong_name_lines =<< trim END + vim9script + import './XnoExport.vim' + END + writefile(import_wrong_name_lines, 'Ximport.vim') + assert_fails('source Ximport.vim', 'E1053:', '', 2, 'Ximport.vim') + + var import_redefining_lines =<< trim END + vim9script + import './Xexport.vim' as exported + var exported = 5 + END + writefile(import_redefining_lines, 'Ximport.vim') + assert_fails('source Ximport.vim', 'E1213: Redefining imported item "exported"', '', 3) + + var import_assign_wrong_type_lines =<< trim END + vim9script + import './Xexport.vim' as expo + expo.exported = 'xxx' + END + writefile(import_assign_wrong_type_lines, 'Ximport.vim') + assert_fails('source Ximport.vim', 'E1012: Type mismatch; expected number but got string', '', 3) + + var import_assign_const_lines =<< trim END + vim9script + import './Xexport.vim' as expo + expo.CONST = 4321 + END + writefile(import_assign_const_lines, 'Ximport.vim') + assert_fails('source Ximport.vim', 'E46: Cannot change read-only variable "CONST"', '', 3) + + delete('Ximport.vim') + delete('Ximport3.vim') + delete('Xexport.vim') + + # Check that in a Vim9 script 'cpo' is set to the Vim default. + # Flags added or removed are also applied to the restored value. + set cpo=abcd + var lines =<< trim END + vim9script + g:cpo_in_vim9script = &cpo + set cpo+=f + set cpo-=c + g:cpo_after_vim9script = &cpo + END + writefile(lines, 'Xvim9_script') + source Xvim9_script + assert_equal('fabd', &cpo) + set cpo&vim + assert_equal(&cpo, g:cpo_in_vim9script) + var newcpo = substitute(&cpo, 'c', '', '') .. 'f' + assert_equal(newcpo, g:cpo_after_vim9script) + + delete('Xvim9_script') + enddef + + def Test_import_funcref() + var lines =<< trim END + vim9script + export def F(): number + return 42 + enddef + export const G = F + END + writefile(lines, 'Xlib.vim') + + lines =<< trim END + vim9script + import './Xlib.vim' as lib + const Foo = lib.G() + assert_equal(42, Foo) + + def DoTest() + const Goo = lib.G() + assert_equal(42, Goo) + enddef + DoTest() + END + CheckScriptSuccess(lines) + + delete('Xlib.vim') + enddef + + def Test_import_fails() + writefile([], 'Xfoo.vim') + var lines =<< trim END + import './Xfoo.vim' as foo + foo = 'bar' + END + CheckDefAndScriptFailure(lines, ['E1094:', 'E1236: Cannot use foo itself']) + lines =<< trim END + vim9script + import './Xfoo.vim' as foo + var that = foo + END + CheckScriptFailure(lines, 'E1060: Expected dot after name: foo') + + lines =<< trim END + vim9script + import './Xfoo.vim' as 9foo + END + CheckScriptFailure(lines, 'E1047:') + lines =<< trim END + vim9script + import './Xfoo.vim' as the#foo + END + CheckScriptFailure(lines, 'E1047:') + lines =<< trim END + vim9script + import './Xfoo.vim' as g:foo + END + CheckScriptFailure(lines, 'E1047:') + + delete('Xfoo.vim') + + lines =<< trim END + vim9script + def TheFunc() + echo 'the func' + enddef + export var Ref = TheFunc + END + writefile([], 'Xthat.vim') + lines =<< trim END + import './Xthat.vim' as That + That() + END + CheckDefAndScriptFailure(lines, ['E1094:', 'E1236: Cannot use That itself']) + + mkdir('Ximport') + + writefile(['vim9script'], 'Ximport/.vim') + lines =<< trim END + vim9script + import './Ximport/.vim' + END + CheckScriptFailure(lines, 'E1261: Cannot import .vim without using "as"') + lines =<< trim END + vim9script + import './Ximport/.vim' as vim + END + CheckScriptSuccess(lines) + + writefile(['vim9script'], 'Ximport/.vimrc') + lines =<< trim END + vim9script + import './Ximport/.vimrc' + END + CheckScriptFailure(lines, 'E1257: Imported script must use "as" or end in .vim') + lines =<< trim END + vim9script + import './Ximport/.vimrc' as vimrc + END + CheckScriptSuccess(lines) + + delete('Ximport', 'rf') + enddef + + func g:Trigger() + source Ximport.vim + return "echo 'yes'\" + endfunc + + def Test_import_export_expr_map() + # check that :import and :export work when buffer is locked + var export_lines =<< trim END + vim9script + export def That(): string + return 'yes' + enddef + END + writefile(export_lines, 'Xexport_that.vim') + + var import_lines =<< trim END + vim9script + import './Xexport_that.vim' as that + assert_equal('yes', that.That()) + END + writefile(import_lines, 'Ximport.vim') + + nnoremap trigger g:Trigger() + feedkeys('trigger', "xt") + + delete('Xexport_that.vim') + delete('Ximport.vim') + nunmap trigger + enddef + + def Test_import_in_filetype() + # check that :import works when the buffer is locked + mkdir('ftplugin', 'p') + var export_lines =<< trim END + vim9script + export var That = 'yes' + END + writefile(export_lines, 'ftplugin/Xexport_ft.vim') + + var import_lines =<< trim END + vim9script + import './Xexport_ft.vim' as ft + assert_equal('yes', ft.That) + g:did_load_mytpe = 1 + END + writefile(import_lines, 'ftplugin/qf.vim') + + var save_rtp = &rtp + &rtp = getcwd() .. ',' .. &rtp + + filetype plugin on + copen + assert_equal(1, g:did_load_mytpe) + + quit! + delete('Xexport_ft.vim') + delete('ftplugin', 'rf') + &rtp = save_rtp + enddef + + def Test_use_import_in_mapping() + var lines =<< trim END + vim9script + export def Funcx() + g:result = 42 + enddef + END + writefile(lines, 'XsomeExport.vim') + lines =<< trim END + vim9script + import './XsomeExport.vim' as some + var Funcy = some.Funcx + nnoremap :call Funcy() + END + writefile(lines, 'Xmapscript.vim') + + source Xmapscript.vim + feedkeys("\", "xt") + assert_equal(42, g:result) + + unlet g:result + delete('XsomeExport.vim') + delete('Xmapscript.vim') + nunmap + enddef + + def Test_export_fails() + CheckScriptFailure(['export var some = 123'], 'E1042:') + CheckScriptFailure(['vim9script', 'export var g:some'], 'E1022:') + CheckScriptFailure(['vim9script', 'export echo 134'], 'E1043:') + + assert_fails('export something', 'E1043:') + enddef + + func Test_import_fails_without_script() + CheckRunVimInTerminal + + " call indirectly to avoid compilation error for missing functions + call Run_Test_import_fails_on_command_line() + endfunc + + def Run_Test_import_fails_on_command_line() + var export =<< trim END + vim9script + export def Foo(): number + return 0 + enddef + END + writefile(export, 'XexportCmd.vim') + + var buf = RunVimInTerminal('-c "import Foo from ''./XexportCmd.vim''"', { + rows: 6, wait_for_ruler: 0}) + WaitForAssert(() => assert_match('^E1094:', term_getline(buf, 5))) + + delete('XexportCmd.vim') + StopVimInTerminal(buf) + enddef + + def Test_vim9_reload_noclear() + var lines =<< trim END + vim9script + export var exported = 'thexport' + + export def TheFunc(x = 0) + enddef + END + writefile(lines, 'XExportReload') + lines =<< trim END + vim9script noclear + g:loadCount += 1 + var s:reloaded = 'init' + import './XExportReload' as exp + + def Again(): string + return 'again' + enddef + + exp.TheFunc() + + if exists('s:loaded') | finish | endif + var s:loaded = true + + var s:notReloaded = 'yes' + s:reloaded = 'first' + def g:Values(): list + return [s:reloaded, s:notReloaded, Again(), Once(), exp.exported] + enddef + + def Once(): string + return 'once' + enddef + END + writefile(lines, 'XReloaded') + g:loadCount = 0 + source XReloaded + assert_equal(1, g:loadCount) + assert_equal(['first', 'yes', 'again', 'once', 'thexport'], g:Values()) + source XReloaded + assert_equal(2, g:loadCount) + assert_equal(['init', 'yes', 'again', 'once', 'thexport'], g:Values()) + source XReloaded + assert_equal(3, g:loadCount) + assert_equal(['init', 'yes', 'again', 'once', 'thexport'], g:Values()) + + delete('XReloaded') + delete('XExportReload') + delfunc g:Values + unlet g:loadCount + + lines =<< trim END + vim9script + def Inner() + enddef + END + lines->writefile('XreloadScript.vim') + source XreloadScript.vim + + lines =<< trim END + vim9script + def Outer() + def Inner() + enddef + enddef + defcompile + END + lines->writefile('XreloadScript.vim') + source XreloadScript.vim + + delete('XreloadScript.vim') + enddef + + def Test_vim9_reload_import() + var lines =<< trim END + vim9script + const var = '' + var valone = 1234 + def MyFunc(arg: string) + valone = 5678 + enddef + END + var morelines =<< trim END + var valtwo = 222 + export def GetValtwo(): number + return valtwo + enddef + END + writefile(lines + morelines, 'Xreload.vim') + source Xreload.vim + source Xreload.vim + source Xreload.vim + + # cannot declare a var twice + lines =<< trim END + vim9script + var valone = 1234 + var valone = 5678 + END + writefile(lines, 'Xreload.vim') + assert_fails('source Xreload.vim', 'E1041:', '', 3, 'Xreload.vim') + + delete('Xreload.vim') + delete('Ximport.vim') + enddef + + " if a script is reloaded with a script-local variable that changed its type, a + " compiled function using that variable must fail. + def Test_script_reload_change_type() + var lines =<< trim END + vim9script noclear + var str = 'string' + def g:GetStr(): string + return str .. 'xxx' + enddef + END + writefile(lines, 'Xreload.vim') + source Xreload.vim + echo g:GetStr() + + lines =<< trim END + vim9script noclear + var str = 1234 + END + writefile(lines, 'Xreload.vim') + source Xreload.vim + assert_fails('echo g:GetStr()', 'E1150:') + + delfunc g:GetStr + delete('Xreload.vim') + enddef + + " Define CallFunc so that the test can be compiled + command CallFunc echo 'nop' + + def Test_script_reload_from_function() + var lines =<< trim END + vim9script + + if exists('g:loaded') + finish + endif + g:loaded = 1 + delcommand CallFunc + command CallFunc Func() + def Func() + so XreloadFunc.vim + g:didTheFunc = 1 + enddef + END + writefile(lines, 'XreloadFunc.vim') + source XreloadFunc.vim + CallFunc + assert_equal(1, g:didTheFunc) + + delete('XreloadFunc.vim') + delcommand CallFunc + unlet g:loaded + unlet g:didTheFunc + enddef + + def s:RetSome(): string + return 'some' + enddef + + " Not exported function that is referenced needs to be accessed by the + " script-local name. + def Test_vim9_funcref() + var sortlines =<< trim END + vim9script + def Compare(i1: number, i2: number): number + return i2 - i1 + enddef + + export def FastSort(): list + return range(5)->sort(Compare) + enddef + + export def GetString(arg: string): string + return arg + enddef + END + writefile(sortlines, 'Xsort.vim') + + var lines =<< trim END + vim9script + import './Xsort.vim' + def Test() + g:result = Xsort.FastSort() + enddef + Test() + + # using a function imported with "as" + import './Xsort.vim' as anAlias + assert_equal('yes', anAlias.GetString('yes')) + + # using the function from a compiled function + def TestMore(): string + var s = s:anAlias.GetString('foo') + return s .. anAlias.GetString('bar') + enddef + assert_equal('foobar', TestMore()) + + # error when using a function that isn't exported + assert_fails('anAlias.Compare(1, 2)', 'E1049:') + END + writefile(lines, 'Xscript.vim') + + source Xscript.vim + assert_equal([4, 3, 2, 1, 0], g:result) + + unlet g:result + delete('Xsort.vim') + delete('Xscript.vim') + + var Funcref = function('s:RetSome') + assert_equal('some', Funcref()) + enddef + + " Check that when searching for "FilterFunc" it finds the import in the + " script where FastFilter() is called from, both as a string and as a direct + " function reference. + def Test_vim9_funcref_other_script() + var filterLines =<< trim END + vim9script + export def FilterFunc(idx: number, val: number): bool + return idx % 2 == 1 + enddef + export def FastFilter(): list + return range(10)->filter('FilterFunc(v:key, v:val)') + enddef + export def FastFilterDirect(): list + return range(10)->filter(FilterFunc) + enddef + END + writefile(filterLines, 'Xfilter.vim') + + var lines =<< trim END + vim9script + import './Xfilter.vim' as filter + def Test() + var x: list = filter.FastFilter() + enddef + Test() + def TestDirect() + var x: list = filter.FastFilterDirect() + enddef + TestDirect() + END + CheckScriptSuccess(lines) + delete('Xfilter.vim') + enddef + + def Test_import_absolute() + var import_lines = [ + 'vim9script', + 'import "' .. escape(getcwd(), '\') .. '/Xexport_abs.vim" as abs', + 'def UseExported()', + ' g:imported_abs = abs.exported', + ' abs.exported = 8888', + ' g:imported_after = abs.exported', + 'enddef', + 'UseExported()', + 'g:import_disassembled = execute("disass UseExported")', + ] + writefile(import_lines, 'Ximport_abs.vim') + writefile(s:export_script_lines, 'Xexport_abs.vim') + + source Ximport_abs.vim + + assert_equal(9876, g:imported_abs) + assert_equal(8888, g:imported_after) + assert_match('\d\+_UseExported\_s*' .. + 'g:imported_abs = abs.exported\_s*' .. + '0 LOADSCRIPT exported-2 from .*Xexport_abs.vim\_s*' .. + '1 STOREG g:imported_abs\_s*' .. + 'abs.exported = 8888\_s*' .. + '2 PUSHNR 8888\_s*' .. + '3 STORESCRIPT exported-2 in .*Xexport_abs.vim\_s*' .. + 'g:imported_after = abs.exported\_s*' .. + '4 LOADSCRIPT exported-2 from .*Xexport_abs.vim\_s*' .. + '5 STOREG g:imported_after', + g:import_disassembled) + + Undo_export_script_lines() + unlet g:imported_abs + unlet g:import_disassembled + + delete('Ximport_abs.vim') + delete('Xexport_abs.vim') + enddef + + def Test_import_rtp() + var import_lines = [ + 'vim9script', + 'import "Xexport_rtp.vim" as rtp', + 'g:imported_rtp = rtp.exported', + ] + writefile(import_lines, 'Ximport_rtp.vim') + mkdir('import', 'p') + writefile(s:export_script_lines, 'import/Xexport_rtp.vim') + + var save_rtp = &rtp + &rtp = getcwd() + source Ximport_rtp.vim + &rtp = save_rtp + + assert_equal(9876, g:imported_rtp) + + Undo_export_script_lines() + unlet g:imported_rtp + delete('Ximport_rtp.vim') + delete('import', 'rf') + enddef + + def Test_import_compile_error() + var export_lines = [ + 'vim9script', + 'export def ExpFunc(): string', + ' return notDefined', + 'enddef', + ] + writefile(export_lines, 'Xexported.vim') + + var import_lines = [ + 'vim9script', + 'import "./Xexported.vim" as expo', + 'def ImpFunc()', + ' echo expo.ExpFunc()', + 'enddef', + 'defcompile', + ] + writefile(import_lines, 'Ximport.vim') + + try + source Ximport.vim + catch /E1001/ + # Error should be before the Xexported.vim file. + assert_match('E1001: Variable not found: notDefined', v:exception) + assert_match('function \d\+_ImpFunc\[1\]..\d\+_ExpFunc, line 1', v:throwpoint) + endtry + + delete('Xexported.vim') + delete('Ximport.vim') + enddef + + def Test_func_overrules_import_fails() + var export_lines =<< trim END + vim9script + export def Func() + echo 'imported' + enddef + END + writefile(export_lines, 'XexportedFunc.vim') + + var lines =<< trim END + vim9script + import './XexportedFunc.vim' as Func + def Func() + echo 'local to function' + enddef + END + CheckScriptFailure(lines, 'E1236:') + + lines =<< trim END + vim9script + import './XexportedFunc.vim' as Func + def Outer() + def Func() + echo 'local to function' + enddef + enddef + defcompile + END + CheckScriptFailure(lines, 'E1236:') + + delete('XexportedFunc.vim') + enddef + + def Test_source_vim9_from_legacy() + var vim9_lines =<< trim END + vim9script + var local = 'local' + g:global = 'global' + export var exported = 'exported' + export def GetText(): string + return 'text' + enddef + END + writefile(vim9_lines, 'Xvim9_script.vim') + + var legacy_lines =<< trim END + source Xvim9_script.vim + + call assert_false(exists('local')) + call assert_false(exists('exported')) + call assert_false(exists('s:exported')) + call assert_equal('global', global) + call assert_equal('global', g:global) + + "" imported variable becomes script-local + "import exported from './Xvim9_script.vim' + "call assert_equal('exported', s:exported) + "call assert_false(exists('exported')) + + "" imported function becomes script-local + "import GetText from './Xvim9_script.vim' + "call assert_equal('text', s:GetText()) + "call assert_false(exists('*GetText')) + END + writefile(legacy_lines, 'Xlegacy_script.vim') + + source Xlegacy_script.vim + assert_equal('global', g:global) + unlet g:global + + delete('Xlegacy_script.vim') + delete('Xvim9_script.vim') + enddef + + def Test_cmdline_win() + # if the Vim syntax highlighting uses Vim9 constructs they can be used from + # the command line window. + mkdir('rtp/syntax', 'p') + var export_lines =<< trim END + vim9script + export var That = 'yes' + END + writefile(export_lines, 'rtp/syntax/Xexport.vim') + var import_lines =<< trim END + vim9script + import './Xexport.vim' as exp + echo exp.That + END + writefile(import_lines, 'rtp/syntax/vim.vim') + var save_rtp = &rtp + &rtp = getcwd() .. '/rtp' .. ',' .. &rtp + syntax on + augroup CmdWin + autocmd CmdwinEnter * g:got_there = 'yes' + augroup END + # this will open and also close the cmdline window + feedkeys('q:', 'xt') + assert_equal('yes', g:got_there) + + augroup CmdWin + au! + augroup END + &rtp = save_rtp + delete('rtp', 'rf') + enddef + + def Test_import_gone_when_sourced_twice() + var exportlines =<< trim END + vim9script + if exists('g:guard') + finish + endif + g:guard = 1 + export var name = 'someName' + END + writefile(exportlines, 'XexportScript.vim') + + var lines =<< trim END + vim9script + import './XexportScript.vim' as expo + def g:GetName(): string + return expo.name + enddef + END + writefile(lines, 'XscriptImport.vim') + so XscriptImport.vim + assert_equal('someName', g:GetName()) + + so XexportScript.vim + assert_fails('call g:GetName()', 'E1149:') + + delfunc g:GetName + delete('XexportScript.vim') + delete('XscriptImport.vim') + unlet g:guard + enddef + + + " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker *** ../vim-8.2.4035/src/testdir/Make_all.mak 2021-08-05 15:23:05.482890089 +0100 --- src/testdir/Make_all.mak 2022-01-07 21:30:27.616378221 +0000 *************** *** 37,42 **** --- 37,43 ---- test_vim9_expr \ test_vim9_fails \ test_vim9_func \ + test_vim9_import \ test_vim9_script TEST_VIM9_RES = \ *************** *** 47,52 **** --- 48,54 ---- test_vim9_expr.res \ test_vim9_fails.res \ test_vim9_func.res \ + test_vim9_import.res \ test_vim9_script.res # Benchmark scripts. *** ../vim-8.2.4035/src/version.c 2022-01-07 20:40:04.670218119 +0000 --- src/version.c 2022-01-07 21:21:09.937377911 +0000 *************** *** 752,753 **** --- 752,755 ---- { /* Add new patch number below this line */ + /**/ + 4036, /**/ -- hundred-and-one symptoms of being an internet addict: 254. You wake up daily with your keyboard printed on your forehead. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///