Skip to content

Commit

Permalink
Create new ActionController::Middleware class that will work as a nor…
Browse files Browse the repository at this point in the history
…mal Rack middleware.

  * This initial implementation is a bit hackish, but it uses a normal middleware API
    so it's future-proof when we improve the internals.
  • Loading branch information
wycats committed Aug 26, 2009
1 parent 78129b1 commit 9408fcd
Show file tree
Hide file tree
Showing 9 changed files with 166 additions and 110 deletions.
1 change: 0 additions & 1 deletion actionpack/lib/abstract_controller/base.rb
Expand Up @@ -89,7 +89,6 @@ def process(action)
end end


process_action(action_name) process_action(action_name)
self
end end


private private
Expand Down
1 change: 1 addition & 0 deletions actionpack/lib/action_controller.rb
Expand Up @@ -3,6 +3,7 @@ module ActionController
autoload :ConditionalGet, "action_controller/metal/conditional_get" autoload :ConditionalGet, "action_controller/metal/conditional_get"
autoload :HideActions, "action_controller/metal/hide_actions" autoload :HideActions, "action_controller/metal/hide_actions"
autoload :Metal, "action_controller/metal" autoload :Metal, "action_controller/metal"
autoload :Middleware, "action_controller/middleware"
autoload :Layouts, "action_controller/metal/layouts" autoload :Layouts, "action_controller/metal/layouts"
autoload :RackConvenience, "action_controller/metal/rack_convenience" autoload :RackConvenience, "action_controller/metal/rack_convenience"
autoload :Rails2Compatibility, "action_controller/metal/compatibility" autoload :Rails2Compatibility, "action_controller/metal/compatibility"
Expand Down
22 changes: 0 additions & 22 deletions actionpack/lib/action_controller/metal.rb
Expand Up @@ -88,23 +88,6 @@ def call(env)
end end
end end


class ActionMiddleware
def initialize(controller, action)
@controller, @action = controller, action
end

def call(env)
controller = @controller.new
controller.app = @app
controller.call(@action, env)
end

def new(app)
@app = app
self
end
end

# Return a rack endpoint for the given action. Memoize the endpoint, so # Return a rack endpoint for the given action. Memoize the endpoint, so
# multiple calls into MyController.action will return the same object # multiple calls into MyController.action will return the same object
# for the same action. # for the same action.
Expand All @@ -118,10 +101,5 @@ def self.action(name)
@actions ||= {} @actions ||= {}
@actions[name.to_s] ||= ActionEndpoint.new(self, name) @actions[name.to_s] ||= ActionEndpoint.new(self, name)
end end

def self.middleware(name)
@middlewares ||= {}
@middlewares[name.to_s] ||= ActionMiddleware.new(self, name)
end
end end
end end
34 changes: 34 additions & 0 deletions actionpack/lib/action_controller/middleware.rb
@@ -0,0 +1,34 @@
module ActionController
class Middleware < Metal
class ActionMiddleware
def initialize(controller)
@controller = controller
end

def call(env)
controller = @controller.allocate
controller.app = @app
controller._call(env)
end

def app=(app)
@app = app
end
end

def self.new(app)
middleware = ActionMiddleware.new(self)
middleware.app = app
middleware
end

def _call(env)
@_env = env
process(:index)
end

def index
call(env)
end
end
end
53 changes: 32 additions & 21 deletions actionpack/test/abstract_controller/abstract_controller_test.rb
Expand Up @@ -19,8 +19,9 @@ def index


class TestBasic < ActiveSupport::TestCase class TestBasic < ActiveSupport::TestCase
test "dispatching works" do test "dispatching works" do
result = Me.new.process(:index) controller = Me.new
assert_equal "Hello world", result.response_body controller.process(:index)
assert_equal "Hello world", controller.response_body
end end
end end


Expand Down Expand Up @@ -67,29 +68,33 @@ def rendering_to_string
end end


class TestRenderingController < ActiveSupport::TestCase class TestRenderingController < ActiveSupport::TestCase
def setup
@controller = Me2.new
end

test "rendering templates works" do test "rendering templates works" do
result = Me2.new.process(:index) @controller.process(:index)
assert_equal "Hello from index.erb", result.response_body assert_equal "Hello from index.erb", @controller.response_body
end end


test "rendering passes ivars to the view" do test "rendering passes ivars to the view" do
result = Me2.new.process(:action_with_ivars) @controller.process(:action_with_ivars)
assert_equal "Hello from index_with_ivars.erb", result.response_body assert_equal "Hello from index_with_ivars.erb", @controller.response_body
end end


test "rendering with no template name" do test "rendering with no template name" do
result = Me2.new.process(:naked_render) @controller.process(:naked_render)
assert_equal "Hello from naked_render.erb", result.response_body assert_equal "Hello from naked_render.erb", @controller.response_body
end end


test "rendering to a rack body" do test "rendering to a rack body" do
result = Me2.new.process(:rendering_to_body) @controller.process(:rendering_to_body)
assert_equal "Hello from naked_render.erb", result.response_body assert_equal "Hello from naked_render.erb", @controller.response_body
end end


test "rendering to a string" do test "rendering to a string" do
result = Me2.new.process(:rendering_to_string) @controller.process(:rendering_to_string)
assert_equal "Hello from naked_render.erb", result.response_body assert_equal "Hello from naked_render.erb", @controller.response_body
end end
end end


Expand Down Expand Up @@ -119,14 +124,18 @@ def formatted
end end


class TestPrefixedViews < ActiveSupport::TestCase class TestPrefixedViews < ActiveSupport::TestCase
def setup
@controller = Me3.new
end

test "templates are located inside their 'prefix' folder" do test "templates are located inside their 'prefix' folder" do
result = Me3.new.process(:index) @controller.process(:index)
assert_equal "Hello from me3/index.erb", result.response_body assert_equal "Hello from me3/index.erb", @controller.response_body
end end


test "templates included their format" do test "templates included their format" do
result = Me3.new.process(:formatted) @controller.process(:formatted)
assert_equal "Hello from me3/formatted.html.erb", result.response_body assert_equal "Hello from me3/formatted.html.erb", @controller.response_body
end end
end end


Expand Down Expand Up @@ -168,8 +177,9 @@ def index


class TestLayouts < ActiveSupport::TestCase class TestLayouts < ActiveSupport::TestCase
test "layouts are included" do test "layouts are included" do
result = Me4.new.process(:index) controller = Me4.new
assert_equal "Me4 Enter : Hello from me4/index.erb : Exit", result.response_body result = controller.process(:index)
assert_equal "Me4 Enter : Hello from me4/index.erb : Exit", controller.response_body
end end
end end


Expand Down Expand Up @@ -203,10 +213,11 @@ def method_for_action(action_name)
end end


class TestRespondToAction < ActiveSupport::TestCase class TestRespondToAction < ActiveSupport::TestCase

def assert_dispatch(klass, body = "success", action = :index) def assert_dispatch(klass, body = "success", action = :index)
response = klass.new.process(action).response_body controller = klass.new
assert_equal body, response controller.process(action)
assert_equal body, controller.response_body
end end


test "an arbitrary method is available as an action by default" do test "an arbitrary method is available as an action by default" do
Expand Down
94 changes: 58 additions & 36 deletions actionpack/test/abstract_controller/callbacks_test.rb
Expand Up @@ -19,10 +19,11 @@ def index
end end
end end


class TestCallbacks < ActiveSupport::TestCase class TestCallbacks1 < ActiveSupport::TestCase
test "basic callbacks work" do test "basic callbacks work" do
result = Callback1.new.process(:index) controller = Callback1.new
assert_equal "Hello world", result.response_body result = controller.process(:index)
assert_equal "Hello world", controller.response_body
end end
end end


Expand Down Expand Up @@ -50,20 +51,24 @@ def index
end end
end end


class TestCallbacks < ActiveSupport::TestCase class TestCallbacks2 < ActiveSupport::TestCase
def setup
@controller = Callback2.new
end

test "before_filter works" do test "before_filter works" do
result = Callback2.new.process(:index) result = @controller.process(:index)
assert_equal "Hello world", result.response_body assert_equal "Hello world", @controller.response_body
end end


test "after_filter works" do test "after_filter works" do
result = Callback2.new.process(:index) @controller.process(:index)
assert_equal "Goodbye", result.instance_variable_get("@second") assert_equal "Goodbye", @controller.instance_variable_get("@second")
end end


test "around_filter works" do test "around_filter works" do
result = Callback2.new.process(:index) @controller.process(:index)
assert_equal "FIRSTSECOND", result.instance_variable_get("@aroundz") assert_equal "FIRSTSECOND", @controller.instance_variable_get("@aroundz")
end end
end end


Expand All @@ -81,15 +86,19 @@ def index
end end
end end


class TestCallbacks < ActiveSupport::TestCase class TestCallbacks3 < ActiveSupport::TestCase
def setup
@controller = Callback3.new
end

test "before_filter works with procs" do test "before_filter works with procs" do
result = Callback3.new.process(:index) result = @controller.process(:index)
assert_equal "Hello world", result.response_body assert_equal "Hello world", @controller.response_body
end end


