actionpack 1.13.6 → 2.0.0
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.
- data/CHANGELOG +1400 -20
- data/MIT-LICENSE +1 -1
- data/README +5 -5
- data/RUNNING_UNIT_TESTS +4 -5
- data/Rakefile +5 -6
- data/install.rb +2 -2
- data/lib/action_controller.rb +11 -15
- data/lib/action_controller/assertions.rb +12 -25
- data/lib/action_controller/assertions/dom_assertions.rb +18 -4
- data/lib/action_controller/assertions/model_assertions.rb +8 -1
- data/lib/action_controller/assertions/response_assertions.rb +35 -12
- data/lib/action_controller/assertions/routing_assertions.rb +56 -12
- data/lib/action_controller/assertions/selector_assertions.rb +105 -38
- data/lib/action_controller/assertions/tag_assertions.rb +28 -15
- data/lib/action_controller/base.rb +318 -250
- data/lib/action_controller/benchmarking.rb +33 -29
- data/lib/action_controller/caching.rb +130 -64
- data/lib/action_controller/cgi_ext.rb +16 -0
- data/lib/action_controller/cgi_ext/{cookie_performance_fix.rb → cookie.rb} +25 -40
- data/lib/action_controller/cgi_ext/query_extension.rb +22 -0
- data/lib/action_controller/cgi_ext/session.rb +73 -0
- data/lib/action_controller/cgi_ext/stdinput.rb +23 -0
- data/lib/action_controller/cgi_process.rb +34 -57
- data/lib/action_controller/components.rb +19 -36
- data/lib/action_controller/cookies.rb +10 -9
- data/lib/action_controller/dispatcher.rb +195 -0
- data/lib/action_controller/filters.rb +35 -34
- data/lib/action_controller/flash.rb +30 -35
- data/lib/action_controller/helpers.rb +121 -47
- data/lib/action_controller/http_authentication.rb +126 -0
- data/lib/action_controller/integration.rb +105 -101
- data/lib/action_controller/layout.rb +59 -47
- data/lib/action_controller/mime_responds.rb +57 -68
- data/lib/action_controller/mime_type.rb +43 -80
- data/lib/action_controller/mime_types.rb +20 -0
- data/lib/action_controller/polymorphic_routes.rb +88 -0
- data/lib/action_controller/record_identifier.rb +91 -0
- data/lib/action_controller/request.rb +553 -88
- data/lib/action_controller/request_forgery_protection.rb +126 -0
- data/lib/action_controller/request_profiler.rb +138 -0
- data/lib/action_controller/rescue.rb +185 -69
- data/lib/action_controller/resources.rb +211 -172
- data/lib/action_controller/response.rb +49 -8
- data/lib/action_controller/routing.rb +359 -236
- data/lib/action_controller/routing_optimisation.rb +119 -0
- data/lib/action_controller/session/active_record_store.rb +3 -2
- data/lib/action_controller/session/cookie_store.rb +161 -0
- data/lib/action_controller/session/mem_cache_store.rb +9 -16
- data/lib/action_controller/session_management.rb +17 -8
- data/lib/action_controller/streaming.rb +6 -3
- data/lib/action_controller/templates/rescues/_request_and_response.erb +24 -0
- data/lib/action_controller/templates/rescues/{_trace.rhtml → _trace.erb} +0 -0
- data/lib/action_controller/templates/rescues/{diagnostics.rhtml → diagnostics.erb} +2 -2
- data/lib/action_controller/templates/rescues/{layout.rhtml → layout.erb} +0 -0
- data/lib/action_controller/templates/rescues/{missing_template.rhtml → missing_template.erb} +0 -0
- data/lib/action_controller/templates/rescues/{routing_error.rhtml → routing_error.erb} +0 -0
- data/lib/action_controller/templates/rescues/{template_error.rhtml → template_error.erb} +2 -2
- data/lib/action_controller/templates/rescues/{unknown_action.rhtml → unknown_action.erb} +0 -0
- data/lib/action_controller/test_case.rb +53 -0
- data/lib/action_controller/test_process.rb +59 -46
- data/lib/action_controller/url_rewriter.rb +48 -24
- data/lib/action_controller/vendor/html-scanner/html/document.rb +7 -4
- data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +173 -0
- data/lib/action_controller/vendor/html-scanner/html/selector.rb +11 -6
- data/lib/action_controller/verification.rb +27 -21
- data/lib/action_pack.rb +1 -1
- data/lib/action_pack/version.rb +4 -4
- data/lib/action_view.rb +2 -3
- data/lib/action_view/base.rb +218 -63
- data/lib/action_view/compiled_templates.rb +1 -2
- data/lib/action_view/helpers/active_record_helper.rb +35 -17
- data/lib/action_view/helpers/asset_tag_helper.rb +395 -87
- data/lib/action_view/helpers/atom_feed_helper.rb +111 -0
- data/lib/action_view/helpers/benchmark_helper.rb +12 -5
- data/lib/action_view/helpers/cache_helper.rb +29 -0
- data/lib/action_view/helpers/capture_helper.rb +97 -63
- data/lib/action_view/helpers/date_helper.rb +295 -35
- data/lib/action_view/helpers/debug_helper.rb +6 -2
- data/lib/action_view/helpers/form_helper.rb +354 -111
- data/lib/action_view/helpers/form_options_helper.rb +171 -109
- data/lib/action_view/helpers/form_tag_helper.rb +332 -76
- data/lib/action_view/helpers/javascript_helper.rb +35 -11
- data/lib/action_view/helpers/javascripts/controls.js +484 -354
- data/lib/action_view/helpers/javascripts/dragdrop.js +88 -58
- data/lib/action_view/helpers/javascripts/effects.js +396 -364
- data/lib/action_view/helpers/javascripts/prototype.js +2817 -1107
- data/lib/action_view/helpers/number_helper.rb +84 -60
- data/lib/action_view/helpers/prototype_helper.rb +419 -43
- data/lib/action_view/helpers/record_identification_helper.rb +20 -0
- data/lib/action_view/helpers/record_tag_helper.rb +59 -0
- data/lib/action_view/helpers/sanitize_helper.rb +223 -0
- data/lib/action_view/helpers/scriptaculous_helper.rb +63 -4
- data/lib/action_view/helpers/tag_helper.rb +69 -39
- data/lib/action_view/helpers/text_helper.rb +221 -148
- data/lib/action_view/helpers/url_helper.rb +283 -165
- data/lib/action_view/partials.rb +134 -62
- data/lib/action_view/template_error.rb +4 -12
- data/lib/actionpack.rb +1 -0
- data/test/abstract_unit.rb +21 -1
- data/test/action_view_test.rb +26 -0
- data/test/active_record_unit.rb +12 -20
- data/test/activerecord/active_record_store_test.rb +2 -2
- data/test/activerecord/render_partial_with_record_identification_test.rb +74 -0
- data/test/controller/action_pack_assertions_test.rb +21 -152
- data/test/controller/addresses_render_test.rb +2 -7
- data/test/controller/assert_select_test.rb +120 -14
- data/test/controller/base_test.rb +11 -13
- data/test/controller/caching_test.rb +125 -5
- data/test/controller/capture_test.rb +23 -16
- data/test/controller/cgi_test.rb +66 -391
- data/test/controller/components_test.rb +31 -42
- data/test/controller/content_type_test.rb +1 -1
- data/test/controller/cookie_test.rb +42 -14
- data/test/controller/deprecation/deprecated_base_methods_test.rb +1 -42
- data/test/controller/dispatcher_test.rb +123 -0
- data/test/controller/fake_models.rb +5 -0
- data/test/controller/filters_test.rb +44 -7
- data/test/controller/flash_test.rb +46 -2
- data/test/controller/fragment_store_setting_test.rb +10 -8
- data/test/controller/helper_test.rb +19 -2
- data/test/controller/html-scanner/document_test.rb +124 -0
- data/test/controller/html-scanner/node_test.rb +69 -0
- data/test/controller/html-scanner/sanitizer_test.rb +250 -0
- data/test/controller/html-scanner/tag_node_test.rb +239 -0
- data/test/controller/html-scanner/text_node_test.rb +51 -0
- data/test/controller/html-scanner/tokenizer_test.rb +125 -0
- data/test/controller/http_authentication_test.rb +54 -0
- data/test/controller/integration_test.rb +12 -26
- data/test/controller/layout_test.rb +64 -12
- data/test/controller/mime_responds_test.rb +193 -38
- data/test/controller/mime_type_test.rb +30 -8
- data/test/controller/new_render_test.rb +104 -22
- data/test/controller/polymorphic_routes_test.rb +98 -0
- data/test/controller/record_identifier_test.rb +103 -0
- data/test/controller/redirect_test.rb +120 -18
- data/test/controller/render_test.rb +195 -45
- data/test/controller/request_forgery_protection_test.rb +217 -0
- data/test/controller/request_test.rb +545 -27
- data/test/controller/rescue_test.rb +501 -0
- data/test/controller/resources_test.rb +258 -132
- data/test/controller/routing_test.rb +502 -106
- data/test/controller/selector_test.rb +5 -5
- data/test/controller/send_file_test.rb +17 -7
- data/test/controller/session/cookie_store_test.rb +246 -0
- data/test/controller/session/mem_cache_store_test.rb +182 -0
- data/test/controller/session_fixation_test.rb +8 -11
- data/test/controller/session_management_test.rb +7 -7
- data/test/controller/test_test.rb +150 -38
- data/test/controller/url_rewriter_test.rb +87 -12
- data/test/controller/verification_test.rb +11 -0
- data/test/controller/view_paths_test.rb +137 -0
- data/test/controller/webservice_test.rb +11 -75
- data/test/fixtures/addresses/{list.rhtml → list.erb} +0 -0
- data/test/fixtures/db_definitions/sqlite.sql +2 -1
- data/test/fixtures/developer.rb +2 -0
- data/test/fixtures/fun/games/{hello_world.rhtml → hello_world.erb} +0 -0
- data/test/fixtures/helpers/fun/pdf_helper.rb +1 -1
- data/test/fixtures/layout_tests/alt/hello.rhtml +1 -0
- data/test/fixtures/layout_tests/layouts/multiple_extensions.html.erb +1 -0
- data/test/fixtures/layouts/{builder.rxml → builder.builder} +0 -0
- data/test/fixtures/layouts/{standard.rhtml → standard.erb} +0 -0
- data/test/fixtures/layouts/{talk_from_action.rhtml → talk_from_action.erb} +0 -0
- data/test/fixtures/layouts/{yield.rhtml → yield.erb} +0 -0
- data/test/fixtures/multipart/binary_file +0 -0
- data/test/fixtures/multipart/bracketed_param +5 -0
- data/test/fixtures/override/test/hello_world.erb +1 -0
- data/test/fixtures/override2/layouts/test/sub.erb +1 -0
- data/test/fixtures/post_test/layouts/post.html.erb +1 -0
- data/test/fixtures/post_test/layouts/super_post.iphone.erb +1 -0
- data/test/fixtures/post_test/post/index.html.erb +1 -0
- data/test/fixtures/post_test/post/index.iphone.erb +1 -0
- data/test/fixtures/post_test/super_post/index.html.erb +1 -0
- data/test/fixtures/post_test/super_post/index.iphone.erb +1 -0
- data/test/fixtures/public/404.html +1 -0
- data/test/fixtures/public/500.html +1 -0
- data/test/fixtures/public/javascripts/application.js +0 -1
- data/test/fixtures/public/javascripts/bank.js +1 -0
- data/test/fixtures/public/javascripts/robber.js +1 -0
- data/test/fixtures/public/stylesheets/bank.css +1 -0
- data/test/fixtures/public/stylesheets/robber.css +1 -0
- data/test/fixtures/replies.yml +2 -0
- data/test/fixtures/reply.rb +2 -1
- data/test/fixtures/respond_to/{all_types_with_layout.rhtml → all_types_with_layout.html.erb} +0 -0
- data/test/fixtures/respond_to/{all_types_with_layout.rjs → all_types_with_layout.js.rjs} +0 -0
- data/test/fixtures/respond_to/custom_constant_handling_without_block.mobile.erb +1 -0
- data/test/fixtures/respond_to/iphone_with_html_response_type.html.erb +1 -0
- data/test/fixtures/respond_to/iphone_with_html_response_type.iphone.erb +1 -0
- data/test/fixtures/respond_to/layouts/missing.html.erb +1 -0
- data/test/fixtures/respond_to/layouts/standard.html.erb +1 -0
- data/test/fixtures/respond_to/layouts/standard.iphone.erb +1 -0
- data/test/fixtures/respond_to/{using_defaults.rhtml → using_defaults.html.erb} +0 -0
- data/test/fixtures/respond_to/{using_defaults.rjs → using_defaults.js.rjs} +0 -0
- data/test/fixtures/respond_to/{using_defaults.rxml → using_defaults.xml.builder} +0 -0
- data/test/fixtures/respond_to/{using_defaults_with_type_list.rhtml → using_defaults_with_type_list.html.erb} +0 -0
- data/test/fixtures/respond_to/{using_defaults_with_type_list.rjs → using_defaults_with_type_list.js.rjs} +0 -0
- data/test/fixtures/respond_to/{using_defaults_with_type_list.rxml → using_defaults_with_type_list.xml.builder} +0 -0
- data/test/fixtures/scope/test/{modgreet.rhtml → modgreet.erb} +0 -0
- data/test/fixtures/test/{_customer.rhtml → _customer.erb} +0 -0
- data/test/fixtures/test/{_customer_greeting.rhtml → _customer_greeting.erb} +0 -0
- data/test/fixtures/test/_hash_greeting.erb +1 -0
- data/test/fixtures/test/_hash_object.erb +2 -0
- data/test/fixtures/test/{_hello.rxml → _hello.builder} +0 -0
- data/test/fixtures/test/_layout_for_partial.html.erb +3 -0
- data/test/fixtures/test/_partial.erb +1 -0
- data/test/fixtures/test/_partial.html.erb +1 -0
- data/test/fixtures/test/_partial.js.erb +1 -0
- data/test/fixtures/test/_partial_for_use_in_layout.html.erb +1 -0
- data/test/fixtures/test/{_partial_only.rhtml → _partial_only.erb} +0 -0
- data/test/fixtures/test/{_person.rhtml → _person.erb} +0 -0
- data/test/fixtures/test/{action_talk_to_layout.rhtml → action_talk_to_layout.erb} +0 -0
- data/test/fixtures/test/{block_content_for.rhtml → block_content_for.erb} +0 -0
- data/test/fixtures/test/calling_partial_with_layout.html.erb +1 -0
- data/test/fixtures/test/{capturing.rhtml → capturing.erb} +0 -0
- data/test/fixtures/test/{content_for.rhtml → content_for.erb} +0 -0
- data/test/fixtures/test/content_for_concatenated.erb +3 -0
- data/test/fixtures/test/content_for_with_parameter.erb +2 -0
- data/test/fixtures/test/dot.directory/{render_file_with_ivar.rhtml → render_file_with_ivar.erb} +0 -0
- data/test/fixtures/test/{erb_content_for.rhtml → erb_content_for.erb} +0 -0
- data/test/fixtures/test/formatted_html_erb.html.erb +1 -0
- data/test/fixtures/test/formatted_xml_erb.builder +1 -0
- data/test/fixtures/test/formatted_xml_erb.html.erb +1 -0
- data/test/fixtures/test/formatted_xml_erb.xml.erb +1 -0
- data/test/fixtures/test/{greeting.rhtml → greeting.erb} +0 -0
- data/test/fixtures/test/{hello.rxml → hello.builder} +0 -0
- data/test/fixtures/test/{hello_world.rxml → hello_world.builder} +0 -0
- data/test/fixtures/test/{hello_world.rhtml → hello_world.erb} +0 -0
- data/test/fixtures/test/{hello_world_container.rxml → hello_world_container.builder} +0 -0
- data/test/fixtures/test/{hello_world_with_layout_false.rhtml → hello_world_with_layout_false.erb} +0 -0
- data/test/fixtures/test/{hello_xml_world.rxml → hello_xml_world.builder} +0 -0
- data/test/fixtures/test/list.erb +1 -0
- data/test/fixtures/test/{non_erb_block_content_for.rxml → non_erb_block_content_for.builder} +0 -0
- data/test/fixtures/test/{potential_conflicts.rhtml → potential_conflicts.erb} +0 -0
- data/test/fixtures/test/{render_file_with_ivar.rhtml → render_file_with_ivar.erb} +0 -0
- data/test/fixtures/test/{render_file_with_locals.rhtml → render_file_with_locals.erb} +0 -0
- data/test/fixtures/test/{render_to_string_test.rhtml → render_to_string_test.erb} +0 -0
- data/test/fixtures/test/{update_element_with_capture.rhtml → update_element_with_capture.erb} +0 -0
- data/test/fixtures/test/using_layout_around_block.html.erb +1 -0
- data/test/fixtures/topic.rb +1 -1
- data/test/template/active_record_helper_test.rb +67 -20
- data/test/template/asset_tag_helper_test.rb +222 -54
- data/test/template/atom_feed_helper_test.rb +101 -0
- data/test/template/benchmark_helper_test.rb +2 -2
- data/test/template/compiled_templates_test.rb +76 -32
- data/test/template/date_helper_test.rb +125 -9
- data/test/template/form_helper_test.rb +326 -33
- data/test/template/form_options_helper_test.rb +822 -15
- data/test/template/form_tag_helper_test.rb +96 -30
- data/test/template/javascript_helper_test.rb +61 -13
- data/test/template/number_helper_test.rb +12 -11
- data/test/template/prototype_helper_test.rb +185 -24
- data/test/template/sanitize_helper_test.rb +49 -0
- data/test/template/scriptaculous_helper_test.rb +9 -3
- data/test/template/tag_helper_test.rb +13 -2
- data/test/template/text_helper_test.rb +38 -52
- data/test/template/url_helper_test.rb +216 -46
- metadata +144 -116
- data/examples/.htaccess +0 -24
- data/examples/address_book/index.rhtml +0 -33
- data/examples/address_book/layout.rhtml +0 -8
- data/examples/address_book_controller.cgi +0 -9
- data/examples/address_book_controller.fcgi +0 -6
- data/examples/address_book_controller.rb +0 -52
- data/examples/address_book_controller.rbx +0 -4
- data/examples/benchmark.rb +0 -52
- data/examples/benchmark_with_ar.fcgi +0 -89
- data/examples/blog_controller.cgi +0 -53
- data/examples/debate/index.rhtml +0 -14
- data/examples/debate/new_topic.rhtml +0 -22
- data/examples/debate/topic.rhtml +0 -32
- data/examples/debate_controller.cgi +0 -57
- data/lib/action_controller/assertions/deprecated_assertions.rb +0 -228
- data/lib/action_controller/cgi_ext/cgi_ext.rb +0 -36
- data/lib/action_controller/cgi_ext/cgi_methods.rb +0 -211
- data/lib/action_controller/cgi_ext/pstore_performance_fix.rb +0 -30
- data/lib/action_controller/cgi_ext/raw_post_data_fix.rb +0 -95
- data/lib/action_controller/cgi_ext/session_performance_fix.rb +0 -30
- data/lib/action_controller/deprecated_dependencies.rb +0 -65
- data/lib/action_controller/deprecated_redirects.rb +0 -17
- data/lib/action_controller/deprecated_request_methods.rb +0 -34
- data/lib/action_controller/macros/auto_complete.rb +0 -53
- data/lib/action_controller/macros/in_place_editing.rb +0 -33
- data/lib/action_controller/pagination.rb +0 -408
- data/lib/action_controller/scaffolding.rb +0 -189
- data/lib/action_controller/templates/rescues/_request_and_response.rhtml +0 -44
- data/lib/action_controller/templates/scaffolds/edit.rhtml +0 -7
- data/lib/action_controller/templates/scaffolds/layout.rhtml +0 -69
- data/lib/action_controller/templates/scaffolds/list.rhtml +0 -27
- data/lib/action_controller/templates/scaffolds/new.rhtml +0 -6
- data/lib/action_controller/templates/scaffolds/show.rhtml +0 -9
- data/lib/action_controller/vendor/xml_node.rb +0 -97
- data/lib/action_view/helpers/deprecated_helper.rb +0 -37
- data/lib/action_view/helpers/java_script_macros_helper.rb +0 -233
- data/lib/action_view/helpers/pagination_helper.rb +0 -86
- data/test/activerecord/active_record_assertions_test.rb +0 -92
- data/test/activerecord/pagination_test.rb +0 -165
- data/test/controller/deprecated_instance_variables_test.rb +0 -48
- data/test/controller/raw_post_test.rb +0 -68
- data/test/fixtures/deprecated_instance_variables/_cookies_ivar.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_cookies_method.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_flash_ivar.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_flash_method.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_headers_ivar.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_headers_method.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_params_ivar.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_params_method.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_request_ivar.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_request_method.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_response_ivar.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_response_method.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_session_ivar.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_session_method.rhtml +0 -1
- data/test/fixtures/respond_to/layouts/standard.rhtml +0 -1
- data/test/fixtures/test/_hash_object.rhtml +0 -1
- data/test/fixtures/test/list.rhtml +0 -1
- data/test/template/deprecated_helper_test.rb +0 -36
- data/test/template/deprecated_instance_variables_test.rb +0 -43
- data/test/template/java_script_macros_helper_test.rb +0 -109
@@ -1,5 +1,7 @@
|
|
1
1
|
module ActionController #:nodoc:
|
2
2
|
module Helpers #:nodoc:
|
3
|
+
HELPERS_DIR = (defined?(RAILS_ROOT) ? "#{RAILS_ROOT}/app/helpers" : "app/helpers")
|
4
|
+
|
3
5
|
def self.included(base)
|
4
6
|
# Initialize the base module to aggregate its helpers.
|
5
7
|
base.class_inheritable_accessor :master_helper_module
|
@@ -16,64 +18,120 @@ module ActionController #:nodoc:
|
|
16
18
|
end
|
17
19
|
end
|
18
20
|
|
19
|
-
# The
|
20
|
-
#
|
21
|
-
#
|
21
|
+
# The Rails framework provides a large number of helpers for working with +assets+, +dates+, +forms+,
|
22
|
+
# +numbers+ and +ActiveRecord+ objects, to name a few. These helpers are available to all templates
|
23
|
+
# by default.
|
22
24
|
#
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#
|
25
|
+
# In addition to using the standard template helpers provided in the Rails framework, creating custom helpers to
|
26
|
+
# extract complicated logic or reusable functionality is strongly encouraged. By default, the controller will
|
27
|
+
# include a helper whose name matches that of the controller, e.g., <tt>MyController</tt> will automatically
|
28
|
+
# include <tt>MyHelper</tt>.
|
26
29
|
#
|
27
|
-
#
|
28
|
-
#
|
30
|
+
# Additional helpers can be specified using the +helper+ class method in <tt>ActionController::Base</tt> or any
|
31
|
+
# controller which inherits from it.
|
32
|
+
#
|
33
|
+
# ==== Examples
|
34
|
+
# The +to_s+ method from the +Time+ class can be wrapped in a helper method to display a custom message if
|
35
|
+
# the Time object is blank:
|
36
|
+
#
|
37
|
+
# module FormattedTimeHelper
|
38
|
+
# def format_time(time, format=:long, blank_message=" ")
|
39
|
+
# time.blank? ? blank_message : time.to_s(format)
|
40
|
+
# end
|
29
41
|
# end
|
30
|
-
#
|
31
|
-
#
|
32
|
-
#
|
33
|
-
# class
|
34
|
-
# helper
|
42
|
+
#
|
43
|
+
# +FormattedTimeHelper+ can now be included in a controller, using the +helper+ class method:
|
44
|
+
#
|
45
|
+
# class EventsController < ActionController::Base
|
46
|
+
# helper FormattedTimeHelper
|
47
|
+
# def index
|
48
|
+
# @events = Event.find(:all)
|
49
|
+
# end
|
35
50
|
# end
|
36
|
-
#
|
37
|
-
#
|
38
|
-
#
|
39
|
-
#
|
51
|
+
#
|
52
|
+
# Then, in any view rendered by <tt>EventController</tt>, the <tt>format_time</tt> method can be called:
|
53
|
+
#
|
54
|
+
# <% @events.each do |event| -%>
|
55
|
+
# <p>
|
56
|
+
# <% format_time(event.time, :short, "N/A") %> | <%= event.name %>
|
57
|
+
# </p>
|
58
|
+
# <% end -%>
|
59
|
+
#
|
60
|
+
# Finally, assuming we have two event instances, one which has a time and one which does not,
|
61
|
+
# the output might look like this:
|
62
|
+
#
|
63
|
+
# 23 Aug 11:30 | Carolina Railhawks Soccer Match
|
64
|
+
# N/A | Carolina Railhaws Training Workshop
|
65
|
+
#
|
40
66
|
module ClassMethods
|
41
67
|
# Makes all the (instance) methods in the helper module available to templates rendered through this controller.
|
42
|
-
# See ActionView::Helpers (link:classes/ActionView/Helpers.html) for more about making your own helper modules
|
68
|
+
# See ActionView::Helpers (link:classes/ActionView/Helpers.html) for more about making your own helper modules
|
43
69
|
# available to the templates.
|
44
70
|
def add_template_helper(helper_module) #:nodoc:
|
45
|
-
master_helper_module.
|
71
|
+
master_helper_module.module_eval { include helper_module }
|
46
72
|
end
|
47
73
|
|
48
|
-
#
|
49
|
-
#
|
50
|
-
#
|
51
|
-
#
|
52
|
-
#
|
53
|
-
#
|
54
|
-
#
|
74
|
+
# The +helper+ class method can take a series of helper module names, a block, or both.
|
75
|
+
#
|
76
|
+
# * <tt>*args</tt>: One or more +Modules+, +Strings+ or +Symbols+, or the special symbol <tt>:all</tt>.
|
77
|
+
# * <tt>&block</tt>: A block defining helper methods.
|
78
|
+
#
|
79
|
+
# ==== Examples
|
80
|
+
# When the argument is a +String+ or +Symbol+, the method will provide the "_helper" suffix, require the file
|
81
|
+
# and include the module in the template class. The second form illustrates how to include custom helpers
|
82
|
+
# when working with namespaced controllers, or other cases where the file containing the helper definition is not
|
83
|
+
# in one of Rails' standard load paths:
|
84
|
+
# helper :foo # => requires 'foo_helper' and includes FooHelper
|
85
|
+
# helper 'resources/foo' # => requires 'resources/foo_helper' and includes Resources::FooHelper
|
86
|
+
#
|
87
|
+
# When the argument is a +Module+, it will be included directly in the template class.
|
88
|
+
# helper FooHelper # => includes FooHelper
|
89
|
+
#
|
90
|
+
# When the argument is the symbol <tt>:all</tt>, the controller will include all helpers from
|
91
|
+
# <tt>app/helpers/**/*.rb</tt> under +RAILS_ROOT+.
|
92
|
+
# helper :all
|
93
|
+
#
|
94
|
+
# Additionally, the +helper+ class method can receive and evaluate a block, making the methods defined available
|
95
|
+
# to the template.
|
96
|
+
# # One line
|
97
|
+
# helper { def hello() "Hello, world!" end }
|
98
|
+
# # Multi-line
|
99
|
+
# helper do
|
100
|
+
# def foo(bar)
|
101
|
+
# "#{bar} is the very best"
|
102
|
+
# end
|
103
|
+
# end
|
104
|
+
#
|
105
|
+
# Finally, all the above styles can be mixed together, and the +helper+ method can be invoked with a mix of
|
106
|
+
# +symbols+, +strings+, +modules+ and blocks.
|
55
107
|
# helper(:three, BlindHelper) { def mice() 'mice' end }
|
56
|
-
#
|
108
|
+
#
|
57
109
|
def helper(*args, &block)
|
58
110
|
args.flatten.each do |arg|
|
59
111
|
case arg
|
60
112
|
when Module
|
61
113
|
add_template_helper(arg)
|
114
|
+
when :all
|
115
|
+
helper(all_application_helpers)
|
62
116
|
when String, Symbol
|
63
117
|
file_name = arg.to_s.underscore + '_helper'
|
64
118
|
class_name = file_name.camelize
|
65
|
-
|
119
|
+
|
66
120
|
begin
|
67
121
|
require_dependency(file_name)
|
68
122
|
rescue LoadError => load_error
|
69
123
|
requiree = / -- (.*?)(\.rb)?$/.match(load_error).to_a[1]
|
70
|
-
|
71
|
-
|
124
|
+
if requiree == file_name
|
125
|
+
msg = "Missing helper file helpers/#{file_name}.rb"
|
126
|
+
raise LoadError.new(msg).copy_blame!(load_error)
|
127
|
+
else
|
128
|
+
raise
|
129
|
+
end
|
72
130
|
end
|
73
131
|
|
74
132
|
add_template_helper(class_name.constantize)
|
75
133
|
else
|
76
|
-
raise ArgumentError,
|
134
|
+
raise ArgumentError, "helper expects String, Symbol, or Module argument (was: #{args.inspect})"
|
77
135
|
end
|
78
136
|
end
|
79
137
|
|
@@ -81,10 +139,14 @@ module ActionController #:nodoc:
|
|
81
139
|
master_helper_module.module_eval(&block) if block_given?
|
82
140
|
end
|
83
141
|
|
84
|
-
# Declare a controller method as a helper.
|
85
|
-
#
|
86
|
-
#
|
87
|
-
#
|
142
|
+
# Declare a controller method as a helper. For example, the following
|
143
|
+
# makes the +current_user+ controller method available to the view:
|
144
|
+
# class ApplicationController < ActionController::Base
|
145
|
+
# helper_method :current_user
|
146
|
+
# def current_user
|
147
|
+
# @current_user ||= User.find(session[:user])
|
148
|
+
# end
|
149
|
+
# end
|
88
150
|
def helper_method(*methods)
|
89
151
|
methods.flatten.each do |method|
|
90
152
|
master_helper_module.module_eval <<-end_eval
|
@@ -95,37 +157,49 @@ module ActionController #:nodoc:
|
|
95
157
|
end
|
96
158
|
end
|
97
159
|
|
98
|
-
#
|
160
|
+
# Declares helper accessors for controller attributes. For example, the
|
161
|
+
# following adds new +name+ and <tt>name=</tt> instance methods to a
|
162
|
+
# controller and makes them available to the view:
|
99
163
|
# helper_attr :name
|
100
164
|
# attr_accessor :name
|
101
|
-
# makes the name and name= controller methods available in the view.
|
102
|
-
# The is a convenience wrapper for helper_method.
|
103
165
|
def helper_attr(*attrs)
|
104
166
|
attrs.flatten.each { |attr| helper_method(attr, "#{attr}=") }
|
105
167
|
end
|
106
168
|
|
107
|
-
|
169
|
+
|
170
|
+
private
|
108
171
|
def default_helper_module!
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
172
|
+
unless name.blank?
|
173
|
+
module_name = name.sub(/Controller$|$/, 'Helper')
|
174
|
+
module_path = module_name.split('::').map { |m| m.underscore }.join('/')
|
175
|
+
require_dependency module_path
|
176
|
+
helper module_name.constantize
|
177
|
+
end
|
178
|
+
rescue MissingSourceFile => e
|
179
|
+
raise unless e.is_missing? module_path
|
114
180
|
logger.debug("#{name}: missing default helper path #{module_path}") if logger
|
115
|
-
rescue NameError
|
181
|
+
rescue NameError => e
|
182
|
+
raise unless e.missing_name? module_name
|
116
183
|
logger.debug("#{name}: missing default helper module #{module_name}") if logger
|
117
184
|
end
|
118
185
|
|
119
186
|
def inherited_with_helper(child)
|
120
187
|
inherited_without_helper(child)
|
188
|
+
|
121
189
|
begin
|
122
190
|
child.master_helper_module = Module.new
|
123
|
-
child.master_helper_module.send :include, master_helper_module
|
124
|
-
child.send :default_helper_module!
|
191
|
+
child.master_helper_module.send! :include, master_helper_module
|
192
|
+
child.send! :default_helper_module!
|
125
193
|
rescue MissingSourceFile => e
|
126
194
|
raise unless e.is_missing?("helpers/#{child.controller_path}_helper")
|
127
195
|
end
|
128
196
|
end
|
197
|
+
|
198
|
+
# Extract helper names from files in app/helpers/**/*.rb
|
199
|
+
def all_application_helpers
|
200
|
+
extract = /^#{Regexp.quote(HELPERS_DIR)}\/?(.*)_helper.rb$/
|
201
|
+
Dir["#{HELPERS_DIR}/**/*_helper.rb"].map { |file| file.sub extract, '\1' }
|
202
|
+
end
|
129
203
|
end
|
130
204
|
end
|
131
205
|
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
require 'base64'
|
2
|
+
|
3
|
+
module ActionController
|
4
|
+
module HttpAuthentication
|
5
|
+
# Makes it dead easy to do HTTP Basic authentication.
|
6
|
+
#
|
7
|
+
# Simple Basic example:
|
8
|
+
#
|
9
|
+
# class PostsController < ApplicationController
|
10
|
+
# USER_NAME, PASSWORD = "dhh", "secret"
|
11
|
+
#
|
12
|
+
# before_filter :authenticate, :except => [ :index ]
|
13
|
+
#
|
14
|
+
# def index
|
15
|
+
# render :text => "Everyone can see me!"
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# def edit
|
19
|
+
# render :text => "I'm only accessible if you know the password"
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# private
|
23
|
+
# def authenticate
|
24
|
+
# authenticate_or_request_with_http_basic do |user_name, password|
|
25
|
+
# user_name == USER_NAME && password == PASSWORD
|
26
|
+
# end
|
27
|
+
# end
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
#
|
31
|
+
# Here is a more advanced Basic example where only Atom feeds and the XML API is protected by HTTP authentication,
|
32
|
+
# the regular HTML interface is protected by a session approach:
|
33
|
+
#
|
34
|
+
# class ApplicationController < ActionController::Base
|
35
|
+
# before_filter :set_account, :authenticate
|
36
|
+
#
|
37
|
+
# protected
|
38
|
+
# def set_account
|
39
|
+
# @account = Account.find_by_url_name(request.subdomains.first)
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
# def authenticate
|
43
|
+
# case request.format
|
44
|
+
# when Mime::XML, Mime::ATOM
|
45
|
+
# if user = authenticate_with_http_basic { |u, p| @account.users.authenticate(u, p) }
|
46
|
+
# @current_user = user
|
47
|
+
# else
|
48
|
+
# request_http_basic_authentication
|
49
|
+
# end
|
50
|
+
# else
|
51
|
+
# if session_authenticated?
|
52
|
+
# @current_user = @account.users.find(session[:authenticated][:user_id])
|
53
|
+
# else
|
54
|
+
# redirect_to(login_url) and return false
|
55
|
+
# end
|
56
|
+
# end
|
57
|
+
# end
|
58
|
+
# end
|
59
|
+
#
|
60
|
+
#
|
61
|
+
# In your integration tests, you can do something like this:
|
62
|
+
#
|
63
|
+
# def test_access_granted_from_xml
|
64
|
+
# get(
|
65
|
+
# "/notes/1.xml", nil,
|
66
|
+
# :authorization => ActionController::HttpAuthentication::Basic.encode_credentials(users(:dhh).name, users(:dhh).password)
|
67
|
+
# )
|
68
|
+
#
|
69
|
+
# assert_equal 200, status
|
70
|
+
# end
|
71
|
+
#
|
72
|
+
#
|
73
|
+
# On shared hosts, Apache sometimes doesn't pass authentication headers to
|
74
|
+
# FCGI instances. If your environment matches this description and you cannot
|
75
|
+
# authenticate, try this rule in public/.htaccess (replace the plain one):
|
76
|
+
#
|
77
|
+
# RewriteRule ^(.*)$ dispatch.fcgi [E=X-HTTP_AUTHORIZATION:%{HTTP:Authorization},QSA,L]
|
78
|
+
module Basic
|
79
|
+
extend self
|
80
|
+
|
81
|
+
module ControllerMethods
|
82
|
+
def authenticate_or_request_with_http_basic(realm = "Application", &login_procedure)
|
83
|
+
authenticate_with_http_basic(&login_procedure) || request_http_basic_authentication(realm)
|
84
|
+
end
|
85
|
+
|
86
|
+
def authenticate_with_http_basic(&login_procedure)
|
87
|
+
HttpAuthentication::Basic.authenticate(self, &login_procedure)
|
88
|
+
end
|
89
|
+
|
90
|
+
def request_http_basic_authentication(realm = "Application")
|
91
|
+
HttpAuthentication::Basic.authentication_request(self, realm)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def authenticate(controller, &login_procedure)
|
96
|
+
unless authorization(controller.request).blank?
|
97
|
+
login_procedure.call(*user_name_and_password(controller.request))
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def user_name_and_password(request)
|
102
|
+
decode_credentials(request).split(/:/, 2)
|
103
|
+
end
|
104
|
+
|
105
|
+
def authorization(request)
|
106
|
+
request.env['HTTP_AUTHORIZATION'] ||
|
107
|
+
request.env['X-HTTP_AUTHORIZATION'] ||
|
108
|
+
request.env['X_HTTP_AUTHORIZATION'] ||
|
109
|
+
request.env['REDIRECT_X_HTTP_AUTHORIZATION']
|
110
|
+
end
|
111
|
+
|
112
|
+
def decode_credentials(request)
|
113
|
+
Base64.decode64(authorization(request).split.last || '')
|
114
|
+
end
|
115
|
+
|
116
|
+
def encode_credentials(user_name, password)
|
117
|
+
"Basic #{Base64.encode64("#{user_name}:#{password}")}"
|
118
|
+
end
|
119
|
+
|
120
|
+
def authentication_request(controller, realm)
|
121
|
+
controller.headers["WWW-Authenticate"] = %(Basic realm="#{realm.gsub(/"/, "")}")
|
122
|
+
controller.send! :render, :text => "HTTP Basic: Access denied.\n", :status => :unauthorized
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -51,7 +51,10 @@ module ActionController
|
|
51
51
|
# A reference to the response instance used by the last request.
|
52
52
|
attr_reader :response
|
53
53
|
|
54
|
-
#
|
54
|
+
# A running counter of the number of requests processed.
|
55
|
+
attr_accessor :request_count
|
56
|
+
|
57
|
+
# Create and initialize a new +Session+ instance.
|
55
58
|
def initialize
|
56
59
|
reset!
|
57
60
|
end
|
@@ -67,19 +70,20 @@ module ActionController
|
|
67
70
|
@https = false
|
68
71
|
@cookies = {}
|
69
72
|
@controller = @request = @response = nil
|
73
|
+
@request_count = 0
|
70
74
|
|
71
75
|
self.host = "www.example.com"
|
72
76
|
self.remote_addr = "127.0.0.1"
|
73
77
|
self.accept = "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"
|
74
78
|
|
75
|
-
unless @named_routes_configured
|
79
|
+
unless defined? @named_routes_configured
|
76
80
|
# install the named routes in this session instance.
|
77
81
|
klass = class<<self; self; end
|
78
|
-
Routing::Routes.
|
82
|
+
Routing::Routes.install_helpers(klass)
|
79
83
|
|
80
84
|
# the helpers are made protected by default--we make them public for
|
81
85
|
# easier access during testing and troubleshooting.
|
82
|
-
klass.
|
86
|
+
klass.module_eval { public *Routing::Routes.named_routes.helpers }
|
83
87
|
@named_routes_configured = true
|
84
88
|
end
|
85
89
|
end
|
@@ -120,17 +124,18 @@ module ActionController
|
|
120
124
|
# Performs a GET request, following any subsequent redirect. Note that
|
121
125
|
# the redirects are followed until the response is not a redirect--this
|
122
126
|
# means you may run into an infinite loop if your redirect loops back to
|
123
|
-
# itself.
|
124
|
-
def get_via_redirect(path, args={})
|
125
|
-
get path, args
|
127
|
+
# itself. Headers are treated in the same way as #get.
|
128
|
+
def get_via_redirect(path, args={}, headers = {})
|
129
|
+
get path, args, headers
|
126
130
|
follow_redirect! while redirect?
|
127
131
|
status
|
128
132
|
end
|
129
133
|
|
130
134
|
# Performs a POST request, following any subsequent redirect. This is
|
131
|
-
# vulnerable to infinite loops, the same as #get_via_redirect.
|
132
|
-
|
133
|
-
|
135
|
+
# vulnerable to infinite loops, the same as #get_via_redirect. Headers are
|
136
|
+
# treated in the same way as #get.
|
137
|
+
def post_via_redirect(path, args={}, headers = {})
|
138
|
+
post path, args, headers
|
134
139
|
follow_redirect! while redirect?
|
135
140
|
status
|
136
141
|
end
|
@@ -148,27 +153,27 @@ module ActionController
|
|
148
153
|
#
|
149
154
|
# You can also perform POST, PUT, DELETE, and HEAD requests with #post,
|
150
155
|
# #put, #delete, and #head.
|
151
|
-
def get(path, parameters=nil, headers=nil)
|
156
|
+
def get(path, parameters = nil, headers = nil)
|
152
157
|
process :get, path, parameters, headers
|
153
158
|
end
|
154
159
|
|
155
160
|
# Performs a POST request with the given parameters. See get() for more details.
|
156
|
-
def post(path, parameters=nil, headers=nil)
|
161
|
+
def post(path, parameters = nil, headers = nil)
|
157
162
|
process :post, path, parameters, headers
|
158
163
|
end
|
159
164
|
|
160
165
|
# Performs a PUT request with the given parameters. See get() for more details.
|
161
|
-
def put(path, parameters=nil, headers=nil)
|
166
|
+
def put(path, parameters = nil, headers = nil)
|
162
167
|
process :put, path, parameters, headers
|
163
168
|
end
|
164
169
|
|
165
170
|
# Performs a DELETE request with the given parameters. See get() for more details.
|
166
|
-
def delete(path, parameters=nil, headers=nil)
|
171
|
+
def delete(path, parameters = nil, headers = nil)
|
167
172
|
process :delete, path, parameters, headers
|
168
173
|
end
|
169
174
|
|
170
175
|
# Performs a HEAD request with the given parameters. See get() for more details.
|
171
|
-
def head(path, parameters=nil, headers=nil)
|
176
|
+
def head(path, parameters = nil, headers = nil)
|
172
177
|
process :head, path, parameters, headers
|
173
178
|
end
|
174
179
|
|
@@ -179,16 +184,7 @@ module ActionController
|
|
179
184
|
# parameters are +nil+, a hash, or a url-encoded or multipart string;
|
180
185
|
# the headers are a hash. Keys are automatically upcased and prefixed
|
181
186
|
# with 'HTTP_' if not already.
|
182
|
-
#
|
183
|
-
# This method used to omit the request_method parameter, assuming it
|
184
|
-
# was :post. This was deprecated in Rails 1.2.4. Always pass the request
|
185
|
-
# method as the first argument.
|
186
187
|
def xml_http_request(request_method, path, parameters = nil, headers = nil)
|
187
|
-
unless request_method.is_a?(Symbol)
|
188
|
-
ActiveSupport::Deprecation.warn 'xml_http_request now takes the request_method (:get, :post, etc.) as the first argument. It used to assume :post, so add the :post argument to your existing method calls to silence this warning.'
|
189
|
-
request_method, path, parameters, headers = :post, request_method, path, parameters
|
190
|
-
end
|
191
|
-
|
192
188
|
headers ||= {}
|
193
189
|
headers['X-Requested-With'] = 'XMLHttpRequest'
|
194
190
|
headers['Accept'] = 'text/javascript, text/html, application/xml, text/xml, */*'
|
@@ -204,15 +200,16 @@ module ActionController
|
|
204
200
|
end
|
205
201
|
|
206
202
|
private
|
207
|
-
class
|
203
|
+
class StubCGI < CGI #:nodoc:
|
208
204
|
attr_accessor :stdinput, :stdoutput, :env_table
|
209
205
|
|
210
|
-
def initialize(env,
|
206
|
+
def initialize(env, stdinput = nil)
|
211
207
|
self.env_table = env
|
212
|
-
self.stdinput = StringIO.new(input || "")
|
213
208
|
self.stdoutput = StringIO.new
|
214
209
|
|
215
|
-
super
|
210
|
+
super
|
211
|
+
|
212
|
+
@stdinput = stdinput.is_a?(IO) ? stdinput : StringIO.new(stdinput || '')
|
216
213
|
end
|
217
214
|
end
|
218
215
|
|
@@ -226,7 +223,7 @@ module ActionController
|
|
226
223
|
end
|
227
224
|
|
228
225
|
# Performs the actual request.
|
229
|
-
def process(method, path, parameters=nil, headers=nil)
|
226
|
+
def process(method, path, parameters = nil, headers = nil)
|
230
227
|
data = requestify(parameters)
|
231
228
|
path = interpret_uri(path) if path =~ %r{://}
|
232
229
|
path = "/#{path}" unless path[0] == ?/
|
@@ -258,14 +255,15 @@ module ActionController
|
|
258
255
|
end
|
259
256
|
|
260
257
|
unless ActionController::Base.respond_to?(:clear_last_instantiation!)
|
261
|
-
ActionController::Base.
|
258
|
+
ActionController::Base.module_eval { include ControllerCapture }
|
262
259
|
end
|
263
260
|
|
264
261
|
ActionController::Base.clear_last_instantiation!
|
265
262
|
|
266
|
-
cgi =
|
263
|
+
cgi = StubCGI.new(env, data)
|
267
264
|
Dispatcher.dispatch(cgi, ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS, cgi.stdoutput)
|
268
265
|
@result = cgi.stdoutput.string
|
266
|
+
@request_count += 1
|
269
267
|
|
270
268
|
@controller = ActionController::Base.last_instantiation
|
271
269
|
@request = @controller.request
|
@@ -294,7 +292,7 @@ module ActionController
|
|
294
292
|
end
|
295
293
|
|
296
294
|
(@headers['set-cookie'] || [] ).each do |string|
|
297
|
-
name, value = string.match(/^(
|
295
|
+
name, value = string.match(/^([^=]*)=([^;]*);/)[1,2]
|
298
296
|
@cookies[name] = value
|
299
297
|
end
|
300
298
|
|
@@ -310,14 +308,14 @@ module ActionController
|
|
310
308
|
end
|
311
309
|
end
|
312
310
|
|
313
|
-
# Get a
|
311
|
+
# Get a temporary URL writer object
|
314
312
|
def generic_url_rewriter
|
315
|
-
cgi =
|
313
|
+
cgi = StubCGI.new('REQUEST_METHOD' => "GET",
|
316
314
|
'QUERY_STRING' => "",
|
317
315
|
"REQUEST_URI" => "/",
|
318
316
|
"HTTP_HOST" => host,
|
319
317
|
"SERVER_PORT" => https? ? "443" : "80",
|
320
|
-
"HTTPS" => https? ? "on" : "off")
|
318
|
+
"HTTPS" => https? ? "on" : "off")
|
321
319
|
ActionController::UrlRewriter.new(ActionController::CgiRequest.new(cgi), {})
|
322
320
|
end
|
323
321
|
|
@@ -339,7 +337,6 @@ module ActionController
|
|
339
337
|
"#{CGI.escape(prefix)}=#{CGI.escape(parameters.to_s)}"
|
340
338
|
end
|
341
339
|
end
|
342
|
-
|
343
340
|
end
|
344
341
|
|
345
342
|
# A module used to extend ActionController::Base, so that integration tests
|
@@ -368,6 +365,76 @@ module ActionController
|
|
368
365
|
end
|
369
366
|
end
|
370
367
|
end
|
368
|
+
|
369
|
+
module Runner
|
370
|
+
# Reset the current session. This is useful for testing multiple sessions
|
371
|
+
# in a single test case.
|
372
|
+
def reset!
|
373
|
+
@integration_session = open_session
|
374
|
+
end
|
375
|
+
|
376
|
+
%w(get post put head delete cookies assigns
|
377
|
+
xml_http_request get_via_redirect post_via_redirect).each do |method|
|
378
|
+
define_method(method) do |*args|
|
379
|
+
reset! unless @integration_session
|
380
|
+
# reset the html_document variable, but only for new get/post calls
|
381
|
+
@html_document = nil unless %w(cookies assigns).include?(method)
|
382
|
+
returning @integration_session.send!(method, *args) do
|
383
|
+
copy_session_variables!
|
384
|
+
end
|
385
|
+
end
|
386
|
+
end
|
387
|
+
|
388
|
+
# Open a new session instance. If a block is given, the new session is
|
389
|
+
# yielded to the block before being returned.
|
390
|
+
#
|
391
|
+
# session = open_session do |sess|
|
392
|
+
# sess.extend(CustomAssertions)
|
393
|
+
# end
|
394
|
+
#
|
395
|
+
# By default, a single session is automatically created for you, but you
|
396
|
+
# can use this method to open multiple sessions that ought to be tested
|
397
|
+
# simultaneously.
|
398
|
+
def open_session
|
399
|
+
session = Integration::Session.new
|
400
|
+
|
401
|
+
# delegate the fixture accessors back to the test instance
|
402
|
+
extras = Module.new { attr_accessor :delegate, :test_result }
|
403
|
+
if self.class.respond_to?(:fixture_table_names)
|
404
|
+
self.class.fixture_table_names.each do |table_name|
|
405
|
+
name = table_name.tr(".", "_")
|
406
|
+
next unless respond_to?(name)
|
407
|
+
extras.send!(:define_method, name) { |*args| delegate.send(name, *args) }
|
408
|
+
end
|
409
|
+
end
|
410
|
+
|
411
|
+
# delegate add_assertion to the test case
|
412
|
+
extras.send!(:define_method, :add_assertion) { test_result.add_assertion }
|
413
|
+
session.extend(extras)
|
414
|
+
session.delegate = self
|
415
|
+
session.test_result = @_result
|
416
|
+
|
417
|
+
yield session if block_given?
|
418
|
+
session
|
419
|
+
end
|
420
|
+
|
421
|
+
# Copy the instance variables from the current session instance into the
|
422
|
+
# test instance.
|
423
|
+
def copy_session_variables! #:nodoc:
|
424
|
+
return unless @integration_session
|
425
|
+
%w(controller response request).each do |var|
|
426
|
+
instance_variable_set("@#{var}", @integration_session.send!(var))
|
427
|
+
end
|
428
|
+
end
|
429
|
+
|
430
|
+
# Delegate unhandled messages to the current session instance.
|
431
|
+
def method_missing(sym, *args, &block)
|
432
|
+
reset! unless @integration_session
|
433
|
+
returning @integration_session.send!(sym, *args, &block) do
|
434
|
+
copy_session_variables!
|
435
|
+
end
|
436
|
+
end
|
437
|
+
end
|
371
438
|
end
|
372
439
|
|
373
440
|
# An IntegrationTest is one that spans multiple controllers and actions,
|
@@ -446,6 +513,8 @@ module ActionController
|
|
446
513
|
# end
|
447
514
|
# end
|
448
515
|
class IntegrationTest < Test::Unit::TestCase
|
516
|
+
include Integration::Runner
|
517
|
+
|
449
518
|
# Work around a bug in test/unit caused by the default test being named
|
450
519
|
# as a symbol (:default_test), which causes regex test filters
|
451
520
|
# (like "ruby test.rb -n /foo/") to fail because =~ doesn't work on
|
@@ -493,70 +562,5 @@ module ActionController
|
|
493
562
|
superclass.use_instantiated_fixtures
|
494
563
|
end
|
495
564
|
end
|
496
|
-
|
497
|
-
# Reset the current session. This is useful for testing multiple sessions
|
498
|
-
# in a single test case.
|
499
|
-
def reset!
|
500
|
-
@integration_session = open_session
|
501
|
-
end
|
502
|
-
|
503
|
-
%w(get post put head delete cookies assigns xml_http_request).each do |method|
|
504
|
-
define_method(method) do |*args|
|
505
|
-
reset! unless @integration_session
|
506
|
-
# reset the html_document variable, but only for new get/post calls
|
507
|
-
@html_document = nil unless %w(cookies assigns).include?(method)
|
508
|
-
returning @integration_session.send(method, *args) do
|
509
|
-
copy_session_variables!
|
510
|
-
end
|
511
|
-
end
|
512
|
-
end
|
513
|
-
|
514
|
-
# Open a new session instance. If a block is given, the new session is
|
515
|
-
# yielded to the block before being returned.
|
516
|
-
#
|
517
|
-
# session = open_session do |sess|
|
518
|
-
# sess.extend(CustomAssertions)
|
519
|
-
# end
|
520
|
-
#
|
521
|
-
# By default, a single session is automatically created for you, but you
|
522
|
-
# can use this method to open multiple sessions that ought to be tested
|
523
|
-
# simultaneously.
|
524
|
-
def open_session
|
525
|
-
session = Integration::Session.new
|
526
|
-
|
527
|
-
# delegate the fixture accessors back to the test instance
|
528
|
-
extras = Module.new { attr_accessor :delegate, :test_result }
|
529
|
-
self.class.fixture_table_names.each do |table_name|
|
530
|
-
name = table_name.tr(".", "_")
|
531
|
-
next unless respond_to?(name)
|
532
|
-
extras.send(:define_method, name) { |*args| delegate.send(name, *args) }
|
533
|
-
end
|
534
|
-
|
535
|
-
# delegate add_assertion to the test case
|
536
|
-
extras.send(:define_method, :add_assertion) { test_result.add_assertion }
|
537
|
-
session.extend(extras)
|
538
|
-
session.delegate = self
|
539
|
-
session.test_result = @_result
|
540
|
-
|
541
|
-
yield session if block_given?
|
542
|
-
session
|
543
|
-
end
|
544
|
-
|
545
|
-
# Copy the instance variables from the current session instance into the
|
546
|
-
# test instance.
|
547
|
-
def copy_session_variables! #:nodoc:
|
548
|
-
return unless @integration_session
|
549
|
-
%w(controller response request).each do |var|
|
550
|
-
instance_variable_set("@#{var}", @integration_session.send(var))
|
551
|
-
end
|
552
|
-
end
|
553
|
-
|
554
|
-
# Delegate unhandled messages to the current session instance.
|
555
|
-
def method_missing(sym, *args, &block)
|
556
|
-
reset! unless @integration_session
|
557
|
-
returning @integration_session.send(sym, *args, &block) do
|
558
|
-
copy_session_variables!
|
559
|
-
end
|
560
|
-
end
|
561
565
|
end
|
562
566
|
end
|