Skip to content

Commit

Permalink
Implement FooController.action(:name)
Browse files Browse the repository at this point in the history
  * Rails actions are now Rack endpoints, and can be retrieved
    via FooController.action(name) and called with an env
  * Updated some tests that relied on the old internal
    #process/#call implementation
  • Loading branch information
wycats committed May 2, 2009
1 parent ad2a1b5 commit 72160d9
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 34 deletions.
27 changes: 11 additions & 16 deletions actionpack/lib/action_controller/base/base.rb
Expand Up @@ -370,18 +370,18 @@ def session
attr_reader :template

class << self
def call(env)
# HACK: For global rescue to have access to the original request and response
request = env["action_controller.rescue.request"] ||= ActionDispatch::Request.new(env)
response = env["action_controller.rescue.response"] ||= ActionDispatch::Response.new
process(request, response)
end

# Factory for the standard create, process loop where the controller is discarded after processing.
def process(request, response) #:nodoc:
new.process(request, response)
def action(name = nil)
@actions ||= {}
@actions[name] ||= proc do |env|
controller = new
# HACK: For global rescue to have access to the original request and response
request = env["action_controller.rescue.request"] ||= ActionDispatch::Request.new(env)
response = env["action_controller.rescue.response"] ||= ActionDispatch::Response.new
controller.action_name = name && name.to_s
controller.process(request, response).to_a
end
end

# Converts the class name from something like "OneModule::TwoModule::NeatController" to "NeatController".
def controller_class_name
@controller_class_name ||= name.demodulize
Expand Down Expand Up @@ -518,7 +518,6 @@ def process(request, response, method = :perform_action, *arguments) #:nodoc:
assign_shortcuts(request, response)
initialize_template_class(response)
initialize_current_url
assign_names

log_processing
send(method, *arguments)
Expand Down Expand Up @@ -883,10 +882,6 @@ def performed?
@performed_render || @performed_redirect
end

def assign_names
@action_name = (params['action'] || 'index')
end

def reset_variables_added_to_assigns
@template.instance_variable_set("@assigns_added", nil)
end
Expand Down
13 changes: 10 additions & 3 deletions actionpack/lib/action_controller/new_base/http.rb
Expand Up @@ -39,13 +39,20 @@ def self.call(env)
end

# :api: private
def call(env)
def call(name, env)
@_request = ActionDispatch::Request.new(env)
@_response = ActionDispatch::Response.new
process(@_request.parameters[:action])
process(name)
@_response.body = response_body
@_response.prepare!
self
to_rack
end

def self.action(name)
@actions ||= {}
@actions[name] ||= proc do |env|
new.call(name, env)
end
end

# :api: private
Expand Down
2 changes: 1 addition & 1 deletion actionpack/lib/action_controller/routing/route_set.rb
Expand Up @@ -430,7 +430,7 @@ def raise_named_route_error(options, named_route, named_route_name)
def call(env)
request = ActionDispatch::Request.new(env)
app = Routing::Routes.recognize(request)
app.call(env).to_a
app.action(request.parameters[:action] || 'index').call(env)
end

def recognize(request)
Expand Down
4 changes: 4 additions & 0 deletions actionpack/lib/action_controller/testing/process.rb
Expand Up @@ -131,7 +131,11 @@ def process(action, parameters = nil, session = nil, flash = nil, http_method =
@request.session["flash"] = ActionController::Flash::FlashHash.new.update(flash) if flash
build_request_uri(action, parameters)

@request.env["action_controller.rescue.request"] = @request
@request.env["action_controller.rescue.request"] = @response

Base.class_eval { include ProcessWithTest } unless Base < ProcessWithTest
@controller.action_name = action.to_s
@controller.process(@request, @response)
end

Expand Down
3 changes: 2 additions & 1 deletion actionpack/test/controller/filters_test.rb
Expand Up @@ -602,8 +602,9 @@ def test_filters_with_mixed_specialization_run_in_order
def test_dynamic_dispatch
%w(foo bar baz).each do |action|
request = ActionController::TestRequest.new
request.env["action_controller.rescue.request"] = request
request.query_parameters[:choose] = action
response = DynamicDispatchController.process(request, ActionController::TestResponse.new)
response = DynamicDispatchController.action.call(request.env).last
assert_equal action, response.body
end
end
Expand Down
40 changes: 28 additions & 12 deletions actionpack/test/controller/helper_test.rb
Expand Up @@ -101,20 +101,30 @@ def test_helper_attr
assert master_helper_methods.include?('delegate_attr=')
end

def test_helper_for_nested_controller
def call_controller(klass, action)
request = ActionController::TestRequest.new
response = ActionController::TestResponse.new
request.action = 'render_hello_world'
request.env["action_controller.rescue.request"] = request
klass.action(action).call(request.env)
end

assert_equal 'hello: Iz guuut!', Fun::GamesController.process(request, response).body
def test_helper_for_nested_controller
assert_equal 'hello: Iz guuut!',
call_controller(Fun::GamesController, "render_hello_world").last.body
# request = ActionController::TestRequest.new
# request.env["action_controller.rescue.request"] = request
#
# resp = Fun::GamesController.action(:render_hello_world).call(request.env)
# assert_equal 'hello: Iz guuut!', resp.last.body
end

def test_helper_for_acronym_controller
request = ActionController::TestRequest.new
response = ActionController::TestResponse.new
request.action = 'test'

assert_equal 'test: baz', Fun::PdfController.process(request, response).body
assert_equal "test: baz", call_controller(Fun::PdfController, "test").last.body
#
# request = ActionController::TestRequest.new
# response = ActionController::TestResponse.new
# request.action = 'test'
#
# assert_equal 'test: baz', Fun::PdfController.process(request, response).body
end

def test_all_helpers
Expand Down Expand Up @@ -204,21 +214,27 @@ def index
end
end

def call_controller(klass, action)
request = ActionController::TestRequest.new
request.env["action_controller.rescue.request"] = request
klass.action(action).call(request.env)
end

def setup
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
@request.action = 'index'
end

def test_helper_in_a
assert_raise(ActionView::TemplateError) { A.process(@request, @response) }
assert_raise(ActionView::TemplateError) { call_controller(A, "index") }
end

def test_helper_in_b
assert_equal 'B', B.process(@request, @response).body
assert_equal 'B', call_controller(B, "index").last.body
end

def test_helper_in_c
assert_equal 'C', C.process(@request, @response).body
assert_equal 'C', call_controller(C, "index").last.body
end
end
2 changes: 1 addition & 1 deletion actionpack/test/new_base/test_helper.rb
Expand Up @@ -66,7 +66,7 @@ def self.get(url)
end

def assert_body(body)
assert_equal body, last_response.body
assert_equal body, Array.wrap(last_response.body).join
end

def self.assert_body(body)
Expand Down

0 comments on commit 72160d9

Please sign in to comment.