Autotest Revisited

I'm currently in the process of setting up a Rails 2.3 stack from scratch, and a few things have changed since the last couple of projects I worked on were tooled up.

One thing which has certainly changed for better is binding rspec, ZenTest and Growl together, previously I posted on some work-arounds for missing messages, adding images, and various other bits ad-hoc. This functionality is now all produced by installing the autotest-growl gem which may also be found on github. Take a look at the readme.rdoc

Of interest to me in particular were changes to ~/.autotest

Mine was quite something previously,

#!/usr/bin/env ruby
# Symlink this to ~/.autotest
require 'autotest/redgreen'
require 'autotest/fsevent'

AUTOTEST_IMAGE_PATH = File.dirname(File.symlink?(__FILE__) ? File.readlink(__FILE__) : File.expand_path(__FILE__))

module Autotest::Growl
  def self.growl title, msg, img, pri=0, stick=""
    system "growlnotify -n autotest --image #{img.inspect} -p #{pri} -m #{msg.inspect} #{title.inspect} #{stick}"
  end

  Autotest.add_hook :ran_command do |autotest|
    filtered = autotest.results.grep(/\d+\s.*examples?/)
    output = filtered.empty? ? "" : filtered.last.slice(/(\d+)\s.*examples?,\s(\d+)\s.*failures?(?:,\s(\d+)\s.*pending)?/)
    if output =~ /[1-9]\sfailures?/
      growl "Test Results", "#{output}", "#{AUTOTEST_IMAGE_PATH}/fail.jpg"
    elsif output =~ /pending/
      growl "Test Results", "#{output}", "#{AUTOTEST_IMAGE_PATH}/pending.jpg"
    else
      growl "Test Results", "#{output}", "#{AUTOTEST_IMAGE_PATH}/ok.jpg"
    end
  end
end

Autotest.add_hook :initialize do |autotest|
  %w{.git .svn .hg .DS_Store ._* vendor}.each {|exception| autotest.add_exception(exception) }
  false

now replaced with

require 'autotest/growl'
require 'autotest/fsevent' #osx specific file changed event notification
Autotest::Growl::show_modified_files = true #which changes prompted the autospec run
Autotest::Growl::remote_notification = true #networked growl, to work-around disappearing notifications
Autotest.add_hook :initialize do |at|
  %w{.git .svn .hg .DS_Store ._* log}.each {|exception|at.add_exception(exception)}
end

The FSEvent gem is well worth a look if you develop on OSX 10.5 (Leopard), it switches autotest from polling your hard drive (i.e. thrashing) to working with the OS's event notification system. Design patterns strike again!

With these updates I gave an old project a spin to see what would happen, and voila, the specs ran as they should, coloured and all.

A particular error I was receiving before doing this update was

script/autospec 
(Not running features.  To run features in autotest, set AUTOFEATURE=true.)
(Not running features.  To run features in autotest, set AUTOFEATURE=true.)
loading autotest/rails_rspec
/Library/Ruby/Site/1.8/rubygems/custom_require.rb:31:in `gem_original_require': no such file to load -- autotest/redgreen (MissingSourceFile)
    from /Library/Ruby/Site/1.8/rubygems/custom_require.rb:31:in `require'
  …
    from /usr/bin/autotest:19:in `load'
    from /usr/bin/autotest:19
Unable to find autotest.  Please install ZenTest or fix your PATH

The culprit being redgreen, which can be uninstalled when using the new ZenTest.