Froze rails gems
[depot.git] / vendor / rails / actionpack / test / controller / filters_test.rb
diff --git a/vendor/rails/actionpack/test/controller/filters_test.rb b/vendor/rails/actionpack/test/controller/filters_test.rb
new file mode 100644 (file)
index 0000000..dafa344
--- /dev/null
@@ -0,0 +1,881 @@
+require 'abstract_unit'
+
+# FIXME: crashes Ruby 1.9
+class FilterTest < Test::Unit::TestCase
+  class TestController < ActionController::Base
+    before_filter :ensure_login
+    after_filter  :clean_up
+
+    def show
+      render :inline => "ran action"
+    end
+
+    private
+      def ensure_login
+        @ran_filter ||= []
+        @ran_filter << "ensure_login"
+      end
+
+      def clean_up
+        @ran_after_filter ||= []
+        @ran_after_filter << "clean_up"
+      end
+  end
+
+  class ChangingTheRequirementsController < TestController
+    before_filter :ensure_login, :except => [:go_wild]
+
+    def go_wild
+      render :text => "gobble"
+    end
+  end
+
+  class TestMultipleFiltersController < ActionController::Base
+    before_filter :try_1
+    before_filter :try_2
+    before_filter :try_3
+
+    (1..3).each do |i|
+      define_method "fail_#{i}" do
+        render :text => i.to_s
+      end
+    end
+
+    protected
+    (1..3).each do |i|
+      define_method "try_#{i}" do
+        instance_variable_set :@try, i
+        if action_name == "fail_#{i}"
+          head(404)
+        end
+      end
+    end
+  end
+
+  class RenderingController < ActionController::Base
+    before_filter :render_something_else
+
+    def show
+      @ran_action = true
+      render :inline => "ran action"
+    end
+
+    private
+      def render_something_else
+        render :inline => "something else"
+      end
+  end
+
+  class ConditionalFilterController < ActionController::Base
+    def show
+      render :inline => "ran action"
+    end
+
+    def another_action
+      render :inline => "ran action"
+    end
+
+    def show_without_filter
+      render :inline => "ran action without filter"
+    end
+
+    private
+      def ensure_login
+        @ran_filter ||= []
+        @ran_filter << "ensure_login"
+      end
+
+      def clean_up_tmp
+        @ran_filter ||= []
+        @ran_filter << "clean_up_tmp"
+      end
+
+      def rescue_action(e) raise(e) end
+  end
+
+  class ConditionalCollectionFilterController < ConditionalFilterController
+    before_filter :ensure_login, :except => [ :show_without_filter, :another_action ]
+  end
+
+  class OnlyConditionSymController < ConditionalFilterController
+    before_filter :ensure_login, :only => :show
+  end
+
+  class ExceptConditionSymController < ConditionalFilterController
+    before_filter :ensure_login, :except => :show_without_filter
+  end
+
+  class BeforeAndAfterConditionController < ConditionalFilterController
+    before_filter :ensure_login, :only => :show
+    after_filter  :clean_up_tmp, :only => :show
+  end
+
+  class OnlyConditionProcController < ConditionalFilterController
+    before_filter(:only => :show) {|c| c.instance_variable_set(:"@ran_proc_filter", true) }
+  end
+
+  class ExceptConditionProcController < ConditionalFilterController
+    before_filter(:except => :show_without_filter) {|c| c.instance_variable_set(:"@ran_proc_filter", true) }
+  end
+
+  class ConditionalClassFilter
+    def self.filter(controller) controller.instance_variable_set(:"@ran_class_filter", true) end
+  end
+
+  class OnlyConditionClassController < ConditionalFilterController
+    before_filter ConditionalClassFilter, :only => :show
+  end
+
+  class ExceptConditionClassController < ConditionalFilterController
+    before_filter ConditionalClassFilter, :except => :show_without_filter
+  end
+
+  class AnomolousYetValidConditionController < ConditionalFilterController
+    before_filter(ConditionalClassFilter, :ensure_login, Proc.new {|c| c.instance_variable_set(:"@ran_proc_filter1", true)}, :except => :show_without_filter) { |c| c.instance_variable_set(:"@ran_proc_filter2", true)}
+  end
+
+  class ConditionalOptionsFilter < ConditionalFilterController
+    before_filter :ensure_login, :if => Proc.new { |c| true }
+    before_filter :clean_up_tmp, :if => Proc.new { |c| false }
+  end
+
+  class EmptyFilterChainController < TestController
+    self.filter_chain.clear
+    def show
+      @action_executed = true
+      render :text => "yawp!"
+    end
+  end
+
+  class PrependingController < TestController
+    prepend_before_filter :wonderful_life
+    # skip_before_filter :fire_flash
+
+    private
+      def wonderful_life
+        @ran_filter ||= []
+        @ran_filter << "wonderful_life"
+      end
+  end
+
+  class SkippingAndLimitedController < TestController
+    skip_before_filter :ensure_login
+    before_filter :ensure_login, :only => :index
+
+    def index
+      render :text => 'ok'
+    end
+    
+    def public
+    end
+  end
+  
+  class SkippingAndReorderingController < TestController
+    skip_before_filter :ensure_login
+    before_filter :find_record
+    before_filter :ensure_login
+
+    private
+      def find_record
+        @ran_filter ||= []
+        @ran_filter << "find_record"
+      end
+  end
+
+  class ConditionalSkippingController < TestController
+    skip_before_filter :ensure_login, :only => [ :login ]
+    skip_after_filter  :clean_up,     :only => [ :login ]
+
+    before_filter :find_user, :only => [ :change_password ]
+
+    def login
+      render :inline => "ran action"
+    end
+
+    def change_password
+      render :inline => "ran action"
+    end
+
+    protected
+      def find_user
+        @ran_filter ||= []
+        @ran_filter << "find_user"
+      end
+  end
+
+  class ConditionalParentOfConditionalSkippingController < ConditionalFilterController
+    before_filter :conditional_in_parent, :only => [:show, :another_action]
+    after_filter  :conditional_in_parent, :only => [:show, :another_action]
+
+    private
+
+      def conditional_in_parent
+        @ran_filter ||= []
+        @ran_filter << 'conditional_in_parent'
+      end
+  end
+
+  class ChildOfConditionalParentController < ConditionalParentOfConditionalSkippingController
+    skip_before_filter :conditional_in_parent, :only => :another_action
+    skip_after_filter  :conditional_in_parent, :only => :another_action
+  end
+
+  class AnotherChildOfConditionalParentController < ConditionalParentOfConditionalSkippingController
+    skip_before_filter :conditional_in_parent, :only => :show
+  end
+
+  class ProcController < PrependingController
+    before_filter(proc { |c| c.instance_variable_set(:"@ran_proc_filter", true) })
+  end
+
+  class ImplicitProcController < PrependingController
+    before_filter { |c| c.instance_variable_set(:"@ran_proc_filter", true) }
+  end
+
+  class AuditFilter
+    def self.filter(controller)
+      controller.instance_variable_set(:"@was_audited", true)
+    end
+  end
+
+  class AroundFilter
+    def before(controller)
+      @execution_log = "before"
+      controller.class.execution_log << " before aroundfilter " if controller.respond_to? :execution_log
+      controller.instance_variable_set(:"@before_ran", true)
+    end
+
+    def after(controller)
+      controller.instance_variable_set(:"@execution_log", @execution_log + " and after")
+      controller.instance_variable_set(:"@after_ran", true)
+      controller.class.execution_log << " after aroundfilter " if controller.respond_to? :execution_log
+    end
+  end
+
+  class AppendedAroundFilter
+    def before(controller)
+      controller.class.execution_log << " before appended aroundfilter "
+    end
+
+    def after(controller)
+      controller.class.execution_log << " after appended aroundfilter "
+    end
+  end
+
+  class AuditController < ActionController::Base
+    before_filter(AuditFilter)
+
+    def show
+      render :text => "hello"
+    end
+  end
+
+  class AroundFilterController < PrependingController
+    around_filter AroundFilter.new
+  end
+
+  class BeforeAfterClassFilterController < PrependingController
+    begin
+      filter = AroundFilter.new
+      before_filter filter
+      after_filter filter
+    end
+  end
+
+  class MixedFilterController < PrependingController
+    cattr_accessor :execution_log
+
+    def initialize
+      @@execution_log = ""
+    end
+
+    before_filter { |c| c.class.execution_log << " before procfilter "  }
+    prepend_around_filter AroundFilter.new
+
+    after_filter  { |c| c.class.execution_log << " after procfilter " }
+    append_around_filter AppendedAroundFilter.new
+  end
+
+  class MixedSpecializationController < ActionController::Base
+    class OutOfOrder < StandardError; end
+
+    before_filter :first
+    before_filter :second, :only => :foo
+
+    def foo
+      render :text => 'foo'
+    end
+
+    def bar
+      render :text => 'bar'
+    end
+
+    protected
+      def first
+        @first = true
+      end
+
+      def second
+        raise OutOfOrder unless @first
+      end
+  end
+
+  class DynamicDispatchController < ActionController::Base
+    before_filter :choose
+
+    %w(foo bar baz).each do |action|
+      define_method(action) { render :text => action }
+    end
+
+    private
+      def choose
+        self.action_name = params[:choose]
+      end
+  end
+
+  class PrependingBeforeAndAfterController < ActionController::Base
+    prepend_before_filter :before_all
+    prepend_after_filter :after_all
+    before_filter :between_before_all_and_after_all
+
+    def before_all
+      @ran_filter ||= []
+      @ran_filter << 'before_all'
+    end
+
+    def after_all
+      @ran_filter ||= []
+      @ran_filter << 'after_all'
+    end
+
+    def between_before_all_and_after_all
+      @ran_filter ||= []
+      @ran_filter << 'between_before_all_and_after_all'
+    end
+    def show
+      render :text => 'hello'
+    end
+  end
+
+  class ErrorToRescue < Exception; end
+
+  class RescuingAroundFilterWithBlock
+    def filter(controller)
+      begin
+        yield
+      rescue ErrorToRescue => ex
+        controller.__send__ :render, :text => "I rescued this: #{ex.inspect}"
+      end
+    end
+  end
+
+  class RescuedController < ActionController::Base
+    around_filter RescuingAroundFilterWithBlock.new
+
+    def show
+      raise ErrorToRescue.new("Something made the bad noise.")
+    end
+
+  private
+    def rescue_action(exception)
+      raise exception
+    end
+  end
+
+  class NonYieldingAroundFilterController < ActionController::Base
+
+    before_filter :filter_one
+    around_filter :non_yielding_filter
+    before_filter :filter_two
+    after_filter :filter_three
+
+    def index
+      render :inline => "index"
+    end
+
+    #make sure the controller complains
+    def rescue_action(e); raise e; end
+
+    private
+
+      def filter_one
+        @filters  ||= []
+        @filters  << "filter_one"
+      end
+
+      def filter_two
+        @filters  << "filter_two"
+      end
+
+      def non_yielding_filter
+        @filters  << "zomg it didn't yield"
+        @filter_return_value
+      end
+
+      def filter_three
+        @filters  << "filter_three"
+      end
+
+  end
+
+  def test_non_yielding_around_filters_not_returning_false_do_not_raise
+    controller = NonYieldingAroundFilterController.new
+    controller.instance_variable_set "@filter_return_value", true
+    assert_nothing_raised do
+      test_process(controller, "index")
+    end
+  end
+
+  def test_non_yielding_around_filters_returning_false_do_not_raise
+    controller = NonYieldingAroundFilterController.new
+    controller.instance_variable_set "@filter_return_value", false
+    assert_nothing_raised do
+      test_process(controller, "index")
+    end
+  end
+
+  def test_after_filters_are_not_run_if_around_filter_returns_false
+    controller = NonYieldingAroundFilterController.new
+    controller.instance_variable_set "@filter_return_value", false
+    test_process(controller, "index")
+    assert_equal ["filter_one", "zomg it didn't yield"], controller.assigns['filters']
+  end
+
+  def test_after_filters_are_not_run_if_around_filter_does_not_yield
+    controller = NonYieldingAroundFilterController.new
+    controller.instance_variable_set "@filter_return_value", true
+    test_process(controller, "index")
+    assert_equal ["filter_one", "zomg it didn't yield"], controller.assigns['filters']
+  end
+
+  def test_empty_filter_chain
+    assert_equal 0, EmptyFilterChainController.filter_chain.size
+    assert test_process(EmptyFilterChainController).template.assigns['action_executed']
+  end
+
+  def test_added_filter_to_inheritance_graph
+    assert_equal [ :ensure_login ], TestController.before_filters
+  end
+
+  def test_base_class_in_isolation
+    assert_equal [ ], ActionController::Base.before_filters
+  end
+
+  def test_prepending_filter
+    assert_equal [ :wonderful_life, :ensure_login ], PrependingController.before_filters
+  end
+
+  def test_running_filters
+    assert_equal %w( wonderful_life ensure_login ), test_process(PrependingController).template.assigns["ran_filter"]
+  end
+
+  def test_running_filters_with_proc
+    assert test_process(ProcController).template.assigns["ran_proc_filter"]
+  end
+
+  def test_running_filters_with_implicit_proc
+    assert test_process(ImplicitProcController).template.assigns["ran_proc_filter"]
+  end
+
+  def test_running_filters_with_class
+    assert test_process(AuditController).template.assigns["was_audited"]
+  end
+
+  def test_running_anomolous_yet_valid_condition_filters
+    response = test_process(AnomolousYetValidConditionController)
+    assert_equal %w( ensure_login ), response.template.assigns["ran_filter"]
+    assert response.template.assigns["ran_class_filter"]
+    assert response.template.assigns["ran_proc_filter1"]
+    assert response.template.assigns["ran_proc_filter2"]
+
+    response = test_process(AnomolousYetValidConditionController, "show_without_filter")
+    assert_equal nil, response.template.assigns["ran_filter"]
+    assert !response.template.assigns["ran_class_filter"]
+    assert !response.template.assigns["ran_proc_filter1"]
+    assert !response.template.assigns["ran_proc_filter2"]
+  end
+
+  def test_running_conditional_options
+    response = test_process(ConditionalOptionsFilter)
+    assert_equal %w( ensure_login ), response.template.assigns["ran_filter"]
+  end
+
+  def test_running_collection_condition_filters
+    assert_equal %w( ensure_login ), test_process(ConditionalCollectionFilterController).template.assigns["ran_filter"]
+    assert_equal nil, test_process(ConditionalCollectionFilterController, "show_without_filter").template.assigns["ran_filter"]
+    assert_equal nil, test_process(ConditionalCollectionFilterController, "another_action").template.assigns["ran_filter"]
+  end
+
+  def test_running_only_condition_filters
+    assert_equal %w( ensure_login ), test_process(OnlyConditionSymController).template.assigns["ran_filter"]
+    assert_equal nil, test_process(OnlyConditionSymController, "show_without_filter").template.assigns["ran_filter"]
+
+    assert test_process(OnlyConditionProcController).template.assigns["ran_proc_filter"]
+    assert !test_process(OnlyConditionProcController, "show_without_filter").template.assigns["ran_proc_filter"]
+
+    assert test_process(OnlyConditionClassController).template.assigns["ran_class_filter"]
+    assert !test_process(OnlyConditionClassController, "show_without_filter").template.assigns["ran_class_filter"]
+  end
+
+  def test_running_except_condition_filters
+    assert_equal %w( ensure_login ), test_process(ExceptConditionSymController).template.assigns["ran_filter"]
+    assert_equal nil, test_process(ExceptConditionSymController, "show_without_filter").template.assigns["ran_filter"]
+
+    assert test_process(ExceptConditionProcController).template.assigns["ran_proc_filter"]
+    assert !test_process(ExceptConditionProcController, "show_without_filter").template.assigns["ran_proc_filter"]
+
+    assert test_process(ExceptConditionClassController).template.assigns["ran_class_filter"]
+    assert !test_process(ExceptConditionClassController, "show_without_filter").template.assigns["ran_class_filter"]
+  end
+
+  def test_running_before_and_after_condition_filters
+    assert_equal %w( ensure_login clean_up_tmp), test_process(BeforeAndAfterConditionController).template.assigns["ran_filter"]
+    assert_equal nil, test_process(BeforeAndAfterConditionController, "show_without_filter").template.assigns["ran_filter"]
+  end
+
+  def test_around_filter
+    controller = test_process(AroundFilterController)
+    assert controller.template.assigns["before_ran"]
+    assert controller.template.assigns["after_ran"]
+  end
+
+  def test_before_after_class_filter
+    controller = test_process(BeforeAfterClassFilterController)
+    assert controller.template.assigns["before_ran"]
+    assert controller.template.assigns["after_ran"]
+  end
+
+  def test_having_properties_in_around_filter
+    controller = test_process(AroundFilterController)
+    assert_equal "before and after", controller.template.assigns["execution_log"]
+  end
+
+  def test_prepending_and_appending_around_filter
+    controller = test_process(MixedFilterController)
+    assert_equal " before aroundfilter  before procfilter  before appended aroundfilter " +
+                 " after appended aroundfilter  after aroundfilter  after procfilter ",
+                 MixedFilterController.execution_log
+  end
+
+  def test_rendering_breaks_filtering_chain
+    response = test_process(RenderingController)
+    assert_equal "something else", response.body
+    assert !response.template.assigns["ran_action"]
+  end
+
+  def test_filters_with_mixed_specialization_run_in_order
+    assert_nothing_raised do
+      response = test_process(MixedSpecializationController, 'bar')
+      assert_equal 'bar', response.body
+    end
+
+    assert_nothing_raised do
+      response = test_process(MixedSpecializationController, 'foo')
+      assert_equal 'foo', response.body
+    end
+  end
+
+  def test_dynamic_dispatch
+    %w(foo bar baz).each do |action|
+      request = ActionController::TestRequest.new
+      request.query_parameters[:choose] = action
+      response = DynamicDispatchController.process(request, ActionController::TestResponse.new)
+      assert_equal action, response.body
+    end
+  end
+
+  def test_running_prepended_before_and_after_filter
+    assert_equal 3, PrependingBeforeAndAfterController.filter_chain.length
+    response = test_process(PrependingBeforeAndAfterController)
+    assert_equal %w( before_all between_before_all_and_after_all after_all ), response.template.assigns["ran_filter"]
+  end
+  
+  def test_skipping_and_limiting_controller
+    assert_equal %w( ensure_login ), test_process(SkippingAndLimitedController, "index").template.assigns["ran_filter"]
+    assert_nil test_process(SkippingAndLimitedController, "public").template.assigns["ran_filter"]
+  end
+
+  def test_skipping_and_reordering_controller
+    assert_equal %w( find_record ensure_login ), test_process(SkippingAndReorderingController, "index").template.assigns["ran_filter"]
+  end
+
+  def test_conditional_skipping_of_filters
+    assert_nil test_process(ConditionalSkippingController, "login").template.assigns["ran_filter"]
+    assert_equal %w( ensure_login find_user ), test_process(ConditionalSkippingController, "change_password").template.assigns["ran_filter"]
+
+    assert_nil test_process(ConditionalSkippingController, "login").template.controller.instance_variable_get("@ran_after_filter")
+    assert_equal %w( clean_up ), test_process(ConditionalSkippingController, "change_password").template.controller.instance_variable_get("@ran_after_filter")
+  end
+
+  def test_conditional_skipping_of_filters_when_parent_filter_is_also_conditional
+    assert_equal %w( conditional_in_parent conditional_in_parent ), test_process(ChildOfConditionalParentController).template.assigns['ran_filter']
+    assert_nil test_process(ChildOfConditionalParentController, 'another_action').template.assigns['ran_filter']
+  end
+
+  def test_condition_skipping_of_filters_when_siblings_also_have_conditions
+    assert_equal %w( conditional_in_parent conditional_in_parent ), test_process(ChildOfConditionalParentController).template.assigns['ran_filter'], "1"
+    assert_equal nil, test_process(AnotherChildOfConditionalParentController).template.assigns['ran_filter']
+    assert_equal %w( conditional_in_parent conditional_in_parent ), test_process(ChildOfConditionalParentController).template.assigns['ran_filter']
+  end
+
+  def test_changing_the_requirements
+    assert_equal nil, test_process(ChangingTheRequirementsController, "go_wild").template.assigns['ran_filter']
+  end
+
+  def test_a_rescuing_around_filter
+    response = nil
+    assert_nothing_raised do
+      response = test_process(RescuedController)
+    end
+
+    assert response.success?
+    assert_equal("I rescued this: #<FilterTest::ErrorToRescue: Something made the bad noise.>", response.body)
+  end
+
+  private
+    def test_process(controller, action = "show")
+      request = ActionController::TestRequest.new
+      request.action = action
+      controller.process(request, ActionController::TestResponse.new)
+    end
+end
+
+
+
+class PostsController < ActionController::Base
+  def rescue_action(e); raise e; end
+
+  module AroundExceptions
+    class Error < StandardError ; end
+    class Before < Error ; end
+    class After < Error ; end
+  end
+  include AroundExceptions
+
+  class DefaultFilter
+    include AroundExceptions
+  end
+
+  module_eval %w(raises_before raises_after raises_both no_raise no_filter).map { |action| "def #{action}; default_action end" }.join("\n")
+
+  private
+    def default_action
+      render :inline => "#{action_name} called"
+    end
+end
+
+class ControllerWithSymbolAsFilter < PostsController
+  around_filter :raise_before, :only => :raises_before
+  around_filter :raise_after, :only => :raises_after
+  around_filter :without_exception, :only => :no_raise
+
+  private
+    def raise_before
+      raise Before
+      yield
+    end
+
+    def raise_after
+      yield
+      raise After
+    end
+
+    def without_exception
+      # Do stuff...
+      1 + 1
+
+      yield
+
+      # Do stuff...
+      1 + 1
+    end
+end
+
+class ControllerWithFilterClass < PostsController
+  class YieldingFilter < DefaultFilter
+    def self.filter(controller)
+      yield
+      raise After
+    end
+  end
+
+  around_filter YieldingFilter, :only => :raises_after
+end
+
+class ControllerWithFilterInstance < PostsController
+  class YieldingFilter < DefaultFilter
+    def filter(controller)
+      yield
+      raise After
+    end
+  end
+
+  around_filter YieldingFilter.new, :only => :raises_after
+end
+
+class ControllerWithFilterMethod < PostsController
+  class YieldingFilter < DefaultFilter
+    def filter(controller)
+      yield
+      raise After
+    end
+  end
+
+  around_filter YieldingFilter.new.method(:filter), :only => :raises_after
+end
+
+class ControllerWithProcFilter < PostsController
+  around_filter(:only => :no_raise) do |c,b|
+    c.instance_variable_set(:"@before", true)
+    b.call
+    c.instance_variable_set(:"@after", true)
+  end
+end
+
+class ControllerWithNestedFilters < ControllerWithSymbolAsFilter
+  around_filter :raise_before, :raise_after, :without_exception, :only => :raises_both
+end
+
+class ControllerWithAllTypesOfFilters < PostsController
+  before_filter :before
+  around_filter :around
+  after_filter :after
+  around_filter :around_again
+
+  private
+  def before
+    @ran_filter ||= []
+    @ran_filter << 'before'
+  end
+
+  def around
+    @ran_filter << 'around (before yield)'
+    yield
+    @ran_filter << 'around (after yield)'
+  end
+
+  def after
+    @ran_filter << 'after'
+  end
+
+  def around_again
+    @ran_filter << 'around_again (before yield)'
+    yield
+    @ran_filter << 'around_again (after yield)'
+  end
+end
+
+class ControllerWithTwoLessFilters < ControllerWithAllTypesOfFilters
+  skip_filter :around_again
+  skip_filter :after
+end
+
+class YieldingAroundFiltersTest < Test::Unit::TestCase
+  include PostsController::AroundExceptions
+
+  def test_filters_registering
+    assert_equal 1, ControllerWithFilterMethod.filter_chain.size
+    assert_equal 1, ControllerWithFilterClass.filter_chain.size
+    assert_equal 1, ControllerWithFilterInstance.filter_chain.size
+    assert_equal 3, ControllerWithSymbolAsFilter.filter_chain.size
+    assert_equal 6, ControllerWithNestedFilters.filter_chain.size
+    assert_equal 4, ControllerWithAllTypesOfFilters.filter_chain.size
+  end
+
+  def test_base
+    controller = PostsController
+    assert_nothing_raised { test_process(controller,'no_raise') }
+    assert_nothing_raised { test_process(controller,'raises_before') }
+    assert_nothing_raised { test_process(controller,'raises_after') }
+    assert_nothing_raised { test_process(controller,'no_filter') }
+  end
+
+  def test_with_symbol
+    controller = ControllerWithSymbolAsFilter
+    assert_nothing_raised { test_process(controller,'no_raise') }
+    assert_raise(Before) { test_process(controller,'raises_before') }
+    assert_raise(After) { test_process(controller,'raises_after') }
+    assert_nothing_raised { test_process(controller,'no_raise') }
+  end
+
+  def test_with_class
+    controller = ControllerWithFilterClass
+    assert_nothing_raised { test_process(controller,'no_raise') }
+    assert_raise(After) { test_process(controller,'raises_after') }
+  end
+
+  def test_with_instance
+    controller = ControllerWithFilterInstance
+    assert_nothing_raised { test_process(controller,'no_raise') }
+    assert_raise(After) { test_process(controller,'raises_after') }
+  end
+
+  def test_with_method
+    controller = ControllerWithFilterMethod
+    assert_nothing_raised { test_process(controller,'no_raise') }
+    assert_raise(After) { test_process(controller,'raises_after') }
+  end
+
+  def test_with_proc
+    controller = test_process(ControllerWithProcFilter,'no_raise')
+    assert controller.template.assigns['before']
+    assert controller.template.assigns['after']
+  end
+
+  def test_nested_filters
+    controller = ControllerWithNestedFilters
+    assert_nothing_raised do
+      begin
+        test_process(controller,'raises_both')
+      rescue Before, After
+      end
+    end
+    assert_raise Before do
+      begin
+        test_process(controller,'raises_both')
+      rescue After
+      end
+    end
+  end
+
+  def test_filter_order_with_all_filter_types
+    controller = test_process(ControllerWithAllTypesOfFilters,'no_raise')
+    assert_equal 'before around (before yield) around_again (before yield) around_again (after yield) around (after yield) after',controller.template.assigns['ran_filter'].join(' ')
+  end
+
+  def test_filter_order_with_skip_filter_method
+    controller = test_process(ControllerWithTwoLessFilters,'no_raise')
+    assert_equal 'before around (before yield) around (after yield)',controller.template.assigns['ran_filter'].join(' ')
+  end
+
+  def test_first_filter_in_multiple_before_filter_chain_halts
+    controller = ::FilterTest::TestMultipleFiltersController.new
+    response = test_process(controller, 'fail_1')
+    assert_equal ' ', response.body
+    assert_equal 1, controller.instance_variable_get(:@try)
+    assert controller.instance_variable_get(:@before_filter_chain_aborted)
+  end
+
+  def test_second_filter_in_multiple_before_filter_chain_halts
+    controller = ::FilterTest::TestMultipleFiltersController.new
+    response = test_process(controller, 'fail_2')
+    assert_equal ' ', response.body
+    assert_equal 2, controller.instance_variable_get(:@try)
+    assert controller.instance_variable_get(:@before_filter_chain_aborted)
+  end
+
+  def test_last_filter_in_multiple_before_filter_chain_halts
+    controller = ::FilterTest::TestMultipleFiltersController.new
+    response = test_process(controller, 'fail_3')
+    assert_equal ' ', response.body
+    assert_equal 3, controller.instance_variable_get(:@try)
+    assert controller.instance_variable_get(:@before_filter_chain_aborted)
+  end
+
+  protected
+    def test_process(controller, action = "show")
+      request = ActionController::TestRequest.new
+      request.action = action
+      controller.process(request, ActionController::TestResponse.new)
+    end
+end