Skip to content
janeiro 9, 2009 / cassiomarques

Executando specs no VIM e exibindo os resultados no Firefox

O problema

No Gedit eu usava esse script para executar o arquivo do Rspec atual, quando desenvolvendo aplicações Rails. Isso sempre foi muito útil para mim porque o script já inclui as depedências necessárias no load path e executa as specs declaradas no arquivo atual sem executar a Rake task db:test:prepare. Isso torna os testes bem mais rápidos, principalmente se quisermos executar apenas as specs de um único arquivo específico. Outra coisa que gosto muito nesse script é que ele utiliza o modo de visualização dos resultados em HTML, exibindo a página gerada em uma nova aba no Firefox. Essa página exibe até mesmo os trechos de código das specs que falharam, o que ajuda bastante na hora de solucionar os problemas.
Como voltei recentemente a utilizar o VIM para desenvolver em Ruby/Rails, fui ver como fazer o mesmo usando o plugin rails.vim. No rails.vim, quando temos um arquivo de specs aberto e executamos :Rake esse arquivo é executado com o Rspec. O lado ruim disso é que todo o banco de dados é carregado, deixando a execução dos testes muito mais lenta do que necessário. Outra coisa que não gosto é que o VIM irá colocar todo o output da execução das specs em um modo de visualização temporário e esperar que você pressione ou execute algum outro comando, voltando imediatamente para o buffer com o arquivo de specs. Se você não lembrar exatamente qual foi a mensagem de erro ou qual spec falhou, vai ter que executar tudo de novo, porque a saída que o VIM mostrou era temporária.

A solução

A solução foi adaptar o script utilizado no Gedit, colocá-lo em um arquivo Ruby externo e criar uma função no meu .vimrc que executa este script. Para utilizar essa solução é necessário que o seu VIM tenha sido compilado com a opção +ruby, a qual habilita uma interface Ruby para criar funções dentro de scripts do VIM. Para verificar se o seu VIM possui essa funcionalidade, faça :version e procure por “+ruby”. Se tudo o que você encontrar for “-ruby”, será necessário que você recompile seu VIM com essa opção habilitada. Dê uma olhada no Makefile do VIM e procure por enable ruby-interp.

Essa funcionalidade foi testada no VIM 7.2 em um Ubuntu 8.04.

Crie um arquivo com o conteúdo abaixo e coloque-o em ~/.vim/bin/run_rspec.rb

spec_dir=File.dirname(ARGV[0])
rails_project_dir="#{spec_dir}/../.."

report_file="#{rails_project_dir}/doc/rspec_report.html"

rspec_rails_plugin = File.join(rails_project_dir,'vendor','plugins','rspec','lib')
if File.directory?(rspec_rails_plugin)
  $LOAD_PATH.unshift(rspec_rails_plugin)
end
require 'rubygems'
require 'spec'
require 'spec/runner/formatter/html_formatter'

module Spec
  module Runner
    module Formatter
      class HtmlFormatter
        def backtrace_line(line)
          line.gsub(/([^:]*\.rb):(\d*)/) do
            "<a href=\"vim://#{File.expand_path($1)}?#{$2}\">#{$1}:#{$2}</a> "
          end
        end
      end
    end
  end
end

if File.exists? report_file
  File.delete report_file
end

argv = [ARGV[0]]
argv << "--c"
argv << "--format"
argv << "html:#{report_file}"

::Spec::Runner::CommandLine.run(::Spec::Runner::OptionParser.parse(argv, STDERR, STDOUT))

if File.exists? report_file
  `firefox #{report_file}`
end
&#91;/source&#93;

Em seguida edite o seu <strong>.vimrc</strong>, que deve estar localizado em <strong>$HOME/.vimrc</strong>, adicionando o conteúdo a seguir

<pre>
<code>
" Run Rspec for the current spec file
function! RunRspec()
ruby &lt;&lt; EOF
  buffer = VIM::Buffer.current
  spec_file = VIM::Buffer.current.name
  command = "ruby ~/.vim/bin/run_rspec.rb #{spec_file}"
  print "Running Rspec for #{spec_file}. Results will be displayed in Firefox."
  system(command)