test "after_filter works with procs" do test "after_filter works with procs" do
result = Callback3.new.process(:index) result = @controller.process(:index)
assert_equal "Goodbye", result.instance_variable_get("@second") assert_equal "Goodbye", @controller.instance_variable_get("@second")
end end
end end


Expand All @@ -116,20 +125,24 @@ def authenticate
end end
end end


class TestCallbacks < ActiveSupport::TestCase class TestCallbacksWithConditions < ActiveSupport::TestCase
def setup
@controller = CallbacksWithConditions.new
end

test "when :only is specified, a before filter is triggered on that action" do test "when :only is specified, a before filter is triggered on that action" do
result = CallbacksWithConditions.new.process(:index) @controller.process(:index)
assert_equal "Hello, World", result.response_body assert_equal "Hello, World", @controller.response_body
end end


test "when :only is specified, a before filter is not triggered on other actions" do test "when :only is specified, a before filter is not triggered on other actions" do
result = CallbacksWithConditions.new.process(:sekrit_data) @controller.process(:sekrit_data)
assert_equal "true", result.response_body assert_equal "true", @controller.response_body
end end


test "when :except is specified, an after filter is not triggered on that action" do test "when :except is specified, an after filter is not triggered on that action" do
result = CallbacksWithConditions.new.process(:index) result = @controller.process(:index)
assert_nil result.instance_variable_get("@authenticated") assert_nil @controller.instance_variable_get("@authenticated")
end end
end end


Expand All @@ -156,20 +169,24 @@ def authenticate
end end
end end


class TestCallbacks < ActiveSupport::TestCase class TestCallbacksWithArrayConditions < ActiveSupport::TestCase
def setup
@controller = CallbacksWithArrayConditions.new
end

test "when :only is specified with an array, a before filter is triggered on that action" do test "when :only is specified with an array, a before filter is triggered on that action" do
result = CallbacksWithArrayConditions.new.process(:index) result = @controller.process(:index)
assert_equal "Hello, World", result.response_body assert_equal "Hello, World", @controller.response_body
end end


test "when :only is specified with an array, a before filter is not triggered on other actions" do test "when :only is specified with an array, a before filter is not triggered on other actions" do
result = CallbacksWithArrayConditions.new.process(:sekrit_data) result = @controller.process(:sekrit_data)
assert_equal "true", result.response_body assert_equal "true", @controller.response_body
end end


test "when :except is specified with an array, an after filter is not triggered on that action" do test "when :except is specified with an array, an after filter is not triggered on that action" do
result = CallbacksWithArrayConditions.new.process(:index) result = @controller.process(:index)
assert_nil result.instance_variable_get("@authenticated") assert_nil @controller.instance_variable_get("@authenticated")
end end
end end


Expand All @@ -181,15 +198,19 @@ def not_index
end end
end end


class TestCallbacks < ActiveSupport::TestCase class TestCallbacksWithChangedConditions < ActiveSupport::TestCase
def setup
@controller = ChangedConditions.new
end

test "when a callback is modified in a child with :only, it works for the :only action" do test "when a callback is modified in a child with :only, it works for the :only action" do
result = ChangedConditions.new.process(:index) result = @controller.process(:index)
assert_equal "Hello world", result.response_body assert_equal "Hello world", @controller.response_body
end end


test "when a callback is modified in a child with :only, it does not work for other actions" do test "when a callback is modified in a child with :only, it does not work for other actions" do
result = ChangedConditions.new.process(:not_index) result = @controller.process(:not_index)
assert_equal "", result.response_body assert_equal "", @controller.response_body
end end
end end


Expand All @@ -207,8 +228,9 @@ def set_body


class TestHalting < ActiveSupport::TestCase class TestHalting < ActiveSupport::TestCase
test "when a callback sets the response body, the action should not be invoked" do test "when a callback sets the response body, the action should not be invoked" do
result = SetsResponseBody.new.process(:index) controller = SetsResponseBody.new
assert_equal "Success", result.response_body controller.process(:index)
assert_equal "Success", controller.response_body
end end
end end


Expand Down
5 changes: 3 additions & 2 deletions actionpack/test/abstract_controller/helper_test.rb
Expand Up @@ -34,8 +34,9 @@ def index


class TestHelpers < ActiveSupport::TestCase class TestHelpers < ActiveSupport::TestCase
def test_helpers def test_helpers
result = MyHelpers1.new.process(:index) controller = MyHelpers1.new
assert_equal "Hello World : Included", result.response_body controller.process(:index)
assert_equal "Hello World : Included", controller.response_body
end end
end end


Expand Down

0 comments on commit 9408fcd

Please sign in to comment.