actionpack 2.3.18 → 3.0.0.beta
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 +15 -64
- data/README +39 -48
- data/lib/abstract_controller.rb +22 -0
- data/lib/abstract_controller/base.rb +191 -0
- data/lib/abstract_controller/callbacks.rb +113 -0
- data/lib/abstract_controller/collector.rb +30 -0
- data/lib/abstract_controller/compatibility.rb +18 -0
- data/lib/abstract_controller/helpers.rb +163 -0
- data/lib/abstract_controller/layouts.rb +413 -0
- data/lib/abstract_controller/localized_cache.rb +49 -0
- data/lib/abstract_controller/logger.rb +13 -0
- data/lib/abstract_controller/rendering.rb +238 -0
- data/lib/{action_controller → abstract_controller}/translation.rb +1 -1
- data/lib/action_controller.rb +68 -102
- data/lib/action_controller/base.rb +77 -1409
- data/lib/action_controller/caching.rb +58 -45
- data/lib/action_controller/caching/actions.rb +100 -114
- data/lib/action_controller/caching/fragments.rb +17 -19
- data/lib/action_controller/caching/pages.rb +12 -6
- data/lib/action_controller/caching/sweeping.rb +42 -0
- data/lib/action_controller/deprecated.rb +5 -0
- data/lib/action_controller/deprecated/dispatcher.rb +28 -0
- data/lib/action_controller/deprecated/integration_test.rb +2 -0
- data/lib/action_controller/deprecated/performance_test.rb +1 -0
- data/lib/action_controller/metal.rb +125 -0
- data/lib/action_controller/metal/compatibility.rb +141 -0
- data/lib/action_controller/metal/conditional_get.rb +86 -0
- data/lib/action_controller/metal/configuration.rb +28 -0
- data/lib/action_controller/metal/cookies.rb +17 -0
- data/lib/action_controller/metal/exceptions.rb +46 -0
- data/lib/action_controller/metal/flash.rb +28 -0
- data/lib/action_controller/metal/head.rb +33 -0
- data/lib/action_controller/metal/helpers.rb +116 -0
- data/lib/action_controller/metal/hide_actions.rb +50 -0
- data/lib/action_controller/{http_authentication.rb → metal/http_authentication.rb} +18 -15
- data/lib/action_controller/metal/instrumentation.rb +99 -0
- data/lib/action_controller/metal/mime_responds.rb +300 -0
- data/lib/action_controller/metal/rack_delegation.rb +35 -0
- data/lib/action_controller/metal/redirecting.rb +90 -0
- data/lib/action_controller/metal/renderers.rb +95 -0
- data/lib/action_controller/metal/rendering.rb +69 -0
- data/lib/action_controller/metal/request_forgery_protection.rb +115 -0
- data/lib/action_controller/metal/rescue.rb +13 -0
- data/lib/action_controller/metal/responder.rb +220 -0
- data/lib/action_controller/{session_management.rb → metal/session_management.rb} +5 -14
- data/lib/action_controller/{streaming.rb → metal/streaming.rb} +13 -12
- data/lib/action_controller/metal/testing.rb +42 -0
- data/lib/action_controller/metal/url_for.rb +157 -0
- data/lib/action_controller/{verification.rb → metal/verification.rb} +41 -41
- data/lib/action_controller/middleware.rb +38 -0
- data/lib/action_controller/polymorphic_routes.rb +20 -26
- data/lib/action_controller/railtie.rb +30 -0
- data/lib/action_controller/railties/subscriber.rb +63 -0
- data/lib/action_controller/record_identifier.rb +3 -16
- data/lib/action_controller/test_case.rb +156 -18
- data/lib/action_controller/url_rewriter.rb +47 -200
- data/lib/action_controller/vendor/html-scanner.rb +16 -12
- data/lib/action_controller/vendor/html-scanner/html/node.rb +1 -1
- data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +12 -9
- data/lib/action_dispatch.rb +88 -0
- data/lib/action_dispatch/http/cache.rb +123 -0
- data/lib/action_dispatch/http/filter_parameters.rb +98 -0
- data/lib/{action_controller → action_dispatch/http}/headers.rb +8 -8
- data/lib/action_dispatch/http/mime_negotiation.rb +101 -0
- data/lib/{action_controller → action_dispatch/http}/mime_type.rb +30 -11
- data/lib/{action_controller → action_dispatch/http}/mime_types.rb +5 -3
- data/lib/action_dispatch/http/parameters.rb +49 -0
- data/lib/action_dispatch/http/request.rb +223 -0
- data/lib/action_dispatch/http/response.rb +209 -0
- data/lib/action_dispatch/http/upload.rb +48 -0
- data/lib/action_dispatch/http/url.rb +129 -0
- data/lib/action_dispatch/middleware/callbacks.rb +50 -0
- data/lib/action_dispatch/middleware/cascade.rb +29 -0
- data/lib/action_dispatch/middleware/cookies.rb +216 -0
- data/lib/{action_controller → action_dispatch/middleware}/flash.rb +51 -90
- data/lib/action_dispatch/middleware/head.rb +18 -0
- data/lib/action_dispatch/middleware/params_parser.rb +78 -0
- data/lib/action_dispatch/middleware/rescue.rb +26 -0
- data/lib/action_dispatch/middleware/session/abstract_store.rb +209 -0
- data/lib/{action_controller → action_dispatch/middleware}/session/cookie_store.rb +56 -60
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +47 -0
- data/lib/action_dispatch/middleware/show_exceptions.rb +173 -0
- data/lib/{action_controller/middleware_stack.rb → action_dispatch/middleware/stack.rb} +23 -13
- data/lib/action_dispatch/middleware/static.rb +44 -0
- data/lib/{action_controller → action_dispatch/middleware}/templates/rescues/_request_and_response.erb +10 -3
- data/lib/{action_controller → action_dispatch/middleware}/templates/rescues/_trace.erb +4 -4
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +10 -0
- data/lib/{action_controller → action_dispatch/middleware}/templates/rescues/layout.erb +2 -2
- data/lib/{action_controller → action_dispatch/middleware}/templates/rescues/missing_template.erb +0 -0
- data/lib/{action_controller → action_dispatch/middleware}/templates/rescues/routing_error.erb +0 -0
- data/lib/{action_controller → action_dispatch/middleware}/templates/rescues/template_error.erb +3 -3
- data/lib/{action_controller → action_dispatch/middleware}/templates/rescues/unknown_action.erb +0 -0
- data/lib/action_dispatch/railtie.rb +15 -0
- data/lib/action_dispatch/routing.rb +217 -0
- data/lib/action_dispatch/routing/deprecated_mapper.rb +877 -0
- data/lib/action_dispatch/routing/mapper.rb +649 -0
- data/lib/action_dispatch/routing/route.rb +55 -0
- data/lib/action_dispatch/routing/route_set.rb +445 -0
- data/lib/action_dispatch/testing/assertions.rb +21 -0
- data/lib/action_dispatch/testing/assertions/dom.rb +37 -0
- data/lib/{action_controller/assertions/model_assertions.rb → action_dispatch/testing/assertions/model.rb} +2 -4
- data/lib/action_dispatch/testing/assertions/response.rb +154 -0
- data/lib/{action_controller/assertions/routing_assertions.rb → action_dispatch/testing/assertions/routing.rb} +72 -34
- data/lib/{action_controller/assertions/selector_assertions.rb → action_dispatch/testing/assertions/selector.rb} +14 -11
- data/lib/{action_controller/assertions/tag_assertions.rb → action_dispatch/testing/assertions/tag.rb} +25 -14
- data/lib/{action_controller → action_dispatch/testing}/integration.rb +173 -406
- data/lib/action_dispatch/testing/performance_test.rb +17 -0
- data/lib/action_dispatch/testing/test_process.rb +42 -0
- data/lib/action_dispatch/testing/test_request.rb +83 -0
- data/lib/action_dispatch/testing/test_response.rb +136 -0
- data/lib/action_pack/version.rb +3 -3
- data/lib/action_view.rb +29 -26
- data/lib/action_view/base.rb +101 -148
- data/lib/action_view/context.rb +44 -0
- data/lib/action_view/helpers.rb +6 -4
- data/lib/action_view/helpers/{active_record_helper.rb → active_model_helper.rb} +63 -63
- data/lib/action_view/helpers/asset_tag_helper.rb +166 -31
- data/lib/action_view/helpers/cache_helper.rb +1 -1
- data/lib/action_view/helpers/capture_helper.rb +40 -8
- data/lib/action_view/helpers/csrf_helper.rb +2 -4
- data/lib/action_view/helpers/date_helper.rb +14 -15
- data/lib/action_view/helpers/form_helper.rb +121 -24
- data/lib/action_view/helpers/form_options_helper.rb +26 -25
- data/lib/action_view/helpers/form_tag_helper.rb +42 -33
- data/lib/action_view/helpers/javascript_helper.rb +1 -109
- data/lib/action_view/helpers/number_helper.rb +4 -1
- data/lib/action_view/helpers/prototype_helper.rb +75 -499
- data/lib/action_view/helpers/raw_output_helper.rb +1 -1
- data/lib/action_view/helpers/record_tag_helper.rb +3 -3
- data/lib/action_view/helpers/sanitize_helper.rb +3 -2
- data/lib/action_view/helpers/scriptaculous_helper.rb +89 -53
- data/lib/action_view/helpers/tag_helper.rb +12 -13
- data/lib/action_view/helpers/text_helper.rb +33 -38
- data/lib/action_view/helpers/translation_helper.rb +11 -35
- data/lib/action_view/helpers/url_helper.rb +140 -134
- data/lib/action_view/locale/en.yml +34 -28
- data/lib/action_view/paths.rb +27 -24
- data/lib/action_view/railtie.rb +17 -0
- data/lib/action_view/railties/subscriber.rb +24 -0
- data/lib/action_view/{partials.rb → render/partials.rb} +161 -51
- data/lib/action_view/render/rendering.rb +117 -0
- data/lib/action_view/template.rb +88 -217
- data/lib/action_view/template/error.rb +105 -0
- data/lib/action_view/template/handler.rb +41 -0
- data/lib/action_view/template/handlers.rb +54 -0
- data/lib/action_view/{template_handlers → template/handlers}/builder.rb +6 -6
- data/lib/action_view/template/handlers/erb.rb +58 -0
- data/lib/action_view/{template_handlers → template/handlers}/rjs.rb +8 -3
- data/lib/action_view/template/resolver.rb +164 -0
- data/lib/action_view/template/text.rb +40 -0
- data/lib/action_view/test_case.rb +18 -18
- metadata +165 -420
- data/RUNNING_UNIT_TESTS +0 -24
- data/Rakefile +0 -158
- data/install.rb +0 -30
- data/lib/action_controller/assertions/dom_assertions.rb +0 -55
- data/lib/action_controller/assertions/response_assertions.rb +0 -169
- data/lib/action_controller/benchmarking.rb +0 -107
- data/lib/action_controller/caching/sweeper.rb +0 -45
- data/lib/action_controller/cgi_ext.rb +0 -15
- data/lib/action_controller/cgi_ext/cookie.rb +0 -112
- data/lib/action_controller/cgi_ext/query_extension.rb +0 -22
- data/lib/action_controller/cgi_ext/stdinput.rb +0 -24
- data/lib/action_controller/cgi_process.rb +0 -77
- data/lib/action_controller/cookies.rb +0 -197
- data/lib/action_controller/dispatcher.rb +0 -133
- data/lib/action_controller/failsafe.rb +0 -87
- data/lib/action_controller/filters.rb +0 -680
- data/lib/action_controller/helpers.rb +0 -225
- data/lib/action_controller/layout.rb +0 -286
- data/lib/action_controller/middlewares.rb +0 -14
- data/lib/action_controller/mime_responds.rb +0 -193
- data/lib/action_controller/params_parser.rb +0 -77
- data/lib/action_controller/performance_test.rb +0 -15
- data/lib/action_controller/rack_lint_patch.rb +0 -36
- data/lib/action_controller/reloader.rb +0 -54
- data/lib/action_controller/request.rb +0 -518
- data/lib/action_controller/request_forgery_protection.rb +0 -116
- data/lib/action_controller/rescue.rb +0 -183
- data/lib/action_controller/resources.rb +0 -682
- data/lib/action_controller/response.rb +0 -237
- data/lib/action_controller/routing.rb +0 -388
- data/lib/action_controller/routing/builder.rb +0 -197
- data/lib/action_controller/routing/optimisations.rb +0 -130
- data/lib/action_controller/routing/recognition_optimisation.rb +0 -167
- data/lib/action_controller/routing/route.rb +0 -265
- data/lib/action_controller/routing/route_set.rb +0 -503
- data/lib/action_controller/routing/routing_ext.rb +0 -49
- data/lib/action_controller/routing/segments.rb +0 -343
- data/lib/action_controller/session/abstract_store.rb +0 -276
- data/lib/action_controller/session/mem_cache_store.rb +0 -60
- data/lib/action_controller/status_codes.rb +0 -88
- data/lib/action_controller/string_coercion.rb +0 -29
- data/lib/action_controller/templates/rescues/diagnostics.erb +0 -11
- data/lib/action_controller/test_process.rb +0 -580
- data/lib/action_controller/uploaded_file.rb +0 -44
- data/lib/action_view/helpers/benchmark_helper.rb +0 -54
- data/lib/action_view/inline_template.rb +0 -19
- data/lib/action_view/reloadable_template.rb +0 -117
- data/lib/action_view/renderable.rb +0 -109
- data/lib/action_view/renderable_partial.rb +0 -53
- data/lib/action_view/template_error.rb +0 -99
- data/lib/action_view/template_handler.rb +0 -34
- data/lib/action_view/template_handlers.rb +0 -48
- data/lib/action_view/template_handlers/erb.rb +0 -25
- data/lib/actionpack.rb +0 -2
- data/test/abstract_unit.rb +0 -78
- data/test/active_record_unit.rb +0 -104
- data/test/activerecord/active_record_store_test.rb +0 -221
- data/test/activerecord/render_partial_with_record_identification_test.rb +0 -188
- data/test/adv_attr_test.rb +0 -20
- data/test/controller/action_pack_assertions_test.rb +0 -545
- data/test/controller/addresses_render_test.rb +0 -37
- data/test/controller/assert_select_test.rb +0 -735
- data/test/controller/base_test.rb +0 -217
- data/test/controller/benchmark_test.rb +0 -32
- data/test/controller/caching_test.rb +0 -743
- data/test/controller/capture_test.rb +0 -66
- data/test/controller/content_type_test.rb +0 -178
- 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 +0 -208
- data/test/controller/deprecation/deprecated_base_methods_test.rb +0 -32
- data/test/controller/dispatcher_test.rb +0 -144
- data/test/controller/dom_assertions_test.rb +0 -53
- data/test/controller/failsafe_test.rb +0 -60
- data/test/controller/fake_controllers.rb +0 -33
- data/test/controller/fake_models.rb +0 -19
- data/test/controller/filter_params_test.rb +0 -52
- data/test/controller/filters_test.rb +0 -885
- data/test/controller/flash_test.rb +0 -174
- data/test/controller/header_test.rb +0 -14
- data/test/controller/helper_test.rb +0 -224
- data/test/controller/html-scanner/cdata_node_test.rb +0 -15
- data/test/controller/html-scanner/document_test.rb +0 -148
- data/test/controller/html-scanner/node_test.rb +0 -89
- data/test/controller/html-scanner/sanitizer_test.rb +0 -300
- data/test/controller/html-scanner/tag_node_test.rb +0 -238
- data/test/controller/html-scanner/text_node_test.rb +0 -50
- data/test/controller/html-scanner/tokenizer_test.rb +0 -131
- data/test/controller/http_basic_authentication_test.rb +0 -113
- data/test/controller/http_digest_authentication_test.rb +0 -254
- data/test/controller/integration_test.rb +0 -526
- data/test/controller/layout_test.rb +0 -215
- data/test/controller/localized_templates_test.rb +0 -24
- data/test/controller/logging_test.rb +0 -46
- data/test/controller/middleware_stack_test.rb +0 -90
- data/test/controller/mime_responds_test.rb +0 -536
- data/test/controller/mime_type_test.rb +0 -93
- data/test/controller/output_escaping_test.rb +0 -19
- data/test/controller/polymorphic_routes_test.rb +0 -297
- data/test/controller/rack_test.rb +0 -308
- data/test/controller/record_identifier_test.rb +0 -139
- data/test/controller/redirect_test.rb +0 -285
- data/test/controller/reloader_test.rb +0 -125
- data/test/controller/render_test.rb +0 -1783
- data/test/controller/request/json_params_parsing_test.rb +0 -65
- data/test/controller/request/multipart_params_parsing_test.rb +0 -177
- data/test/controller/request/query_string_parsing_test.rb +0 -129
- data/test/controller/request/test_request_test.rb +0 -35
- data/test/controller/request/url_encoded_params_parsing_test.rb +0 -146
- data/test/controller/request/xml_params_parsing_test.rb +0 -103
- data/test/controller/request_forgery_protection_test.rb +0 -233
- data/test/controller/request_test.rb +0 -398
- data/test/controller/rescue_test.rb +0 -541
- data/test/controller/resources_test.rb +0 -1393
- data/test/controller/routing_test.rb +0 -2592
- data/test/controller/selector_test.rb +0 -628
- data/test/controller/send_file_test.rb +0 -171
- data/test/controller/session/abstract_store_test.rb +0 -64
- data/test/controller/session/cookie_store_test.rb +0 -354
- data/test/controller/session/mem_cache_store_test.rb +0 -187
- data/test/controller/session/test_session_test.rb +0 -58
- data/test/controller/test_test.rb +0 -700
- data/test/controller/translation_test.rb +0 -26
- data/test/controller/url_rewriter_test.rb +0 -395
- data/test/controller/verification_test.rb +0 -270
- data/test/controller/view_paths_test.rb +0 -141
- data/test/controller/webservice_test.rb +0 -273
- data/test/fixtures/_top_level_partial.html.erb +0 -1
- data/test/fixtures/_top_level_partial_only.erb +0 -1
- data/test/fixtures/addresses/list.erb +0 -1
- data/test/fixtures/alternate_helpers/foo_helper.rb +0 -3
- data/test/fixtures/bad_customers/_bad_customer.html.erb +0 -1
- data/test/fixtures/companies.yml +0 -24
- data/test/fixtures/company.rb +0 -10
- data/test/fixtures/content_type/render_default_content_types_for_respond_to.rhtml +0 -1
- data/test/fixtures/content_type/render_default_for_rhtml.rhtml +0 -1
- data/test/fixtures/content_type/render_default_for_rjs.rjs +0 -1
- data/test/fixtures/content_type/render_default_for_rxml.rxml +0 -1
- data/test/fixtures/customers/_customer.html.erb +0 -1
- data/test/fixtures/db_definitions/sqlite.sql +0 -49
- data/test/fixtures/developer.rb +0 -9
- data/test/fixtures/developers.yml +0 -21
- data/test/fixtures/developers/_developer.erb +0 -1
- data/test/fixtures/developers_projects.yml +0 -13
- data/test/fixtures/failsafe/500.html +0 -1
- data/test/fixtures/fun/games/_game.erb +0 -1
- data/test/fixtures/fun/games/hello_world.erb +0 -1
- data/test/fixtures/fun/serious/games/_game.erb +0 -1
- data/test/fixtures/functional_caching/_partial.erb +0 -3
- data/test/fixtures/functional_caching/formatted_fragment_cached.html.erb +0 -3
- data/test/fixtures/functional_caching/formatted_fragment_cached.js.rjs +0 -6
- data/test/fixtures/functional_caching/formatted_fragment_cached.xml.builder +0 -5
- data/test/fixtures/functional_caching/fragment_cached.html.erb +0 -2
- data/test/fixtures/functional_caching/html_fragment_cached_with_partial.html.erb +0 -1
- data/test/fixtures/functional_caching/inline_fragment_cached.html.erb +0 -2
- data/test/fixtures/functional_caching/js_fragment_cached_with_partial.js.rjs +0 -1
- data/test/fixtures/good_customers/_good_customer.html.erb +0 -1
- data/test/fixtures/helpers/abc_helper.rb +0 -5
- data/test/fixtures/helpers/fun/games_helper.rb +0 -3
- data/test/fixtures/helpers/fun/pdf_helper.rb +0 -3
- data/test/fixtures/layout_tests/abs_path_layout.rhtml +0 -1
- data/test/fixtures/layout_tests/alt/hello.rhtml +0 -1
- data/test/fixtures/layout_tests/alt/layouts/alt.rhtml +0 -0
- data/test/fixtures/layout_tests/layouts/controller_name_space/nested.rhtml +0 -1
- data/test/fixtures/layout_tests/layouts/item.rhtml +0 -1
- data/test/fixtures/layout_tests/layouts/layout_test.rhtml +0 -1
- data/test/fixtures/layout_tests/layouts/multiple_extensions.html.erb +0 -1
- data/test/fixtures/layout_tests/layouts/third_party_template_library.mab +0 -1
- data/test/fixtures/layout_tests/views/hello.rhtml +0 -1
- data/test/fixtures/layouts/_column.html.erb +0 -2
- data/test/fixtures/layouts/block_with_layout.erb +0 -3
- data/test/fixtures/layouts/builder.builder +0 -3
- data/test/fixtures/layouts/default_html.html.erb +0 -1
- data/test/fixtures/layouts/partial_with_layout.erb +0 -3
- data/test/fixtures/layouts/standard.erb +0 -1
- data/test/fixtures/layouts/talk_from_action.erb +0 -2
- data/test/fixtures/layouts/xhr.html.erb +0 -2
- data/test/fixtures/layouts/yield.erb +0 -2
- data/test/fixtures/localized/hello_world.de.html +0 -1
- data/test/fixtures/localized/hello_world.en.html +0 -1
- data/test/fixtures/mascot.rb +0 -3
- data/test/fixtures/mascots.yml +0 -4
- data/test/fixtures/mascots/_mascot.html.erb +0 -1
- data/test/fixtures/multipart/binary_file +0 -0
- data/test/fixtures/multipart/boundary_problem_file +0 -10
- data/test/fixtures/multipart/bracketed_param +0 -5
- data/test/fixtures/multipart/empty +0 -10
- data/test/fixtures/multipart/hello.txt +0 -1
- data/test/fixtures/multipart/large_text_file +0 -10
- data/test/fixtures/multipart/mixed_files +0 -0
- data/test/fixtures/multipart/mona_lisa.jpg +0 -0
- data/test/fixtures/multipart/none +0 -9
- data/test/fixtures/multipart/single_parameter +0 -5
- data/test/fixtures/multipart/text_file +0 -10
- data/test/fixtures/override/test/hello_world.erb +0 -1
- data/test/fixtures/override2/layouts/test/sub.erb +0 -1
- data/test/fixtures/post_test/layouts/post.html.erb +0 -1
- data/test/fixtures/post_test/layouts/super_post.iphone.erb +0 -1
- data/test/fixtures/post_test/post/index.html.erb +0 -1
- data/test/fixtures/post_test/post/index.iphone.erb +0 -1
- data/test/fixtures/post_test/super_post/index.html.erb +0 -1
- data/test/fixtures/post_test/super_post/index.iphone.erb +0 -1
- data/test/fixtures/project.rb +0 -3
- data/test/fixtures/projects.yml +0 -7
- data/test/fixtures/projects/_project.erb +0 -1
- data/test/fixtures/public/404.html +0 -1
- data/test/fixtures/public/500.da.html +0 -1
- data/test/fixtures/public/500.html +0 -1
- data/test/fixtures/public/absolute/test.css +0 -23
- data/test/fixtures/public/absolute/test.js +0 -63
- data/test/fixtures/public/images/rails.png +0 -0
- data/test/fixtures/public/javascripts/application.js +0 -1
- data/test/fixtures/public/javascripts/bank.js +0 -1
- data/test/fixtures/public/javascripts/controls.js +0 -1
- data/test/fixtures/public/javascripts/dragdrop.js +0 -1
- data/test/fixtures/public/javascripts/effects.js +0 -1
- data/test/fixtures/public/javascripts/prototype.js +0 -1
- data/test/fixtures/public/javascripts/robber.js +0 -1
- data/test/fixtures/public/javascripts/subdir/subdir.js +0 -1
- data/test/fixtures/public/javascripts/version.1.0.js +0 -1
- data/test/fixtures/public/stylesheets/bank.css +0 -1
- data/test/fixtures/public/stylesheets/robber.css +0 -1
- data/test/fixtures/public/stylesheets/subdir/subdir.css +0 -1
- data/test/fixtures/public/stylesheets/version.1.0.css +0 -1
- data/test/fixtures/quiz/questions/_question.html.erb +0 -1
- data/test/fixtures/replies.yml +0 -15
- data/test/fixtures/replies/_reply.erb +0 -1
- data/test/fixtures/reply.rb +0 -7
- data/test/fixtures/respond_to/all_types_with_layout.html.erb +0 -1
- data/test/fixtures/respond_to/all_types_with_layout.js.rjs +0 -1
- data/test/fixtures/respond_to/custom_constant_handling_without_block.mobile.erb +0 -1
- data/test/fixtures/respond_to/iphone_with_html_response_type.html.erb +0 -1
- data/test/fixtures/respond_to/iphone_with_html_response_type.iphone.erb +0 -1
- data/test/fixtures/respond_to/layouts/missing.html.erb +0 -1
- data/test/fixtures/respond_to/layouts/standard.html.erb +0 -1
- data/test/fixtures/respond_to/layouts/standard.iphone.erb +0 -1
- data/test/fixtures/respond_to/using_defaults.html.erb +0 -1
- data/test/fixtures/respond_to/using_defaults.js.rjs +0 -1
- data/test/fixtures/respond_to/using_defaults.xml.builder +0 -1
- data/test/fixtures/respond_to/using_defaults_with_type_list.html.erb +0 -1
- data/test/fixtures/respond_to/using_defaults_with_type_list.js.rjs +0 -1
- data/test/fixtures/respond_to/using_defaults_with_type_list.xml.builder +0 -1
- data/test/fixtures/scope/test/modgreet.erb +0 -1
- data/test/fixtures/session_autoload_test/session_autoload_test/foo.rb +0 -10
- data/test/fixtures/shared.html.erb +0 -1
- data/test/fixtures/symlink_parent/symlinked_layout.erb +0 -5
- data/test/fixtures/test/_counter.html.erb +0 -1
- data/test/fixtures/test/_customer.erb +0 -1
- data/test/fixtures/test/_customer_counter.erb +0 -1
- data/test/fixtures/test/_customer_counter_with_as.erb +0 -1
- data/test/fixtures/test/_customer_greeting.erb +0 -1
- data/test/fixtures/test/_customer_with_var.erb +0 -1
- data/test/fixtures/test/_form.erb +0 -1
- data/test/fixtures/test/_from_helper.erb +0 -1
- data/test/fixtures/test/_hash_greeting.erb +0 -1
- data/test/fixtures/test/_hash_object.erb +0 -2
- data/test/fixtures/test/_hello.builder +0 -1
- data/test/fixtures/test/_labelling_form.erb +0 -1
- data/test/fixtures/test/_layout_for_block_with_args.html.erb +0 -3
- data/test/fixtures/test/_layout_for_partial.html.erb +0 -3
- data/test/fixtures/test/_local_inspector.html.erb +0 -1
- data/test/fixtures/test/_one.html.erb +0 -1
- data/test/fixtures/test/_partial.erb +0 -1
- data/test/fixtures/test/_partial.html.erb +0 -1
- data/test/fixtures/test/_partial.js.erb +0 -1
- data/test/fixtures/test/_partial_for_use_in_layout.html.erb +0 -1
- data/test/fixtures/test/_partial_only.erb +0 -1
- data/test/fixtures/test/_partial_with_only_html_version.html.erb +0 -1
- data/test/fixtures/test/_person.erb +0 -2
- data/test/fixtures/test/_raise.html.erb +0 -1
- data/test/fixtures/test/_two.html.erb +0 -1
- data/test/fixtures/test/_utf8_partial.html.erb +0 -1
- data/test/fixtures/test/_utf8_partial_magic.html.erb +0 -2
- data/test/fixtures/test/action_talk_to_layout.erb +0 -2
- data/test/fixtures/test/array_translation.erb +0 -1
- data/test/fixtures/test/calling_partial_with_layout.html.erb +0 -1
- data/test/fixtures/test/capturing.erb +0 -4
- data/test/fixtures/test/content_for.erb +0 -2
- data/test/fixtures/test/content_for_concatenated.erb +0 -3
- data/test/fixtures/test/content_for_with_parameter.erb +0 -2
- data/test/fixtures/test/delete_with_js.rjs +0 -2
- data/test/fixtures/test/dont_pick_me +0 -1
- data/test/fixtures/test/dot.directory/render_file_with_ivar.erb +0 -1
- data/test/fixtures/test/enum_rjs_test.rjs +0 -6
- data/test/fixtures/test/formatted_html_erb.html.erb +0 -1
- data/test/fixtures/test/formatted_xml_erb.builder +0 -1
- data/test/fixtures/test/formatted_xml_erb.html.erb +0 -1
- data/test/fixtures/test/formatted_xml_erb.xml.erb +0 -1
- data/test/fixtures/test/greeting.erb +0 -1
- data/test/fixtures/test/greeting.js.rjs +0 -1
- data/test/fixtures/test/hello.builder +0 -4
- data/test/fixtures/test/hello_world.da.html.erb +0 -1
- data/test/fixtures/test/hello_world.erb +0 -1
- data/test/fixtures/test/hello_world.erb~ +0 -1
- data/test/fixtures/test/hello_world.pt-BR.html.erb +0 -1
- data/test/fixtures/test/hello_world_container.builder +0 -3
- data/test/fixtures/test/hello_world_from_rxml.builder +0 -4
- data/test/fixtures/test/hello_world_with_layout_false.erb +0 -1
- data/test/fixtures/test/hello_xml_world.builder +0 -11
- data/test/fixtures/test/hyphen-ated.erb +0 -1
- data/test/fixtures/test/implicit_content_type.atom.builder +0 -2
- data/test/fixtures/test/list.erb +0 -1
- data/test/fixtures/test/malformed/malformed.en.html.erb~ +0 -1
- data/test/fixtures/test/malformed/malformed.erb~ +0 -1
- data/test/fixtures/test/malformed/malformed.html.erb~ +0 -1
- data/test/fixtures/test/nested_layout.erb +0 -3
- data/test/fixtures/test/non_erb_block_content_for.builder +0 -4
- data/test/fixtures/test/potential_conflicts.erb +0 -4
- data/test/fixtures/test/render_explicit_html_template.js.rjs +0 -1
- data/test/fixtures/test/render_file_from_template.html.erb +0 -1
- data/test/fixtures/test/render_file_with_ivar.erb +0 -1
- data/test/fixtures/test/render_file_with_locals.erb +0 -1
- data/test/fixtures/test/render_implicit_html_template.js.rjs +0 -1
- data/test/fixtures/test/render_implicit_html_template_from_xhr_request.da.html.erb +0 -1
- data/test/fixtures/test/render_implicit_html_template_from_xhr_request.html.erb +0 -1
- data/test/fixtures/test/render_implicit_js_template_without_layout.js.erb +0 -1
- data/test/fixtures/test/render_to_string_test.erb +0 -1
- data/test/fixtures/test/scoped_array_translation.erb +0 -1
- data/test/fixtures/test/sub_template_raise.html.erb +0 -1
- data/test/fixtures/test/template.erb +0 -1
- data/test/fixtures/test/translation.erb +0 -1
- data/test/fixtures/test/update_element_with_capture.erb +0 -9
- data/test/fixtures/test/using_layout_around_block.html.erb +0 -1
- data/test/fixtures/test/using_layout_around_block_with_args.html.erb +0 -1
- data/test/fixtures/test/utf8.html.erb +0 -4
- data/test/fixtures/test/utf8_magic.html.erb +0 -5
- data/test/fixtures/test/utf8_magic_with_bare_partial.html.erb +0 -5
- data/test/fixtures/topic.rb +0 -3
- data/test/fixtures/topics.yml +0 -22
- data/test/fixtures/topics/_topic.html.erb +0 -1
- data/test/template/active_record_helper_i18n_test.rb +0 -51
- data/test/template/active_record_helper_test.rb +0 -302
- data/test/template/asset_tag_helper_test.rb +0 -770
- data/test/template/atom_feed_helper_test.rb +0 -315
- data/test/template/benchmark_helper_test.rb +0 -86
- data/test/template/compiled_templates_test.rb +0 -204
- data/test/template/date_helper_i18n_test.rb +0 -121
- data/test/template/date_helper_test.rb +0 -2603
- data/test/template/erb_util_test.rb +0 -36
- data/test/template/form_helper_test.rb +0 -1447
- data/test/template/form_options_helper_i18n_test.rb +0 -27
- data/test/template/form_options_helper_test.rb +0 -811
- data/test/template/form_tag_helper_test.rb +0 -356
- data/test/template/javascript_helper_test.rb +0 -106
- data/test/template/number_helper_i18n_test.rb +0 -69
- data/test/template/number_helper_test.rb +0 -132
- data/test/template/prototype_helper_test.rb +0 -639
- data/test/template/raw_output_helper_test.rb +0 -21
- data/test/template/record_tag_helper_test.rb +0 -58
- data/test/template/render_test.rb +0 -329
- data/test/template/sanitize_helper_test.rb +0 -57
- data/test/template/scriptaculous_helper_test.rb +0 -90
- data/test/template/tag_helper_test.rb +0 -98
- data/test/template/template_test.rb +0 -32
- data/test/template/test_test.rb +0 -54
- data/test/template/text_helper_test.rb +0 -601
- data/test/template/translation_helper_test.rb +0 -95
- data/test/template/url_helper_test.rb +0 -641
- data/test/testing_sandbox.rb +0 -15
- data/test/view/test_case_test.rb +0 -176
@@ -1,197 +0,0 @@
|
|
1
|
-
module ActionController
|
2
|
-
module Routing
|
3
|
-
class RouteBuilder #:nodoc:
|
4
|
-
attr_reader :separators, :optional_separators
|
5
|
-
attr_reader :separator_regexp, :nonseparator_regexp, :interval_regexp
|
6
|
-
|
7
|
-
def initialize
|
8
|
-
@separators = Routing::SEPARATORS
|
9
|
-
@optional_separators = %w( / )
|
10
|
-
|
11
|
-
@separator_regexp = /[#{Regexp.escape(separators.join)}]/
|
12
|
-
@nonseparator_regexp = /\A([^#{Regexp.escape(separators.join)}]+)/
|
13
|
-
@interval_regexp = /(.*?)(#{separator_regexp}|$)/
|
14
|
-
end
|
15
|
-
|
16
|
-
# Accepts a "route path" (a string defining a route), and returns the array
|
17
|
-
# of segments that corresponds to it. Note that the segment array is only
|
18
|
-
# partially initialized--the defaults and requirements, for instance, need
|
19
|
-
# to be set separately, via the +assign_route_options+ method, and the
|
20
|
-
# <tt>optional?</tt> method for each segment will not be reliable until after
|
21
|
-
# +assign_route_options+ is called, as well.
|
22
|
-
def segments_for_route_path(path)
|
23
|
-
rest, segments = path, []
|
24
|
-
|
25
|
-
until rest.empty?
|
26
|
-
segment, rest = segment_for(rest)
|
27
|
-
segments << segment
|
28
|
-
end
|
29
|
-
segments
|
30
|
-
end
|
31
|
-
|
32
|
-
# A factory method that returns a new segment instance appropriate for the
|
33
|
-
# format of the given string.
|
34
|
-
def segment_for(string)
|
35
|
-
segment =
|
36
|
-
case string
|
37
|
-
when /\A\.(:format)?\//
|
38
|
-
OptionalFormatSegment.new
|
39
|
-
when /\A:(\w+)/
|
40
|
-
key = $1.to_sym
|
41
|
-
key == :controller ? ControllerSegment.new(key) : DynamicSegment.new(key)
|
42
|
-
when /\A\*(\w+)/
|
43
|
-
PathSegment.new($1.to_sym, :optional => true)
|
44
|
-
when /\A\?(.*?)\?/
|
45
|
-
StaticSegment.new($1, :optional => true)
|
46
|
-
when nonseparator_regexp
|
47
|
-
StaticSegment.new($1)
|
48
|
-
when separator_regexp
|
49
|
-
DividerSegment.new($&, :optional => optional_separators.include?($&))
|
50
|
-
end
|
51
|
-
[segment, $~.post_match]
|
52
|
-
end
|
53
|
-
|
54
|
-
# Split the given hash of options into requirement and default hashes. The
|
55
|
-
# segments are passed alongside in order to distinguish between default values
|
56
|
-
# and requirements.
|
57
|
-
def divide_route_options(segments, options)
|
58
|
-
options = options.except(:path_prefix, :name_prefix)
|
59
|
-
|
60
|
-
if options[:namespace]
|
61
|
-
options[:controller] = "#{options.delete(:namespace).sub(/\/$/, '')}/#{options[:controller]}"
|
62
|
-
end
|
63
|
-
|
64
|
-
requirements = (options.delete(:requirements) || {}).dup
|
65
|
-
defaults = (options.delete(:defaults) || {}).dup
|
66
|
-
conditions = (options.delete(:conditions) || {}).dup
|
67
|
-
|
68
|
-
validate_route_conditions(conditions)
|
69
|
-
|
70
|
-
path_keys = segments.collect { |segment| segment.key if segment.respond_to?(:key) }.compact
|
71
|
-
options.each do |key, value|
|
72
|
-
hash = (path_keys.include?(key) && ! value.is_a?(Regexp)) ? defaults : requirements
|
73
|
-
hash[key] = value
|
74
|
-
end
|
75
|
-
|
76
|
-
[defaults, requirements, conditions]
|
77
|
-
end
|
78
|
-
|
79
|
-
# Takes a hash of defaults and a hash of requirements, and assigns them to
|
80
|
-
# the segments. Any unused requirements (which do not correspond to a segment)
|
81
|
-
# are returned as a hash.
|
82
|
-
def assign_route_options(segments, defaults, requirements)
|
83
|
-
route_requirements = {} # Requirements that do not belong to a segment
|
84
|
-
|
85
|
-
segment_named = Proc.new do |key|
|
86
|
-
segments.detect { |segment| segment.key == key if segment.respond_to?(:key) }
|
87
|
-
end
|
88
|
-
|
89
|
-
requirements.each do |key, requirement|
|
90
|
-
segment = segment_named[key]
|
91
|
-
if segment
|
92
|
-
raise TypeError, "#{key}: requirements on a path segment must be regular expressions" unless requirement.is_a?(Regexp)
|
93
|
-
if requirement.source =~ %r{\A(\\A|\^)|(\\Z|\\z|\$)\Z}
|
94
|
-
raise ArgumentError, "Regexp anchor characters are not allowed in routing requirements: #{requirement.inspect}"
|
95
|
-
end
|
96
|
-
if requirement.multiline?
|
97
|
-
raise ArgumentError, "Regexp multiline option not allowed in routing requirements: #{requirement.inspect}"
|
98
|
-
end
|
99
|
-
segment.regexp = requirement
|
100
|
-
else
|
101
|
-
route_requirements[key] = requirement
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
defaults.each do |key, default|
|
106
|
-
segment = segment_named[key]
|
107
|
-
raise ArgumentError, "#{key}: No matching segment exists; cannot assign default" unless segment
|
108
|
-
segment.is_optional = true
|
109
|
-
segment.default = default.to_param if default
|
110
|
-
end
|
111
|
-
|
112
|
-
assign_default_route_options(segments)
|
113
|
-
ensure_required_segments(segments)
|
114
|
-
route_requirements
|
115
|
-
end
|
116
|
-
|
117
|
-
# Assign default options, such as 'index' as a default for <tt>:action</tt>. This
|
118
|
-
# method must be run *after* user supplied requirements and defaults have
|
119
|
-
# been applied to the segments.
|
120
|
-
def assign_default_route_options(segments)
|
121
|
-
segments.each do |segment|
|
122
|
-
next unless segment.is_a? DynamicSegment
|
123
|
-
case segment.key
|
124
|
-
when :action
|
125
|
-
if segment.regexp.nil? || segment.regexp.match('index').to_s == 'index'
|
126
|
-
segment.default ||= 'index'
|
127
|
-
segment.is_optional = true
|
128
|
-
end
|
129
|
-
when :id
|
130
|
-
if segment.default.nil? && segment.regexp.nil? || segment.regexp =~ ''
|
131
|
-
segment.is_optional = true
|
132
|
-
end
|
133
|
-
end
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
# Makes sure that there are no optional segments that precede a required
|
138
|
-
# segment. If any are found that precede a required segment, they are
|
139
|
-
# made required.
|
140
|
-
def ensure_required_segments(segments)
|
141
|
-
allow_optional = true
|
142
|
-
segments.reverse_each do |segment|
|
143
|
-
allow_optional &&= segment.optional?
|
144
|
-
if !allow_optional && segment.optional?
|
145
|
-
unless segment.optionality_implied?
|
146
|
-
warn "Route segment \"#{segment.to_s}\" cannot be optional because it precedes a required segment. This segment will be required."
|
147
|
-
end
|
148
|
-
segment.is_optional = false
|
149
|
-
elsif allow_optional && segment.respond_to?(:default) && segment.default
|
150
|
-
# if a segment has a default, then it is optional
|
151
|
-
segment.is_optional = true
|
152
|
-
end
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
|
-
# Construct and return a route with the given path and options.
|
157
|
-
def build(path, options)
|
158
|
-
# Wrap the path with slashes
|
159
|
-
path = "/#{path}" unless path[0] == ?/
|
160
|
-
path = "#{path}/" unless path[-1] == ?/
|
161
|
-
|
162
|
-
prefix = options[:path_prefix].to_s.gsub(/^\//,'')
|
163
|
-
path = "/#{prefix}#{path}" unless prefix.blank?
|
164
|
-
|
165
|
-
segments = segments_for_route_path(path)
|
166
|
-
defaults, requirements, conditions = divide_route_options(segments, options)
|
167
|
-
requirements = assign_route_options(segments, defaults, requirements)
|
168
|
-
|
169
|
-
# TODO: Segments should be frozen on initialize
|
170
|
-
segments.each { |segment| segment.freeze }
|
171
|
-
|
172
|
-
route = Route.new(segments, requirements, conditions)
|
173
|
-
|
174
|
-
if !route.significant_keys.include?(:controller)
|
175
|
-
raise ArgumentError, "Illegal route: the :controller must be specified!"
|
176
|
-
end
|
177
|
-
|
178
|
-
route.freeze
|
179
|
-
end
|
180
|
-
|
181
|
-
private
|
182
|
-
def validate_route_conditions(conditions)
|
183
|
-
if method = conditions[:method]
|
184
|
-
[method].flatten.each do |m|
|
185
|
-
if m == :head
|
186
|
-
raise ArgumentError, "HTTP method HEAD is invalid in route conditions. Rails processes HEAD requests the same as GETs, returning just the response headers"
|
187
|
-
end
|
188
|
-
|
189
|
-
unless HTTP_METHODS.include?(m.to_sym)
|
190
|
-
raise ArgumentError, "Invalid HTTP method specified in route conditions: #{conditions.inspect}"
|
191
|
-
end
|
192
|
-
end
|
193
|
-
end
|
194
|
-
end
|
195
|
-
end
|
196
|
-
end
|
197
|
-
end
|
@@ -1,130 +0,0 @@
|
|
1
|
-
module ActionController
|
2
|
-
module Routing
|
3
|
-
# Much of the slow performance from routes comes from the
|
4
|
-
# complexity of expiry, <tt>:requirements</tt> matching, defaults providing
|
5
|
-
# and figuring out which url pattern to use. With named routes
|
6
|
-
# we can avoid the expense of finding the right route. So if
|
7
|
-
# they've provided the right number of arguments, and have no
|
8
|
-
# <tt>:requirements</tt>, we can just build up a string and return it.
|
9
|
-
#
|
10
|
-
# To support building optimisations for other common cases, the
|
11
|
-
# generation code is separated into several classes
|
12
|
-
module Optimisation
|
13
|
-
def generate_optimisation_block(route, kind)
|
14
|
-
return "" unless route.optimise?
|
15
|
-
OPTIMISERS.inject("") do |memo, klazz|
|
16
|
-
memo << klazz.new(route, kind).source_code
|
17
|
-
memo
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
class Optimiser
|
22
|
-
attr_reader :route, :kind
|
23
|
-
GLOBAL_GUARD_CONDITIONS = [
|
24
|
-
"(!defined?(default_url_options) || default_url_options.blank?)",
|
25
|
-
"(!defined?(controller.default_url_options) || controller.default_url_options.blank?)",
|
26
|
-
"defined?(request)",
|
27
|
-
"request"
|
28
|
-
]
|
29
|
-
|
30
|
-
def initialize(route, kind)
|
31
|
-
@route = route
|
32
|
-
@kind = kind
|
33
|
-
end
|
34
|
-
|
35
|
-
def guard_conditions
|
36
|
-
["false"]
|
37
|
-
end
|
38
|
-
|
39
|
-
def generation_code
|
40
|
-
'nil'
|
41
|
-
end
|
42
|
-
|
43
|
-
def source_code
|
44
|
-
if applicable?
|
45
|
-
guard_condition = (GLOBAL_GUARD_CONDITIONS + guard_conditions).join(" && ")
|
46
|
-
"return #{generation_code} if #{guard_condition}\n"
|
47
|
-
else
|
48
|
-
"\n"
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
# Temporarily disabled <tt>:url</tt> optimisation pending proper solution to
|
53
|
-
# Issues around request.host etc.
|
54
|
-
def applicable?
|
55
|
-
true
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
# Given a route
|
60
|
-
#
|
61
|
-
# map.person '/people/:id'
|
62
|
-
#
|
63
|
-
# If the user calls <tt>person_url(@person)</tt>, we can simply
|
64
|
-
# return a string like "/people/#{@person.to_param}"
|
65
|
-
# rather than triggering the expensive logic in +url_for+.
|
66
|
-
class PositionalArguments < Optimiser
|
67
|
-
def guard_conditions
|
68
|
-
number_of_arguments = route.required_segment_keys.size
|
69
|
-
# if they're using foo_url(:id=>2) it's one
|
70
|
-
# argument, but we don't want to generate /foos/id2
|
71
|
-
if number_of_arguments == 1
|
72
|
-
["args.size == 1", "!args.first.is_a?(Hash)"]
|
73
|
-
else
|
74
|
-
["args.size == #{number_of_arguments}"]
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
def generation_code
|
79
|
-
elements = []
|
80
|
-
idx = 0
|
81
|
-
|
82
|
-
if kind == :url
|
83
|
-
elements << '#{request.protocol}'
|
84
|
-
elements << '#{request.host_with_port}'
|
85
|
-
end
|
86
|
-
|
87
|
-
elements << '#{ActionController::Base.relative_url_root if ActionController::Base.relative_url_root}'
|
88
|
-
|
89
|
-
# The last entry in <tt>route.segments</tt> appears to *always* be a
|
90
|
-
# 'divider segment' for '/' but we have assertions to ensure that
|
91
|
-
# we don't include the trailing slashes, so skip them.
|
92
|
-
(route.segments.size == 1 ? route.segments : route.segments[0..-2]).each do |segment|
|
93
|
-
if segment.is_a?(DynamicSegment)
|
94
|
-
elements << segment.interpolation_chunk("args[#{idx}].to_param")
|
95
|
-
idx += 1
|
96
|
-
else
|
97
|
-
elements << segment.interpolation_chunk
|
98
|
-
end
|
99
|
-
end
|
100
|
-
%("#{elements * ''}")
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
# This case is mostly the same as the positional arguments case
|
105
|
-
# above, but it supports additional query parameters as the last
|
106
|
-
# argument
|
107
|
-
class PositionalArgumentsWithAdditionalParams < PositionalArguments
|
108
|
-
def guard_conditions
|
109
|
-
["args.size == #{route.segment_keys.size + 1}"] +
|
110
|
-
UrlRewriter::RESERVED_OPTIONS.collect{ |key| "!args.last.has_key?(:#{key})" }
|
111
|
-
end
|
112
|
-
|
113
|
-
# This case uses almost the same code as positional arguments,
|
114
|
-
# but add a question mark and args.last.to_query on the end,
|
115
|
-
# unless the last arg is empty
|
116
|
-
def generation_code
|
117
|
-
super.insert(-2, '#{\'?\' + args.last.to_query unless args.last.empty?}')
|
118
|
-
end
|
119
|
-
|
120
|
-
# To avoid generating "http://localhost/?host=foo.example.com" we
|
121
|
-
# can't use this optimisation on routes without any segments
|
122
|
-
def applicable?
|
123
|
-
super && route.segment_keys.size > 0
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
OPTIMISERS = [PositionalArguments, PositionalArgumentsWithAdditionalParams]
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
@@ -1,167 +0,0 @@
|
|
1
|
-
module ActionController
|
2
|
-
module Routing
|
3
|
-
# BEFORE: 0.191446860631307 ms/url
|
4
|
-
# AFTER: 0.029847304022858 ms/url
|
5
|
-
# Speed up: 6.4 times
|
6
|
-
#
|
7
|
-
# Route recognition is slow due to one-by-one iterating over
|
8
|
-
# a whole routeset (each map.resources generates at least 14 routes)
|
9
|
-
# and matching weird regexps on each step.
|
10
|
-
#
|
11
|
-
# We optimize this by skipping all URI segments that 100% sure can't
|
12
|
-
# be matched, moving deeper in a tree of routes (where node == segment)
|
13
|
-
# until first possible match is accured. In such case, we start walking
|
14
|
-
# a flat list of routes, matching them with accurate matcher.
|
15
|
-
# So, first step: search a segment tree for the first relevant index.
|
16
|
-
# Second step: iterate routes starting with that index.
|
17
|
-
#
|
18
|
-
# How tree is walked? We can do a recursive tests, but it's smarter:
|
19
|
-
# We just create a tree of if-s and elsif-s matching segments.
|
20
|
-
#
|
21
|
-
# We have segments of 3 flavors:
|
22
|
-
# 1) nil (no segment, route finished)
|
23
|
-
# 2) const-dot-dynamic (like "/posts.:xml", "/preview.:size.jpg")
|
24
|
-
# 3) const (like "/posts", "/comments")
|
25
|
-
# 4) dynamic ("/:id", "file.:size.:extension")
|
26
|
-
#
|
27
|
-
# We split incoming string into segments and iterate over them.
|
28
|
-
# When segment is nil, we drop immediately, on a current node index.
|
29
|
-
# When segment is equal to some const, we step into branch.
|
30
|
-
# If none constants matched, we step into 'dynamic' branch (it's a last).
|
31
|
-
# If we can't match anything, we drop to last index on a level.
|
32
|
-
#
|
33
|
-
# Note: we maintain the original routes order, so we finish building
|
34
|
-
# steps on a first dynamic segment.
|
35
|
-
#
|
36
|
-
#
|
37
|
-
# Example. Given the routes:
|
38
|
-
# 0 /posts/
|
39
|
-
# 1 /posts/:id
|
40
|
-
# 2 /posts/:id/comments
|
41
|
-
# 3 /posts/blah
|
42
|
-
# 4 /users/
|
43
|
-
# 5 /users/:id
|
44
|
-
# 6 /users/:id/profile
|
45
|
-
#
|
46
|
-
# request_uri = /users/123
|
47
|
-
#
|
48
|
-
# There will be only 4 iterations:
|
49
|
-
# 1) segm test for /posts prefix, skip all /posts/* routes
|
50
|
-
# 2) segm test for /users/
|
51
|
-
# 3) segm test for /users/:id
|
52
|
-
# (jump to list index = 5)
|
53
|
-
# 4) full test for /users/:id => here we are!
|
54
|
-
class RouteSet
|
55
|
-
def recognize_path(path, environment={})
|
56
|
-
result = recognize_optimized(path, environment) and return result
|
57
|
-
|
58
|
-
# Route was not recognized. Try to find out why (maybe wrong verb).
|
59
|
-
allows = HTTP_METHODS.select { |verb| routes.find { |r| r.recognize(path, environment.merge(:method => verb)) } }
|
60
|
-
|
61
|
-
if environment[:method] && !HTTP_METHODS.include?(environment[:method])
|
62
|
-
raise NotImplemented.new(*allows)
|
63
|
-
elsif !allows.empty?
|
64
|
-
raise MethodNotAllowed.new(*allows)
|
65
|
-
else
|
66
|
-
raise RoutingError, "No route matches #{path.inspect} with #{environment.inspect}"
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
def segment_tree(routes)
|
71
|
-
tree = [0]
|
72
|
-
|
73
|
-
i = -1
|
74
|
-
routes.each do |route|
|
75
|
-
i += 1
|
76
|
-
# not fast, but runs only once
|
77
|
-
segments = to_plain_segments(route.segments.inject("") { |str,s| str << s.to_s })
|
78
|
-
|
79
|
-
node = tree
|
80
|
-
segments.each do |seg|
|
81
|
-
seg = :dynamic if seg && seg[0] == ?:
|
82
|
-
node << [seg, [i]] if node.empty? || node[node.size - 1][0] != seg
|
83
|
-
node = node[node.size - 1][1]
|
84
|
-
end
|
85
|
-
end
|
86
|
-
tree
|
87
|
-
end
|
88
|
-
|
89
|
-
def generate_code(list, padding=' ', level = 0)
|
90
|
-
# a digit
|
91
|
-
return padding + "#{list[0]}\n" if list.size == 1 && !(Array === list[0])
|
92
|
-
|
93
|
-
body = padding + "(seg = segments[#{level}]; \n"
|
94
|
-
|
95
|
-
i = 0
|
96
|
-
was_nil = false
|
97
|
-
list.each do |item|
|
98
|
-
if Array === item
|
99
|
-
i += 1
|
100
|
-
start = (i == 1)
|
101
|
-
tag, sub = item
|
102
|
-
if tag == :dynamic
|
103
|
-
body += padding + "#{start ? 'if' : 'elsif'} true\n"
|
104
|
-
body += generate_code(sub, padding + " ", level + 1)
|
105
|
-
break
|
106
|
-
elsif tag == nil && !was_nil
|
107
|
-
was_nil = true
|
108
|
-
body += padding + "#{start ? 'if' : 'elsif'} seg.nil?\n"
|
109
|
-
body += generate_code(sub, padding + " ", level + 1)
|
110
|
-
else
|
111
|
-
body += padding + "#{start ? 'if' : 'elsif'} seg == '#{tag}'\n"
|
112
|
-
body += generate_code(sub, padding + " ", level + 1)
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
116
|
-
body += padding + "else\n"
|
117
|
-
body += padding + " #{list[0]}\n"
|
118
|
-
body += padding + "end)\n"
|
119
|
-
body
|
120
|
-
end
|
121
|
-
|
122
|
-
# this must be really fast
|
123
|
-
def to_plain_segments(str)
|
124
|
-
str = str.dup
|
125
|
-
str.sub!(/^\/+/,'')
|
126
|
-
str.sub!(/\/+$/,'')
|
127
|
-
segments = str.split(/\.[^\/]+\/+|\/+|\.[^\/]+\Z/) # cut off ".format" also
|
128
|
-
segments << nil
|
129
|
-
segments
|
130
|
-
end
|
131
|
-
|
132
|
-
private
|
133
|
-
def write_recognize_optimized!
|
134
|
-
tree = segment_tree(routes)
|
135
|
-
body = generate_code(tree)
|
136
|
-
|
137
|
-
remove_recognize_optimized!
|
138
|
-
|
139
|
-
instance_eval %{
|
140
|
-
def recognize_optimized(path, env)
|
141
|
-
segments = to_plain_segments(path)
|
142
|
-
index = #{body}
|
143
|
-
return nil unless index
|
144
|
-
while index < routes.size
|
145
|
-
result = routes[index].recognize(path, env) and return result
|
146
|
-
index += 1
|
147
|
-
end
|
148
|
-
nil
|
149
|
-
end
|
150
|
-
}, '(recognize_optimized)', 1
|
151
|
-
end
|
152
|
-
|
153
|
-
def clear_recognize_optimized!
|
154
|
-
remove_recognize_optimized!
|
155
|
-
write_recognize_optimized!
|
156
|
-
end
|
157
|
-
|
158
|
-
def remove_recognize_optimized!
|
159
|
-
if respond_to?(:recognize_optimized)
|
160
|
-
class << self
|
161
|
-
remove_method :recognize_optimized
|
162
|
-
end
|
163
|
-
end
|
164
|
-
end
|
165
|
-
end
|
166
|
-
end
|
167
|
-
end
|