From a0c677c8e630fb4681153290494ae7abfb1675a2 Mon Sep 17 00:00:00 2001
From: Jeremy Kemper <jeremy@bitsweat.net>
Date: Fri, 22 Sep 2006 03:41:03 +0000
Subject: Filters overhaul including meantime filter support for around
 filters. Closes #5949.

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@5163 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
---
 actionpack/test/active_record_unit.rb      |   1 +
 actionpack/test/controller/filters_test.rb | 249 +++++++++++++++++++++++++++--
 2 files changed, 235 insertions(+), 15 deletions(-)

(limited to 'actionpack/test')

diff --git a/actionpack/test/active_record_unit.rb b/actionpack/test/active_record_unit.rb
index 2555eb7c1a..02cf3f707d 100644
--- a/actionpack/test/active_record_unit.rb
+++ b/actionpack/test/active_record_unit.rb
@@ -106,6 +106,7 @@ class ActiveRecordTestCase < Test::Unit::TestCase
   private
     # If things go wrong, we don't want to run our test cases. We'll just define them to test nothing.
     def abort_tests
+      $stderr.puts 'No Active Record connection, aborting tests.'
       self.class.public_instance_methods.grep(/^test./).each do |method|
         self.class.class_eval { define_method(method.to_sym){} }
       end
diff --git a/actionpack/test/controller/filters_test.rb b/actionpack/test/controller/filters_test.rb
index d92143e41d..a8bb11f7eb 100644
--- a/actionpack/test/controller/filters_test.rb
+++ b/actionpack/test/controller/filters_test.rb
@@ -198,15 +198,6 @@ class FilterTest < Test::Unit::TestCase
     end
   end
 
-  class BadFilterController < ActionController::Base
-    before_filter 2
-    
-    def show() "show" end
-    
-    protected
-      def rescue_action(e) raise(e) end
-  end
-
   class AroundFilterController < PrependingController
     around_filter AroundFilter.new
   end
@@ -336,19 +327,20 @@ class FilterTest < Test::Unit::TestCase
     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_bad_filter
-    assert_raises(ActionController::ActionControllerError) { 
-      test_process(BadFilterController)
-    }
+    bad_filter_controller = Class.new(ActionController::Base)
+    assert_raises(ActionController::ActionControllerError) do
+      bad_filter_controller.before_filter 2
+    end
   end
-  
+
   def test_around_filter
     controller = test_process(AroundFilterController)
     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"]
@@ -408,3 +400,230 @@ class FilterTest < Test::Unit::TestCase
       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.assigns['before'] = true
+    b.call
+    c.assigns['after'] = true
+  end
+end
+
+class ControllerWithWrongFilterType < PostsController
+  around_filter lambda { yield }, :only => :no_raise
+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 1, ControllerWithWrongFilterType.filter_chain.size
+    assert_equal 6, ControllerWithNestedFilters.filter_chain.size
+    assert_equal 4, ControllerWithAllTypesOfFilters.filter_chain.size
+  end
+
+  def test_wrong_filter_type
+    assert_raise(ActionController::ActionControllerError) do
+      test_process(ControllerWithWrongFilterType,'no_raise')
+    end
+  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
+
+  protected
+    def test_process(controller, action = "show")
+      request = ActionController::TestRequest.new
+      request.action = action
+      controller.process(request, ActionController::TestResponse.new)
+    end
+end
-- 
cgit v1.2.3