EOF
endfunction
map &lt;F7&gt; :call RunRspec()&lt;cr&gt;

</code>
</pre>
Aqui eu mapeei a tecla F7 para executar as specs, mas você pode alterar a função e mapear a combinação de teclas que preferir. Agora basta estar com algum arquivo de specs aberto e apertar F7 para que suas specs sejam executadas e o resultado apresentado no Firefox. 

ATUALIZADO: <br>
Preste atenção ao fato de que cada erro exibido no Firefox terá um link clicável, o qual abrirá o respectivo arquivo no Vim, exatamente na linha de código da spec que falhou. Para que isso funcione, você terá que fazer algumas configurações:

<ul>
	<li>Abra o endereço <strong>about:config</strong> no seu Firefox</li>
	<li>O Firefox irá exibir uma tela de avisa, diga a ele que você terá cuidado...</li>
	<li>CLique com o botão direito em qualquer local da página, escolha "nova opção" e então "boolean". Coloque <strong>network.protocol-handler.external.vim</strong> como o nome da opção e defina seu valor como <strong>true</strong></li>
	<li>Novamente, clique com o botão direito, escolha "nova opção" e então "string". Coloque <strong>network.protocol-handler.app.vim</strong> como o nome da opção e <strong>~/.vim/bin/open_vim</strong> como seu valor</li>
	<li>Feche a página <strong>about:config</strong></li>
</ul>

Agora você terá que criar o script que será chamado quando você clicar em uma linha de erro e cuidará de abrir o seu arquivo com specs usando o Vim (na verdade o script está configurado para usar o GVim, mas você pode alterar isso se quiser). O arquivo será aberto em uma instância do Vim já em execução, usando uma nova aba. Crie um arquivo chamado <strong>open_vim</strong> dentro de <strong>$HOME/.vim/bin</strong>, com o seguinte conteúdo:


#!/usr/bin/ruby
regex = /(.+)\?(\d+)/
ARGV[0] =~ regex
system("gvim --remote-silent +#{$2} #{$1}") 

Salve e feche o arquivo. Agora dê permissão de execução a ele executando chmod +x ~/.vim/bin/open_vim. Na primeira vez que você clicar em uma linha de erro no Firefox ele irá exibir um diálogo para que você confirme que quer utilizar o programa open_vim para abrir links no formato vim://. Apenas dê “OK” e tudo estará certo.

Se você tiver feito alguma alteração no banco e quiser que essas alterações sejam refletidas no banco de testes antes de executar as specs, basta fazer rake db:test:prepare.

5 Comentários

Deixe um comentário
  1. Jonatas Davi Paganini / jan 9 2009 8:55 pm

    Muito legal mesmo Cassio, eu sempre usei o terminal na aba do lado para fazer este e gostei mais de usar o autospec.
    Os specs em html ficam mto bonitos mesmo! :D

  2. cassiomarques / jan 9 2009 9:04 pm

    @Jonatas,

    Eu já tentei várias vezes, mas sei lá porque eu nunca me dei muito bem com o autospec…

  3. Max / jan 9 2009 11:28 pm

    Cassio,

    otimo post. Cai perfeito pra mim. Somente acho que o engine do blog substituiu o : ( (tudo junto) na linha line.gsub(/([^:]*\.rb)…?

  4. Philipe Farias / jan 10 2009 12:18 am

    Cássio,

    Obrigado por portar esse script pro vim.
    Só tem um problema…o wordpress está bagunçando ele…
    Na linha 19, no primeiro parâmetro do gsub ele está trocando ‘: (‘ por um smile (a sad one). Veja que no código que aparece no blog tem o código em html com o caminho para a imagem do maldito smile.

  5. cassiomarques / jan 10 2009 1:31 am

    @Max e @Philipe, muito obrigado pelo toque. Era uma configuração besta no wordpress que eu precisava desmarcar.

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

%d blogueiros gostam disto: