actionpack 3.2.22.5 → 4.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of actionpack might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +641 -418
- data/MIT-LICENSE +1 -1
- data/README.rdoc +5 -288
- data/lib/abstract_controller.rb +1 -8
- data/lib/abstract_controller/asset_paths.rb +2 -2
- data/lib/abstract_controller/base.rb +39 -37
- data/lib/abstract_controller/callbacks.rb +101 -82
- data/lib/abstract_controller/collector.rb +7 -3
- data/lib/abstract_controller/helpers.rb +23 -11
- data/lib/abstract_controller/layouts.rb +68 -73
- data/lib/abstract_controller/logger.rb +1 -2
- data/lib/abstract_controller/rendering.rb +22 -13
- data/lib/abstract_controller/translation.rb +16 -1
- data/lib/abstract_controller/url_for.rb +6 -6
- data/lib/abstract_controller/view_paths.rb +1 -1
- data/lib/action_controller.rb +15 -6
- data/lib/action_controller/base.rb +46 -22
- data/lib/action_controller/caching.rb +46 -33
- data/lib/action_controller/caching/fragments.rb +23 -53
- data/lib/action_controller/deprecated.rb +5 -1
- data/lib/action_controller/deprecated/integration_test.rb +3 -0
- data/lib/action_controller/log_subscriber.rb +11 -8
- data/lib/action_controller/metal.rb +16 -30
- data/lib/action_controller/metal/conditional_get.rb +76 -32
- data/lib/action_controller/metal/data_streaming.rb +20 -26
- data/lib/action_controller/metal/exceptions.rb +19 -6
- data/lib/action_controller/metal/flash.rb +24 -9
- data/lib/action_controller/metal/force_ssl.rb +32 -9
- data/lib/action_controller/metal/head.rb +25 -4
- data/lib/action_controller/metal/helpers.rb +6 -9
- data/lib/action_controller/metal/hide_actions.rb +1 -2
- data/lib/action_controller/metal/http_authentication.rb +105 -87
- data/lib/action_controller/metal/implicit_render.rb +1 -1
- data/lib/action_controller/metal/instrumentation.rb +2 -1
- data/lib/action_controller/metal/live.rb +141 -0
- data/lib/action_controller/metal/mime_responds.rb +161 -47
- data/lib/action_controller/metal/params_wrapper.rb +112 -74
- data/lib/action_controller/metal/rack_delegation.rb +9 -3
- data/lib/action_controller/metal/redirecting.rb +15 -20
- data/lib/action_controller/metal/renderers.rb +11 -9
- data/lib/action_controller/metal/rendering.rb +8 -0
- data/lib/action_controller/metal/request_forgery_protection.rb +112 -19
- data/lib/action_controller/metal/responder.rb +20 -19
- data/lib/action_controller/metal/streaming.rb +12 -18
- data/lib/action_controller/metal/strong_parameters.rb +516 -0
- data/lib/action_controller/metal/testing.rb +13 -18
- data/lib/action_controller/metal/url_for.rb +27 -25
- data/lib/action_controller/model_naming.rb +12 -0
- data/lib/action_controller/railtie.rb +33 -17
- data/lib/action_controller/railties/helpers.rb +22 -0
- data/lib/action_controller/record_identifier.rb +18 -72
- data/lib/action_controller/test_case.rb +215 -123
- data/lib/action_controller/vendor/html-scanner.rb +4 -19
- data/lib/action_dispatch.rb +27 -19
- data/lib/action_dispatch/http/cache.rb +63 -11
- data/lib/action_dispatch/http/filter_parameters.rb +18 -8
- data/lib/action_dispatch/http/filter_redirect.rb +37 -0
- data/lib/action_dispatch/http/headers.rb +27 -19
- data/lib/action_dispatch/http/mime_negotiation.rb +25 -2
- data/lib/action_dispatch/http/mime_type.rb +145 -113
- data/lib/action_dispatch/http/mime_types.rb +1 -1
- data/lib/action_dispatch/http/parameter_filter.rb +44 -46
- data/lib/action_dispatch/http/parameters.rb +12 -5
- data/lib/action_dispatch/http/rack_cache.rb +2 -3
- data/lib/action_dispatch/http/request.rb +49 -18
- data/lib/action_dispatch/http/response.rb +129 -35
- data/lib/action_dispatch/http/upload.rb +60 -17
- data/lib/action_dispatch/http/url.rb +53 -31
- data/lib/action_dispatch/journey.rb +5 -0
- data/lib/action_dispatch/journey/backwards.rb +5 -0
- data/lib/action_dispatch/journey/formatter.rb +146 -0
- data/lib/action_dispatch/journey/gtg/builder.rb +162 -0
- data/lib/action_dispatch/journey/gtg/simulator.rb +44 -0
- data/lib/action_dispatch/journey/gtg/transition_table.rb +156 -0
- data/lib/action_dispatch/journey/nfa/builder.rb +76 -0
- data/lib/action_dispatch/journey/nfa/dot.rb +36 -0
- data/lib/action_dispatch/journey/nfa/simulator.rb +47 -0
- data/lib/action_dispatch/journey/nfa/transition_table.rb +163 -0
- data/lib/action_dispatch/journey/nodes/node.rb +124 -0
- data/lib/action_dispatch/journey/parser.rb +206 -0
- data/lib/action_dispatch/journey/parser.y +47 -0
- data/lib/action_dispatch/journey/parser_extras.rb +23 -0
- data/lib/action_dispatch/journey/path/pattern.rb +196 -0
- data/lib/action_dispatch/journey/route.rb +116 -0
- data/lib/action_dispatch/journey/router.rb +164 -0
- data/lib/action_dispatch/journey/router/strexp.rb +24 -0
- data/lib/action_dispatch/journey/router/utils.rb +54 -0
- data/lib/action_dispatch/journey/routes.rb +75 -0
- data/lib/action_dispatch/journey/scanner.rb +61 -0
- data/lib/action_dispatch/journey/visitors.rb +189 -0
- data/lib/action_dispatch/journey/visualizer/fsm.css +34 -0
- data/lib/action_dispatch/journey/visualizer/fsm.js +134 -0
- data/lib/action_dispatch/journey/visualizer/index.html.erb +52 -0
- data/lib/action_dispatch/middleware/callbacks.rb +9 -4
- data/lib/action_dispatch/middleware/cookies.rb +168 -57
- data/lib/action_dispatch/middleware/debug_exceptions.rb +26 -17
- data/lib/action_dispatch/middleware/exception_wrapper.rb +27 -3
- data/lib/action_dispatch/middleware/flash.rb +58 -58
- data/lib/action_dispatch/middleware/params_parser.rb +14 -29
- data/lib/action_dispatch/middleware/public_exceptions.rb +31 -14
- data/lib/action_dispatch/middleware/reloader.rb +6 -6
- data/lib/action_dispatch/middleware/remote_ip.rb +145 -39
- data/lib/action_dispatch/middleware/request_id.rb +2 -6
- data/lib/action_dispatch/middleware/session/abstract_store.rb +22 -20
- data/lib/action_dispatch/middleware/session/cache_store.rb +3 -3
- data/lib/action_dispatch/middleware/session/cookie_store.rb +81 -7
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +8 -3
- data/lib/action_dispatch/middleware/show_exceptions.rb +12 -45
- data/lib/action_dispatch/middleware/ssl.rb +70 -0
- data/lib/action_dispatch/middleware/stack.rb +6 -1
- data/lib/action_dispatch/middleware/static.rb +5 -24
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +14 -11
- data/lib/action_dispatch/middleware/templates/rescues/_source.erb +25 -0
- data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +15 -9
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +121 -5
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +7 -2
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.erb +30 -15
- data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +39 -13
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.erb +6 -2
- data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +16 -0
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +144 -0
- data/lib/action_dispatch/railtie.rb +16 -6
- data/lib/action_dispatch/request/session.rb +181 -0
- data/lib/action_dispatch/routing.rb +41 -40
- data/lib/action_dispatch/routing/inspector.rb +240 -0
- data/lib/action_dispatch/routing/mapper.rb +501 -273
- data/lib/action_dispatch/routing/polymorphic_routes.rb +16 -20
- data/lib/action_dispatch/routing/redirection.rb +46 -29
- data/lib/action_dispatch/routing/route_set.rb +203 -164
- data/lib/action_dispatch/routing/routes_proxy.rb +2 -0
- data/lib/action_dispatch/routing/url_for.rb +48 -33
- data/lib/action_dispatch/testing/assertions/dom.rb +3 -13
- data/lib/action_dispatch/testing/assertions/response.rb +32 -40
- data/lib/action_dispatch/testing/assertions/routing.rb +40 -39
- data/lib/action_dispatch/testing/assertions/selector.rb +15 -20
- data/lib/action_dispatch/testing/assertions/tag.rb +20 -23
- data/lib/action_dispatch/testing/integration.rb +41 -22
- data/lib/action_dispatch/testing/test_process.rb +9 -6
- data/lib/action_dispatch/testing/test_request.rb +7 -3
- data/lib/action_pack.rb +1 -1
- data/lib/action_pack/version.rb +4 -4
- data/lib/action_view.rb +17 -8
- data/lib/action_view/base.rb +15 -34
- data/lib/action_view/buffers.rb +1 -1
- data/lib/action_view/context.rb +4 -4
- data/lib/action_view/dependency_tracker.rb +91 -0
- data/lib/action_view/digestor.rb +85 -0
- data/lib/action_view/flows.rb +1 -4
- data/lib/action_view/helpers.rb +2 -4
- data/lib/action_view/helpers/active_model_helper.rb +3 -4
- data/lib/action_view/helpers/asset_tag_helper.rb +211 -353
- data/lib/action_view/helpers/asset_url_helper.rb +354 -0
- data/lib/action_view/helpers/atom_feed_helper.rb +13 -10
- data/lib/action_view/helpers/cache_helper.rb +150 -18
- data/lib/action_view/helpers/capture_helper.rb +42 -29
- data/lib/action_view/helpers/csrf_helper.rb +0 -2
- data/lib/action_view/helpers/date_helper.rb +268 -247
- data/lib/action_view/helpers/debug_helper.rb +10 -11
- data/lib/action_view/helpers/form_helper.rb +904 -547
- data/lib/action_view/helpers/form_options_helper.rb +341 -166
- data/lib/action_view/helpers/form_tag_helper.rb +188 -88
- data/lib/action_view/helpers/javascript_helper.rb +23 -16
- data/lib/action_view/helpers/number_helper.rb +148 -354
- data/lib/action_view/helpers/output_safety_helper.rb +3 -3
- data/lib/action_view/helpers/record_tag_helper.rb +17 -22
- data/lib/action_view/helpers/rendering_helper.rb +2 -4
- data/lib/action_view/helpers/sanitize_helper.rb +3 -6
- data/lib/action_view/helpers/tag_helper.rb +43 -37
- data/lib/action_view/helpers/tags.rb +39 -0
- data/lib/action_view/helpers/tags/base.rb +148 -0
- data/lib/action_view/helpers/tags/check_box.rb +64 -0
- data/lib/action_view/helpers/tags/checkable.rb +16 -0
- data/lib/action_view/helpers/tags/collection_check_boxes.rb +43 -0
- data/lib/action_view/helpers/tags/collection_helpers.rb +83 -0
- data/lib/action_view/helpers/tags/collection_radio_buttons.rb +36 -0
- data/lib/action_view/helpers/tags/collection_select.rb +28 -0
- data/lib/action_view/helpers/tags/color_field.rb +25 -0
- data/lib/action_view/helpers/tags/date_field.rb +13 -0
- data/lib/action_view/helpers/tags/date_select.rb +72 -0
- data/lib/action_view/helpers/tags/datetime_field.rb +22 -0
- data/lib/action_view/helpers/tags/datetime_local_field.rb +19 -0
- data/lib/action_view/helpers/tags/datetime_select.rb +8 -0
- data/lib/action_view/helpers/tags/email_field.rb +8 -0
- data/lib/action_view/helpers/tags/file_field.rb +8 -0
- data/lib/action_view/helpers/tags/grouped_collection_select.rb +29 -0
- data/lib/action_view/helpers/tags/hidden_field.rb +8 -0
- data/lib/action_view/helpers/tags/label.rb +65 -0
- data/lib/action_view/helpers/tags/month_field.rb +13 -0
- data/lib/action_view/helpers/tags/number_field.rb +18 -0
- data/lib/action_view/helpers/tags/password_field.rb +12 -0
- data/lib/action_view/helpers/tags/radio_button.rb +31 -0
- data/lib/action_view/helpers/tags/range_field.rb +8 -0
- data/lib/action_view/helpers/tags/search_field.rb +24 -0
- data/lib/action_view/helpers/tags/select.rb +41 -0
- data/lib/action_view/helpers/tags/tel_field.rb +8 -0
- data/lib/action_view/helpers/tags/text_area.rb +18 -0
- data/lib/action_view/helpers/tags/text_field.rb +29 -0
- data/lib/action_view/helpers/tags/time_field.rb +13 -0
- data/lib/action_view/helpers/tags/time_select.rb +8 -0
- data/lib/action_view/helpers/tags/time_zone_select.rb +20 -0
- data/lib/action_view/helpers/tags/url_field.rb +8 -0
- data/lib/action_view/helpers/tags/week_field.rb +13 -0
- data/lib/action_view/helpers/text_helper.rb +126 -113
- data/lib/action_view/helpers/translation_helper.rb +32 -16
- data/lib/action_view/helpers/url_helper.rb +200 -271
- data/lib/action_view/locale/en.yml +1 -105
- data/lib/action_view/log_subscriber.rb +6 -4
- data/lib/action_view/lookup_context.rb +15 -39
- data/lib/action_view/model_naming.rb +12 -0
- data/lib/action_view/path_set.rb +9 -39
- data/lib/action_view/railtie.rb +6 -22
- data/lib/action_view/record_identifier.rb +84 -0
- data/lib/action_view/renderer/abstract_renderer.rb +10 -19
- data/lib/action_view/renderer/partial_renderer.rb +144 -81
- data/lib/action_view/renderer/renderer.rb +2 -19
- data/lib/action_view/renderer/streaming_template_renderer.rb +2 -5
- data/lib/action_view/renderer/template_renderer.rb +14 -13
- data/lib/action_view/routing_url_for.rb +107 -0
- data/lib/action_view/template.rb +22 -21
- data/lib/action_view/template/error.rb +22 -12
- data/lib/action_view/template/handlers.rb +12 -9
- data/lib/action_view/template/handlers/builder.rb +1 -1
- data/lib/action_view/template/handlers/erb.rb +11 -16
- data/lib/action_view/template/handlers/raw.rb +11 -0
- data/lib/action_view/template/resolver.rb +111 -83
- data/lib/action_view/template/text.rb +12 -8
- data/lib/action_view/template/types.rb +57 -0
- data/lib/action_view/test_case.rb +66 -43
- data/lib/action_view/testing/resolvers.rb +3 -2
- data/lib/action_view/vendor/html-scanner.rb +20 -0
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/document.rb +0 -0
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/node.rb +12 -12
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/sanitizer.rb +18 -7
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/selector.rb +1 -1
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/tokenizer.rb +1 -1
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/version.rb +0 -0
- metadata +135 -125
- data/lib/action_controller/caching/actions.rb +0 -185
- data/lib/action_controller/caching/pages.rb +0 -187
- data/lib/action_controller/caching/sweeping.rb +0 -97
- data/lib/action_controller/deprecated/performance_test.rb +0 -1
- data/lib/action_controller/metal/compatibility.rb +0 -65
- data/lib/action_controller/metal/session_management.rb +0 -14
- data/lib/action_controller/railties/paths.rb +0 -25
- data/lib/action_dispatch/middleware/best_standards_support.rb +0 -30
- data/lib/action_dispatch/middleware/body_proxy.rb +0 -30
- data/lib/action_dispatch/middleware/head.rb +0 -18
- data/lib/action_dispatch/middleware/rescue.rb +0 -26
- data/lib/action_dispatch/testing/performance_test.rb +0 -10
- data/lib/action_view/asset_paths.rb +0 -142
- data/lib/action_view/helpers/asset_paths.rb +0 -7
- data/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb +0 -146
- data/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb +0 -93
- data/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb +0 -193
- data/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb +0 -148
- data/lib/sprockets/assets.rake +0 -99
- data/lib/sprockets/bootstrap.rb +0 -37
- data/lib/sprockets/compressors.rb +0 -83
- data/lib/sprockets/helpers.rb +0 -6
- data/lib/sprockets/helpers/isolated_helper.rb +0 -13
- data/lib/sprockets/helpers/rails_helper.rb +0 -182
- data/lib/sprockets/railtie.rb +0 -62
- data/lib/sprockets/static_compiler.rb +0 -56
@@ -4,30 +4,25 @@ module ActionController
|
|
4
4
|
|
5
5
|
include RackDelegation
|
6
6
|
|
7
|
-
def recycle!
|
8
|
-
@_url_options = nil
|
9
|
-
end
|
10
|
-
|
11
|
-
|
12
|
-
# TODO: Clean this up
|
13
|
-
def process_with_new_base_test(request, response)
|
14
|
-
@_request = request
|
15
|
-
@_response = response
|
16
|
-
@_response.request = request
|
17
|
-
ret = process(request.parameters[:action])
|
18
|
-
if cookies = @_request.env['action_dispatch.cookies']
|
19
|
-
cookies.write(@_response)
|
20
|
-
end
|
21
|
-
@_response.prepare!
|
22
|
-
ret
|
23
|
-
end
|
24
|
-
|
25
7
|
# TODO : Rewrite tests using controller.headers= to use Rack env
|
26
8
|
def headers=(new_headers)
|
27
9
|
@_response ||= ActionDispatch::Response.new
|
28
10
|
@_response.headers.replace(new_headers)
|
29
11
|
end
|
30
12
|
|
13
|
+
# Behavior specific to functional tests
|
14
|
+
module Functional # :nodoc:
|
15
|
+
def set_response!(request)
|
16
|
+
end
|
17
|
+
|
18
|
+
def recycle!
|
19
|
+
@_url_options = nil
|
20
|
+
self.response_body = nil
|
21
|
+
self.formats = nil
|
22
|
+
self.params = nil
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
31
26
|
module ClassMethods
|
32
27
|
def before_filters
|
33
28
|
_process_action_callbacks.find_all{|x| x.kind == :before}.map{|x| x.name}
|
@@ -1,25 +1,22 @@
|
|
1
|
-
# Includes +url_for+ into the host class. The class has to provide a +RouteSet+ by implementing
|
2
|
-
# the <tt>_routes</tt> method. Otherwise, an exception will be raised.
|
3
|
-
#
|
4
|
-
# In addition to <tt>AbstractController::UrlFor</tt>, this module accesses the HTTP layer to define
|
5
|
-
# url options like the +host+. In order to do so, this module requires the host class
|
6
|
-
# to implement +env+ and +request+, which need to be a Rack-compatible.
|
7
|
-
#
|
8
|
-
# Example:
|
9
|
-
#
|
10
|
-
# class RootUrl
|
11
|
-
# include ActionController::UrlFor
|
12
|
-
# include Rails.application.routes.url_helpers
|
13
|
-
#
|
14
|
-
# delegate :env, :request, :to => :controller
|
15
|
-
#
|
16
|
-
# def initialize(controller)
|
17
|
-
# @controller = controller
|
18
|
-
# @url = root_path # named route from the application.
|
19
|
-
# end
|
20
|
-
# end
|
21
|
-
#
|
22
1
|
module ActionController
|
2
|
+
# Includes +url_for+ into the host class. The class has to provide a +RouteSet+ by implementing
|
3
|
+
# the <tt>_routes</tt> method. Otherwise, an exception will be raised.
|
4
|
+
#
|
5
|
+
# In addition to <tt>AbstractController::UrlFor</tt>, this module accesses the HTTP layer to define
|
6
|
+
# url options like the +host+. In order to do so, this module requires the host class
|
7
|
+
# to implement +env+ and +request+, which need to be a Rack-compatible.
|
8
|
+
#
|
9
|
+
# class RootUrl
|
10
|
+
# include ActionController::UrlFor
|
11
|
+
# include Rails.application.routes.url_helpers
|
12
|
+
#
|
13
|
+
# delegate :env, :request, to: :controller
|
14
|
+
#
|
15
|
+
# def initialize(controller)
|
16
|
+
# @controller = controller
|
17
|
+
# @url = root_path # named route from the application.
|
18
|
+
# end
|
19
|
+
# end
|
23
20
|
module UrlFor
|
24
21
|
extend ActiveSupport::Concern
|
25
22
|
|
@@ -30,18 +27,23 @@ module ActionController
|
|
30
27
|
:host => request.host,
|
31
28
|
:port => request.optional_port,
|
32
29
|
:protocol => request.protocol,
|
33
|
-
:
|
30
|
+
:_recall => request.symbolized_path_parameters
|
34
31
|
).freeze
|
35
32
|
|
36
|
-
if _routes.equal?(env["action_dispatch.routes"])
|
33
|
+
if (same_origin = _routes.equal?(env["action_dispatch.routes"])) ||
|
34
|
+
(script_name = env["ROUTES_#{_routes.object_id}_SCRIPT_NAME"]) ||
|
35
|
+
(original_script_name = env['SCRIPT_NAME'])
|
37
36
|
@_url_options.dup.tap do |options|
|
38
|
-
|
37
|
+
if original_script_name
|
38
|
+
options[:original_script_name] = original_script_name
|
39
|
+
else
|
40
|
+
options[:script_name] = same_origin ? request.script_name.dup : script_name
|
41
|
+
end
|
39
42
|
options.freeze
|
40
43
|
end
|
41
44
|
else
|
42
45
|
@_url_options
|
43
46
|
end
|
44
47
|
end
|
45
|
-
|
46
48
|
end
|
47
49
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module ActionController
|
2
|
+
module ModelNaming
|
3
|
+
# Converts the given object to an ActiveModel compliant one.
|
4
|
+
def convert_to_model(object)
|
5
|
+
object.respond_to?(:to_model) ? object.to_model : object
|
6
|
+
end
|
7
|
+
|
8
|
+
def model_name_from_record_or_class(record_or_class)
|
9
|
+
(record_or_class.is_a?(Class) ? record_or_class : convert_to_model(record_or_class).class).model_name
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -3,42 +3,58 @@ require "action_controller"
|
|
3
3
|
require "action_dispatch/railtie"
|
4
4
|
require "action_view/railtie"
|
5
5
|
require "abstract_controller/railties/routes_helpers"
|
6
|
-
require "action_controller/railties/
|
6
|
+
require "action_controller/railties/helpers"
|
7
7
|
|
8
8
|
module ActionController
|
9
|
-
class Railtie < Rails::Railtie
|
9
|
+
class Railtie < Rails::Railtie #:nodoc:
|
10
10
|
config.action_controller = ActiveSupport::OrderedOptions.new
|
11
11
|
|
12
|
-
|
13
|
-
|
12
|
+
config.eager_load_namespaces << ActionController
|
13
|
+
|
14
|
+
initializer "action_controller.assets_config", :group => :all do |app|
|
15
|
+
app.config.action_controller.assets_dir ||= app.config.paths["public"].first
|
14
16
|
end
|
15
17
|
|
16
|
-
initializer "action_controller.
|
17
|
-
|
18
|
+
initializer "action_controller.set_helpers_path" do |app|
|
19
|
+
ActionController::Helpers.helpers_path = app.helpers_paths
|
18
20
|
end
|
19
21
|
|
20
|
-
initializer "action_controller.
|
21
|
-
|
22
|
+
initializer "action_controller.parameters_config" do |app|
|
23
|
+
options = app.config.action_controller
|
24
|
+
|
25
|
+
ActionController::Parameters.permit_all_parameters = options.delete(:permit_all_parameters) { false }
|
26
|
+
ActionController::Parameters.action_on_unpermitted_parameters = options.delete(:action_on_unpermitted_parameters) do
|
27
|
+
(Rails.env.test? || Rails.env.development?) ? :log : false
|
28
|
+
end
|
22
29
|
end
|
23
30
|
|
24
31
|
initializer "action_controller.set_configs" do |app|
|
25
32
|
paths = app.config.paths
|
26
33
|
options = app.config.action_controller
|
27
34
|
|
28
|
-
options.
|
29
|
-
options.
|
30
|
-
options.page_cache_directory ||= paths["public"].first
|
35
|
+
options.logger ||= Rails.logger
|
36
|
+
options.cache_store ||= Rails.cache
|
31
37
|
|
32
|
-
|
33
|
-
options.
|
34
|
-
|
35
|
-
|
38
|
+
options.javascripts_dir ||= paths["public/javascripts"].first
|
39
|
+
options.stylesheets_dir ||= paths["public/stylesheets"].first
|
40
|
+
|
41
|
+
# Ensure readers methods get compiled
|
42
|
+
options.asset_host ||= app.config.asset_host
|
43
|
+
options.relative_url_root ||= app.config.relative_url_root
|
36
44
|
|
37
45
|
ActiveSupport.on_load(:action_controller) do
|
38
46
|
include app.routes.mounted_helpers
|
39
47
|
extend ::AbstractController::Railties::RoutesHelpers.with(app.routes)
|
40
|
-
extend ::ActionController::Railties::
|
41
|
-
|
48
|
+
extend ::ActionController::Railties::Helpers
|
49
|
+
|
50
|
+
options.each do |k,v|
|
51
|
+
k = "#{k}="
|
52
|
+
if respond_to?(k)
|
53
|
+
send(k, v)
|
54
|
+
elsif !Base.respond_to?(k)
|
55
|
+
raise "Invalid option key: #{k}"
|
56
|
+
end
|
57
|
+
end
|
42
58
|
end
|
43
59
|
end
|
44
60
|
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module ActionController
|
2
|
+
module Railties
|
3
|
+
module Helpers
|
4
|
+
def inherited(klass)
|
5
|
+
super
|
6
|
+
return unless klass.respond_to?(:helpers_path=)
|
7
|
+
|
8
|
+
if namespace = klass.parents.detect { |m| m.respond_to?(:railtie_helpers_paths) }
|
9
|
+
paths = namespace.railtie_helpers_paths
|
10
|
+
else
|
11
|
+
paths = ActionController::Helpers.helpers_path
|
12
|
+
end
|
13
|
+
|
14
|
+
klass.helpers_path = paths
|
15
|
+
|
16
|
+
if klass.superclass == ActionController::Base && ActionController::Base.include_all_helpers
|
17
|
+
klass.helper :all
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -1,85 +1,31 @@
|
|
1
|
-
require '
|
1
|
+
require 'action_view/record_identifier'
|
2
2
|
|
3
3
|
module ActionController
|
4
|
-
# The record identifier encapsulates a number of naming conventions for dealing with records, like Active Records or
|
5
|
-
# Active Resources or pretty much any other model type that has an id. These patterns are then used to try elevate
|
6
|
-
# the view actions to a higher logical level. Example:
|
7
|
-
#
|
8
|
-
# # routes
|
9
|
-
# resources :posts
|
10
|
-
#
|
11
|
-
# # view
|
12
|
-
# <%= div_for(post) do %> <div id="post_45" class="post">
|
13
|
-
# <%= post.body %> What a wonderful world!
|
14
|
-
# <% end %> </div>
|
15
|
-
#
|
16
|
-
# # controller
|
17
|
-
# def update
|
18
|
-
# post = Post.find(params[:id])
|
19
|
-
# post.update_attributes(params[:post])
|
20
|
-
#
|
21
|
-
# redirect_to(post) # Calls polymorphic_url(post) which in turn calls post_url(post)
|
22
|
-
# end
|
23
|
-
#
|
24
|
-
# As the example above shows, you can stop caring to a large extent what the actual id of the post is.
|
25
|
-
# You just know that one is being assigned and that the subsequent calls in redirect_to expect that
|
26
|
-
# same naming convention and allows you to write less code if you follow it.
|
27
4
|
module RecordIdentifier
|
28
|
-
|
5
|
+
MODULE_MESSAGE = 'Calling ActionController::RecordIdentifier.%s is deprecated and ' \
|
6
|
+
'will be removed in Rails 4.1, please call using ActionView::RecordIdentifier instead.'
|
7
|
+
INSTANCE_MESSAGE = '%s method will no longer be included by default in controllers ' \
|
8
|
+
'since Rails 4.1. If you would like to use it in controllers, please include ' \
|
9
|
+
'ActionView::RecordIdentifier module.'
|
29
10
|
|
30
|
-
JOIN = '_'.freeze
|
31
|
-
NEW = 'new'.freeze
|
32
|
-
|
33
|
-
# The DOM class convention is to use the singular form of an object or class. Examples:
|
34
|
-
#
|
35
|
-
# dom_class(post) # => "post"
|
36
|
-
# dom_class(Person) # => "person"
|
37
|
-
#
|
38
|
-
# If you need to address multiple instances of the same class in the same view, you can prefix the dom_class:
|
39
|
-
#
|
40
|
-
# dom_class(post, :edit) # => "edit_post"
|
41
|
-
# dom_class(Person, :edit) # => "edit_person"
|
42
|
-
def dom_class(record_or_class, prefix = nil)
|
43
|
-
singular = ActiveModel::Naming.param_key(record_or_class)
|
44
|
-
prefix ? "#{prefix}#{JOIN}#{singular}" : singular
|
45
|
-
end
|
46
|
-
|
47
|
-
# The DOM id convention is to use the singular form of an object or class with the id following an underscore.
|
48
|
-
# If no id is found, prefix with "new_" instead. Examples:
|
49
|
-
#
|
50
|
-
# dom_id(Post.find(45)) # => "post_45"
|
51
|
-
# dom_id(Post.new) # => "new_post"
|
52
|
-
#
|
53
|
-
# If you need to address multiple instances of the same class in the same view, you can prefix the dom_id:
|
54
|
-
#
|
55
|
-
# dom_id(Post.find(45), :edit) # => "edit_post_45"
|
56
11
|
def dom_id(record, prefix = nil)
|
57
|
-
|
58
|
-
|
59
|
-
else
|
60
|
-
dom_class(record, prefix || NEW)
|
61
|
-
end
|
12
|
+
ActiveSupport::Deprecation.warn(INSTANCE_MESSAGE % 'dom_id')
|
13
|
+
ActionView::RecordIdentifier.dom_id(record, prefix)
|
62
14
|
end
|
63
15
|
|
64
|
-
|
16
|
+
def dom_class(record, prefix = nil)
|
17
|
+
ActiveSupport::Deprecation.warn(INSTANCE_MESSAGE % 'dom_class')
|
18
|
+
ActionView::RecordIdentifier.dom_class(record, prefix)
|
19
|
+
end
|
65
20
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
# you should write a helper like 'person_record_from_dom_id' that will extract the key either based
|
70
|
-
# on the default implementation (which just joins all key attributes with '_') or on your own
|
71
|
-
# overwritten version of the method. By default, this implementation passes the key string through a
|
72
|
-
# method that replaces all characters that are invalid inside DOM ids, with valid ones. You need to
|
73
|
-
# make sure yourself that your dom ids are valid, in case you overwrite this method.
|
74
|
-
def record_key_for_dom_id(record)
|
75
|
-
record = record.to_model if record.respond_to?(:to_model)
|
76
|
-
key = record.to_key
|
77
|
-
key ? sanitize_dom_id(key.join('_')) : key
|
21
|
+
def self.dom_id(record, prefix = nil)
|
22
|
+
ActiveSupport::Deprecation.warn(MODULE_MESSAGE % 'dom_id')
|
23
|
+
ActionView::RecordIdentifier.dom_id(record, prefix)
|
78
24
|
end
|
79
25
|
|
80
|
-
|
81
|
-
|
82
|
-
|
26
|
+
def self.dom_class(record, prefix = nil)
|
27
|
+
ActiveSupport::Deprecation.warn(MODULE_MESSAGE % 'dom_class')
|
28
|
+
ActionView::RecordIdentifier.dom_class(record, prefix)
|
83
29
|
end
|
84
30
|
end
|
85
31
|
end
|
@@ -1,8 +1,7 @@
|
|
1
1
|
require 'rack/session/abstract/id'
|
2
|
-
require 'active_support/core_ext/object/blank'
|
3
2
|
require 'active_support/core_ext/object/to_query'
|
4
|
-
require 'active_support/core_ext/class/attribute'
|
5
3
|
require 'active_support/core_ext/module/anonymous'
|
4
|
+
require 'active_support/core_ext/hash/keys'
|
6
5
|
|
7
6
|
module ActionController
|
8
7
|
module TemplateAssertions
|
@@ -14,16 +13,16 @@ module ActionController
|
|
14
13
|
end
|
15
14
|
|
16
15
|
def setup_subscriptions
|
17
|
-
@
|
18
|
-
@
|
19
|
-
@
|
16
|
+
@_partials = Hash.new(0)
|
17
|
+
@_templates = Hash.new(0)
|
18
|
+
@_layouts = Hash.new(0)
|
20
19
|
|
21
20
|
ActiveSupport::Notifications.subscribe("render_template.action_view") do |name, start, finish, id, payload|
|
22
21
|
path = payload[:layout]
|
23
22
|
if path
|
24
|
-
@
|
23
|
+
@_layouts[path] += 1
|
25
24
|
if path =~ /^layouts\/(.*)/
|
26
|
-
@
|
25
|
+
@_layouts[$1] += 1
|
27
26
|
end
|
28
27
|
end
|
29
28
|
end
|
@@ -32,13 +31,13 @@ module ActionController
|
|
32
31
|
path = payload[:virtual_path]
|
33
32
|
next unless path
|
34
33
|
partial = path =~ /^.*\/_[^\/]*$/
|
34
|
+
|
35
35
|
if partial
|
36
|
-
@
|
37
|
-
@
|
38
|
-
@templates[path] += 1
|
39
|
-
else
|
40
|
-
@templates[path] += 1
|
36
|
+
@_partials[path] += 1
|
37
|
+
@_partials[path.split("/").last] += 1
|
41
38
|
end
|
39
|
+
|
40
|
+
@_templates[path] += 1
|
42
41
|
end
|
43
42
|
end
|
44
43
|
|
@@ -48,107 +47,121 @@ module ActionController
|
|
48
47
|
end
|
49
48
|
|
50
49
|
def process(*args)
|
51
|
-
@
|
52
|
-
@
|
53
|
-
@
|
50
|
+
@_partials = Hash.new(0)
|
51
|
+
@_templates = Hash.new(0)
|
52
|
+
@_layouts = Hash.new(0)
|
54
53
|
super
|
55
54
|
end
|
56
55
|
|
57
56
|
# Asserts that the request was rendered with the appropriate template file or partials.
|
58
57
|
#
|
59
|
-
# ==== Examples
|
60
|
-
#
|
61
58
|
# # assert that the "new" view template was rendered
|
62
59
|
# assert_template "new"
|
63
60
|
#
|
61
|
+
# # assert that the exact template "admin/posts/new" was rendered
|
62
|
+
# assert_template %r{\Aadmin/posts/new\Z}
|
63
|
+
#
|
64
64
|
# # assert that the layout 'admin' was rendered
|
65
|
-
# assert_template :
|
66
|
-
# assert_template :
|
67
|
-
# assert_template :
|
65
|
+
# assert_template layout: 'admin'
|
66
|
+
# assert_template layout: 'layouts/admin'
|
67
|
+
# assert_template layout: :admin
|
68
68
|
#
|
69
69
|
# # assert that no layout was rendered
|
70
|
-
# assert_template :
|
71
|
-
# assert_template :
|
70
|
+
# assert_template layout: nil
|
71
|
+
# assert_template layout: false
|
72
72
|
#
|
73
73
|
# # assert that the "_customer" partial was rendered twice
|
74
|
-
# assert_template :
|
74
|
+
# assert_template partial: '_customer', count: 2
|
75
75
|
#
|
76
76
|
# # assert that no partials were rendered
|
77
|
-
# assert_template :
|
77
|
+
# assert_template partial: false
|
78
78
|
#
|
79
79
|
# In a view test case, you can also assert that specific locals are passed
|
80
80
|
# to partials:
|
81
81
|
#
|
82
82
|
# # assert that the "_customer" partial was rendered with a specific object
|
83
|
-
# assert_template :
|
84
|
-
#
|
83
|
+
# assert_template partial: '_customer', locals: { customer: @customer }
|
85
84
|
def assert_template(options = {}, message = nil)
|
86
|
-
|
87
|
-
# Force body to be read in case the template is being streamed
|
85
|
+
# Force body to be read in case the template is being streamed.
|
88
86
|
response.body
|
89
87
|
|
90
88
|
case options
|
91
|
-
when NilClass, String, Symbol
|
89
|
+
when NilClass, Regexp, String, Symbol
|
92
90
|
options = options.to_s if Symbol === options
|
93
|
-
rendered = @
|
94
|
-
msg =
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
91
|
+
rendered = @_templates
|
92
|
+
msg = message || sprintf("expecting <%s> but rendering with <%s>",
|
93
|
+
options.inspect, rendered.keys)
|
94
|
+
matches_template =
|
95
|
+
case options
|
96
|
+
when String
|
97
|
+
!options.empty? && rendered.any? do |t, num|
|
98
|
+
options_splited = options.split(File::SEPARATOR)
|
99
|
+
t_splited = t.split(File::SEPARATOR)
|
100
|
+
t_splited.last(options_splited.size) == options_splited
|
101
|
+
end
|
102
|
+
when Regexp
|
99
103
|
rendered.any? { |t,num| t.match(options) }
|
100
|
-
|
101
|
-
|
104
|
+
when NilClass
|
105
|
+
rendered.blank?
|
102
106
|
end
|
103
|
-
|
107
|
+
assert matches_template, msg
|
104
108
|
when Hash
|
109
|
+
options.assert_valid_keys(:layout, :partial, :locals, :count)
|
110
|
+
|
105
111
|
if options.key?(:layout)
|
106
112
|
expected_layout = options[:layout]
|
107
|
-
msg =
|
108
|
-
|
109
|
-
expected_layout, @layouts.keys)
|
113
|
+
msg = message || sprintf("expecting layout <%s> but action rendered <%s>",
|
114
|
+
expected_layout, @_layouts.keys)
|
110
115
|
|
111
116
|
case expected_layout
|
112
117
|
when String, Symbol
|
113
|
-
|
118
|
+
assert_includes @_layouts.keys, expected_layout.to_s, msg
|
114
119
|
when Regexp
|
115
|
-
assert(@
|
120
|
+
assert(@_layouts.keys.any? {|l| l =~ expected_layout }, msg)
|
116
121
|
when nil, false
|
117
|
-
assert(@
|
122
|
+
assert(@_layouts.empty?, msg)
|
118
123
|
end
|
119
124
|
end
|
120
125
|
|
121
126
|
if expected_partial = options[:partial]
|
122
127
|
if expected_locals = options[:locals]
|
123
|
-
if defined?(@
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
+
if defined?(@_rendered_views)
|
129
|
+
view = expected_partial.to_s.sub(/^_/, '').sub(/\/_(?=[^\/]+\z)/, '/')
|
130
|
+
|
131
|
+
partial_was_not_rendered_msg = "expected %s to be rendered but it was not." % view
|
132
|
+
assert_includes @_rendered_views.rendered_views, view, partial_was_not_rendered_msg
|
133
|
+
|
134
|
+
msg = 'expecting %s to be rendered with %s but was with %s' % [expected_partial,
|
135
|
+
expected_locals,
|
136
|
+
@_rendered_views.locals_for(view)]
|
137
|
+
assert(@_rendered_views.view_rendered?(view, options[:locals]), msg)
|
128
138
|
else
|
129
139
|
warn "the :locals option to #assert_template is only supported in a ActionView::TestCase"
|
130
140
|
end
|
131
141
|
elsif expected_count = options[:count]
|
132
|
-
actual_count = @
|
133
|
-
msg =
|
134
|
-
"expecting ? to be rendered ? time(s) but rendered ? time(s)",
|
142
|
+
actual_count = @_partials[expected_partial]
|
143
|
+
msg = message || sprintf("expecting %s to be rendered %s time(s) but rendered %s time(s)",
|
135
144
|
expected_partial, expected_count, actual_count)
|
136
145
|
assert(actual_count == expected_count.to_i, msg)
|
137
146
|
else
|
138
|
-
msg =
|
139
|
-
|
140
|
-
|
141
|
-
assert(@partials.include?(expected_partial), msg)
|
147
|
+
msg = message || sprintf("expecting partial <%s> but action rendered <%s>",
|
148
|
+
options[:partial], @_partials.keys)
|
149
|
+
assert_includes @_partials, expected_partial, msg
|
142
150
|
end
|
143
151
|
elsif options.key?(:partial)
|
144
|
-
assert @
|
152
|
+
assert @_partials.empty?,
|
145
153
|
"Expected no partials to be rendered"
|
146
154
|
end
|
155
|
+
else
|
156
|
+
raise ArgumentError, "assert_template only accepts a String, Symbol, Hash, Regexp, or nil"
|
147
157
|
end
|
148
158
|
end
|
149
159
|
end
|
150
160
|
|
151
161
|
class TestRequest < ActionDispatch::TestRequest #:nodoc:
|
162
|
+
DEFAULT_ENV = ActionDispatch::TestRequest::DEFAULT_ENV.dup
|
163
|
+
DEFAULT_ENV.delete 'PATH_INFO'
|
164
|
+
|
152
165
|
def initialize(env = {})
|
153
166
|
super
|
154
167
|
|
@@ -156,13 +169,6 @@ module ActionController
|
|
156
169
|
self.session_options = TestSession::DEFAULT_OPTIONS.merge(:id => SecureRandom.hex(16))
|
157
170
|
end
|
158
171
|
|
159
|
-
class Result < ::Array #:nodoc:
|
160
|
-
def to_s() join '/' end
|
161
|
-
def self.new_escaped(strings)
|
162
|
-
new strings.collect {|str| uri_parser.unescape str}
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
172
|
def assign_parameters(routes, controller_path, action, parameters = {})
|
167
173
|
parameters = parameters.symbolize_keys.merge(:controller => controller_path, :action => action)
|
168
174
|
extra_keys = routes.extra_keys(parameters)
|
@@ -180,7 +186,7 @@ module ActionController
|
|
180
186
|
non_path_parameters[key] = value
|
181
187
|
else
|
182
188
|
if value.is_a?(Array)
|
183
|
-
value =
|
189
|
+
value = value.map(&:to_param)
|
184
190
|
else
|
185
191
|
value = value.to_param
|
186
192
|
end
|
@@ -220,33 +226,53 @@ module ActionController
|
|
220
226
|
cookie_jar.update(@set_cookies)
|
221
227
|
cookie_jar.recycle!
|
222
228
|
end
|
229
|
+
|
230
|
+
private
|
231
|
+
|
232
|
+
def default_env
|
233
|
+
DEFAULT_ENV
|
234
|
+
end
|
223
235
|
end
|
224
236
|
|
225
237
|
class TestResponse < ActionDispatch::TestResponse
|
226
238
|
def recycle!
|
227
|
-
|
228
|
-
@header = {}
|
229
|
-
@writer = lambda { |x| @body << x }
|
230
|
-
@block = nil
|
231
|
-
@length = 0
|
232
|
-
@body = []
|
233
|
-
@charset = @content_type = nil
|
234
|
-
@request = @template = nil
|
239
|
+
initialize
|
235
240
|
end
|
236
241
|
end
|
237
242
|
|
243
|
+
# Methods #destroy and #load! are overridden to avoid calling methods on the
|
244
|
+
# @store object, which does not exist for the TestSession class.
|
238
245
|
class TestSession < Rack::Session::Abstract::SessionHash #:nodoc:
|
239
246
|
DEFAULT_OPTIONS = Rack::Session::Abstract::ID::DEFAULT_OPTIONS
|
240
247
|
|
241
248
|
def initialize(session = {})
|
242
249
|
super(nil, nil)
|
243
|
-
|
250
|
+
@id = SecureRandom.hex(16)
|
251
|
+
@data = stringify_keys(session)
|
244
252
|
@loaded = true
|
245
253
|
end
|
246
254
|
|
247
255
|
def exists?
|
248
256
|
true
|
249
257
|
end
|
258
|
+
|
259
|
+
def keys
|
260
|
+
@data.keys
|
261
|
+
end
|
262
|
+
|
263
|
+
def values
|
264
|
+
@data.values
|
265
|
+
end
|
266
|
+
|
267
|
+
def destroy
|
268
|
+
clear
|
269
|
+
end
|
270
|
+
|
271
|
+
private
|
272
|
+
|
273
|
+
def load!
|
274
|
+
@id
|
275
|
+
end
|
250
276
|
end
|
251
277
|
|
252
278
|
# Superclass for ActionController functional tests. Functional tests allow you to
|
@@ -258,7 +284,7 @@ module ActionController
|
|
258
284
|
# == Basic example
|
259
285
|
#
|
260
286
|
# Functional tests are written as follows:
|
261
|
-
# 1. First, one uses the +get+, +post+, +put+, +delete+ or +head+ method to simulate
|
287
|
+
# 1. First, one uses the +get+, +post+, +patch+, +put+, +delete+ or +head+ method to simulate
|
262
288
|
# an HTTP request.
|
263
289
|
# 2. Then, one asserts whether the current state is as expected. "State" can be anything:
|
264
290
|
# the controller's HTTP response, the database contents, etc.
|
@@ -268,7 +294,7 @@ module ActionController
|
|
268
294
|
# class BooksControllerTest < ActionController::TestCase
|
269
295
|
# def test_create
|
270
296
|
# # Simulate a POST response with the given HTTP parameters.
|
271
|
-
# post(:create, :
|
297
|
+
# post(:create, book: { title: "Love Hina" })
|
272
298
|
#
|
273
299
|
# # Assert that the controller tried to redirect us to
|
274
300
|
# # the created book's URI.
|
@@ -279,6 +305,13 @@ module ActionController
|
|
279
305
|
# end
|
280
306
|
# end
|
281
307
|
#
|
308
|
+
# You can also send a real document in the simulated HTTP request.
|
309
|
+
#
|
310
|
+
# def test_create
|
311
|
+
# json = {book: { title: "Love Hina" }}.to_json
|
312
|
+
# post :create, json
|
313
|
+
# end
|
314
|
+
#
|
282
315
|
# == Special instance variables
|
283
316
|
#
|
284
317
|
# ActionController::TestCase will also automatically provide the following instance
|
@@ -349,29 +382,28 @@ module ActionController
|
|
349
382
|
# == \Testing named routes
|
350
383
|
#
|
351
384
|
# If you're using named routes, they can be easily tested using the original named routes' methods straight in the test case.
|
352
|
-
# Example:
|
353
385
|
#
|
354
|
-
# assert_redirected_to page_url(:
|
386
|
+
# assert_redirected_to page_url(title: 'foo')
|
355
387
|
class TestCase < ActiveSupport::TestCase
|
356
388
|
module Behavior
|
357
389
|
extend ActiveSupport::Concern
|
358
390
|
include ActionDispatch::TestProcess
|
391
|
+
include ActiveSupport::Testing::ConstantLookup
|
359
392
|
|
360
393
|
attr_reader :response, :request
|
361
394
|
|
362
395
|
module ClassMethods
|
363
396
|
|
364
397
|
# Sets the controller class name. Useful if the name can't be inferred from test class.
|
365
|
-
# Normalizes +controller_class+ before using.
|
398
|
+
# Normalizes +controller_class+ before using.
|
366
399
|
#
|
367
400
|
# tests WidgetController
|
368
401
|
# tests :widget
|
369
402
|
# tests 'widget'
|
370
|
-
#
|
371
403
|
def tests(controller_class)
|
372
404
|
case controller_class
|
373
405
|
when String, Symbol
|
374
|
-
self.controller_class = "#{controller_class.to_s.
|
406
|
+
self.controller_class = "#{controller_class.to_s.camelize}Controller".constantize
|
375
407
|
when Class
|
376
408
|
self.controller_class = controller_class
|
377
409
|
else
|
@@ -393,7 +425,9 @@ module ActionController
|
|
393
425
|
end
|
394
426
|
|
395
427
|
def determine_default_controller_class(name)
|
396
|
-
name
|
428
|
+
determine_constant_from_test_name(name) do |constant|
|
429
|
+
Class === constant && constant < ActionController::Metal
|
430
|
+
end
|
397
431
|
end
|
398
432
|
|
399
433
|
def prepare_controller_class(new_class)
|
@@ -403,28 +437,38 @@ module ActionController
|
|
403
437
|
end
|
404
438
|
|
405
439
|
# Executes a request simulating GET HTTP method and set/volley the response
|
406
|
-
def get(action,
|
407
|
-
process(action,
|
440
|
+
def get(action, *args)
|
441
|
+
process(action, "GET", *args)
|
408
442
|
end
|
409
443
|
|
410
444
|
# Executes a request simulating POST HTTP method and set/volley the response
|
411
|
-
def post(action,
|
412
|
-
process(action,
|
445
|
+
def post(action, *args)
|
446
|
+
process(action, "POST", *args)
|
447
|
+
end
|
448
|
+
|
449
|
+
# Executes a request simulating PATCH HTTP method and set/volley the response
|
450
|
+
def patch(action, *args)
|
451
|
+
process(action, "PATCH", *args)
|
413
452
|
end
|
414
453
|
|
415
454
|
# Executes a request simulating PUT HTTP method and set/volley the response
|
416
|
-
def put(action,
|
417
|
-
process(action,
|
455
|
+
def put(action, *args)
|
456
|
+
process(action, "PUT", *args)
|
418
457
|
end
|
419
458
|
|
420
459
|
# Executes a request simulating DELETE HTTP method and set/volley the response
|
421
|
-
def delete(action,
|
422
|
-
process(action,
|
460
|
+
def delete(action, *args)
|
461
|
+
process(action, "DELETE", *args)
|
423
462
|
end
|
424
463
|
|
425
464
|
# Executes a request simulating HEAD HTTP method and set/volley the response
|
426
|
-
def head(action,
|
427
|
-
process(action,
|
465
|
+
def head(action, *args)
|
466
|
+
process(action, "HEAD", *args)
|
467
|
+
end
|
468
|
+
|
469
|
+
# Executes a request simulating OPTIONS HTTP method and set/volley the response
|
470
|
+
def options(action, *args)
|
471
|
+
process(action, "OPTIONS", *args)
|
428
472
|
end
|
429
473
|
|
430
474
|
def xml_http_request(request_method, action, parameters = nil, session = nil, flash = nil)
|
@@ -450,65 +494,94 @@ module ActionController
|
|
450
494
|
end
|
451
495
|
end
|
452
496
|
|
453
|
-
def process(action,
|
497
|
+
def process(action, http_method = 'GET', *args)
|
498
|
+
check_required_ivars
|
499
|
+
http_method, args = handle_old_process_api(http_method, args, caller)
|
500
|
+
|
501
|
+
if args.first.is_a?(String) && http_method != 'HEAD'
|
502
|
+
@request.env['RAW_POST_DATA'] = args.shift
|
503
|
+
end
|
504
|
+
|
505
|
+
parameters, session, flash = args
|
506
|
+
|
454
507
|
# Ensure that numbers and symbols passed as params are converted to
|
455
508
|
# proper params, as is the case when engaging rack.
|
456
509
|
parameters = paramify_values(parameters) if html_format?(parameters)
|
457
510
|
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
end
|
511
|
+
@html_document = nil
|
512
|
+
|
513
|
+
unless @controller.respond_to?(:recycle!)
|
514
|
+
@controller.extend(Testing::Functional)
|
515
|
+
@controller.class.class_eval { include Testing }
|
464
516
|
end
|
465
517
|
|
466
518
|
@request.recycle!
|
467
519
|
@response.recycle!
|
468
|
-
@controller.
|
469
|
-
@controller.formats = nil
|
470
|
-
@controller.params = nil
|
520
|
+
@controller.recycle!
|
471
521
|
|
472
|
-
@html_document = nil
|
473
522
|
@request.env['REQUEST_METHOD'] = http_method
|
474
523
|
|
475
524
|
parameters ||= {}
|
476
525
|
controller_class_name = @controller.class.anonymous? ?
|
477
|
-
"
|
478
|
-
@controller.class.
|
526
|
+
"anonymous" :
|
527
|
+
@controller.class.name.underscore.sub(/_controller$/, '')
|
479
528
|
|
480
529
|
@request.assign_parameters(@routes, controller_class_name, action.to_s, parameters)
|
481
530
|
|
482
|
-
@request.session
|
483
|
-
@request.
|
484
|
-
|
531
|
+
@request.session.update(session) if session
|
532
|
+
@request.flash.update(flash || {})
|
533
|
+
|
534
|
+
@controller.request = @request
|
535
|
+
@controller.response = @response
|
485
536
|
|
486
|
-
@controller.request = @request
|
487
537
|
build_request_uri(action, parameters)
|
488
|
-
|
489
|
-
@
|
490
|
-
|
538
|
+
|
539
|
+
name = @request.parameters[:action]
|
540
|
+
|
541
|
+
@controller.process(name)
|
542
|
+
|
543
|
+
if cookies = @request.env['action_dispatch.cookies']
|
544
|
+
cookies.write(@response)
|
545
|
+
end
|
546
|
+
@response.prepare!
|
547
|
+
|
491
548
|
@assigns = @controller.respond_to?(:view_assigns) ? @controller.view_assigns : {}
|
549
|
+
@request.session['flash'] = @request.flash.to_session_value
|
492
550
|
@request.session.delete('flash') if @request.session['flash'].blank?
|
493
551
|
@response
|
494
552
|
end
|
495
553
|
|
496
554
|
def setup_controller_request_and_response
|
497
|
-
@request
|
498
|
-
@response
|
555
|
+
@request = build_request
|
556
|
+
@response = build_response
|
557
|
+
@response.request = @request
|
558
|
+
|
559
|
+
@controller = nil unless defined? @controller
|
499
560
|
|
500
561
|
if klass = self.class.controller_class
|
501
|
-
@controller
|
562
|
+
unless @controller
|
563
|
+
begin
|
564
|
+
@controller = klass.new
|
565
|
+
rescue
|
566
|
+
warn "could not construct controller #{klass}" if $VERBOSE
|
567
|
+
end
|
568
|
+
end
|
502
569
|
end
|
503
570
|
|
504
|
-
@
|
505
|
-
|
506
|
-
if defined?(@controller) && @controller
|
571
|
+
if @controller
|
507
572
|
@controller.request = @request
|
508
573
|
@controller.params = {}
|
509
574
|
end
|
510
575
|
end
|
511
576
|
|
577
|
+
def build_request
|
578
|
+
TestRequest.new
|
579
|
+
end
|
580
|
+
|
581
|
+
def build_response
|
582
|
+
TestResponse.new
|
583
|
+
end
|
584
|
+
|
512
585
|
included do
|
513
586
|
include ActionController::TemplateAssertions
|
514
587
|
include ActionDispatch::Assertions
|
@@ -516,7 +589,27 @@ module ActionController
|
|
516
589
|
setup :setup_controller_request_and_response
|
517
590
|
end
|
518
591
|
|
519
|
-
|
592
|
+
private
|
593
|
+
def check_required_ivars
|
594
|
+
# Sanity check for required instance variables so we can give an
|
595
|
+
# understandable error message.
|
596
|
+
[:@routes, :@controller, :@request, :@response].each do |iv_name|
|
597
|
+
if !instance_variable_defined?(iv_name) || instance_variable_get(iv_name).nil?
|
598
|
+
raise "#{iv_name} is nil: make sure you set it in your test's setup method."
|
599
|
+
end
|
600
|
+
end
|
601
|
+
end
|
602
|
+
|
603
|
+
def handle_old_process_api(http_method, args, callstack)
|
604
|
+
# 4.0: Remove this method.
|
605
|
+
if http_method.is_a?(Hash)
|
606
|
+
ActiveSupport::Deprecation.warn("TestCase#process now expects the HTTP method as second argument: process(action, http_method, params, session, flash)", callstack)
|
607
|
+
args.unshift(http_method)
|
608
|
+
http_method = args.last.is_a?(String) ? args.last : "GET"
|
609
|
+
end
|
610
|
+
|
611
|
+
[http_method, args]
|
612
|
+
end
|
520
613
|
|
521
614
|
def build_request_uri(action, parameters)
|
522
615
|
unless @request.env["PATH_INFO"]
|
@@ -525,7 +618,7 @@ module ActionController
|
|
525
618
|
:only_path => true,
|
526
619
|
:action => action,
|
527
620
|
:relative_url_root => nil,
|
528
|
-
:
|
621
|
+
:_recall => @request.symbolized_path_parameters)
|
529
622
|
|
530
623
|
url, query_string = @routes.url_for(options).split("?", 2)
|
531
624
|
|
@@ -537,8 +630,7 @@ module ActionController
|
|
537
630
|
|
538
631
|
def html_format?(parameters)
|
539
632
|
return true unless parameters.is_a?(Hash)
|
540
|
-
|
541
|
-
format.nil? || format.html?
|
633
|
+
Mime.fetch(parameters[:format]) { Mime['html'] }.html?
|
542
634
|
end
|
543
635
|
end
|
544
636
|
|
@@ -549,7 +641,7 @@ module ActionController
|
|
549
641
|
#
|
550
642
|
# The exception is stored in the exception accessor for further inspection.
|
551
643
|
module RaiseActionExceptions
|
552
|
-
def self.included(base)
|
644
|
+
def self.included(base) #:nodoc:
|
553
645
|
unless base.method_defined?(:exception) && base.method_defined?(:exception=)
|
554
646
|
base.class_eval do
|
555
647
|
attr_accessor :exception
|