我正在使用Vimrunner对Vim插件进行单元测试。一切正常,但我正在寻找一种更好/规范的方式来执行脚本本地功能。由于它们不是在脚本之外直接可见,我现在正在公开脚本的<SID>
并将其添加到我的调用中以便运行它们。
我必须将此代码添加到我的插件中以公开SID:
function! s:SID()
let fullname = expand("<sfile>")
return matchstr(fullname, '<SNR>\d\+_')
endfunction
let g:my_plugin_SID = s:SID()
这会将SID公开为例如<SNR>18_
。由于Vim函数都是全局函数,并且只是名称,因此可以通过为SID添加前缀来在脚本外部调用脚本本地函数:
:call <SNR>18_some_function()
然后我在规范中这样做:
describe "s:reverse_string" do
let!(:sid) { VIM.command("echo g:my_plugin_SID") }
def reverse_string(string)
VIM.command("echo #{sid}reverse_string('#{string}')")
end
it "does something" do
reverse_string("foo").should == "oof"
end
end
有更好的方法吗?
答案 0 :(得分:5)
最简单的方法是简单地公开脚本本地函数:将s:MyFunc
转换为MyPlugin#MyFunc
。毕竟,无论如何,功能可见性只能按惯例进行;没有(除了繁琐的名称查找),无论如何都不会被调用脚本本地函数。
有时候,我偏离了这一点,并希望从测试中调用脚本本地函数。我的方法与你的方法非常相似,但是我没有在插件中公开<SID>
,而是编写了帮助函数来解析<SID>
输出中的:scriptnames
。它更慢(我不在乎;我的测试是集成测试),但我不必用测试代码污染插件本身。以下是显示Sid()
和SidInvoke()
助手的示例:
let s:SID = Sid('autoload/EditSimilar/Substitute.vim')
function! s:Is( input, expected, description )
let l:got = SidInvoke(s:SID, printf("IsWildcardPathPattern('%s')", a:input))
call vimtap#Is(l:got, a:expected, a:description)
endfunction
答案 1 :(得分:1)
使用此命令获取脚本编号:
let sid = matchlist(execute('scriptnames'), '\([0-9]\+\): [^ ]*autoload/my_vimscript.vim')[1]
这将调用脚本本地函数(在此示例中为s:Test()
)
execute("call <snr>" . sid . "_Test()")