Rails tip #2: Faking DATA in tests

Ruby gives you access to the raw text after an __END__ statement in the currently running file through the DATA IO object.

Sometimes you'd like to use DATA in a test. You'll find it works when you run the test individually but then fails when you run the whole suite. (Remember DATA comes from $0, the currently running file, only.)

We've found a nice way to fake it in the rubyforge gem: read __FILE__ instead, then split the results.

Here's an example of the technique in use, functionally testing a wiki parser we've been tinkering with. It can often be painful to work with metaprogrammed tests like this, but on balance, we like the results here:

require 'test_helper'

class TestParser < Test::Unit::TestCase
  EXAMPLES = /={80}\n/m
  PARTS    = /-{80}\n/m

  # Faking data = DATA.read
  data = File.read(__FILE__).split('__END__').last

  data.split(EXAMPLES).map { |example| example.split(PARTS) }.each do |comment, markup, html|
    define_method "test_#{comment.strip.downcase.gsub(/\W/, '_')}" do
      assert_equal html, Parser.new.parse(markup).result.to_html
    end
  end
end

__END__
A single wiki word should be linked and wrapped in a paragraph.
--------------------------------------------------------------------------------
WikiWord
--------------------------------------------------------------------------------
<p><a href="WikiWord">WikiWord</a></p>
================================================================================
Two wiki words on separate lines should become two paragraphs
--------------------------------------------------------------------------------
WikiWord
WikiWord
--------------------------------------------------------------------------------
<p><a href="WikiWord">WikiWord</a></p>
<p><a href="WikiWord">WikiWord</a></p>

5 Rails tips

Each day this week, Joachim and I will post something we've learned in our time programming together. It's fun to do, and we might just win something as well.

So far, we've written:

  1. Reloadable custom FormBuilder
  2. Faking DATA in tests