Testing Helpers in Rails

Posted by Peter Donald Wed, 13 Jun 2007 14:01:00 GMT

It can be useful at times to unit test helpers to make sure they generate correct html. It is not obvious how to do this at first. So far I have been testing my helper by defining a class “MyClass” at the top of my unit test and including all the appropriate modules. I also need to define a url_for method if I ever want to test helpers that generate links.

The code follows (Replace MyHelper with your appropriate helper class);

class MyClass
  include ERB::Util
  include ActionView::Helpers::TagHelper
  include ActionView::Helpers::UrlHelper
  include MyHelper

  def url_for(options)
    ActionController::Routing::Routes.reload if ActionController::Routing::Routes.empty?
    generated_path, extra_keys = ActionController::Routing::Routes.generate_extras(options, {})
    generated_path
  end
end

Then in my tests I do something like;

def test_revision_link
  assert_equal(
    "<a href=\"http://svn.sourceforge.net/viewvc/jikesrvm?view=rev&amp;revision=22\">22</a>", 
    MyClass.new.revision_link(22))
end

Seems easy enough to do in retrospect but things usually do.

Posted in  | 3 comments | no trackbacks

Enhanced Rails Plugin to Validate (X)HTML and CSS

Posted by Peter Donald Wed, 09 May 2007 05:17:00 GMT

It feels like forever ago that I was last working with ruby on rails. But I am back hacking away at a few rails and I slowly getting more familiarity with ruby itself rather than just using it as part of the rails platform.

Something I have wanted to do for a long time is automagically validate content such as (X)HTML, CSS, atom feeds etc that is generated by the web application. A while ago I put together the assert-valid-asset plugin that allowed you to assert (in functional tests) that the content generated is valid. However you still had to explicitly call the assert.

So recently I enhanced the plugin so that it can automatically validate generated content when configured to do so. To configure auto validation you need to set a class variable in Test::Unit::TestCase via code such as;

    class Test::Unit::TestCase
      self.auto_validate = true
    end

Then anytime content is generated in tests (such as via get and post methods) it will check the mime type of the content. If the content has a mime type of ‘text/html’ or ‘text/xhtml’ it will pass it to the ‘assert_valid_markup’ method. If the content is ‘text/css’ then it will be validated by the ‘assert_valid_css’ method.

Of course you may have tests that generate invalid (X)HTML or CSS (to work with specific unnamed browsers) and you may want to exclude these tests from the automatic content validation. This can be done by adding the test symbol to the exclude list or alternatively by adding the desired test symbols to an include list. Both of the following examples have identical behavior;

Example 1:
    class FooControllerTest < Test::Unit::TestCase
      ...
      self.auto_validate_excludes = [:test_foo,:test_bar]

      def test_foo; ... ; end
      def test_bar; ... ; end
      def test_baz; ... ; end
    end
Example 2:
    class FooControllerTest < Test::Unit::TestCase
      ...
      self.auto_validate_includes = [:test_baz]

      def test_foo; ... ; end
      def test_bar; ... ; end
      def test_baz; ... ; end
    end

You can grab it from subversion at;

http://www.realityforge.org/svn/code/assert-valid-asset/trunk/

The original article describing the plugin is here .

Posted in  | no comments | no trackbacks

Eyelook: Rails photo gallery

Posted by Peter Donald Fri, 21 Apr 2006 04:55:00 GMT

Eyelook is a photo gallery I created over a weekend when I was home sick. It is amazing how productive rails can make you because within 8 hours I had the code in place and had set it up on my personal web server.

Very little of that time was spent coding – most of it was spent working on re-arranging the xhtml+css or figuring out how to go about Loading Binary Data into Rails Fixtures.

Every eyelook application has a set of users who have a list of albums with pictures. The image data is stored in the database and cached on the filesystem on demand. This way a backup of the database backs up the complete system.

An example of users page that lists galleries is

You can select one of these galleries and it will bring up a list of images such as

From there you can either download the original or can view a larger lightbox style image

The admin section is not as sexy but it is functional.

You can grab the source from subversion via the following command. Read the README.txt for installation instructions.

svn co http://www.realityforge.org/svn/code/eyelook/trunk eyelook

Posted in  | 8 comments | no trackbacks

Loading Binary Data into Rails Fixtures

Posted by Peter Donald Wed, 05 Apr 2006 21:50:00 GMT

Loading image data into fixtures was a chore until recently as I had been using separate rake tasks to do the job. The following code demonstrates how easy it is to load binary data such as images into the fixtures via standard mechanisms. It loads some image data from within the $RAILS_ROOT/test/fixtures/ directory and puts it in database.

<%
def fixture_data(name)
  render_binary("#{RAILS_ROOT}/test/fixtures/#{name}")
end

def render_binary(filename)
  data = File.open(filename,'rb').read
  "!binary | #{[data].pack('m').gsub(/\n/,"\n    ")}\n"
end
%>
picture_data_1:
  id: 1
  picture_id: 1
  content_type: 'image/jpg'
  data: <%= fixture_data("picture_data_1.jpg") %>
picture_data_2:
  id: 2
  picture_id: 2
  content_type: 'image/gif'
  data: <%= fixture_data("picture_data_2.gif") %>

If you do not use two spaces as your indent then you will need to alter the line in render_binary(filename) that replaces newline so that every newline is replaced with two indents.

Easy peasy!

Update on 16th April 2006

It turns out that it was not as easy peasy under postgres as the driver did not know it had to escape the data as binary as fixtures don’t actually load the column type. The simplest hack around it is to add in the following bit of code somewhere that just patches the driver if a 0 is in the data. This may not always work but it works with my test data so that is good enough for me at the moment.

class ActiveRecord::ConnectionAdapters::PostgreSQLAdapter < ActiveRecord::ConnectionAdapters::AbstractAdapter
  def quote(value, column = nil)
    if (value.kind_of?(String) && column && column.type == :binary) || (value.kind_of?(String) && value.include?(0))
      "'#{escape_bytea(value)}'"
    else
      super
    end
  end
end

Posted in  | Tags , , ,  | 5 comments | 1 trackback

Rails Plugin to Help Debug Views

Posted by Peter Donald Mon, 20 Mar 2006 03:02:00 GMT

The debug_view_helper plugin was developed to make it easy to add debug information into your views. It was derived from techniques described in HowtoDebugViews and it makes it possible to expose the followng following debug data;

  • Request Parameters
  • Session Variables
  • Flash Variables
  • Assigned Template Variables

Typically you add code such as the following to the bottom of your layout that exposes the debug button in development mode.

<% if RAILS_ENV == 'development' %>
<center>
  <button onclick="show_debug_popup(); return false;">
    Show debug popup
  </button>
</center>
<%= debug_popup %>
<% end %>

You can grab the plugin from subversion at;

http://www.realityforge.org/svn/code/debug-view-helper/trunk/

Update: Added the ability to add inline debug information via the following. Suggestion by John Dell.

<% if RAILS_ENV == 'development' %>
<%= debug_inline %>
<% end %>

Posted in  | Tags ,  | 2 comments | no trackbacks

Older posts: 1 2 3 4