294 lines
7.9 KiB
VimL
294 lines
7.9 KiB
VimL
" Vim plugin for running ruby tests
|
|
" Last Change: May 13 2009
|
|
" Maintainer: Jan <jan.h.xie@gmail.com>
|
|
" License: MIT License
|
|
|
|
if exists("rubytest_loaded")
|
|
finish
|
|
endif
|
|
let rubytest_loaded = 1
|
|
|
|
if !exists("g:rubytest_in_quickfix")
|
|
let g:rubytest_in_quickfix = 0
|
|
endif
|
|
if !exists("g:rubytest_spec_drb")
|
|
let g:rubytest_spec_drb = 0
|
|
endif
|
|
if !exists("g:rubytest_cmd_test")
|
|
let g:rubytest_cmd_test = "ruby %p"
|
|
endif
|
|
if !exists("g:rubytest_cmd_testcase")
|
|
let g:rubytest_cmd_testcase = "ruby %p -n '/%c/'"
|
|
endif
|
|
if !exists("g:rubytest_cmd_spec")
|
|
let g:rubytest_cmd_spec = "spec -f specdoc %p"
|
|
endif
|
|
if !exists("g:rubytest_cmd_example")
|
|
let g:rubytest_cmd_example = "spec -f specdoc %p -l %c"
|
|
endif
|
|
if !exists("g:rubytest_cmd_feature")
|
|
let g:rubytest_cmd_feature = "cucumber %p"
|
|
endif
|
|
if !exists("g:rubytest_cmd_story")
|
|
let g:rubytest_cmd_story = "cucumber %p -n '%c'"
|
|
endif
|
|
|
|
function s:FindCase(patterns)
|
|
let ln = a:firstline
|
|
while ln > 0
|
|
let line = getline(ln)
|
|
for pattern in keys(a:patterns)
|
|
if line =~ pattern
|
|
if s:pattern == 'spec'
|
|
return a:patterns[pattern](ln)
|
|
else
|
|
return a:patterns[pattern](line)
|
|
endif
|
|
endif
|
|
endfor
|
|
let ln -= 1
|
|
endwhile
|
|
return 'false'
|
|
endfunction
|
|
|
|
|
|
function s:EscapeBackSlash(str)
|
|
return substitute(a:str, '\', '\\\\', 'g')
|
|
endfunction
|
|
|
|
function s:RunTest()
|
|
if s:test_scope == 1
|
|
let cmd = g:rubytest_cmd_testcase
|
|
elseif s:test_scope == 2
|
|
let cmd = g:rubytest_cmd_test
|
|
end
|
|
|
|
let case = s:FindCase(s:test_case_patterns['test'])
|
|
if s:test_scope == 2 || case != 'false'
|
|
let case = substitute(case, "'\\|\"", '.', 'g')
|
|
let cmd = substitute(cmd, '%c', case, '')
|
|
let cmd = substitute(cmd, '%p', s:EscapeBackSlash(@%), '')
|
|
|
|
if @% =~ '^test'
|
|
let cmd = substitute(cmd, '^ruby ', 'ruby -Itest -rtest_helper ', '')
|
|
endif
|
|
|
|
if g:rubytest_in_quickfix > 0
|
|
let s:oldefm = &efm
|
|
let &efm = s:efm . s:efm_backtrace . ',' . s:efm_ruby . ',' . s:oldefm . ',%-G%.%#'
|
|
|
|
cex system(cmd)
|
|
cw
|
|
|
|
let &efm = s:oldefm
|
|
else
|
|
exe "!echo '" . cmd . "' && " . cmd
|
|
endif
|
|
else
|
|
echo 'No test case found.'
|
|
endif
|
|
endfunction
|
|
|
|
function s:RunSpec()
|
|
if s:test_scope == 1
|
|
let cmd = g:rubytest_cmd_example
|
|
elseif s:test_scope == 2
|
|
let cmd = g:rubytest_cmd_spec
|
|
endif
|
|
|
|
if g:rubytest_spec_drb > 0
|
|
let cmd = cmd . " --drb"
|
|
endif
|
|
|
|
let case = s:FindCase(s:test_case_patterns['spec'])
|
|
if s:test_scope == 2 || case != 'false'
|
|
let cmd = substitute(cmd, '%c', case, '')
|
|
let cmd = substitute(cmd, '%p', s:EscapeBackSlash(@%), '')
|
|
if g:rubytest_in_quickfix > 0
|
|
let s:oldefm = &efm
|
|
let &efm = s:efm . s:efm_backtrace . ',' . s:efm_ruby . ',' . s:oldefm . ',%-G%.%#'
|
|
|
|
cex system(cmd)
|
|
cw
|
|
|
|
let &efm = s:oldefm
|
|
else
|
|
exe "!echo '" . cmd . "' && " . cmd
|
|
endif
|
|
else
|
|
echo 'No spec found.'
|
|
endif
|
|
endfunction
|
|
|
|
function s:RunFeature()
|
|
let s:old_in_quickfix = g:rubytest_in_quickfix
|
|
let g:rubytest_in_quickfix = 0
|
|
|
|
if s:test_scope == 1
|
|
let cmd = g:rubytest_cmd_story
|
|
elseif s:test_scope == 2
|
|
let cmd = g:rubytest_cmd_feature
|
|
endif
|
|
|
|
let case = s:FindCase(s:test_case_patterns['feature'])
|
|
if s:test_scope == 2 || case != 'false'
|
|
let cmd = substitute(cmd, '%c', case, '')
|
|
let cmd = substitute(cmd, '%p', s:EscapeBackSlash(@%), '')
|
|
if g:rubytest_in_quickfix > 0
|
|
let s:oldefm = &efm
|
|
let &efm = s:efm . s:efm_backtrace . ',' . s:efm_ruby . ',' . s:oldefm . ',%-G%.%#'
|
|
|
|
cex system(cmd)
|
|
cw
|
|
|
|
let &efm = s:oldefm
|
|
else
|
|
exe "!echo '" . cmd . "' && " . cmd
|
|
endif
|
|
else
|
|
echo 'No story found.'
|
|
endif
|
|
|
|
let g:rubytest_in_quickfix = s:old_in_quickfix
|
|
endfunction
|
|
|
|
let s:test_patterns = {}
|
|
let s:test_patterns['test'] = function('s:RunTest')
|
|
let s:test_patterns['spec'] = function('s:RunSpec')
|
|
let s:test_patterns['\.feature$'] = function('s:RunFeature')
|
|
|
|
function s:GetTestCaseName1(str)
|
|
return split(a:str)[1]
|
|
endfunction
|
|
|
|
function s:GetTestCaseName2(str)
|
|
return "test_" . join(split(split(a:str, '"')[1]), '_')
|
|
endfunction
|
|
|
|
function s:GetTestCaseName3(str)
|
|
return split(a:str, '"')[1]
|
|
endfunction
|
|
|
|
function s:GetTestCaseName4(str)
|
|
return "test_" . join(split(split(a:str, "'")[1]), '_')
|
|
endfunction
|
|
|
|
function s:GetTestCaseName5(str)
|
|
return split(a:str, "'")[1]
|
|
endfunction
|
|
|
|
function s:GetSpecLine(str)
|
|
return a:str
|
|
endfunction
|
|
|
|
function s:GetStoryLine(str)
|
|
return join(split(split(a:str, "Scenario:")[1]))
|
|
endfunction
|
|
|
|
let s:test_case_patterns = {}
|
|
let s:test_case_patterns['test'] = {'^\s*def test':function('s:GetTestCaseName1'), '^\s*test \s*"':function('s:GetTestCaseName2'), "^\\s*test \\s*'":function('s:GetTestCaseName4'), '^\s*should \s*"':function('s:GetTestCaseName3'), "^\\s*should \\s*'":function('s:GetTestCaseName5')}
|
|
let s:test_case_patterns['spec'] = {'^\s*\(it\|example\|describe\|context\) \s*':function('s:GetSpecLine')}
|
|
let s:test_case_patterns['feature'] = {'^\s*Scenario:':function('s:GetStoryLine')}
|
|
|
|
let s:save_cpo = &cpo
|
|
set cpo&vim
|
|
|
|
if !hasmapto('<Plug>RubyTestRun')
|
|
map <unique> <Leader>rt <Plug>RubyTestRun
|
|
endif
|
|
if !hasmapto('<Plug>RubyFileRun')
|
|
map <unique> <Leader>rT <Plug>RubyFileRun
|
|
endif
|
|
|
|
function s:IsRubyTest()
|
|
for pattern in keys(s:test_patterns)
|
|
if @% =~ pattern
|
|
let s:pattern = pattern
|
|
return 1
|
|
endif
|
|
endfor
|
|
endfunction
|
|
|
|
function s:Run(scope)
|
|
if !s:IsRubyTest()
|
|
echo "This file doesn't contain ruby test."
|
|
else
|
|
" test scope define what to test
|
|
" 1: test case under cursor
|
|
" 2: all tests in file
|
|
let s:test_scope = a:scope
|
|
call s:test_patterns[s:pattern]()
|
|
endif
|
|
endfunction
|
|
|
|
noremap <unique> <script> <Plug>RubyTestRun <SID>Run
|
|
noremap <unique> <script> <Plug>RubyFileRun <SID>RunFile
|
|
noremap <SID>Run :call <SID>Run(1)<CR>
|
|
noremap <SID>RunFile :call <SID>Run(2)<CR>
|
|
|
|
let s:efm='%A%\\d%\\+)%.%#,'
|
|
|
|
" below errorformats are copied from rails.vim
|
|
" Current directory
|
|
let s:efm=s:efm . '%D(in\ %f),'
|
|
" Failure and Error headers, start a multiline message
|
|
let s:efm=s:efm
|
|
\.'%A\ %\\+%\\d%\\+)\ Failure:,'
|
|
\.'%A\ %\\+%\\d%\\+)\ Error:,'
|
|
\.'%+A'."'".'%.%#'."'".'\ FAILED,'
|
|
" Exclusions
|
|
let s:efm=s:efm
|
|
\.'%C%.%#(eval)%.%#,'
|
|
\.'%C-e:%.%#,'
|
|
\.'%C%.%#/lib/gems/%\\d.%\\d/gems/%.%#,'
|
|
\.'%C%.%#/lib/ruby/%\\d.%\\d/%.%#,'
|
|
\.'%C%.%#/vendor/rails/%.%#,'
|
|
" Specific to template errors
|
|
let s:efm=s:efm
|
|
\.'%C\ %\\+On\ line\ #%l\ of\ %f,'
|
|
\.'%CActionView::TemplateError:\ compile\ error,'
|
|
" stack backtrace is in brackets. if multiple lines, it starts on a new line.
|
|
let s:efm=s:efm
|
|
\.'%Ctest_%.%#(%.%#):%#,'
|
|
\.'%C%.%#\ [%f:%l]:,'
|
|
\.'%C\ \ \ \ [%f:%l:%.%#,'
|
|
\.'%C\ \ \ \ %f:%l:%.%#,'
|
|
\.'%C\ \ \ \ \ %f:%l:%.%#]:,'
|
|
\.'%C\ \ \ \ \ %f:%l:%.%#,'
|
|
" Catch all
|
|
let s:efm=s:efm
|
|
\.'%Z%f:%l:\ %#%m,'
|
|
\.'%Z%f:%l:,'
|
|
\.'%C%m,'
|
|
" Syntax errors in the test itself
|
|
let s:efm=s:efm
|
|
\.'%.%#.rb:%\\d%\\+:in\ `load'."'".':\ %f:%l:\ syntax\ error\\\, %m,'
|
|
\.'%.%#.rb:%\\d%\\+:in\ `load'."'".':\ %f:%l:\ %m,'
|
|
" And required files
|
|
let s:efm=s:efm
|
|
\.'%.%#:in\ `require'."'".':in\ `require'."'".':\ %f:%l:\ syntax\ error\\\, %m,'
|
|
\.'%.%#:in\ `require'."'".':in\ `require'."'".':\ %f:%l:\ %m,'
|
|
" Exclusions
|
|
let s:efm=s:efm
|
|
\.'%-G%.%#/lib/gems/%\\d.%\\d/gems/%.%#,'
|
|
\.'%-G%.%#/lib/ruby/%\\d.%\\d/%.%#,'
|
|
\.'%-G%.%#/vendor/rails/%.%#,'
|
|
\.'%-G%.%#%\\d%\\d:%\\d%\\d:%\\d%\\d%.%#,'
|
|
" Final catch all for one line errors
|
|
let s:efm=s:efm
|
|
\.'%-G%\\s%#from\ %.%#,'
|
|
\.'%f:%l:\ %#%m,'
|
|
|
|
let s:efm_backtrace='%D(in\ %f),'
|
|
\.'%\\s%#from\ %f:%l:%m,'
|
|
\.'%\\s%#from\ %f:%l:,'
|
|
\.'%\\s#{RAILS_ROOT}/%f:%l:\ %#%m,'
|
|
\.'%\\s%#[%f:%l:\ %#%m,'
|
|
\.'%\\s%#%f:%l:\ %#%m,'
|
|
\.'%\\s%#%f:%l:,'
|
|
\.'%m\ [%f:%l]:'
|
|
|
|
let s:efm_ruby='\%-E-e:%.%#,\%+E%f:%l:\ parse\ error,%W%f:%l:\ warning:\ %m,%E%f:%l:in\ %*[^:]:\ %m,%E%f:%l:\ %m,%-C%\tfrom\ %f:%l:in\ %.%#,%-Z%\tfrom\ %f:%l,%-Z%p^'
|
|
|
|
let &cpo = s:save_cpo
|