2013-03-24 16 views
6

Sto utilizzando Vimrunner per testare un plug-in Vim. Tutto funziona, ma sto cercando un modo migliore/canonico per eseguire funzioni locali di script. Dal momento che non sono direttamente visibili al di fuori dello script, al momento sto esponendo lo script <SID> e prependo quello alle mie chiamate per eseguirli.Test delle unità Funzioni locali di script Vim con Vimrunner

devo aggiungere questo codice al mio plugin per esporre il SID:

function! s:SID() 
    let fullname = expand("<sfile>") 
    return matchstr(fullname, '<SNR>\d\+_') 
endfunction 
let g:my_plugin_SID = s:SID() 

che esporrà il SID, come ad esempio <SNR>18_. Dal momento che le funzioni di Vim sono tutti globali, e proprio nome-munged, funzioni script locale possono essere richiamati al di fuori dello script anteponendo al SID:

:call <SNR>18_some_function() 

Poi faccio questo in una specifica:

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 

C'è un modo migliore per farlo?

risposta

5

Il modo più semplice è esporre semplicemente le funzioni locali dello script: Trasforma s:MyFunc in MyPlugin#MyFunc. Dopotutto, la visibilità della funzione è solo per convenzione, comunque; nulla (eccetto la laboriosa ricerca del nome) impedisce comunque che vengano chiamate le funzioni locali dello script.

A volte, devo deviare da quello e voglio invocare le funzioni locali dello script dai test. Il mio approccio è del tutto simile al tuo, ma invece di esporre lo <SID> dal plugin, ho scritto delle funzioni di supporto per analizzare lo <SID> dall'uscita :scriptnames. È più lento (non mi interessa, i miei test sono test di integrazione), ma non devo inquinare il plugin stesso con il codice di test. Ecco un esempio che mostra le Sid() e SidInvoke() aiutanti:

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 
+0

Mi stavo dirigendo in quella direzione, ma sono riluttante a esaminare le cose per i test. So che non ha molta importanza, ma mi piace mantenere gli spazi dei nomi più significativi di quanto permetta Vim. Mi piace l'idea di parsing di ': scriptnames' per evitare di iniettare il codice di test in produzione. Ancora aperto ad altri suggerimenti. –

+0

Ho cercato di sostituire my: MyFunction() con MyPlugin # MyFunction(), ma una chiamata ad esso in una mappatura nello stesso file sembra non funzionare. Mi sto perdendo qualcosa qui? – NicolasWebDev

+0

@Sathors: 'MyPlugin' deve essere il nome esatto del tuo plugin, ovviamente. –

1

Usare questo per ottenere il numero di script:

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

e questo per invocare una funzione di script-locale (s:Test() in questo esempio)

execute("call <snr>" . sid . "_Test()") 
Problemi correlati