Using simply_helpful with rspec controller tests

Rspec currently doesn't play well on Edge Rails with the simply_helpful plugin.

The cause

simply_helpful plugin hook (init.rb):

require 'simply_helpful'
ActionController::Base.send :include, SimplyHelpful::RecordIdentificationHelper
ActionController::Base.helper SimplyHelpful::RecordIdentificationHelper, SimplyHelpful::RecordTagHelper

Rspec's ActionController::Base definition (lib/extensions/action_controller/base.rb):

module ActionController
  class Base
  end
end

ActionController::Base is stripped from all modules included with the

ActionController::Base.send :include, SomeModule

syntax.

Monkey patch to fix

Include in spec/spec_helper.rb, before your Test::Rails::TestCase definition:

module Spec
  module Rails
    class ControllerContext < Rails::Context
        module ContextEvalInstanceMethods
          def setup_extra
            (class << @controller; self; end).class_eval do
              include ControllerInstanceMethods
            end
            @controller.integrate_views! if @integrate_views
            @controller.session = session

            #extend the controller instance with simply_helpful modules
            @controller.extend SimplyHelpful::RecordIdentificationHelper
            @controller.class.helper SimplyHelpful::RecordIdentificationHelper, SimplyHelpful::RecordTagHelper
          end          
        end        
    end
  end
end    

Running controller/view specifications using simplyhelpful helper methods, such as domid(), should not raise NoMethodErrors anymore.

Inline RJS in respond_to blocks

This snippet chokes (see comments) when referenced from a controller specification in isolation mode:

 #@language is set in a before_filter
  def create
    @account.supported_languages << @language

    #@language != nil
    respond_to do |format|
      format.js { #@language != nil 
                  render :update do |page|
                    #@language is nil
                    page.replace( dom_id( @language ), :partial => 'shared/admin/language', :locals => { :language => @language  } )
                    page.visual_effect :highlight, dom_id( @language )
                    page.call('Marmalade.Messaging.flash', 'success', "Added language %s" / @language.to_s)
                  end }
      format.xml { @account.languages.to_xml }
    end
  end

Explicitly integrating views with

 integrate_views

properly instantiates a JavaScriptGenerator object, thus preserving controller instance variables within the render :update block.

Any thoughts on this behaviour, or is inline RJS in respond_to blocks generally frowned upon?


About this entry