eactionpack 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +7 -0
- data/MIT-LICENSE +21 -0
- data/README +469 -0
- data/RUNNING_UNIT_TESTS +24 -0
- data/Rakefile +146 -0
- data/install.rb +30 -0
- data/lib/action_controller.rb +79 -0
- data/lib/action_controller/assertions.rb +69 -0
- data/lib/action_controller/assertions/dom_assertions.rb +39 -0
- data/lib/action_controller/assertions/model_assertions.rb +20 -0
- data/lib/action_controller/assertions/response_assertions.rb +172 -0
- data/lib/action_controller/assertions/routing_assertions.rb +146 -0
- data/lib/action_controller/assertions/selector_assertions.rb +491 -0
- data/lib/action_controller/assertions/tag_assertions.rb +130 -0
- data/lib/action_controller/base.rb +1288 -0
- data/lib/action_controller/benchmarking.rb +94 -0
- data/lib/action_controller/caching.rb +72 -0
- data/lib/action_controller/caching/actions.rb +144 -0
- data/lib/action_controller/caching/fragments.rb +138 -0
- data/lib/action_controller/caching/pages.rb +154 -0
- data/lib/action_controller/caching/sql_cache.rb +18 -0
- data/lib/action_controller/caching/sweeping.rb +97 -0
- data/lib/action_controller/cgi_ext.rb +16 -0
- data/lib/action_controller/cgi_ext/cookie.rb +110 -0
- 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 +24 -0
- data/lib/action_controller/cgi_process.rb +223 -0
- data/lib/action_controller/components.rb +166 -0
- data/lib/action_controller/cookies.rb +96 -0
- data/lib/action_controller/dispatcher.rb +162 -0
- data/lib/action_controller/filters.rb +642 -0
- data/lib/action_controller/flash.rb +172 -0
- data/lib/action_controller/headers.rb +31 -0
- data/lib/action_controller/helpers.rb +221 -0
- data/lib/action_controller/http_authentication.rb +124 -0
- data/lib/action_controller/integration.rb +634 -0
- data/lib/action_controller/layout.rb +309 -0
- data/lib/action_controller/mime_responds.rb +173 -0
- data/lib/action_controller/mime_type.rb +186 -0
- data/lib/action_controller/mime_types.rb +20 -0
- data/lib/action_controller/polymorphic_routes.rb +191 -0
- data/lib/action_controller/record_identifier.rb +102 -0
- data/lib/action_controller/request.rb +764 -0
- data/lib/action_controller/request_forgery_protection.rb +140 -0
- data/lib/action_controller/request_profiler.rb +169 -0
- data/lib/action_controller/rescue.rb +258 -0
- data/lib/action_controller/resources.rb +572 -0
- data/lib/action_controller/response.rb +76 -0
- data/lib/action_controller/routing.rb +387 -0
- data/lib/action_controller/routing/builder.rb +203 -0
- data/lib/action_controller/routing/optimisations.rb +120 -0
- data/lib/action_controller/routing/recognition_optimisation.rb +162 -0
- data/lib/action_controller/routing/route.rb +240 -0
- data/lib/action_controller/routing/route_set.rb +436 -0
- data/lib/action_controller/routing/routing_ext.rb +46 -0
- data/lib/action_controller/routing/segments.rb +283 -0
- data/lib/action_controller/session/active_record_store.rb +340 -0
- data/lib/action_controller/session/cookie_store.rb +166 -0
- data/lib/action_controller/session/drb_server.rb +32 -0
- data/lib/action_controller/session/drb_store.rb +35 -0
- data/lib/action_controller/session/mem_cache_store.rb +98 -0
- data/lib/action_controller/session_management.rb +158 -0
- data/lib/action_controller/status_codes.rb +88 -0
- data/lib/action_controller/streaming.rb +155 -0
- data/lib/action_controller/templates/rescues/_request_and_response.erb +24 -0
- data/lib/action_controller/templates/rescues/_trace.erb +26 -0
- data/lib/action_controller/templates/rescues/diagnostics.erb +11 -0
- data/lib/action_controller/templates/rescues/layout.erb +29 -0
- data/lib/action_controller/templates/rescues/missing_template.erb +2 -0
- data/lib/action_controller/templates/rescues/routing_error.erb +10 -0
- data/lib/action_controller/templates/rescues/template_error.erb +21 -0
- data/lib/action_controller/templates/rescues/unknown_action.erb +2 -0
- data/lib/action_controller/test_case.rb +83 -0
- data/lib/action_controller/test_process.rb +526 -0
- data/lib/action_controller/url_rewriter.rb +142 -0
- data/lib/action_controller/vendor/html-scanner/html/document.rb +68 -0
- data/lib/action_controller/vendor/html-scanner/html/node.rb +537 -0
- data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +173 -0
- data/lib/action_controller/vendor/html-scanner/html/selector.rb +828 -0
- data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +105 -0
- data/lib/action_controller/vendor/html-scanner/html/version.rb +11 -0
- data/lib/action_controller/verification.rb +130 -0
- data/lib/action_pack.rb +24 -0
- data/lib/action_pack/version.rb +9 -0
- data/lib/action_view.rb +44 -0
- data/lib/action_view/base.rb +335 -0
- data/lib/action_view/helpers/active_record_helper.rb +276 -0
- data/lib/action_view/helpers/asset_tag_helper.rb +599 -0
- data/lib/action_view/helpers/atom_feed_helper.rb +143 -0
- data/lib/action_view/helpers/benchmark_helper.rb +33 -0
- data/lib/action_view/helpers/cache_helper.rb +40 -0
- data/lib/action_view/helpers/capture_helper.rb +161 -0
- data/lib/action_view/helpers/date_helper.rb +711 -0
- data/lib/action_view/helpers/debug_helper.rb +31 -0
- data/lib/action_view/helpers/form_helper.rb +767 -0
- data/lib/action_view/helpers/form_options_helper.rb +458 -0
- data/lib/action_view/helpers/form_tag_helper.rb +458 -0
- data/lib/action_view/helpers/javascript_helper.rb +148 -0
- data/lib/action_view/helpers/number_helper.rb +186 -0
- 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 +229 -0
- data/lib/action_view/helpers/tag_helper.rb +134 -0
- data/lib/action_view/helpers/text_helper.rb +507 -0
- data/lib/action_view/helpers/url_helper.rb +573 -0
- data/lib/action_view/inline_template.rb +20 -0
- data/lib/action_view/partial_template.rb +70 -0
- data/lib/action_view/partials.rb +158 -0
- data/lib/action_view/template.rb +125 -0
- data/lib/action_view/template_error.rb +110 -0
- data/lib/action_view/template_finder.rb +176 -0
- data/lib/action_view/template_handler.rb +34 -0
- data/lib/action_view/template_handlers/builder.rb +27 -0
- data/lib/action_view/template_handlers/compilable.rb +128 -0
- data/lib/action_view/template_handlers/erb.rb +56 -0
- data/lib/action_view/test_case.rb +58 -0
- data/lib/actionpack.rb +1 -0
- data/test/abstract_unit.rb +36 -0
- data/test/active_record_unit.rb +105 -0
- data/test/activerecord/active_record_store_test.rb +141 -0
- data/test/activerecord/render_partial_with_record_identification_test.rb +191 -0
- data/test/adv_attr_test.rb +20 -0
- data/test/controller/action_pack_assertions_test.rb +543 -0
- data/test/controller/addresses_render_test.rb +43 -0
- data/test/controller/assert_select_test.rb +331 -0
- data/test/controller/base_test.rb +219 -0
- data/test/controller/benchmark_test.rb +32 -0
- data/test/controller/caching_test.rb +581 -0
- data/test/controller/capture_test.rb +89 -0
- data/test/controller/cgi_test.rb +116 -0
- data/test/controller/components_test.rb +140 -0
- data/test/controller/content_type_test.rb +139 -0
- data/test/controller/controller_fixtures/app/controllers/admin/user_controller.rb +0 -0
- data/test/controller/controller_fixtures/app/controllers/user_controller.rb +0 -0
- data/test/controller/controller_fixtures/vendor/plugins/bad_plugin/lib/plugin_controller.rb +0 -0
- data/test/controller/cookie_test.rb +146 -0
- data/test/controller/custom_handler_test.rb +45 -0
- data/test/controller/deprecation/deprecated_base_methods_test.rb +37 -0
- data/test/controller/dispatcher_test.rb +105 -0
- data/test/controller/fake_controllers.rb +33 -0
- data/test/controller/fake_models.rb +11 -0
- data/test/controller/filter_params_test.rb +49 -0
- data/test/controller/filters_test.rb +881 -0
- data/test/controller/flash_test.rb +146 -0
- data/test/controller/header_test.rb +14 -0
- data/test/controller/helper_test.rb +210 -0
- data/test/controller/html-scanner/cdata_node_test.rb +15 -0
- data/test/controller/html-scanner/document_test.rb +148 -0
- data/test/controller/html-scanner/node_test.rb +89 -0
- data/test/controller/html-scanner/sanitizer_test.rb +269 -0
- data/test/controller/html-scanner/tag_node_test.rb +238 -0
- data/test/controller/html-scanner/text_node_test.rb +50 -0
- data/test/controller/html-scanner/tokenizer_test.rb +131 -0
- data/test/controller/http_authentication_test.rb +54 -0
- data/test/controller/integration_test.rb +252 -0
- data/test/controller/integration_upload_test.rb +43 -0
- data/test/controller/layout_test.rb +255 -0
- data/test/controller/mime_responds_test.rb +514 -0
- data/test/controller/mime_type_test.rb +84 -0
- data/test/controller/new_render_test.rb +843 -0
- data/test/controller/polymorphic_routes_test.rb +174 -0
- data/test/controller/record_identifier_test.rb +139 -0
- data/test/controller/redirect_test.rb +289 -0
- data/test/controller/render_test.rb +484 -0
- data/test/controller/request_forgery_protection_test.rb +305 -0
- data/test/controller/request_test.rb +928 -0
- data/test/controller/rescue_test.rb +517 -0
- data/test/controller/resources_test.rb +873 -0
- data/test/controller/routing_test.rb +2464 -0
- data/test/controller/selector_test.rb +628 -0
- data/test/controller/send_file_test.rb +138 -0
- data/test/controller/session/cookie_store_test.rb +258 -0
- data/test/controller/session/mem_cache_store_test.rb +181 -0
- data/test/controller/session_fixation_test.rb +89 -0
- data/test/controller/session_management_test.rb +178 -0
- data/test/controller/test_test.rb +695 -0
- data/test/controller/url_rewriter_test.rb +310 -0
- data/test/controller/verification_test.rb +270 -0
- data/test/controller/view_paths_test.rb +140 -0
- data/test/controller/webservice_test.rb +229 -0
- data/test/fixtures/addresses/list.erb +1 -0
- data/test/fixtures/bad_customers/_bad_customer.html.erb +1 -0
- data/test/fixtures/companies.yml +24 -0
- data/test/fixtures/company.rb +10 -0
- data/test/fixtures/content_type/render_default_content_types_for_respond_to.rhtml +1 -0
- data/test/fixtures/content_type/render_default_for_js.js.erb +1 -0
- data/test/fixtures/content_type/render_default_for_rhtml.rhtml +1 -0
- data/test/fixtures/content_type/render_default_for_rxml.rxml +1 -0
- data/test/fixtures/customers/_customer.html.erb +1 -0
- data/test/fixtures/db_definitions/sqlite.sql +49 -0
- data/test/fixtures/developer.rb +9 -0
- data/test/fixtures/developers.yml +21 -0
- data/test/fixtures/developers_projects.yml +13 -0
- data/test/fixtures/fun/games/hello_world.erb +1 -0
- data/test/fixtures/functional_caching/_partial.erb +3 -0
- data/test/fixtures/functional_caching/fragment_cached.html.erb +2 -0
- data/test/fixtures/functional_caching/html_fragment_cached_with_partial.html.erb +1 -0
- data/test/fixtures/functional_caching/js_fragment_cached_with_partial.js.rjs +1 -0
- data/test/fixtures/good_customers/_good_customer.html.erb +1 -0
- data/test/fixtures/helpers/abc_helper.rb +5 -0
- data/test/fixtures/helpers/fun/games_helper.rb +3 -0
- data/test/fixtures/helpers/fun/pdf_helper.rb +3 -0
- data/test/fixtures/layout_tests/alt/hello.rhtml +1 -0
- data/test/fixtures/layout_tests/layouts/controller_name_space/nested.rhtml +1 -0
- data/test/fixtures/layout_tests/layouts/item.rhtml +1 -0
- data/test/fixtures/layout_tests/layouts/layout_test.rhtml +1 -0
- data/test/fixtures/layout_tests/layouts/multiple_extensions.html.erb +1 -0
- data/test/fixtures/layout_tests/layouts/third_party_template_library.mab +1 -0
- data/test/fixtures/layout_tests/views/hello.rhtml +1 -0
- data/test/fixtures/layouts/block_with_layout.erb +3 -0
- data/test/fixtures/layouts/builder.builder +3 -0
- data/test/fixtures/layouts/partial_with_layout.erb +3 -0
- data/test/fixtures/layouts/standard.erb +1 -0
- data/test/fixtures/layouts/talk_from_action.erb +2 -0
- data/test/fixtures/layouts/yield.erb +2 -0
- data/test/fixtures/mascot.rb +3 -0
- data/test/fixtures/mascots.yml +4 -0
- data/test/fixtures/mascots/_mascot.html.erb +1 -0
- data/test/fixtures/multipart/binary_file +0 -0
- data/test/fixtures/multipart/boundary_problem_file +10 -0
- data/test/fixtures/multipart/bracketed_param +5 -0
- data/test/fixtures/multipart/large_text_file +10 -0
- data/test/fixtures/multipart/mixed_files +0 -0
- data/test/fixtures/multipart/mona_lisa.jpg +0 -0
- data/test/fixtures/multipart/single_parameter +5 -0
- data/test/fixtures/multipart/text_file +10 -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/project.rb +3 -0
- data/test/fixtures/projects.yml +7 -0
- data/test/fixtures/public/404.html +1 -0
- data/test/fixtures/public/500.html +1 -0
- data/test/fixtures/public/images/rails.png +0 -0
- data/test/fixtures/public/javascripts/application.js +1 -0
- data/test/fixtures/public/javascripts/bank.js +1 -0
- data/test/fixtures/public/javascripts/robber.js +1 -0
- data/test/fixtures/public/javascripts/version.1.0.js +1 -0
- data/test/fixtures/public/stylesheets/bank.css +1 -0
- data/test/fixtures/public/stylesheets/robber.css +1 -0
- data/test/fixtures/public/stylesheets/version.1.0.css +1 -0
- data/test/fixtures/replies.yml +15 -0
- data/test/fixtures/reply.rb +7 -0
- data/test/fixtures/respond_to/all_types_with_layout.html.erb +1 -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.html.erb +1 -0
- data/test/fixtures/respond_to/using_defaults.js.rjs +1 -0
- data/test/fixtures/respond_to/using_defaults.xml.builder +1 -0
- data/test/fixtures/respond_to/using_defaults_with_type_list.html.erb +1 -0
- data/test/fixtures/respond_to/using_defaults_with_type_list.js.rjs +1 -0
- data/test/fixtures/respond_to/using_defaults_with_type_list.xml.builder +1 -0
- data/test/fixtures/scope/test/modgreet.erb +1 -0
- data/test/fixtures/shared.html.erb +1 -0
- data/test/fixtures/symlink_parent/symlinked_layout.erb +5 -0
- data/test/fixtures/test/_customer.erb +1 -0
- data/test/fixtures/test/_customer_counter.erb +1 -0
- data/test/fixtures/test/_customer_greeting.erb +1 -0
- data/test/fixtures/test/_form.erb +1 -0
- data/test/fixtures/test/_hash_greeting.erb +1 -0
- data/test/fixtures/test/_hash_object.erb +2 -0
- data/test/fixtures/test/_hello.builder +1 -0
- data/test/fixtures/test/_labelling_form.erb +1 -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.erb +1 -0
- data/test/fixtures/test/_person.erb +2 -0
- data/test/fixtures/test/_raise.html.erb +1 -0
- data/test/fixtures/test/action_talk_to_layout.erb +2 -0
- data/test/fixtures/test/block_content_for.erb +2 -0
- data/test/fixtures/test/calling_partial_with_layout.html.erb +1 -0
- data/test/fixtures/test/capturing.erb +4 -0
- data/test/fixtures/test/content_for.erb +2 -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/delete_with_js.rjs +2 -0
- data/test/fixtures/test/dot.directory/render_file_with_ivar.erb +1 -0
- data/test/fixtures/test/enum_rjs_test.rjs +6 -0
- data/test/fixtures/test/erb_content_for.erb +2 -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.erb +1 -0
- data/test/fixtures/test/greeting.js.rjs +1 -0
- data/test/fixtures/test/hello.builder +4 -0
- data/test/fixtures/test/hello_world.erb +1 -0
- data/test/fixtures/test/hello_world_container.builder +3 -0
- data/test/fixtures/test/hello_world_from_rxml.builder +4 -0
- data/test/fixtures/test/hello_world_with_layout_false.erb +1 -0
- data/test/fixtures/test/hello_xml_world.builder +11 -0
- data/test/fixtures/test/list.erb +1 -0
- data/test/fixtures/test/non_erb_block_content_for.builder +4 -0
- data/test/fixtures/test/potential_conflicts.erb +4 -0
- data/test/fixtures/test/render_file_from_template.html.erb +1 -0
- data/test/fixtures/test/render_file_with_ivar.erb +1 -0
- data/test/fixtures/test/render_file_with_locals.erb +1 -0
- data/test/fixtures/test/render_to_string_test.erb +1 -0
- data/test/fixtures/test/update_element_with_capture.erb +9 -0
- data/test/fixtures/test/using_layout_around_block.html.erb +1 -0
- data/test/fixtures/topic.rb +3 -0
- data/test/fixtures/topics.yml +22 -0
- data/test/fixtures/topics/_topic.html.erb +1 -0
- data/test/template/active_record_helper_test.rb +268 -0
- data/test/template/asset_tag_helper_test.rb +514 -0
- data/test/template/atom_feed_helper_test.rb +179 -0
- data/test/template/benchmark_helper_test.rb +60 -0
- data/test/template/date_helper_test.rb +1791 -0
- data/test/template/deprecated_erb_variable_test.rb +9 -0
- data/test/template/erb_util_test.rb +24 -0
- data/test/template/form_helper_test.rb +885 -0
- data/test/template/form_options_helper_test.rb +1333 -0
- data/test/template/form_tag_helper_test.rb +272 -0
- data/test/template/javascript_helper_test.rb +73 -0
- data/test/template/number_helper_test.rb +97 -0
- data/test/template/record_tag_helper_test.rb +54 -0
- data/test/template/sanitize_helper_test.rb +48 -0
- data/test/template/tag_helper_test.rb +77 -0
- data/test/template/template_finder_test.rb +73 -0
- data/test/template/template_object_test.rb +95 -0
- data/test/template/test_test.rb +56 -0
- data/test/template/text_helper_test.rb +367 -0
- data/test/template/url_helper_test.rb +544 -0
- data/test/testing_sandbox.rb +15 -0
- metadata +469 -0
|
@@ -0,0 +1,634 @@
|
|
|
1
|
+
require 'stringio'
|
|
2
|
+
require 'uri'
|
|
3
|
+
|
|
4
|
+
require 'action_controller/dispatcher'
|
|
5
|
+
require 'action_controller/test_process'
|
|
6
|
+
|
|
7
|
+
module ActionController
|
|
8
|
+
module Integration #:nodoc:
|
|
9
|
+
# An integration Session instance represents a set of requests and responses
|
|
10
|
+
# performed sequentially by some virtual user. Becase you can instantiate
|
|
11
|
+
# multiple sessions and run them side-by-side, you can also mimic (to some
|
|
12
|
+
# limited extent) multiple simultaneous users interacting with your system.
|
|
13
|
+
#
|
|
14
|
+
# Typically, you will instantiate a new session using IntegrationTest#open_session,
|
|
15
|
+
# rather than instantiating Integration::Session directly.
|
|
16
|
+
class Session
|
|
17
|
+
include Test::Unit::Assertions
|
|
18
|
+
include ActionController::Assertions
|
|
19
|
+
include ActionController::TestProcess
|
|
20
|
+
|
|
21
|
+
# The integer HTTP status code of the last request.
|
|
22
|
+
attr_reader :status
|
|
23
|
+
|
|
24
|
+
# The status message that accompanied the status code of the last request.
|
|
25
|
+
attr_reader :status_message
|
|
26
|
+
|
|
27
|
+
# The URI of the last request.
|
|
28
|
+
attr_reader :path
|
|
29
|
+
|
|
30
|
+
# The hostname used in the last request.
|
|
31
|
+
attr_accessor :host
|
|
32
|
+
|
|
33
|
+
# The remote_addr used in the last request.
|
|
34
|
+
attr_accessor :remote_addr
|
|
35
|
+
|
|
36
|
+
# The Accept header to send.
|
|
37
|
+
attr_accessor :accept
|
|
38
|
+
|
|
39
|
+
# A map of the cookies returned by the last response, and which will be
|
|
40
|
+
# sent with the next request.
|
|
41
|
+
attr_reader :cookies
|
|
42
|
+
|
|
43
|
+
# A map of the headers returned by the last response.
|
|
44
|
+
attr_reader :headers
|
|
45
|
+
|
|
46
|
+
# A reference to the controller instance used by the last request.
|
|
47
|
+
attr_reader :controller
|
|
48
|
+
|
|
49
|
+
# A reference to the request instance used by the last request.
|
|
50
|
+
attr_reader :request
|
|
51
|
+
|
|
52
|
+
# A reference to the response instance used by the last request.
|
|
53
|
+
attr_reader :response
|
|
54
|
+
|
|
55
|
+
# A running counter of the number of requests processed.
|
|
56
|
+
attr_accessor :request_count
|
|
57
|
+
|
|
58
|
+
class MultiPartNeededException < Exception
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Create and initialize a new Session instance.
|
|
62
|
+
def initialize
|
|
63
|
+
reset!
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Resets the instance. This can be used to reset the state information
|
|
67
|
+
# in an existing session instance, so it can be used from a clean-slate
|
|
68
|
+
# condition.
|
|
69
|
+
#
|
|
70
|
+
# session.reset!
|
|
71
|
+
def reset!
|
|
72
|
+
@status = @path = @headers = nil
|
|
73
|
+
@result = @status_message = nil
|
|
74
|
+
@https = false
|
|
75
|
+
@cookies = {}
|
|
76
|
+
@controller = @request = @response = nil
|
|
77
|
+
@request_count = 0
|
|
78
|
+
|
|
79
|
+
self.host = "www.example.com"
|
|
80
|
+
self.remote_addr = "127.0.0.1"
|
|
81
|
+
self.accept = "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"
|
|
82
|
+
|
|
83
|
+
unless defined? @named_routes_configured
|
|
84
|
+
# install the named routes in this session instance.
|
|
85
|
+
klass = class<<self; self; end
|
|
86
|
+
Routing::Routes.install_helpers(klass)
|
|
87
|
+
|
|
88
|
+
# the helpers are made protected by default--we make them public for
|
|
89
|
+
# easier access during testing and troubleshooting.
|
|
90
|
+
klass.module_eval { public *Routing::Routes.named_routes.helpers }
|
|
91
|
+
@named_routes_configured = true
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Specify whether or not the session should mimic a secure HTTPS request.
|
|
96
|
+
#
|
|
97
|
+
# session.https!
|
|
98
|
+
# session.https!(false)
|
|
99
|
+
def https!(flag=true)
|
|
100
|
+
@https = flag
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Return +true+ if the session is mimicing a secure HTTPS request.
|
|
104
|
+
#
|
|
105
|
+
# if session.https?
|
|
106
|
+
# ...
|
|
107
|
+
# end
|
|
108
|
+
def https?
|
|
109
|
+
@https
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Set the host name to use in the next request.
|
|
113
|
+
#
|
|
114
|
+
# session.host! "www.example.com"
|
|
115
|
+
def host!(name)
|
|
116
|
+
@host = name
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Follow a single redirect response. If the last response was not a
|
|
120
|
+
# redirect, an exception will be raised. Otherwise, the redirect is
|
|
121
|
+
# performed on the location header.
|
|
122
|
+
def follow_redirect!
|
|
123
|
+
raise "not a redirect! #{@status} #{@status_message}" unless redirect?
|
|
124
|
+
get(interpret_uri(headers['location'].first))
|
|
125
|
+
status
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# Performs a request using the specified method, following any subsequent
|
|
129
|
+
# redirect. Note that the redirects are followed until the response is
|
|
130
|
+
# not a redirect--this means you may run into an infinite loop if your
|
|
131
|
+
# redirect loops back to itself.
|
|
132
|
+
def request_via_redirect(http_method, path, parameters = nil, headers = nil)
|
|
133
|
+
send(http_method, path, parameters, headers)
|
|
134
|
+
follow_redirect! while redirect?
|
|
135
|
+
status
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# Performs a GET request, following any subsequent redirect.
|
|
139
|
+
# See +request_via_redirect+ for more information.
|
|
140
|
+
def get_via_redirect(path, parameters = nil, headers = nil)
|
|
141
|
+
request_via_redirect(:get, path, parameters, headers)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
# Performs a POST request, following any subsequent redirect.
|
|
145
|
+
# See +request_via_redirect+ for more information.
|
|
146
|
+
def post_via_redirect(path, parameters = nil, headers = nil)
|
|
147
|
+
request_via_redirect(:post, path, parameters, headers)
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# Performs a PUT request, following any subsequent redirect.
|
|
151
|
+
# See +request_via_redirect+ for more information.
|
|
152
|
+
def put_via_redirect(path, parameters = nil, headers = nil)
|
|
153
|
+
request_via_redirect(:put, path, parameters, headers)
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# Performs a DELETE request, following any subsequent redirect.
|
|
157
|
+
# See +request_via_redirect+ for more information.
|
|
158
|
+
def delete_via_redirect(path, parameters = nil, headers = nil)
|
|
159
|
+
request_via_redirect(:delete, path, parameters, headers)
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# Returns +true+ if the last response was a redirect.
|
|
163
|
+
def redirect?
|
|
164
|
+
status/100 == 3
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
# Performs a GET request with the given parameters. The parameters may
|
|
168
|
+
# be +nil+, a Hash, or a string that is appropriately encoded
|
|
169
|
+
# (<tt>application/x-www-form-urlencoded</tt> or <tt>multipart/form-data</tt>).
|
|
170
|
+
# The headers should be a hash. The keys will automatically be upcased, with the
|
|
171
|
+
# prefix 'HTTP_' added if needed.
|
|
172
|
+
#
|
|
173
|
+
# You can also perform POST, PUT, DELETE, and HEAD requests with +post+,
|
|
174
|
+
# +put+, +delete+, and +head+.
|
|
175
|
+
def get(path, parameters = nil, headers = nil)
|
|
176
|
+
process :get, path, parameters, headers
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
# Performs a POST request with the given parameters. See get() for more details.
|
|
180
|
+
def post(path, parameters = nil, headers = nil)
|
|
181
|
+
process :post, path, parameters, headers
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
# Performs a PUT request with the given parameters. See get() for more details.
|
|
185
|
+
def put(path, parameters = nil, headers = nil)
|
|
186
|
+
process :put, path, parameters, headers
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
# Performs a DELETE request with the given parameters. See get() for more details.
|
|
190
|
+
def delete(path, parameters = nil, headers = nil)
|
|
191
|
+
process :delete, path, parameters, headers
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
# Performs a HEAD request with the given parameters. See get() for more details.
|
|
195
|
+
def head(path, parameters = nil, headers = nil)
|
|
196
|
+
process :head, path, parameters, headers
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# Performs an XMLHttpRequest request with the given parameters, mirroring
|
|
200
|
+
# a request from the Prototype library.
|
|
201
|
+
#
|
|
202
|
+
# The request_method is :get, :post, :put, :delete or :head; the
|
|
203
|
+
# parameters are +nil+, a hash, or a url-encoded or multipart string;
|
|
204
|
+
# the headers are a hash. Keys are automatically upcased and prefixed
|
|
205
|
+
# with 'HTTP_' if not already.
|
|
206
|
+
def xml_http_request(request_method, path, parameters = nil, headers = nil)
|
|
207
|
+
headers ||= {}
|
|
208
|
+
headers['X-Requested-With'] = 'XMLHttpRequest'
|
|
209
|
+
headers['Accept'] ||= 'text/javascript, text/html, application/xml, text/xml, */*'
|
|
210
|
+
|
|
211
|
+
process(request_method, path, parameters, headers)
|
|
212
|
+
end
|
|
213
|
+
alias xhr :xml_http_request
|
|
214
|
+
|
|
215
|
+
# Returns the URL for the given options, according to the rules specified
|
|
216
|
+
# in the application's routes.
|
|
217
|
+
def url_for(options)
|
|
218
|
+
controller ? controller.url_for(options) : generic_url_rewriter.rewrite(options)
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
private
|
|
222
|
+
class StubCGI < CGI #:nodoc:
|
|
223
|
+
attr_accessor :stdinput, :stdoutput, :env_table
|
|
224
|
+
|
|
225
|
+
def initialize(env, stdinput = nil)
|
|
226
|
+
self.env_table = env
|
|
227
|
+
self.stdoutput = StringIO.new
|
|
228
|
+
|
|
229
|
+
super
|
|
230
|
+
|
|
231
|
+
stdinput.set_encoding(Encoding::BINARY) if stdinput.respond_to?(:set_encoding)
|
|
232
|
+
stdinput.force_encoding(Encoding::BINARY) if stdinput.respond_to?(:force_encoding)
|
|
233
|
+
@stdinput = stdinput.is_a?(IO) ? stdinput : StringIO.new(stdinput || '')
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
# Tailors the session based on the given URI, setting the HTTPS value
|
|
238
|
+
# and the hostname.
|
|
239
|
+
def interpret_uri(path)
|
|
240
|
+
location = URI.parse(path)
|
|
241
|
+
https! URI::HTTPS === location if location.scheme
|
|
242
|
+
host! location.host if location.host
|
|
243
|
+
location.query ? "#{location.path}?#{location.query}" : location.path
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
# Performs the actual request.
|
|
247
|
+
def process(method, path, parameters = nil, headers = nil)
|
|
248
|
+
data = requestify(parameters)
|
|
249
|
+
path = interpret_uri(path) if path =~ %r{://}
|
|
250
|
+
path = "/#{path}" unless path[0] == ?/
|
|
251
|
+
@path = path
|
|
252
|
+
env = {}
|
|
253
|
+
|
|
254
|
+
if method == :get
|
|
255
|
+
env["QUERY_STRING"] = data
|
|
256
|
+
data = nil
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
env.update(
|
|
260
|
+
"REQUEST_METHOD" => method.to_s.upcase,
|
|
261
|
+
"REQUEST_URI" => path,
|
|
262
|
+
"HTTP_HOST" => host,
|
|
263
|
+
"REMOTE_ADDR" => remote_addr,
|
|
264
|
+
"SERVER_PORT" => (https? ? "443" : "80"),
|
|
265
|
+
"CONTENT_TYPE" => "application/x-www-form-urlencoded",
|
|
266
|
+
"CONTENT_LENGTH" => data ? data.length.to_s : nil,
|
|
267
|
+
"HTTP_COOKIE" => encode_cookies,
|
|
268
|
+
"HTTPS" => https? ? "on" : "off",
|
|
269
|
+
"HTTP_ACCEPT" => accept
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
(headers || {}).each do |key, value|
|
|
273
|
+
key = key.to_s.upcase.gsub(/-/, "_")
|
|
274
|
+
key = "HTTP_#{key}" unless env.has_key?(key) || key =~ /^HTTP_/
|
|
275
|
+
env[key] = value
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
unless ActionController::Base.respond_to?(:clear_last_instantiation!)
|
|
279
|
+
ActionController::Base.module_eval { include ControllerCapture }
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
ActionController::Base.clear_last_instantiation!
|
|
283
|
+
|
|
284
|
+
cgi = StubCGI.new(env, data)
|
|
285
|
+
ActionController::Dispatcher.dispatch(cgi, ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS, cgi.stdoutput)
|
|
286
|
+
@result = cgi.stdoutput.string
|
|
287
|
+
@request_count += 1
|
|
288
|
+
|
|
289
|
+
@controller = ActionController::Base.last_instantiation
|
|
290
|
+
@request = @controller.request
|
|
291
|
+
@response = @controller.response
|
|
292
|
+
|
|
293
|
+
# Decorate the response with the standard behavior of the TestResponse
|
|
294
|
+
# so that things like assert_response can be used in integration
|
|
295
|
+
# tests.
|
|
296
|
+
@response.extend(TestResponseBehavior)
|
|
297
|
+
|
|
298
|
+
@html_document = nil
|
|
299
|
+
|
|
300
|
+
parse_result
|
|
301
|
+
return status
|
|
302
|
+
rescue MultiPartNeededException
|
|
303
|
+
boundary = "----------XnJLe9ZIbbGUYtzPQJ16u1"
|
|
304
|
+
status = process(method, path, multipart_body(parameters, boundary), (headers || {}).merge({"CONTENT_TYPE" => "multipart/form-data; boundary=#{boundary}"}))
|
|
305
|
+
return status
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
# Parses the result of the response and extracts the various values,
|
|
309
|
+
# like cookies, status, headers, etc.
|
|
310
|
+
def parse_result
|
|
311
|
+
response_headers, result_body = @result.split(/\r\n\r\n/, 2)
|
|
312
|
+
|
|
313
|
+
@headers = Hash.new { |h,k| h[k] = [] }
|
|
314
|
+
response_headers.to_s.each_line do |line|
|
|
315
|
+
key, value = line.strip.split(/:\s*/, 2)
|
|
316
|
+
@headers[key.downcase] << value
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
(@headers['set-cookie'] || [] ).each do |string|
|
|
320
|
+
name, value = string.match(/^([^=]*)=([^;]*);/)[1,2]
|
|
321
|
+
@cookies[name] = value
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
@status, @status_message = @headers["status"].first.to_s.split(/ /)
|
|
325
|
+
@status = @status.to_i
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
# Encode the cookies hash in a format suitable for passing to a
|
|
329
|
+
# request.
|
|
330
|
+
def encode_cookies
|
|
331
|
+
cookies.inject("") do |string, (name, value)|
|
|
332
|
+
string << "#{name}=#{value}; "
|
|
333
|
+
end
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
# Get a temporary URL writer object
|
|
337
|
+
def generic_url_rewriter
|
|
338
|
+
cgi = StubCGI.new('REQUEST_METHOD' => "GET",
|
|
339
|
+
'QUERY_STRING' => "",
|
|
340
|
+
"REQUEST_URI" => "/",
|
|
341
|
+
"HTTP_HOST" => host,
|
|
342
|
+
"SERVER_PORT" => https? ? "443" : "80",
|
|
343
|
+
"HTTPS" => https? ? "on" : "off")
|
|
344
|
+
ActionController::UrlRewriter.new(ActionController::CgiRequest.new(cgi), {})
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
def name_with_prefix(prefix, name)
|
|
348
|
+
prefix ? "#{prefix}[#{name}]" : name.to_s
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
# Convert the given parameters to a request string. The parameters may
|
|
352
|
+
# be a string, +nil+, or a Hash.
|
|
353
|
+
def requestify(parameters, prefix=nil)
|
|
354
|
+
if TestUploadedFile === parameters
|
|
355
|
+
raise MultiPartNeededException
|
|
356
|
+
elsif Hash === parameters
|
|
357
|
+
return nil if parameters.empty?
|
|
358
|
+
parameters.map { |k,v| requestify(v, name_with_prefix(prefix, k)) }.join("&")
|
|
359
|
+
elsif Array === parameters
|
|
360
|
+
parameters.map { |v| requestify(v, name_with_prefix(prefix, "")) }.join("&")
|
|
361
|
+
elsif prefix.nil?
|
|
362
|
+
parameters
|
|
363
|
+
else
|
|
364
|
+
"#{CGI.escape(prefix)}=#{CGI.escape(parameters.to_s)}"
|
|
365
|
+
end
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
def multipart_requestify(params, first=true)
|
|
369
|
+
returning Hash.new do |p|
|
|
370
|
+
params.each do |key, value|
|
|
371
|
+
k = first ? CGI.escape(key.to_s) : "[#{CGI.escape(key.to_s)}]"
|
|
372
|
+
if Hash === value
|
|
373
|
+
multipart_requestify(value, false).each do |subkey, subvalue|
|
|
374
|
+
p[k + subkey] = subvalue
|
|
375
|
+
end
|
|
376
|
+
else
|
|
377
|
+
p[k] = value
|
|
378
|
+
end
|
|
379
|
+
end
|
|
380
|
+
end
|
|
381
|
+
end
|
|
382
|
+
|
|
383
|
+
def multipart_body(params, boundary)
|
|
384
|
+
multipart_requestify(params).map do |key, value|
|
|
385
|
+
if value.respond_to?(:original_filename)
|
|
386
|
+
File.open(value.path) do |f|
|
|
387
|
+
f.set_encoding(Encoding::BINARY) if f.respond_to?(:set_encoding)
|
|
388
|
+
|
|
389
|
+
<<-EOF
|
|
390
|
+
--#{boundary}\r
|
|
391
|
+
Content-Disposition: form-data; name="#{key}"; filename="#{CGI.escape(value.original_filename)}"\r
|
|
392
|
+
Content-Type: #{value.content_type}\r
|
|
393
|
+
Content-Length: #{File.stat(value.path).size}\r
|
|
394
|
+
\r
|
|
395
|
+
#{f.read}\r
|
|
396
|
+
EOF
|
|
397
|
+
end
|
|
398
|
+
else
|
|
399
|
+
<<-EOF
|
|
400
|
+
--#{boundary}\r
|
|
401
|
+
Content-Disposition: form-data; name="#{key}"\r
|
|
402
|
+
\r
|
|
403
|
+
#{value}\r
|
|
404
|
+
EOF
|
|
405
|
+
end
|
|
406
|
+
end.join("")+"--#{boundary}--\r"
|
|
407
|
+
end
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
# A module used to extend ActionController::Base, so that integration tests
|
|
411
|
+
# can capture the controller used to satisfy a request.
|
|
412
|
+
module ControllerCapture #:nodoc:
|
|
413
|
+
def self.included(base)
|
|
414
|
+
base.extend(ClassMethods)
|
|
415
|
+
base.class_eval do
|
|
416
|
+
class << self
|
|
417
|
+
alias_method_chain :new, :capture
|
|
418
|
+
end
|
|
419
|
+
end
|
|
420
|
+
end
|
|
421
|
+
|
|
422
|
+
module ClassMethods #:nodoc:
|
|
423
|
+
mattr_accessor :last_instantiation
|
|
424
|
+
|
|
425
|
+
def clear_last_instantiation!
|
|
426
|
+
self.last_instantiation = nil
|
|
427
|
+
end
|
|
428
|
+
|
|
429
|
+
def new_with_capture(*args)
|
|
430
|
+
controller = new_without_capture(*args)
|
|
431
|
+
self.last_instantiation ||= controller
|
|
432
|
+
controller
|
|
433
|
+
end
|
|
434
|
+
end
|
|
435
|
+
end
|
|
436
|
+
|
|
437
|
+
module Runner
|
|
438
|
+
# Reset the current session. This is useful for testing multiple sessions
|
|
439
|
+
# in a single test case.
|
|
440
|
+
def reset!
|
|
441
|
+
@integration_session = open_session
|
|
442
|
+
end
|
|
443
|
+
|
|
444
|
+
%w(get post put head delete cookies assigns
|
|
445
|
+
xml_http_request get_via_redirect post_via_redirect).each do |method|
|
|
446
|
+
define_method(method) do |*args|
|
|
447
|
+
reset! unless @integration_session
|
|
448
|
+
# reset the html_document variable, but only for new get/post calls
|
|
449
|
+
@html_document = nil unless %w(cookies assigns).include?(method)
|
|
450
|
+
returning @integration_session.send!(method, *args) do
|
|
451
|
+
copy_session_variables!
|
|
452
|
+
end
|
|
453
|
+
end
|
|
454
|
+
end
|
|
455
|
+
|
|
456
|
+
# Open a new session instance. If a block is given, the new session is
|
|
457
|
+
# yielded to the block before being returned.
|
|
458
|
+
#
|
|
459
|
+
# session = open_session do |sess|
|
|
460
|
+
# sess.extend(CustomAssertions)
|
|
461
|
+
# end
|
|
462
|
+
#
|
|
463
|
+
# By default, a single session is automatically created for you, but you
|
|
464
|
+
# can use this method to open multiple sessions that ought to be tested
|
|
465
|
+
# simultaneously.
|
|
466
|
+
def open_session
|
|
467
|
+
session = Integration::Session.new
|
|
468
|
+
|
|
469
|
+
# delegate the fixture accessors back to the test instance
|
|
470
|
+
extras = Module.new { attr_accessor :delegate, :test_result }
|
|
471
|
+
if self.class.respond_to?(:fixture_table_names)
|
|
472
|
+
self.class.fixture_table_names.each do |table_name|
|
|
473
|
+
name = table_name.tr(".", "_")
|
|
474
|
+
next unless respond_to?(name)
|
|
475
|
+
extras.send!(:define_method, name) { |*args| delegate.send(name, *args) }
|
|
476
|
+
end
|
|
477
|
+
end
|
|
478
|
+
|
|
479
|
+
# delegate add_assertion to the test case
|
|
480
|
+
extras.send!(:define_method, :add_assertion) { test_result.add_assertion }
|
|
481
|
+
session.extend(extras)
|
|
482
|
+
session.delegate = self
|
|
483
|
+
session.test_result = @_result
|
|
484
|
+
|
|
485
|
+
yield session if block_given?
|
|
486
|
+
session
|
|
487
|
+
end
|
|
488
|
+
|
|
489
|
+
# Copy the instance variables from the current session instance into the
|
|
490
|
+
# test instance.
|
|
491
|
+
def copy_session_variables! #:nodoc:
|
|
492
|
+
return unless @integration_session
|
|
493
|
+
%w(controller response request).each do |var|
|
|
494
|
+
instance_variable_set("@#{var}", @integration_session.send!(var))
|
|
495
|
+
end
|
|
496
|
+
end
|
|
497
|
+
|
|
498
|
+
# Delegate unhandled messages to the current session instance.
|
|
499
|
+
def method_missing(sym, *args, &block)
|
|
500
|
+
reset! unless @integration_session
|
|
501
|
+
returning @integration_session.send!(sym, *args, &block) do
|
|
502
|
+
copy_session_variables!
|
|
503
|
+
end
|
|
504
|
+
end
|
|
505
|
+
end
|
|
506
|
+
end
|
|
507
|
+
|
|
508
|
+
# An IntegrationTest is one that spans multiple controllers and actions,
|
|
509
|
+
# tying them all together to ensure they work together as expected. It tests
|
|
510
|
+
# more completely than either unit or functional tests do, exercising the
|
|
511
|
+
# entire stack, from the dispatcher to the database.
|
|
512
|
+
#
|
|
513
|
+
# At its simplest, you simply extend IntegrationTest and write your tests
|
|
514
|
+
# using the get/post methods:
|
|
515
|
+
#
|
|
516
|
+
# require "#{File.dirname(__FILE__)}/test_helper"
|
|
517
|
+
#
|
|
518
|
+
# class ExampleTest < ActionController::IntegrationTest
|
|
519
|
+
# fixtures :people
|
|
520
|
+
#
|
|
521
|
+
# def test_login
|
|
522
|
+
# # get the login page
|
|
523
|
+
# get "/login"
|
|
524
|
+
# assert_equal 200, status
|
|
525
|
+
#
|
|
526
|
+
# # post the login and follow through to the home page
|
|
527
|
+
# post "/login", :username => people(:jamis).username,
|
|
528
|
+
# :password => people(:jamis).password
|
|
529
|
+
# follow_redirect!
|
|
530
|
+
# assert_equal 200, status
|
|
531
|
+
# assert_equal "/home", path
|
|
532
|
+
# end
|
|
533
|
+
# end
|
|
534
|
+
#
|
|
535
|
+
# However, you can also have multiple session instances open per test, and
|
|
536
|
+
# even extend those instances with assertions and methods to create a very
|
|
537
|
+
# powerful testing DSL that is specific for your application. You can even
|
|
538
|
+
# reference any named routes you happen to have defined!
|
|
539
|
+
#
|
|
540
|
+
# require "#{File.dirname(__FILE__)}/test_helper"
|
|
541
|
+
#
|
|
542
|
+
# class AdvancedTest < ActionController::IntegrationTest
|
|
543
|
+
# fixtures :people, :rooms
|
|
544
|
+
#
|
|
545
|
+
# def test_login_and_speak
|
|
546
|
+
# jamis, david = login(:jamis), login(:david)
|
|
547
|
+
# room = rooms(:office)
|
|
548
|
+
#
|
|
549
|
+
# jamis.enter(room)
|
|
550
|
+
# jamis.speak(room, "anybody home?")
|
|
551
|
+
#
|
|
552
|
+
# david.enter(room)
|
|
553
|
+
# david.speak(room, "hello!")
|
|
554
|
+
# end
|
|
555
|
+
#
|
|
556
|
+
# private
|
|
557
|
+
#
|
|
558
|
+
# module CustomAssertions
|
|
559
|
+
# def enter(room)
|
|
560
|
+
# # reference a named route, for maximum internal consistency!
|
|
561
|
+
# get(room_url(:id => room.id))
|
|
562
|
+
# assert(...)
|
|
563
|
+
# ...
|
|
564
|
+
# end
|
|
565
|
+
#
|
|
566
|
+
# def speak(room, message)
|
|
567
|
+
# xml_http_request "/say/#{room.id}", :message => message
|
|
568
|
+
# assert(...)
|
|
569
|
+
# ...
|
|
570
|
+
# end
|
|
571
|
+
# end
|
|
572
|
+
#
|
|
573
|
+
# def login(who)
|
|
574
|
+
# open_session do |sess|
|
|
575
|
+
# sess.extend(CustomAssertions)
|
|
576
|
+
# who = people(who)
|
|
577
|
+
# sess.post "/login", :username => who.username,
|
|
578
|
+
# :password => who.password
|
|
579
|
+
# assert(...)
|
|
580
|
+
# end
|
|
581
|
+
# end
|
|
582
|
+
# end
|
|
583
|
+
class IntegrationTest < Test::Unit::TestCase
|
|
584
|
+
include Integration::Runner
|
|
585
|
+
|
|
586
|
+
# Work around a bug in test/unit caused by the default test being named
|
|
587
|
+
# as a symbol (:default_test), which causes regex test filters
|
|
588
|
+
# (like "ruby test.rb -n /foo/") to fail because =~ doesn't work on
|
|
589
|
+
# symbols.
|
|
590
|
+
def initialize(name) #:nodoc:
|
|
591
|
+
super(name.to_s)
|
|
592
|
+
end
|
|
593
|
+
|
|
594
|
+
# Work around test/unit's requirement that every subclass of TestCase have
|
|
595
|
+
# at least one test method. Note that this implementation extends to all
|
|
596
|
+
# subclasses, as well, so subclasses of IntegrationTest may also exist
|
|
597
|
+
# without any test methods.
|
|
598
|
+
def run(*args) #:nodoc:
|
|
599
|
+
return if @method_name == "default_test"
|
|
600
|
+
super
|
|
601
|
+
end
|
|
602
|
+
|
|
603
|
+
# Because of how use_instantiated_fixtures and use_transactional_fixtures
|
|
604
|
+
# are defined, we need to treat them as special cases. Otherwise, users
|
|
605
|
+
# would potentially have to set their values for both Test::Unit::TestCase
|
|
606
|
+
# ActionController::IntegrationTest, since by the time the value is set on
|
|
607
|
+
# TestCase, IntegrationTest has already been defined and cannot inherit
|
|
608
|
+
# changes to those variables. So, we make those two attributes copy-on-write.
|
|
609
|
+
|
|
610
|
+
class << self
|
|
611
|
+
def use_transactional_fixtures=(flag) #:nodoc:
|
|
612
|
+
@_use_transactional_fixtures = true
|
|
613
|
+
@use_transactional_fixtures = flag
|
|
614
|
+
end
|
|
615
|
+
|
|
616
|
+
def use_instantiated_fixtures=(flag) #:nodoc:
|
|
617
|
+
@_use_instantiated_fixtures = true
|
|
618
|
+
@use_instantiated_fixtures = flag
|
|
619
|
+
end
|
|
620
|
+
|
|
621
|
+
def use_transactional_fixtures #:nodoc:
|
|
622
|
+
@_use_transactional_fixtures ?
|
|
623
|
+
@use_transactional_fixtures :
|
|
624
|
+
superclass.use_transactional_fixtures
|
|
625
|
+
end
|
|
626
|
+
|
|
627
|
+
def use_instantiated_fixtures #:nodoc:
|
|
628
|
+
@_use_instantiated_fixtures ?
|
|
629
|
+
@use_instantiated_fixtures :
|
|
630
|
+
superclass.use_instantiated_fixtures
|
|
631
|
+
end
|
|
632
|
+
end
|
|
633
|
+
end
|
|
634
|
+
end
|