[rspec-users] Rails matcher render_template is wrong when using GetText, looking for flexible solution

David Chelimsky dchelimsky at gmail.com
Mon May 28 09:41:06 EDT 2007


On 5/28/07, Daniel Sandbecker <daniel.sandbecker at gmail.com> wrote:
> I have a problem with a mismatch between RSpec Rails and the actual
> behavior when using GetText, and would be glad for suggestions how to
> best solve this.
>
> When using GetText a failure is reported for the following simplified
> specification:
>
> describe SamplesController, "when requesting /samples" do
>   it "should render index " do
>     get 'index'
>     response.should render_template("index")
>   end
> end
>
> The result is:
>
> SamplesController when requesting /samples
> - should render index (FAILED - 1)
>
> 1)
> 'SamplesController when requesting /samples should render index' FAILED
> expected "index", got "index_en"
>
> When I run the application, the template index.rhtml do get rendered
> (I don't have any "index_en.rhtml").
>
> The source of this mismatch is that GetText overrides
> ActionView::Base.render_file, testing each possible localized template
> path and passes the first existing path to the original render_file
> method :
>
> return render_file_without_locale(localized_path, use_full_path,
> local_assigns) if file_exists? localized_path
>
> This line always evaluates to true in RSpec context, but to false in
> the application.
>
> After a lot of digging  I found out that RspecOnRails overrides
> file_exists? with a stub when integrate_views is not set
> (lib/spec/rails/dsl/behaviour/controller.rb:57):
>
> @template.stub!(:file_exists?).and_return(true)
>
>
>
> Now I'm not sure what would be the best solution.
>
> Since I know about this, I could simply add the same extension as
> GetText does to the expected rendered view path:
>
> response.should render_template("index" + "_" + GetText.locale.to_general)
>
> But adding this to every check would be ugly and not very DRY.
>
> I've tried to override the render_template matcher in my SpecHelper
> with a method doing the addition before passing it on to the matcher.
>
> module Spec::Rails::Matchers
>   alias render_template_without_gettext_fix render_template
>   def render_template(path)
>         path += "_" + GetText.locale.to_general
>         render_template_without_gettext_fix(path)
>   end
> end
>
> But that breaks any spec that calls integrate_views. And I can't see
> how I can check the status of integrate_views in this override, since
> it doesn't have access to a controller instance. (My Ruby skills are
> not very advanced. And the code I've read hunting this problem down
> has made me dizzy.)
>
> What I (think I) would like to achieve is some kind of check on each
> Controller instance before the specs are run, and overriding
> render_template if necessary. Is this possible/reasonable?

Not sure if this is the best solution, but you should be able to do
this with the current trunk (doesn't work before that due to a bug)
like this:

#in spec_helper.rb
Spec::Runner.configure do |config|
  config.before(:each) do
    if @using_gettext
      #redefine render_template
    end
  end
end

# in samples_controller_spec.rb
describe SamplesController, "when requesting /samples" do
 prepend_before(:each) do
   @using_gettext = true
 end
 it "should render index " do
   get 'index'
   response.should render_template("index")
 end
end

>
> Maybe I'm just stupid. Should I care about this error, or simply not
> use "render_template" in isolated controller tests?

I would care about it. This specifies what template should be
rendered, which is something you want.

>
> I'm thankful for any advice!
>
> /Daniel
>
> RSpec 1.0.2
> Spec::Rails 1.0.2
> Rails 1.2.2
> Ruby-GetText 1.9.0 (MsWin)
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users
>


More information about the rspec-users mailing list