RSpec/Textmate Pro-Tip

Posted by Rick DeNatale Wed, 23 Sep 2009 12:34:00 GMT

I often need to output debugging info in specs when something just isn't working. No sweat, just put in a puts or two, and run the spec.

Of course I'm usually doing this in Textmate using the RSpec bundle, which displays the results in a nice window formatted with html.

RSpecFormattedResults

But that causes problems with my debugging output

Bad Puts Format

The problem is that the puts output is just raw text so the HTML formatter ignores line breaks.

At one of the Radiant hack fests, either John Long or Adam Williams taught this old dog a simple new trick. The suggestion was to define a new Kernel#rputs method as a wrapper for puts which 'wraps' the arguments in an html <pre> tag. Then just call rputs (the r is for rspec of course) in the spec and or code under test.

Good Rputs Format

This works great as long as you run the specs under RSpec. But if you run them in the shell you see something like this:

$ spec spec/ri_cal/bugreports_spec.rb <pre> Booga booga </pre> <pre> this should be another line </pre> ....... Finished in 0.525324 seconds 7 examples, 0 failures

I've been putting up with this minor annoyance for a while, but this morning it struck me that I could define rputs conditionally depending on whether the spec was being run in Textmate or not. The trick is that Textmate defines one or more environment variables whose name starts with 'TM_'. So, without further ado, here's the new fragment from my spec_helper.rb:

  module Kernel
    if ENV.keys.find {|env_var| env_var.match(/^TM_/)}
      def rputs(*args)
        puts( *["<pre>", args.collect {|a| CGI.escapeHTML(a.to_s)}, "</pre>"])
      end
    else
      alias_method :rputs, :puts
    end
  end

With this change, running in the shell now looks like this:

$ spec spec/ri_cal/bugreports_spec.rb Booga booga this should be another line ....... Finished in 0.348086 seconds 7 examples, 0 failures

A nice refinement to my bag of tricks!

Update 27 Sept 2009

One slight change. I notice that String#start_with? only exists in Ruby 1.8.7, 1.9 and is apparently also defined the activesupport gem for <1.8.7. I changed the spec helper to use a regular expression match instead which works in all cases.


Trackbacks

Use the following link to trackback from your own site:
http://talklikeaduck.denhaven2.com/trackbacks?article_id=576

Comments

  1. Mark Wilden about 5 hours later:

    It would be great if something like this was combined with my lll gem http://github.com/mwilden/lll/network, which labels debug output. You do



    lll{'user.followers.first.gamername'}
    

    and you get this output on the console and in the log:


    user.followers.first.gamername = "Mark Wilden"
    

    as well as the time and the file location. It also prints its output in reverse video.

  2. Rick DeNatale about 5 hours later:

    And perhaps with this:

    http://blog.thinkrelevance.com/2009/9/23/quick-and-easy-logging-with-logbuddy

    There must be something in the air today!

  3. Dr Nic 2 days later:

    Thanks for this helper Rick; I’ve cursed many times for the lack of a simple “just please print out this object’s #inspect dump nicely?!?” helper many times, but never got off my arse to write it. This is now in my default spec_helper.rb for all new projects.