Generic Fixture Selection

I have done a lot of generic test writing in the last months, and one thing that always resurfaced was:

item = send(@obj.class.to_s.underscore.pluralize,:one)
item = send(@item_name.to_s.pluralize.:one)
...

What does it do ? It load the fixture :one for this objects class, since i always keep a fixture :one and :two around to make generic tests less painful. But all this send madness was unreadable, so i factored out some fixture calling.

#spec/spec_helper.rb OR test/test_helper.rb

#helper for generic fixture calling
#fixture 'user','one' = users('one')
#fixture @user,'one' = users('one')
#fixture User,'one' = users('one')
def fixture(singular,name)
  klas = input_to_class(singular)
  fixture = find_fixture(klas,name)
  raise "fixtures for #{klas} not loaded!" unless fixture
  fixture
end

def find_fixture(klas,name)
  table = klas.to_s.underscore.pluralize
  return send(table,name) if respond_to? table
  false
end

def input_to_class(val)
  return val if val.kind_of? Class
  return val.class if val.kind_of? ActiveRecord::Base
  return val.to_s.classify.constantize
end

Fixing upadtepo, Duplicated Messages

So far i found 2 causes of duplicated messages (duplicate message definition) when updating po files(rake updatepo)

  1. Subclassing — hard to fix, official manual says: ” write a model per a file(modelname.rb)”, which helped me really…not.. adding common columns id/created_at/updated_at to untranslated colums can help
      GetText::ActiveRecordParser.init(
        :untranslate_columns => %w[id created_at updated_at user_id]
      ) 
    

    You can also limit the classes that will be parsed with :activerecord_classes = [‘name’], which will be used like current_class =~ /class.*name /, so one could add wildcards and stuff.

  2. Observers: deactivate them in environment.rb while updating

While trying through these options, remember to always clenup or delete your old pot file, or updatepo can never succeed.

BTW: never try to use :use_classes => false,

Include all Helpers for Testing

When your helpers use each other, or your view tests use many, it gets frustrating to include them by hand…
This will load all helpers from app/helpers dir and include them!
Happy, stress-free testing!

def include_helpers
  Dir.glob("#{RAILS_ROOT}/app/helpers/*_helper.rb").each do |file|
    helper = File.basename(file).sub('.rb','').camelcase.constantize
    include helper
  end
end

Your Controller/View/Helper test would look like this:

describe MoviesHelper do
  include_helpers
  ...
end

Getting all other helpers(e.g. from helpers/admin is more complicated, but surely possible…)

inside_layout Broken in Rails 2.1

My good old friend for nested layouts, inside_layout

def inside_layout(layout, &block)
  layout = layout.include?('/') ? layout : "layouts/#{layout}"
  concat(@template.render_file(layout, true,
    '@content_for_layout' => capture(&block)), block.binding)
end

suddenly stopped to work, and since i am so grateful for his long months of service, he got replaced by the next best thing 😉

<% @content_for_layout = capture do %>
...some text or html...
<%= render :file=>'layouts/application', :content_for_layout => @content_for_layout %>
 

Fixing GetText Gem

Update:Fast Gettext gem has resolved all major problems of GetText 😉

Update: gettext 1.92.0 has fixed this issue, update if you can…

Just got a surprising:
NoMethodError (undefined method `file_exists?’ for File:Class):
gettext/rails.rb:281

281c281
<       return render_file_without_locale(localized_path, use_full_path, local_assigns) if file_exists?(localized_path)
---
>       return render_file_without_locale(localized_path, use_full_path, local_assigns) if (respond_to?(:finder) ? finder.file_exists?(localized_path) : file_exists?(localized_path))

put it in a gettext.patch and then:

sudo patch /usr/lib/ruby/gems/1.8/gems/gettext-1.91.0/lib/gettext/rails.rb < gettext.patch

Cause of failure: file_exists?(=cached checking if a file exists) was moved to finder in Rails 2.1
Alternatively one could monkeypatch rails to make it work for Rails 2.1