6

我正在使用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 公开为 eg <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

有一个更好的方法吗?

4

2 回答 2

5

最简单的方法是简单地公开脚本本地函数:s:MyFunc变成MyPlugin#MyFunc. 毕竟,无论如何,功能可见性只是约定俗成的;无论如何,没有任何东西(除了繁琐的名称查找)可以防止调用脚本本地函数。

有时,我会偏离这一点,并且确实想从测试中调用脚本本地函数。我的方法与您的方法非常相似,但是<SID>我没有在插件中公开 from ,而是编写了帮助函数来解析<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
于 2013-03-24T08:34:05.177 回答
2

使用它来获取脚本编号:

let sid = matchlist(execute('scriptnames'), '\([0-9]\+\): [^ ]*autoload/my_vimscript.vim')[1]

这将调用脚本本地函数(s:Test()在本例中)

execute("call <snr>" . sid . "_Test()")
于 2017-02-15T10:06:55.107 回答