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

process_action(action_name)
self
end

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 :HideActions, "action_controller/metal/hide_actions"
autoload :Metal, "action_controller/metal"
autoload :Middleware, "action_controller/middleware"
autoload :Layouts, "action_controller/metal/layouts"
autoload :RackConvenience, "action_controller/metal/rack_convenience"
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

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
# multiple calls into MyController.action will return the same object
# for the same action.
Expand All @@ -118,10 +101,5 @@ def self.action(name)
@actions ||= {}
@actions[name.to_s] ||= ActionEndpoint.new(self, name)
end

def self.middleware(name)
@middlewares ||= {}
@middlewares[name.to_s] ||= ActionMiddleware.new(self, name)
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
test "dispatching works" do
result = Me.new.process(:index)
assert_equal "Hello world", result.response_body
controller = Me.new
controller.process(:index)
assert_equal "Hello world", controller.response_body
end
end

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

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

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

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

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

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

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

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

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

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

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

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

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

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

class TestRespondToAction < ActiveSupport::TestCase

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

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

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

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

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

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

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

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

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

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

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

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

Expand All @@ -116,20 +125,24 @@ def authenticate
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
result = CallbacksWithConditions.new.process(:index)
assert_equal "Hello, World", result.response_body
@controller.process(:index)
assert_equal "Hello, World", @controller.response_body
end

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

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

Expand All @@ -156,20 +169,24 @@ def authenticate
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
result = CallbacksWithArrayConditions.new.process(:index)
assert_equal "Hello, World", result.response_body
result = @controller.process(:index)
assert_equal "Hello, World", @controller.response_body
end

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

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

Expand All @@ -181,15 +198,19 @@ def not_index
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
result = ChangedConditions.new.process(:index)
assert_equal "Hello world", result.response_body
result = @controller.process(:index)
assert_equal "Hello world", @controller.response_body
end

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)
assert_equal "", result.response_body
result = @controller.process(:not_index)
assert_equal "", @controller.response_body
end
end

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

class TestHalting < ActiveSupport::TestCase
test "when a callback sets the response body, the action should not be invoked" do
result = SetsResponseBody.new.process(:index)
assert_equal "Success", result.response_body
controller = SetsResponseBody.new
controller.process(:index)
assert_equal "Success", controller.response_body
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
def test_helpers
result = MyHelpers1.new.process(:index)
assert_equal "Hello World : Included", result.response_body
controller = MyHelpers1.new
controller.process(:index)
assert_equal "Hello World : Included", controller.response_body
end
end

Expand Down

0 comments on commit 9408fcd

Please sign in to comment.