From f86421fb282ff2d209914db736ca64380dab044d Mon Sep 17 00:00:00 2001 From: Bruno Michel Date: Sat, 13 Feb 2010 19:53:26 -0200 Subject: content_tag should escape its input Signed-off-by: Yehuda Katz --- .../lib/action_view/helpers/active_model_helper.rb | 6 +++--- actionpack/lib/action_view/helpers/date_helper.rb | 6 +++--- .../lib/action_view/helpers/form_options_helper.rb | 5 ++--- actionpack/lib/action_view/helpers/form_tag_helper.rb | 6 +++--- actionpack/lib/action_view/helpers/javascript_helper.rb | 2 +- actionpack/lib/action_view/helpers/tag_helper.rb | 2 +- actionpack/lib/action_view/helpers/url_helper.rb | 2 +- actionpack/test/template/form_tag_helper_test.rb | 16 ++++++++-------- actionpack/test/template/tag_helper_test.rb | 2 ++ actionpack/test/template/url_helper_test.rb | 2 +- 10 files changed, 25 insertions(+), 24 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/active_model_helper.rb b/actionpack/lib/action_view/helpers/active_model_helper.rb index e106bb0897..c87e216c32 100644 --- a/actionpack/lib/action_view/helpers/active_model_helper.rb +++ b/actionpack/lib/action_view/helpers/active_model_helper.rb @@ -127,7 +127,7 @@ module ActionView if (obj = (object.respond_to?(:errors) ? object : instance_variable_get("@#{object}"))) && (errors = obj.errors[method]) content_tag("div", - "#{options[:prepend_text]}#{ERB::Util.html_escape(errors.first)}#{options[:append_text]}", + "#{options[:prepend_text]}#{ERB::Util.html_escape(errors.first)}#{options[:append_text]}".html_safe, :class => options[:css_class] ) else @@ -228,14 +228,14 @@ module ActionView object.errors.full_messages.map do |msg| content_tag(:li, ERB::Util.html_escape(msg)) end - end.join + end.join.html_safe contents = '' contents << content_tag(options[:header_tag] || :h2, header_message) unless header_message.blank? contents << content_tag(:p, message) unless message.blank? contents << content_tag(:ul, error_messages) - content_tag(:div, contents, html) + content_tag(:div, contents.html_safe, html) end else '' diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb index 8be2f76bd6..c2810b3190 100644 --- a/actionpack/lib/action_view/helpers/date_helper.rb +++ b/actionpack/lib/action_view/helpers/date_helper.rb @@ -815,7 +815,7 @@ module ActionView tag_options[:selected] = "selected" if selected == i select_options << content_tag(:option, value, tag_options) end - select_options.join("\n") + "\n" + (select_options.join("\n") + "\n").html_safe end # Builds select tag from date type and html select options @@ -833,9 +833,9 @@ module ActionView select_html = "\n" select_html << content_tag(:option, '', :value => '') + "\n" if @options[:include_blank] select_html << prompt_option_tag(type, @options[:prompt]) + "\n" if @options[:prompt] - select_html << select_options_as_html.to_s + select_html << select_options_as_html - (content_tag(:select, select_html, select_options) + "\n").html_safe + (content_tag(:select, select_html.html_safe, select_options) + "\n").html_safe end # Builds a prompt option tag with supplied options or from default options diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb index 0ffe770f5f..7f74be27cb 100644 --- a/actionpack/lib/action_view/helpers/form_options_helper.rb +++ b/actionpack/lib/action_view/helpers/form_options_helper.rb @@ -572,10 +572,9 @@ module ActionView end if value.blank? && options[:prompt] prompt = options[:prompt].kind_of?(String) ? options[:prompt] : I18n.translate('helpers.select.prompt', :default => 'Please select') - "\n" + option_tags - else - option_tags + option_tags = "\n" + option_tags end + option_tags.html_safe end end diff --git a/actionpack/lib/action_view/helpers/form_tag_helper.rb b/actionpack/lib/action_view/helpers/form_tag_helper.rb index 6ed6c3101b..7dcaee7e34 100644 --- a/actionpack/lib/action_view/helpers/form_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/form_tag_helper.rb @@ -90,9 +90,9 @@ module ActionView html_name = (options[:multiple] == true && !name.to_s.ends_with?("[]")) ? "#{name}[]" : name if blank = options.delete(:include_blank) if blank.kind_of?(String) - option_tags = "" + option_tags + option_tags = "".html_safe + option_tags else - option_tags = "" + option_tags + option_tags = "".html_safe + option_tags end end content_tag :select, option_tags, { "name" => html_name, "id" => sanitize_to_id(name) }.update(options.stringify_keys) @@ -279,7 +279,7 @@ module ActionView escape = options.key?("escape") ? options.delete("escape") : true content = html_escape(content) if escape - content_tag :textarea, content, { "name" => name, "id" => sanitize_to_id(name) }.update(options) + content_tag :textarea, content.html_safe, { "name" => name, "id" => sanitize_to_id(name) }.update(options) end # Creates a check box form input tag. diff --git a/actionpack/lib/action_view/helpers/javascript_helper.rb b/actionpack/lib/action_view/helpers/javascript_helper.rb index 8fdaa8cf8d..2c73ff88f7 100644 --- a/actionpack/lib/action_view/helpers/javascript_helper.rb +++ b/actionpack/lib/action_view/helpers/javascript_helper.rb @@ -93,7 +93,7 @@ module ActionView end def javascript_cdata_section(content) #:nodoc: - "\n//#{cdata_section("\n#{content}\n//")}\n" + "\n//#{cdata_section("\n#{content}\n//")}\n".html_safe end end end diff --git a/actionpack/lib/action_view/helpers/tag_helper.rb b/actionpack/lib/action_view/helpers/tag_helper.rb index a3a8185f40..1c3eb20e19 100644 --- a/actionpack/lib/action_view/helpers/tag_helper.rb +++ b/actionpack/lib/action_view/helpers/tag_helper.rb @@ -127,7 +127,7 @@ module ActionView def content_tag_string(name, content, options, escape = true) tag_options = tag_options(options, escape) if options - "<#{name}#{tag_options}>#{content}".html_safe + "<#{name}#{tag_options}>#{ERB::Util.h content}".html_safe end def tag_options(options, escape = true) diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb index 168a3bdbc0..88ce2a2c0c 100644 --- a/actionpack/lib/action_view/helpers/url_helper.rb +++ b/actionpack/lib/action_view/helpers/url_helper.rb @@ -493,7 +493,7 @@ module ActionView char = c.chr string << (char =~ /\w/ ? sprintf("%%%x", c) : char) end - content_tag "a", name || email_address_encoded, html_options.merge({ "href" => "#{string}#{extras}" }) + content_tag "a", name || email_address_encoded.html_safe, html_options.merge({ "href" => "#{string}#{extras}" }) else content_tag "a", name || email_address_obfuscated, html_options.merge({ "href" => "mailto:#{email_address}#{extras}" }) end diff --git a/actionpack/test/template/form_tag_helper_test.rb b/actionpack/test/template/form_tag_helper_test.rb index 6ac5df1ea9..0ceec1afbf 100644 --- a/actionpack/test/template/form_tag_helper_test.rb +++ b/actionpack/test/template/form_tag_helper_test.rb @@ -127,19 +127,19 @@ class FormTagHelperTest < ActionView::TestCase end def test_select_tag - actual = select_tag "people", "" + actual = select_tag "people", "".html_safe expected = %() assert_dom_equal expected, actual end def test_select_tag_with_multiple - actual = select_tag "colors", "", :multiple => :true + actual = select_tag "colors", "".html_safe, :multiple => :true expected = %() assert_dom_equal expected, actual end def test_select_tag_disabled - actual = select_tag "places", "", :disabled => :true + actual = select_tag "places", "".html_safe, :disabled => :true expected = %() assert_dom_equal expected, actual end @@ -150,13 +150,13 @@ class FormTagHelperTest < ActionView::TestCase end def test_select_tag_with_include_blank - actual = select_tag "places", "", :include_blank => true + actual = select_tag "places", "".html_safe, :include_blank => true expected = %() assert_dom_equal expected, actual end def test_select_tag_with_include_blank_with_string - actual = select_tag "places", "", :include_blank => "string" + actual = select_tag "places", "".html_safe, :include_blank => "string" expected = %() assert_dom_equal expected, actual end @@ -282,9 +282,9 @@ class FormTagHelperTest < ActionView::TestCase assert_dom_equal %(), check_box_tag("admin", 1, true, 'disabled' => true, :readonly => "yes") assert_dom_equal %(), check_box_tag("admin", 1, true, :disabled => false, :readonly => nil) assert_dom_equal %(), tag(:input, :type => "checkbox", :checked => false) - assert_dom_equal %(), select_tag("people", "", :multiple => true) - assert_dom_equal %(), select_tag("people[]", "", :multiple => true) - assert_dom_equal %(), select_tag("people", "", :multiple => nil) + assert_dom_equal %(), select_tag("people", "".html_safe, :multiple => true) + assert_dom_equal %(), select_tag("people[]", "".html_safe, :multiple => true) + assert_dom_equal %(), select_tag("people", "".html_safe, :multiple => nil) end def test_stringify_symbol_keys diff --git a/actionpack/test/template/tag_helper_test.rb b/actionpack/test/template/tag_helper_test.rb index 433f6514cf..3858ffde40 100644 --- a/actionpack/test/template/tag_helper_test.rb +++ b/actionpack/test/template/tag_helper_test.rb @@ -37,6 +37,8 @@ class TagHelperTest < ActionView::TestCase assert content_tag("a", "Create", "href" => "create").html_safe? assert_equal content_tag("a", "Create", "href" => "create"), content_tag("a", "Create", :href => "create") + assert_equal "

<script>evil_js</script>

", + content_tag(:p, '') end def test_content_tag_with_block_in_erb diff --git a/actionpack/test/template/url_helper_test.rb b/actionpack/test/template/url_helper_test.rb index e904e88f49..418c050906 100644 --- a/actionpack/test/template/url_helper_test.rb +++ b/actionpack/test/template/url_helper_test.rb @@ -346,7 +346,7 @@ class UrlHelperTest < ActionView::TestCase end def test_mail_to_with_img - assert_dom_equal %(), mail_to('feedback@example.com', '') + assert_dom_equal %(), mail_to('feedback@example.com', ''.html_safe) end def test_mail_to_with_hex -- cgit v1.2.3 From 9f1900ec7a8a27e1a0eeef93e1226c09a79666b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Santiago=20Pastorino=20and=20Jos=C3=A9=20Ignacio=20Costa?= Date: Sat, 13 Feb 2010 19:55:58 -0200 Subject: html_escape mail_to when encode javascript and not hex Signed-off-by: Yehuda Katz --- actionpack/lib/action_view/helpers/url_helper.rb | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb index 88ce2a2c0c..4690161497 100644 --- a/actionpack/lib/action_view/helpers/url_helper.rb +++ b/actionpack/lib/action_view/helpers/url_helper.rb @@ -469,14 +469,12 @@ module ActionView extras << "subject=#{Rack::Utils.escape(subject).gsub("+", "%20")}&" unless subject.nil? extras = "?" << extras.gsub!(/&?$/,"") unless extras.empty? - email_address = email_address.to_s - - email_address_obfuscated = email_address.dup + email_address_obfuscated = html_escape(email_address) email_address_obfuscated.gsub!(/@/, html_options.delete("replace_at")) if html_options.has_key?("replace_at") email_address_obfuscated.gsub!(/\./, html_options.delete("replace_dot")) if html_options.has_key?("replace_dot") if encode == "javascript" - "document.write('#{content_tag("a", name || email_address_obfuscated, html_options.merge({ "href" => "mailto:"+email_address+extras }))}');".each_byte do |c| + "document.write('#{content_tag("a", name || email_address_obfuscated.html_safe, html_options.merge({ "href" => "mailto:"+email_address+extras }))}');".each_byte do |c| string << sprintf("%%%x", c) end "" @@ -495,7 +493,7 @@ module ActionView end content_tag "a", name || email_address_encoded.html_safe, html_options.merge({ "href" => "#{string}#{extras}" }) else - content_tag "a", name || email_address_obfuscated, html_options.merge({ "href" => "mailto:#{email_address}#{extras}" }) + content_tag "a", name || email_address_obfuscated.html_safe, html_options.merge({ "href" => "mailto:#{email_address}#{extras}" }) end end -- cgit v1.2.3 From 98a5bf8ff219f796e6db2d8d8b21dd114be47965 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Santiago=20Pastorino=20and=20Jos=C3=A9=20Ignacio=20Costa?= Date: Sun, 14 Feb 2010 01:46:02 -0200 Subject: Explicit html_escape removed when not needed Signed-off-by: Yehuda Katz --- actionpack/lib/action_view/helpers/active_model_helper.rb | 4 ++-- actionpack/lib/action_view/helpers/tag_helper.rb | 2 +- actionpack/lib/action_view/helpers/url_helper.rb | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/active_model_helper.rb b/actionpack/lib/action_view/helpers/active_model_helper.rb index c87e216c32..2f309fcca0 100644 --- a/actionpack/lib/action_view/helpers/active_model_helper.rb +++ b/actionpack/lib/action_view/helpers/active_model_helper.rb @@ -127,7 +127,7 @@ module ActionView if (obj = (object.respond_to?(:errors) ? object : instance_variable_get("@#{object}"))) && (errors = obj.errors[method]) content_tag("div", - "#{options[:prepend_text]}#{ERB::Util.html_escape(errors.first)}#{options[:append_text]}".html_safe, + (options[:prepend_text].html_safe << errors.first).safe_concat(options[:append_text]), :class => options[:css_class] ) else @@ -226,7 +226,7 @@ module ActionView error_messages = objects.sum do |object| object.errors.full_messages.map do |msg| - content_tag(:li, ERB::Util.html_escape(msg)) + content_tag(:li, msg) end end.join.html_safe diff --git a/actionpack/lib/action_view/helpers/tag_helper.rb b/actionpack/lib/action_view/helpers/tag_helper.rb index 1c3eb20e19..513d72880c 100644 --- a/actionpack/lib/action_view/helpers/tag_helper.rb +++ b/actionpack/lib/action_view/helpers/tag_helper.rb @@ -127,7 +127,7 @@ module ActionView def content_tag_string(name, content, options, escape = true) tag_options = tag_options(options, escape) if options - "<#{name}#{tag_options}>#{ERB::Util.h content}".html_safe + ("<#{name}#{tag_options}>".html_safe << content.to_s).safe_concat("") end def tag_options(options, escape = true) diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb index 4690161497..04a2743b9c 100644 --- a/actionpack/lib/action_view/helpers/url_helper.rb +++ b/actionpack/lib/action_view/helpers/url_helper.rb @@ -226,7 +226,7 @@ module ActionView end href_attr = "href=\"#{url}\"" unless href - "#{ERB::Util.h(name || url)}".html_safe + ("".html_safe << (name || url)).safe_concat("") end end -- cgit v1.2.3 From 7cff54f5d3ae2e364f0d147ceb86ea701b21389c Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Sun, 14 Feb 2010 22:05:02 +0100 Subject: name.blank? -> anonymous? Signed-off-by: Yehuda Katz --- actionpack/lib/abstract_controller/helpers.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller/helpers.rb b/actionpack/lib/abstract_controller/helpers.rb index 578b884a4d..9ff67cbf88 100644 --- a/actionpack/lib/abstract_controller/helpers.rb +++ b/actionpack/lib/abstract_controller/helpers.rb @@ -1,6 +1,7 @@ require 'active_support/dependencies' require 'active_support/core_ext/class/attribute' require 'active_support/core_ext/module/delegation' +require 'active_support/core_ext/module/anonymous' module AbstractController module Helpers @@ -27,7 +28,7 @@ module AbstractController def inherited(klass) helpers = _helpers klass._helpers = Module.new { include helpers } - klass.class_eval { default_helper_module! unless name.blank? } + klass.class_eval { default_helper_module! unless anonymous? } super end -- cgit v1.2.3 From eec2d301d4ce9df9c71c1a5aa63053eb970b6818 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Mon, 15 Feb 2010 10:20:11 -0600 Subject: Fix test load paths for those not using bundler --- actionpack/test/abstract_unit.rb | 8 +++++++- actionpack/test/activerecord/controller_runtime_test.rb | 9 ++++++--- actionpack/test/controller/subscriber_test.rb | 3 +++ actionpack/test/template/subscriber_test.rb | 5 ++++- 4 files changed, 20 insertions(+), 5 deletions(-) (limited to 'actionpack') diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb index 867e50d5b9..655a133c96 100644 --- a/actionpack/test/abstract_unit.rb +++ b/actionpack/test/abstract_unit.rb @@ -1,4 +1,10 @@ -require File.expand_path('../../../load_paths', __FILE__) +require File.expand_path('../../../bundler', __FILE__) + +lib = File.expand_path("#{File.dirname(__FILE__)}/../lib") +$:.unshift(lib) unless $:.include?('lib') || $:.include?(lib) + +activemodel_path = File.expand_path('../../../activemodel/lib', __FILE__) +$:.unshift(activemodel_path) if File.directory?(activemodel_path) && !$:.include?(activemodel_path) $:.unshift(File.dirname(__FILE__) + '/lib') $:.unshift(File.dirname(__FILE__) + '/fixtures/helpers') diff --git a/actionpack/test/activerecord/controller_runtime_test.rb b/actionpack/test/activerecord/controller_runtime_test.rb index ed8e324938..f044e714d8 100644 --- a/actionpack/test/activerecord/controller_runtime_test.rb +++ b/actionpack/test/activerecord/controller_runtime_test.rb @@ -1,3 +1,6 @@ +railties_path = File.expand_path('../../../../railties/lib', __FILE__) +$:.unshift(railties_path) if File.directory?(railties_path) && !$:.include?(railties_path) + require 'active_record_unit' require 'active_record/railties/controller_runtime' require 'fixtures/project' @@ -12,7 +15,7 @@ class ControllerRuntimeSubscriberTest < ActionController::TestCase render :inline => "<%= Project.all %>" end end - + include Rails::Subscriber::TestHelper tests SubscriberController @@ -31,7 +34,7 @@ class ControllerRuntimeSubscriberTest < ActionController::TestCase def set_logger(logger) ActionController::Base.logger = logger end - + def test_log_with_active_record get :show wait @@ -39,4 +42,4 @@ class ControllerRuntimeSubscriberTest < ActionController::TestCase assert_equal 2, @logger.logged(:info).size assert_match /\(Views: [\d\.]+ms | ActiveRecord: [\d\.]+ms\)/, @logger.logged(:info)[1] end -end \ No newline at end of file +end diff --git a/actionpack/test/controller/subscriber_test.rb b/actionpack/test/controller/subscriber_test.rb index d7c1166f14..72368df93b 100644 --- a/actionpack/test/controller/subscriber_test.rb +++ b/actionpack/test/controller/subscriber_test.rb @@ -1,3 +1,6 @@ +railties_path = File.expand_path('../../../../railties/lib', __FILE__) +$:.unshift(railties_path) if File.directory?(railties_path) && !$:.include?(railties_path) + require "abstract_unit" require "rails/subscriber/test_helper" require "action_controller/railties/subscriber" diff --git a/actionpack/test/template/subscriber_test.rb b/actionpack/test/template/subscriber_test.rb index 8bacab7088..8470f3c931 100644 --- a/actionpack/test/template/subscriber_test.rb +++ b/actionpack/test/template/subscriber_test.rb @@ -1,3 +1,6 @@ +railties_path = File.expand_path('../../../../railties/lib', __FILE__) +$:.unshift(railties_path) if File.directory?(railties_path) && !$:.include?(railties_path) + require "abstract_unit" require "rails/subscriber/test_helper" require "action_view/railties/subscriber" @@ -90,4 +93,4 @@ class AVSubscriberTest < ActiveSupport::TestCase assert_equal 1, @logger.logged(:info).size assert_match /Rendered collection/, @logger.logged(:info).last end -end \ No newline at end of file +end -- cgit v1.2.3 From 3cecc44cb9898a3486e74d9f27a2462c7e3f4d2e Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Mon, 15 Feb 2010 11:16:56 -0600 Subject: rack-mount 0.5 support --- actionpack/actionpack.gemspec | 2 +- actionpack/lib/action_dispatch/routing/route_set.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'actionpack') diff --git a/actionpack/actionpack.gemspec b/actionpack/actionpack.gemspec index 8a7169bfa1..00c4d7de1c 100644 --- a/actionpack/actionpack.gemspec +++ b/actionpack/actionpack.gemspec @@ -21,6 +21,6 @@ Gem::Specification.new do |s| s.add_dependency('activemodel', '= 3.0.0.beta1') s.add_dependency('rack', '~> 1.1.0') s.add_dependency('rack-test', '~> 0.5.0') - s.add_dependency('rack-mount', '~> 0.4.7') + s.add_dependency('rack-mount', '~> 0.5.1') s.add_dependency('erubis', '~> 2.6.5') end diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index dcf98b729b..ee60112bbc 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -431,7 +431,7 @@ module ActionDispatch end req = Rack::Request.new(env) - @set.recognize(req) do |route, params| + @set.recognize(req) do |route, matches, params| dispatcher = route.app if dispatcher.is_a?(Dispatcher) && dispatcher.controller(params) dispatcher.prepare_params!(params) -- cgit v1.2.3 From ac956c4aee7e2108033af087845f4f01c591d52f Mon Sep 17 00:00:00 2001 From: Yehuda Katz Date: Tue, 16 Feb 2010 10:45:59 -0800 Subject: Update AP to start locking down a public API. This work is parallel to some docs I'm working on. --- actionpack/lib/abstract_controller/helpers.rb | 4 ++-- actionpack/lib/abstract_controller/rendering.rb | 2 +- actionpack/lib/action_controller/base.rb | 2 +- actionpack/lib/action_controller/metal.rb | 8 ++++++++ actionpack/lib/action_controller/metal/helpers.rb | 4 ++-- actionpack/lib/action_controller/metal/hide_actions.rb | 10 ++++------ 6 files changed, 18 insertions(+), 12 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller/helpers.rb b/actionpack/lib/abstract_controller/helpers.rb index 9ff67cbf88..ca3a7550e5 100644 --- a/actionpack/lib/abstract_controller/helpers.rb +++ b/actionpack/lib/abstract_controller/helpers.rb @@ -100,7 +100,7 @@ module AbstractController def helper(*args, &block) self._helper_serial = AbstractController::Helpers.next_serial + 1 - _modules_for_helpers(args).each do |mod| + modules_for_helpers(args).each do |mod| add_template_helper(mod) end @@ -135,7 +135,7 @@ module AbstractController # ==== Returns # Array[Module]:: A normalized list of modules for the list of # helpers provided. - def _modules_for_helpers(args) + def modules_for_helpers(args) args.flatten.map! do |arg| case arg when String, Symbol diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb index 619a49571b..f5c20e8013 100644 --- a/actionpack/lib/abstract_controller/rendering.rb +++ b/actionpack/lib/abstract_controller/rendering.rb @@ -37,7 +37,7 @@ module AbstractController # options:: See _render_template_with_layout in ActionView::Base # partial:: Whether or not the template to render is a partial # - # Override this method in a to change the default behavior. + # Override this method in a module to change the default behavior. def view_context @_view_context ||= ActionView::Base.for_controller(self) end diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index 10244f8216..7f1aa95f6f 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -52,7 +52,7 @@ module ActionController def method_for_action(action_name) super || begin - if template_exists?(action_name.to_s, {:formats => formats}, :_prefix => controller_path) + if view_paths.exists?(action_name.to_s, {:formats => formats}, controller_path) "default_render" end end diff --git a/actionpack/lib/action_controller/metal.rb b/actionpack/lib/action_controller/metal.rb index 2b35e111ec..4fd37e7f31 100644 --- a/actionpack/lib/action_controller/metal.rb +++ b/actionpack/lib/action_controller/metal.rb @@ -49,6 +49,14 @@ module ActionController headers["Content-Type"] = type.to_s end + def content_type + headers["Content-Type"] + end + + def location + headers["Location"] + end + def location=(url) headers["Location"] = url end diff --git a/actionpack/lib/action_controller/metal/helpers.rb b/actionpack/lib/action_controller/metal/helpers.rb index 1b5a4c3080..8efe01e37b 100644 --- a/actionpack/lib/action_controller/metal/helpers.rb +++ b/actionpack/lib/action_controller/metal/helpers.rb @@ -86,7 +86,7 @@ module ActionController end private - # Overwrite _modules_for_helpers to accept :all as argument, which loads + # Overwrite modules_for_helpers to accept :all as argument, which loads # all helpers in helpers_dir. # # ==== Parameters @@ -95,7 +95,7 @@ module ActionController # ==== Returns # Array[Module]:: A normalized list of modules for the list of # helpers provided. - def _modules_for_helpers(args) + def modules_for_helpers(args) args += all_application_helpers if args.delete(:all) super(args) end diff --git a/actionpack/lib/action_controller/metal/hide_actions.rb b/actionpack/lib/action_controller/metal/hide_actions.rb index e893acffdf..3358d80c35 100644 --- a/actionpack/lib/action_controller/metal/hide_actions.rb +++ b/actionpack/lib/action_controller/metal/hide_actions.rb @@ -15,10 +15,8 @@ module ActionController # Overrides AbstractController::Base#action_method? to return false if the # action name is in the list of hidden actions. - def action_method?(action_name) - self.class.visible_action?(action_name) do - !self.class.hidden_actions.include?(action_name) && super - end + def method_for_action(action_name) + self.class.visible_action?(action_name) && super end module ClassMethods @@ -31,13 +29,13 @@ module ActionController end def inherited(klass) - klass.instance_variable_set("@visible_actions", {}) + klass.class_eval { @visible_actions = {} } super end def visible_action?(action_name) return @visible_actions[action_name] if @visible_actions.key?(action_name) - @visible_actions[action_name] = yield + @visible_actions[action_name] = !hidden_actions.include?(action_name) end # Overrides AbstractController::Base#action_methods to remove any methods -- cgit v1.2.3 From f0523f72b46db14e2f50c8347a8708734c650f84 Mon Sep 17 00:00:00 2001 From: Prem Sichanugrist Date: Mon, 15 Feb 2010 21:44:30 +0700 Subject: Rename Rails::Subscriber to Rails::LogSubscriber --- actionpack/lib/action_controller/railtie.rb | 4 +- .../action_controller/railties/log_subscriber.rb | 62 ++++++++ .../lib/action_controller/railties/subscriber.rb | 62 -------- actionpack/lib/action_view/railtie.rb | 4 +- .../lib/action_view/railties/log_subscriber.rb | 24 +++ actionpack/lib/action_view/railties/subscriber.rb | 24 --- .../test/activerecord/controller_runtime_test.rb | 16 +- actionpack/test/controller/log_subscriber_test.rb | 172 +++++++++++++++++++++ actionpack/test/controller/subscriber_test.rb | 172 --------------------- actionpack/test/template/log_subscriber_test.rb | 93 +++++++++++ actionpack/test/template/subscriber_test.rb | 93 ----------- 11 files changed, 363 insertions(+), 363 deletions(-) create mode 100644 actionpack/lib/action_controller/railties/log_subscriber.rb delete mode 100644 actionpack/lib/action_controller/railties/subscriber.rb create mode 100644 actionpack/lib/action_view/railties/log_subscriber.rb delete mode 100644 actionpack/lib/action_view/railties/subscriber.rb create mode 100644 actionpack/test/controller/log_subscriber_test.rb delete mode 100644 actionpack/test/controller/subscriber_test.rb create mode 100644 actionpack/test/template/log_subscriber_test.rb delete mode 100644 actionpack/test/template/subscriber_test.rb (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb index 55a5c22ac0..015a8212c4 100644 --- a/actionpack/lib/action_controller/railtie.rb +++ b/actionpack/lib/action_controller/railtie.rb @@ -6,8 +6,8 @@ module ActionController class Railtie < Rails::Railtie railtie_name :action_controller - require "action_controller/railties/subscriber" - subscriber ActionController::Railties::Subscriber.new + require "action_controller/railties/log_subscriber" + log_subscriber ActionController::Railties::LogSubscriber.new initializer "action_controller.logger" do ActionController::Base.logger ||= Rails.logger diff --git a/actionpack/lib/action_controller/railties/log_subscriber.rb b/actionpack/lib/action_controller/railties/log_subscriber.rb new file mode 100644 index 0000000000..df9ffa1717 --- /dev/null +++ b/actionpack/lib/action_controller/railties/log_subscriber.rb @@ -0,0 +1,62 @@ +module ActionController + module Railties + class LogSubscriber < Rails::LogSubscriber + INTERNAL_PARAMS = %w(controller action format _method only_path) + + def start_processing(event) + payload = event.payload + params = payload[:params].except(*INTERNAL_PARAMS) + + info " Processing by #{payload[:controller]}##{payload[:action]} as #{payload[:formats].first.to_s.upcase}" + info " Parameters: #{params.inspect}" unless params.empty? + end + + def process_action(event) + payload = event.payload + additions = ActionController::Base.log_process_action(payload) + + message = "Completed #{payload[:status]} #{Rack::Utils::HTTP_STATUS_CODES[payload[:status]]} in %.0fms" % event.duration + message << " (#{additions.join(" | ")})" unless additions.blank? + + info(message) + end + + def send_file(event) + message = if event.payload[:x_sendfile] + header = ActionController::Streaming::X_SENDFILE_HEADER + "Sent #{header} header %s" + elsif event.payload[:stream] + "Streamed file %s" + else + "Sent file %s" + end + + message << " (%.1fms)" + info(message % [event.payload[:path], event.duration]) + end + + def redirect_to(event) + info "Redirected to #{event.payload[:location]}" + end + + def send_data(event) + info("Sent data %s (%.1fms)" % [event.payload[:filename], event.duration]) + end + + %w(write_fragment read_fragment exist_fragment? + expire_fragment expire_page write_page).each do |method| + class_eval <<-METHOD, __FILE__, __LINE__ + 1 + def #{method}(event) + key_or_path = event.payload[:key] || event.payload[:path] + human_name = #{method.to_s.humanize.inspect} + info("\#{human_name} \#{key_or_path} (%.1fms)" % event.duration) + end + METHOD + end + + def logger + ActionController::Base.logger + end + end + end +end \ No newline at end of file diff --git a/actionpack/lib/action_controller/railties/subscriber.rb b/actionpack/lib/action_controller/railties/subscriber.rb deleted file mode 100644 index 4499e82292..0000000000 --- a/actionpack/lib/action_controller/railties/subscriber.rb +++ /dev/null @@ -1,62 +0,0 @@ -module ActionController - module Railties - class Subscriber < Rails::Subscriber - INTERNAL_PARAMS = %w(controller action format _method only_path) - - def start_processing(event) - payload = event.payload - params = payload[:params].except(*INTERNAL_PARAMS) - - info " Processing by #{payload[:controller]}##{payload[:action]} as #{payload[:formats].first.to_s.upcase}" - info " Parameters: #{params.inspect}" unless params.empty? - end - - def process_action(event) - payload = event.payload - additions = ActionController::Base.log_process_action(payload) - - message = "Completed #{payload[:status]} #{Rack::Utils::HTTP_STATUS_CODES[payload[:status]]} in %.0fms" % event.duration - message << " (#{additions.join(" | ")})" unless additions.blank? - - info(message) - end - - def send_file(event) - message = if event.payload[:x_sendfile] - header = ActionController::Streaming::X_SENDFILE_HEADER - "Sent #{header} header %s" - elsif event.payload[:stream] - "Streamed file %s" - else - "Sent file %s" - end - - message << " (%.1fms)" - info(message % [event.payload[:path], event.duration]) - end - - def redirect_to(event) - info "Redirected to #{event.payload[:location]}" - end - - def send_data(event) - info("Sent data %s (%.1fms)" % [event.payload[:filename], event.duration]) - end - - %w(write_fragment read_fragment exist_fragment? - expire_fragment expire_page write_page).each do |method| - class_eval <<-METHOD, __FILE__, __LINE__ + 1 - def #{method}(event) - key_or_path = event.payload[:key] || event.payload[:path] - human_name = #{method.to_s.humanize.inspect} - info("\#{human_name} \#{key_or_path} (%.1fms)" % event.duration) - end - METHOD - end - - def logger - ActionController::Base.logger - end - end - end -end \ No newline at end of file diff --git a/actionpack/lib/action_view/railtie.rb b/actionpack/lib/action_view/railtie.rb index d9e2557d89..03f18ac172 100644 --- a/actionpack/lib/action_view/railtie.rb +++ b/actionpack/lib/action_view/railtie.rb @@ -5,8 +5,8 @@ module ActionView class Railtie < Rails::Railtie railtie_name :action_view - require "action_view/railties/subscriber" - subscriber ActionView::Railties::Subscriber.new + require "action_view/railties/log_subscriber" + log_subscriber ActionView::Railties::LogSubscriber.new initializer "action_view.cache_asset_timestamps" do |app| unless app.config.cache_classes diff --git a/actionpack/lib/action_view/railties/log_subscriber.rb b/actionpack/lib/action_view/railties/log_subscriber.rb new file mode 100644 index 0000000000..9487a10706 --- /dev/null +++ b/actionpack/lib/action_view/railties/log_subscriber.rb @@ -0,0 +1,24 @@ +module ActionView + module Railties + class LogSubscriber < Rails::LogSubscriber + def render_template(event) + message = "Rendered #{from_rails_root(event.payload[:identifier])}" + message << " within #{from_rails_root(event.payload[:layout])}" if event.payload[:layout] + message << (" (%.1fms)" % event.duration) + info(message) + end + alias :render_partial :render_template + alias :render_collection :render_template + + def logger + ActionController::Base.logger + end + + protected + + def from_rails_root(string) + string.sub("#{Rails.root}/", "").sub(/^app\/views\//, "") + end + end + end +end \ No newline at end of file diff --git a/actionpack/lib/action_view/railties/subscriber.rb b/actionpack/lib/action_view/railties/subscriber.rb deleted file mode 100644 index 803f19379c..0000000000 --- a/actionpack/lib/action_view/railties/subscriber.rb +++ /dev/null @@ -1,24 +0,0 @@ -module ActionView - module Railties - class Subscriber < Rails::Subscriber - def render_template(event) - message = "Rendered #{from_rails_root(event.payload[:identifier])}" - message << " within #{from_rails_root(event.payload[:layout])}" if event.payload[:layout] - message << (" (%.1fms)" % event.duration) - info(message) - end - alias :render_partial :render_template - alias :render_collection :render_template - - def logger - ActionController::Base.logger - end - - protected - - def from_rails_root(string) - string.sub("#{Rails.root}/", "").sub(/^app\/views\//, "") - end - end - end -end \ No newline at end of file diff --git a/actionpack/test/activerecord/controller_runtime_test.rb b/actionpack/test/activerecord/controller_runtime_test.rb index ed8e324938..4d2a7b9b5a 100644 --- a/actionpack/test/activerecord/controller_runtime_test.rb +++ b/actionpack/test/activerecord/controller_runtime_test.rb @@ -1,30 +1,30 @@ require 'active_record_unit' require 'active_record/railties/controller_runtime' require 'fixtures/project' -require 'rails/subscriber/test_helper' -require 'action_controller/railties/subscriber' +require 'rails/log_subscriber/test_helper' +require 'action_controller/railties/log_subscriber' ActionController::Base.send :include, ActiveRecord::Railties::ControllerRuntime -class ControllerRuntimeSubscriberTest < ActionController::TestCase - class SubscriberController < ActionController::Base +class ControllerRuntimeLogSubscriberTest < ActionController::TestCase + class LogSubscriberController < ActionController::Base def show render :inline => "<%= Project.all %>" end end - include Rails::Subscriber::TestHelper - tests SubscriberController + include Rails::LogSubscriber::TestHelper + tests LogSubscriberController def setup @old_logger = ActionController::Base.logger - Rails::Subscriber.add(:action_controller, ActionController::Railties::Subscriber.new) + Rails::LogSubscriber.add(:action_controller, ActionController::Railties::LogSubscriber.new) super end def teardown super - Rails::Subscriber.subscribers.clear + Rails::LogSubscriber.log_subscribers.clear ActionController::Base.logger = @old_logger end diff --git a/actionpack/test/controller/log_subscriber_test.rb b/actionpack/test/controller/log_subscriber_test.rb new file mode 100644 index 0000000000..182f343b2f --- /dev/null +++ b/actionpack/test/controller/log_subscriber_test.rb @@ -0,0 +1,172 @@ +require "abstract_unit" +require "rails/log_subscriber/test_helper" +require "action_controller/railties/log_subscriber" + +module Another + class LogSubscribersController < ActionController::Base + def show + render :nothing => true + end + + def redirector + redirect_to "http://foo.bar/" + end + + def data_sender + send_data "cool data", :filename => "file.txt" + end + + def xfile_sender + send_file File.expand_path("company.rb", FIXTURE_LOAD_PATH), :x_sendfile => true + end + + def file_sender + send_file File.expand_path("company.rb", FIXTURE_LOAD_PATH) + end + + def with_fragment_cache + render :inline => "<%= cache('foo'){ 'bar' } %>" + end + + def with_page_cache + cache_page("Super soaker", "/index.html") + render :nothing => true + end + end +end + +class ACLogSubscriberTest < ActionController::TestCase + tests Another::LogSubscribersController + include Rails::LogSubscriber::TestHelper + + def setup + @old_logger = ActionController::Base.logger + + @cache_path = File.expand_path('../temp/test_cache', File.dirname(__FILE__)) + ActionController::Base.page_cache_directory = @cache_path + ActionController::Base.cache_store = :file_store, @cache_path + + Rails::LogSubscriber.add(:action_controller, ActionController::Railties::LogSubscriber.new) + super + end + + def teardown + super + Rails::LogSubscriber.log_subscribers.clear + FileUtils.rm_rf(@cache_path) + ActionController::Base.logger = @old_logger + end + + def set_logger(logger) + ActionController::Base.logger = logger + end + + def test_start_processing + get :show + wait + assert_equal 2, logs.size + assert_equal "Processing by Another::LogSubscribersController#show as HTML", logs.first + end + + def test_process_action + get :show + wait + assert_equal 2, logs.size + assert_match /Completed/, logs.last + assert_match /200 OK/, logs.last + end + + def test_process_action_without_parameters + get :show + wait + assert_nil logs.detect {|l| l =~ /Parameters/ } + end + + def test_process_action_with_parameters + get :show, :id => '10' + wait + + assert_equal 3, logs.size + assert_equal 'Parameters: {"id"=>"10"}', logs[1] + end + + def test_process_action_with_view_runtime + get :show + wait + assert_match /\(Views: [\d\.]+ms\)/, logs[1] + end + + def test_process_action_with_filter_parameters + @request.env["action_dispatch.parameter_filter"] = [:lifo, :amount] + + get :show, :lifo => 'Pratik', :amount => '420', :step => '1' + wait + + params = logs[1] + assert_match /"amount"=>"\[FILTERED\]"/, params + assert_match /"lifo"=>"\[FILTERED\]"/, params + assert_match /"step"=>"1"/, params + end + + def test_redirect_to + get :redirector + wait + + assert_equal 3, logs.size + assert_equal "Redirected to http://foo.bar/", logs[1] + end + + def test_send_data + get :data_sender + wait + + assert_equal 3, logs.size + assert_match /Sent data file\.txt/, logs[1] + end + + def test_send_file + get :file_sender + wait + + assert_equal 3, logs.size + assert_match /Sent file/, logs[1] + assert_match /test\/fixtures\/company\.rb/, logs[1] + end + + def test_send_xfile + get :xfile_sender + wait + + assert_equal 3, logs.size + assert_match /Sent X\-Sendfile header/, logs[1] + assert_match /test\/fixtures\/company\.rb/, logs[1] + end + + def test_with_fragment_cache + ActionController::Base.perform_caching = true + get :with_fragment_cache + wait + + assert_equal 4, logs.size + assert_match /Exist fragment\? views\/foo/, logs[1] + assert_match /Write fragment views\/foo/, logs[2] + ensure + ActionController::Base.perform_caching = true + end + + def test_with_page_cache + ActionController::Base.perform_caching = true + get :with_page_cache + wait + + assert_equal 3, logs.size + assert_match /Write page/, logs[1] + assert_match /\/index\.html/, logs[1] + ensure + ActionController::Base.perform_caching = true + end + + def logs + @logs ||= @logger.logged(:info) + end +end diff --git a/actionpack/test/controller/subscriber_test.rb b/actionpack/test/controller/subscriber_test.rb deleted file mode 100644 index d7c1166f14..0000000000 --- a/actionpack/test/controller/subscriber_test.rb +++ /dev/null @@ -1,172 +0,0 @@ -require "abstract_unit" -require "rails/subscriber/test_helper" -require "action_controller/railties/subscriber" - -module Another - class SubscribersController < ActionController::Base - def show - render :nothing => true - end - - def redirector - redirect_to "http://foo.bar/" - end - - def data_sender - send_data "cool data", :filename => "file.txt" - end - - def xfile_sender - send_file File.expand_path("company.rb", FIXTURE_LOAD_PATH), :x_sendfile => true - end - - def file_sender - send_file File.expand_path("company.rb", FIXTURE_LOAD_PATH) - end - - def with_fragment_cache - render :inline => "<%= cache('foo'){ 'bar' } %>" - end - - def with_page_cache - cache_page("Super soaker", "/index.html") - render :nothing => true - end - end -end - -class ACSubscriberTest < ActionController::TestCase - tests Another::SubscribersController - include Rails::Subscriber::TestHelper - - def setup - @old_logger = ActionController::Base.logger - - @cache_path = File.expand_path('../temp/test_cache', File.dirname(__FILE__)) - ActionController::Base.page_cache_directory = @cache_path - ActionController::Base.cache_store = :file_store, @cache_path - - Rails::Subscriber.add(:action_controller, ActionController::Railties::Subscriber.new) - super - end - - def teardown - super - Rails::Subscriber.subscribers.clear - FileUtils.rm_rf(@cache_path) - ActionController::Base.logger = @old_logger - end - - def set_logger(logger) - ActionController::Base.logger = logger - end - - def test_start_processing - get :show - wait - assert_equal 2, logs.size - assert_equal "Processing by Another::SubscribersController#show as HTML", logs.first - end - - def test_process_action - get :show - wait - assert_equal 2, logs.size - assert_match /Completed/, logs.last - assert_match /200 OK/, logs.last - end - - def test_process_action_without_parameters - get :show - wait - assert_nil logs.detect {|l| l =~ /Parameters/ } - end - - def test_process_action_with_parameters - get :show, :id => '10' - wait - - assert_equal 3, logs.size - assert_equal 'Parameters: {"id"=>"10"}', logs[1] - end - - def test_process_action_with_view_runtime - get :show - wait - assert_match /\(Views: [\d\.]+ms\)/, logs[1] - end - - def test_process_action_with_filter_parameters - @request.env["action_dispatch.parameter_filter"] = [:lifo, :amount] - - get :show, :lifo => 'Pratik', :amount => '420', :step => '1' - wait - - params = logs[1] - assert_match /"amount"=>"\[FILTERED\]"/, params - assert_match /"lifo"=>"\[FILTERED\]"/, params - assert_match /"step"=>"1"/, params - end - - def test_redirect_to - get :redirector - wait - - assert_equal 3, logs.size - assert_equal "Redirected to http://foo.bar/", logs[1] - end - - def test_send_data - get :data_sender - wait - - assert_equal 3, logs.size - assert_match /Sent data file\.txt/, logs[1] - end - - def test_send_file - get :file_sender - wait - - assert_equal 3, logs.size - assert_match /Sent file/, logs[1] - assert_match /test\/fixtures\/company\.rb/, logs[1] - end - - def test_send_xfile - get :xfile_sender - wait - - assert_equal 3, logs.size - assert_match /Sent X\-Sendfile header/, logs[1] - assert_match /test\/fixtures\/company\.rb/, logs[1] - end - - def test_with_fragment_cache - ActionController::Base.perform_caching = true - get :with_fragment_cache - wait - - assert_equal 4, logs.size - assert_match /Exist fragment\? views\/foo/, logs[1] - assert_match /Write fragment views\/foo/, logs[2] - ensure - ActionController::Base.perform_caching = true - end - - def test_with_page_cache - ActionController::Base.perform_caching = true - get :with_page_cache - wait - - assert_equal 3, logs.size - assert_match /Write page/, logs[1] - assert_match /\/index\.html/, logs[1] - ensure - ActionController::Base.perform_caching = true - end - - def logs - @logs ||= @logger.logged(:info) - end -end diff --git a/actionpack/test/template/log_subscriber_test.rb b/actionpack/test/template/log_subscriber_test.rb new file mode 100644 index 0000000000..2eb2484cf5 --- /dev/null +++ b/actionpack/test/template/log_subscriber_test.rb @@ -0,0 +1,93 @@ +require "abstract_unit" +require "rails/log_subscriber/test_helper" +require "action_view/railties/log_subscriber" +require "controller/fake_models" + +class AVLogSubscriberTest < ActiveSupport::TestCase + include Rails::LogSubscriber::TestHelper + + def setup + @old_logger = ActionController::Base.logger + @view = ActionView::Base.new(ActionController::Base.view_paths, {}) + Rails.stubs(:root).returns(File.expand_path(FIXTURE_LOAD_PATH)) + Rails::LogSubscriber.add(:action_view, ActionView::Railties::LogSubscriber.new) + super + end + + def teardown + super + Rails::LogSubscriber.log_subscribers.clear + ActionController::Base.logger = @old_logger + end + + def set_logger(logger) + ActionController::Base.logger = logger + end + + def test_render_file_template + @view.render(:file => "test/hello_world.erb") + wait + + assert_equal 1, @logger.logged(:info).size + assert_match /Rendered test\/hello_world\.erb/, @logger.logged(:info).last + end + + def test_render_text_template + @view.render(:text => "TEXT") + wait + + assert_equal 1, @logger.logged(:info).size + assert_match /Rendered text template/, @logger.logged(:info).last + end + + def test_render_inline_template + @view.render(:inline => "<%= 'TEXT' %>") + wait + + assert_equal 1, @logger.logged(:info).size + assert_match /Rendered inline template/, @logger.logged(:info).last + end + + def test_render_partial_template + @view.render(:partial => "test/customer") + wait + + assert_equal 1, @logger.logged(:info).size + assert_match /Rendered test\/_customer.erb/, @logger.logged(:info).last + end + + def test_render_partial_with_implicit_path + @view.stubs(:controller_path).returns("test") + @view.render(Customer.new("david"), :greeting => "hi") + wait + + assert_equal 1, @logger.logged(:info).size + assert_match /Rendered customers\/_customer\.html\.erb/, @logger.logged(:info).last + end + + def test_render_collection_template + @view.render(:partial => "test/customer", :collection => [ Customer.new("david"), Customer.new("mary") ]) + wait + + assert_equal 1, @logger.logged(:info).size + assert_match /Rendered test\/_customer.erb/, @logger.logged(:info).last + end + + def test_render_collection_with_implicit_path + @view.stubs(:controller_path).returns("test") + @view.render([ Customer.new("david"), Customer.new("mary") ], :greeting => "hi") + wait + + assert_equal 1, @logger.logged(:info).size + assert_match /Rendered customers\/_customer\.html\.erb/, @logger.logged(:info).last + end + + def test_render_collection_template_without_path + @view.stubs(:controller_path).returns("test") + @view.render([ GoodCustomer.new("david"), Customer.new("mary") ], :greeting => "hi") + wait + + assert_equal 1, @logger.logged(:info).size + assert_match /Rendered collection/, @logger.logged(:info).last + end +end \ No newline at end of file diff --git a/actionpack/test/template/subscriber_test.rb b/actionpack/test/template/subscriber_test.rb deleted file mode 100644 index 8bacab7088..0000000000 --- a/actionpack/test/template/subscriber_test.rb +++ /dev/null @@ -1,93 +0,0 @@ -require "abstract_unit" -require "rails/subscriber/test_helper" -require "action_view/railties/subscriber" -require "controller/fake_models" - -class AVSubscriberTest < ActiveSupport::TestCase - include Rails::Subscriber::TestHelper - - def setup - @old_logger = ActionController::Base.logger - @view = ActionView::Base.new(ActionController::Base.view_paths, {}) - Rails.stubs(:root).returns(File.expand_path(FIXTURE_LOAD_PATH)) - Rails::Subscriber.add(:action_view, ActionView::Railties::Subscriber.new) - super - end - - def teardown - super - Rails::Subscriber.subscribers.clear - ActionController::Base.logger = @old_logger - end - - def set_logger(logger) - ActionController::Base.logger = logger - end - - def test_render_file_template - @view.render(:file => "test/hello_world.erb") - wait - - assert_equal 1, @logger.logged(:info).size - assert_match /Rendered test\/hello_world\.erb/, @logger.logged(:info).last - end - - def test_render_text_template - @view.render(:text => "TEXT") - wait - - assert_equal 1, @logger.logged(:info).size - assert_match /Rendered text template/, @logger.logged(:info).last - end - - def test_render_inline_template - @view.render(:inline => "<%= 'TEXT' %>") - wait - - assert_equal 1, @logger.logged(:info).size - assert_match /Rendered inline template/, @logger.logged(:info).last - end - - def test_render_partial_template - @view.render(:partial => "test/customer") - wait - - assert_equal 1, @logger.logged(:info).size - assert_match /Rendered test\/_customer.erb/, @logger.logged(:info).last - end - - def test_render_partial_with_implicit_path - @view.stubs(:controller_path).returns("test") - @view.render(Customer.new("david"), :greeting => "hi") - wait - - assert_equal 1, @logger.logged(:info).size - assert_match /Rendered customers\/_customer\.html\.erb/, @logger.logged(:info).last - end - - def test_render_collection_template - @view.render(:partial => "test/customer", :collection => [ Customer.new("david"), Customer.new("mary") ]) - wait - - assert_equal 1, @logger.logged(:info).size - assert_match /Rendered test\/_customer.erb/, @logger.logged(:info).last - end - - def test_render_collection_with_implicit_path - @view.stubs(:controller_path).returns("test") - @view.render([ Customer.new("david"), Customer.new("mary") ], :greeting => "hi") - wait - - assert_equal 1, @logger.logged(:info).size - assert_match /Rendered customers\/_customer\.html\.erb/, @logger.logged(:info).last - end - - def test_render_collection_template_without_path - @view.stubs(:controller_path).returns("test") - @view.render([ GoodCustomer.new("david"), Customer.new("mary") ], :greeting => "hi") - wait - - assert_equal 1, @logger.logged(:info).size - assert_match /Rendered collection/, @logger.logged(:info).last - end -end \ No newline at end of file -- cgit v1.2.3 From 72cb0bf4146444c80319503b5813b967454ec77d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Tue, 16 Feb 2010 22:09:42 +0100 Subject: Do not swallow controller loading errors unless required. --- actionpack/lib/action_dispatch/routing/route_set.rb | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index dcf98b729b..7092eb6cef 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -19,12 +19,7 @@ module ActionDispatch def call(env) params = env[PARAMETERS_KEY] prepare_params!(params) - - unless controller = controller(params) - return [404, {'X-Cascade' => 'pass'}, []] - end - - controller.action(params[:action]).call(env) + controller(params).action(params[:action]).call(env) end def prepare_params!(params) @@ -39,14 +34,13 @@ module ActionDispatch end end - def controller(params) + def controller(params, swallow=false) if params && params.has_key?(:controller) controller = "#{params[:controller].camelize}Controller" ActiveSupport::Inflector.constantize(controller) end rescue NameError => e - raise unless e.message.include?(controller) - nil + raise ActionController::RoutingError, e.message, e.backtrace unless swallow end private @@ -433,7 +427,7 @@ module ActionDispatch req = Rack::Request.new(env) @set.recognize(req) do |route, params| dispatcher = route.app - if dispatcher.is_a?(Dispatcher) && dispatcher.controller(params) + if dispatcher.is_a?(Dispatcher) && dispatcher.controller(params, true) dispatcher.prepare_params!(params) return params end -- cgit v1.2.3 From 19787e62596ebba23da776946d2da72ae6243001 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Tue, 16 Feb 2010 22:31:40 +0100 Subject: Should allow symbols in :only and :except in routes. --- actionpack/lib/action_dispatch/routing/mapper.rb | 10 +++++----- actionpack/test/dispatch/routing_test.rb | 11 +++++++++-- 2 files changed, 14 insertions(+), 7 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 8de68b3174..0e9291490c 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -367,9 +367,9 @@ module ActionDispatch def actions if only = options[:only] - only.map(&:to_sym) + Array(only).map(&:to_sym) elsif except = options[:except] - default_actions - except.map(&:to_sym) + default_actions - Array(except).map(&:to_sym) else default_actions end @@ -443,7 +443,7 @@ module ActionDispatch def resource(*resources, &block) options = resources.extract_options! - if verify_common_behavior_for(:resource, resources, options, &block) + if apply_common_behavior_for(:resource, resources, options, &block) return self end @@ -468,7 +468,7 @@ module ActionDispatch def resources(*resources, &block) options = resources.extract_options! - if verify_common_behavior_for(:resources, resources, options, &block) + if apply_common_behavior_for(:resources, resources, options, &block) return self end @@ -591,7 +591,7 @@ module ActionDispatch path_names[name.to_sym] || name.to_s end - def verify_common_behavior_for(method, resources, options, &block) + def apply_common_behavior_for(method, resources, options, &block) if resources.length > 1 resources.each { |r| send(method, r, options, &block) } return true diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb index bcb97e4ae0..0cd1fddff1 100644 --- a/actionpack/test/dispatch/routing_test.rb +++ b/actionpack/test/dispatch/routing_test.rb @@ -104,7 +104,9 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest end end - resources :posts, :only => [:index, :show] + resources :posts, :only => [:index, :show] do + resources :comments, :except => :destroy + end match 'sprockets.js' => ::TestRoutingMapper::SprocketsApp @@ -471,7 +473,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest end end - def test_posts + def test_resource_routes_with_only_and_except with_test_routes do get '/posts' assert_equal 'posts#index', @response.body @@ -481,9 +483,14 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest assert_equal 'posts#show', @response.body assert_equal '/posts/1', post_path(:id => 1) + get '/posts/1/comments' + assert_equal 'comments#index', @response.body + assert_equal '/posts/1/comments', post_comments_path(:post_id => 1) + assert_raise(ActionController::RoutingError) { post '/posts' } assert_raise(ActionController::RoutingError) { put '/posts/1' } assert_raise(ActionController::RoutingError) { delete '/posts/1' } + assert_raise(ActionController::RoutingError) { delete '/posts/1/comments' } end end -- cgit v1.2.3 From 47a236e291f0235a08ce4bb2a2d43fe221794461 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Tue, 16 Feb 2010 22:54:56 +0100 Subject: AD::TestProcess relies on request.flash, so let's load it. --- actionpack/lib/action_dispatch/testing/test_process.rb | 2 ++ 1 file changed, 2 insertions(+) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/testing/test_process.rb b/actionpack/lib/action_dispatch/testing/test_process.rb index eae703e1b6..d4eecac2de 100644 --- a/actionpack/lib/action_dispatch/testing/test_process.rb +++ b/actionpack/lib/action_dispatch/testing/test_process.rb @@ -1,3 +1,5 @@ +require 'action_dispatch/middleware/flash' + module ActionDispatch module TestProcess def assigns(key = nil) -- cgit v1.2.3 From b1edd096626d6f536b87ff5e307c37a89dd78133 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Tue, 16 Feb 2010 23:26:29 +0100 Subject: Ensure render :text => resource first tries to invoke :to_text on it --- actionpack/lib/action_controller/metal/rendering.rb | 7 +++++++ actionpack/test/controller/render_test.rb | 9 +++++++++ actionpack/test/lib/controller/fake_models.rb | 1 + 3 files changed, 17 insertions(+) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/rendering.rb b/actionpack/lib/action_controller/metal/rendering.rb index 0aae9f8579..0bd362fd64 100644 --- a/actionpack/lib/action_controller/metal/rendering.rb +++ b/actionpack/lib/action_controller/metal/rendering.rb @@ -36,6 +36,13 @@ module ActionController super end + def _determine_template(options) + if options.key?(:text) && options[:text].respond_to?(:to_text) + options[:text] = options[:text].to_text + end + super + end + def format_for_text formats.first end diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb index 2c3dc2a72d..eceec3b08e 100644 --- a/actionpack/test/controller/render_test.rb +++ b/actionpack/test/controller/render_test.rb @@ -214,6 +214,10 @@ class TestController < ActionController::Base render :text => false end + def render_text_with_resource + render :text => Customer.new("David") + end + # :ported: def render_nothing_with_appendix render :text => "appended" @@ -817,6 +821,11 @@ class RenderTest < ActionController::TestCase assert_equal 'appended', @response.body end + def test_render_text_with_resource + get :render_text_with_resource + assert_equal 'name: David', @response.body + end + # :ported: def test_attempt_to_access_object_method assert_raise(ActionController::UnknownAction, "No action responded to [clone]") { get :clone } diff --git a/actionpack/test/lib/controller/fake_models.rb b/actionpack/test/lib/controller/fake_models.rb index 7346cb22bc..a8c86f70b6 100644 --- a/actionpack/test/lib/controller/fake_models.rb +++ b/actionpack/test/lib/controller/fake_models.rb @@ -21,6 +21,7 @@ class Customer < Struct.new(:name, :id) def to_js(options={}) "name: #{name.inspect}" end + alias :to_text :to_js def errors [] -- cgit v1.2.3 From e8ef12e39d4af20c5211cd92aa560590fa5387cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 17 Feb 2010 00:14:49 +0100 Subject: Make Railties tests green again. --- actionpack/lib/action_dispatch/routing/route_set.rb | 19 ++++++++++++------- actionpack/test/controller/render_test.rb | 2 +- 2 files changed, 13 insertions(+), 8 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 7092eb6cef..c3fda0aaef 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -11,15 +11,21 @@ module ActionDispatch PARAMETERS_KEY = 'action_dispatch.request.path_parameters' class Dispatcher - def initialize(options = {}) - defaults = options[:defaults] + def initialize(options={}) + @defaults = options[:defaults] @glob_param = options.delete(:glob) end def call(env) params = env[PARAMETERS_KEY] prepare_params!(params) - controller(params).action(params[:action]).call(env) + + # Just raise undefined constant errors if a controller was specified as default. + unless controller = controller(params, @defaults.key?(:controller)) + return [404, {'X-Cascade' => 'pass'}, []] + end + + controller.action(params[:action]).call(env) end def prepare_params!(params) @@ -34,13 +40,13 @@ module ActionDispatch end end - def controller(params, swallow=false) + def controller(params, raise_error=true) if params && params.has_key?(:controller) controller = "#{params[:controller].camelize}Controller" ActiveSupport::Inflector.constantize(controller) end rescue NameError => e - raise ActionController::RoutingError, e.message, e.backtrace unless swallow + raise ActionController::RoutingError, e.message, e.backtrace if raise_error end private @@ -53,7 +59,6 @@ module ActionDispatch end end - # A NamedRouteCollection instance is a collection of named routes, and also # maintains an anonymous module that can be used to install helpers for the # named routes. @@ -427,7 +432,7 @@ module ActionDispatch req = Rack::Request.new(env) @set.recognize(req) do |route, params| dispatcher = route.app - if dispatcher.is_a?(Dispatcher) && dispatcher.controller(params, true) + if dispatcher.is_a?(Dispatcher) && dispatcher.controller(params, false) dispatcher.prepare_params!(params) return params end diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb index eceec3b08e..3cc22cc316 100644 --- a/actionpack/test/controller/render_test.rb +++ b/actionpack/test/controller/render_test.rb @@ -823,7 +823,7 @@ class RenderTest < ActionController::TestCase def test_render_text_with_resource get :render_text_with_resource - assert_equal 'name: David', @response.body + assert_equal 'name: "David"', @response.body end # :ported: -- cgit v1.2.3 From 7189e3c8816ea4dc88c09bdd109c4a503fc5c4dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 17 Feb 2010 18:43:24 +0100 Subject: Rename router internal option :namespace to :controller_namespace which is its real purpose. --- actionpack/lib/action_dispatch/routing/mapper.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 0e9291490c..bead321c9c 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -283,7 +283,7 @@ module ActionDispatch end def namespace(path) - scope(path.to_s, :name_prefix => path.to_s, :namespace => path.to_s) { yield } + scope(path.to_s, :name_prefix => path.to_s, :controller_namespace => path.to_s) { yield } end def constraints(constraints = {}) @@ -318,12 +318,12 @@ module ActionDispatch parent ? "#{parent}_#{child}" : child end - def merge_namespace_scope(parent, child) + def merge_controller_namespace_scope(parent, child) parent ? "#{parent}/#{child}" : child end def merge_controller_scope(parent, child) - @scope[:namespace] ? "#{@scope[:namespace]}/#{child}" : child + @scope[:controller_namespace] ? "#{@scope[:controller_namespace]}/#{child}" : child end def merge_resources_path_names_scope(parent, child) -- cgit v1.2.3 From 8a1f057a26135f9b94717d72fff704843f56f521 Mon Sep 17 00:00:00 2001 From: Yehuda Katz Date: Thu, 18 Feb 2010 12:26:16 -0800 Subject: Update Renderer --- actionpack/lib/action_controller/metal/rendering.rb | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/rendering.rb b/actionpack/lib/action_controller/metal/rendering.rb index 0bd362fd64..b1dab8497b 100644 --- a/actionpack/lib/action_controller/metal/rendering.rb +++ b/actionpack/lib/action_controller/metal/rendering.rb @@ -2,13 +2,12 @@ module ActionController module Rendering extend ActiveSupport::Concern - included do - include AbstractController::Rendering - include AbstractController::LocalizedCache - end + include RackDelegation + include AbstractController::Rendering + include AbstractController::LocalizedCache def process_action(*) - self.formats = request.formats.map {|x| x.to_sym} + self.formats = request.formats.map {|x| x.to_sym } super end -- cgit v1.2.3 From af05420d6bf7cb1c337e95f9941e7db30c521d31 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Thu, 18 Feb 2010 22:33:24 -0200 Subject: i18n translate with arrays issue solved Signed-off-by: Yehuda Katz --- actionpack/lib/action_view/helpers/translation_helper.rb | 5 +++-- actionpack/test/template/translation_helper_test.rb | 5 +++++ 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/translation_helper.rb b/actionpack/lib/action_view/helpers/translation_helper.rb index c348ea7a0d..a42e5542f2 100644 --- a/actionpack/lib/action_view/helpers/translation_helper.rb +++ b/actionpack/lib/action_view/helpers/translation_helper.rb @@ -12,7 +12,8 @@ module ActionView # prepend the key with a period, nothing is converted. def translate(key, options = {}) options[:raise] = true - I18n.translate(scope_key_by_partial(key), options).html_safe + translation = I18n.translate(scope_key_by_partial(key), options) + translation.is_a?(Array) ? translation.map { |entry| entry.html_safe } : translation.html_safe rescue I18n::MissingTranslationData => e keys = I18n.send(:normalize_translation_keys, e.locale, e.key, e.options[:scope]) content_tag('span', keys.join(', '), :class => 'translation_missing') @@ -40,4 +41,4 @@ module ActionView end end end -end \ No newline at end of file +end diff --git a/actionpack/test/template/translation_helper_test.rb b/actionpack/test/template/translation_helper_test.rb index 4b73c44f7e..699fb2f5bc 100644 --- a/actionpack/test/template/translation_helper_test.rb +++ b/actionpack/test/template/translation_helper_test.rb @@ -18,6 +18,11 @@ class TranslationHelperTest < ActiveSupport::TestCase assert_equal expected, translate(:foo) end + def test_translation_of_an_array + I18n.expects(:translate).with(["foo", "bar"], :raise => true).returns(["foo", "bar"]) + assert_equal ["foo", "bar"], translate(["foo", "bar"]) + end + def test_delegates_localize_to_i18n @time = Time.utc(2008, 7, 8, 12, 18, 38) I18n.expects(:localize).with(@time) -- cgit v1.2.3 From e2806929ec4bc3d429011039f4b046b600b7c8f8 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Thu, 18 Feb 2010 23:02:41 -0200 Subject: ruby 1.9 array.to_s returns a string representing an escaped array Signed-off-by: Yehuda Katz --- actionpack/lib/action_view/helpers/translation_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/translation_helper.rb b/actionpack/lib/action_view/helpers/translation_helper.rb index a42e5542f2..7d954b3a2f 100644 --- a/actionpack/lib/action_view/helpers/translation_helper.rb +++ b/actionpack/lib/action_view/helpers/translation_helper.rb @@ -29,7 +29,7 @@ module ActionView private def scope_key_by_partial(key) - if key.to_s.first == "." + if (key.respond_to?(:join) ? key.join : key.to_s).first == "." if @_virtual_path @_virtual_path.gsub(%r{/_?}, ".") + key.to_s else -- cgit v1.2.3 From e49f94d71cdcdd3b891959e59203fd5e664c8add Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Fri, 19 Feb 2010 08:02:28 +0100 Subject: Revert behavior from a5684dfa3c16472bfa5d5d861ba78cb6dbadcb59 and ensure after_initializer is executed after to_prepare callbacks. --- actionpack/lib/action_dispatch/middleware/callbacks.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/middleware/callbacks.rb b/actionpack/lib/action_dispatch/middleware/callbacks.rb index 7cf75ffe63..d07841218a 100644 --- a/actionpack/lib/action_dispatch/middleware/callbacks.rb +++ b/actionpack/lib/action_dispatch/middleware/callbacks.rb @@ -37,7 +37,7 @@ module ActionDispatch def initialize(app, prepare_each_request = false) @app, @prepare_each_request = app, prepare_each_request - run_callbacks(:prepare) unless @prepare_each_request + run_callbacks(:prepare) end def call(env) -- cgit v1.2.3 From 7d7f9ccfdf986099e3c5abf05af37a886daba0b5 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Fri, 19 Feb 2010 09:31:10 -0600 Subject: Reinstate pending tests that were supposed to be fixed before the beta. Shout louder this time so they actually get fixed. --- actionpack/test/controller/send_file_test.rb | 24 +++++++++++------------- actionpack/test/dispatch/response_test.rb | 24 ++++++++---------------- 2 files changed, 19 insertions(+), 29 deletions(-) (limited to 'actionpack') diff --git a/actionpack/test/controller/send_file_test.rb b/actionpack/test/controller/send_file_test.rb index 0afebac68c..aebbd893a8 100644 --- a/actionpack/test/controller/send_file_test.rb +++ b/actionpack/test/controller/send_file_test.rb @@ -51,19 +51,17 @@ class SendFileTest < ActionController::TestCase end def test_file_stream - pending do - response = nil - assert_nothing_raised { response = process('file') } - assert_not_nil response - assert_kind_of Array, response.body_parts - - require 'stringio' - output = StringIO.new - output.binmode - output.string.force_encoding(file_data.encoding) if output.string.respond_to?(:force_encoding) - assert_nothing_raised { response.body_parts.each { |part| output << part.to_s } } - assert_equal file_data, output.string - end + response = nil + assert_nothing_raised { response = process('file') } + assert_not_nil response + assert_kind_of Array, response.body_parts + + require 'stringio' + output = StringIO.new + output.binmode + output.string.force_encoding(file_data.encoding) if output.string.respond_to?(:force_encoding) + assert_nothing_raised { response.body_parts.each { |part| output << part.to_s } } + assert_equal file_data, output.string end def test_file_url_based_filename diff --git a/actionpack/test/dispatch/response_test.rb b/actionpack/test/dispatch/response_test.rb index 4697fa3e2b..c7f7f3102d 100644 --- a/actionpack/test/dispatch/response_test.rb +++ b/actionpack/test/dispatch/response_test.rb @@ -165,10 +165,8 @@ class ResponseIntegrationTest < ActionDispatch::IntegrationTest assert_equal('public', @response.headers['Cache-Control']) assert_equal('"202cb962ac59075b964b07152d234b70"', @response.headers['ETag']) - pending do - assert_equal('"202cb962ac59075b964b07152d234b70"', @response.etag) - assert_equal({:public => true}, @response.cache_control) - end + assert_equal('"202cb962ac59075b964b07152d234b70"', @response.etag) + assert_equal({:public => true}, @response.cache_control) end test "response cache control from rackish app" do @@ -184,10 +182,8 @@ class ResponseIntegrationTest < ActionDispatch::IntegrationTest assert_equal('public', @response.headers['Cache-Control']) assert_equal('"202cb962ac59075b964b07152d234b70"', @response.headers['ETag']) - pending do - assert_equal('"202cb962ac59075b964b07152d234b70"', @response.etag) - assert_equal({:public => true}, @response.cache_control) - end + assert_equal('"202cb962ac59075b964b07152d234b70"', @response.etag) + assert_equal({:public => true}, @response.cache_control) end test "response charset and content type from railsish app" do @@ -202,10 +198,8 @@ class ResponseIntegrationTest < ActionDispatch::IntegrationTest get '/' assert_response :success - pending do - assert_equal('utf-16', @response.charset) - assert_equal(Mime::XML, @response.content_type) - end + assert_equal('utf-16', @response.charset) + assert_equal(Mime::XML, @response.content_type) assert_equal('application/xml; charset=utf-16', @response.headers['Content-Type']) end @@ -220,10 +214,8 @@ class ResponseIntegrationTest < ActionDispatch::IntegrationTest get '/' assert_response :success - pending do - assert_equal('utf-16', @response.charset) - assert_equal(Mime::XML, @response.content_type) - end + assert_equal('utf-16', @response.charset) + assert_equal(Mime::XML, @response.content_type) assert_equal('application/xml; charset=utf-16', @response.headers['Content-Type']) end -- cgit v1.2.3 From a0a01d0c98e7f04a5bfff450f6758c89ef897b96 Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Fri, 19 Feb 2010 22:08:47 +0100 Subject: Remove empty line and trailing hash, breaks documentation generation Signed-off-by: Yehuda Katz --- actionpack/lib/action_view/helpers/url_helper.rb | 2 -- 1 file changed, 2 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb index 04a2743b9c..6ca1a5d730 100644 --- a/actionpack/lib/action_view/helpers/url_helper.rb +++ b/actionpack/lib/action_view/helpers/url_helper.rb @@ -202,8 +202,6 @@ module ActionView # # link_to("Destroy", "http://www.example.com", :method => :delete, :confirm => "Are you sure?") # # => Destroy - - # def link_to(*args, &block) if block_given? options = args.first || {} -- cgit v1.2.3 From e7055e5b084f5e29e9cf8dab8d56943da65ccb43 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 19 Feb 2010 19:57:08 -0200 Subject: i18n translate with arrays issue solved --- actionpack/test/template/translation_helper_test.rb | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'actionpack') diff --git a/actionpack/test/template/translation_helper_test.rb b/actionpack/test/template/translation_helper_test.rb index 699fb2f5bc..1a9c9fa35c 100644 --- a/actionpack/test/template/translation_helper_test.rb +++ b/actionpack/test/template/translation_helper_test.rb @@ -17,6 +17,11 @@ class TranslationHelperTest < ActiveSupport::TestCase expected = 'en, foo' assert_equal expected, translate(:foo) end + + def test_translation_of_an_array + I18n.expects(:translate).with(["foo", "bar"], :raise => true).returns(["foo", "bar"]) + assert_equal ["foo", "bar"], translate(["foo", "bar"]) + end def test_translation_of_an_array I18n.expects(:translate).with(["foo", "bar"], :raise => true).returns(["foo", "bar"]) -- cgit v1.2.3 From bf8898b49b5a8c03d328bde7b6ee30edb02d873b Mon Sep 17 00:00:00 2001 From: Yehuda Katz Date: Fri, 19 Feb 2010 15:05:46 -0800 Subject: Revert "i18n translate with arrays issue solved" This reverts commit e7055e5b084f5e29e9cf8dab8d56943da65ccb43. --- actionpack/test/template/translation_helper_test.rb | 5 ----- 1 file changed, 5 deletions(-) (limited to 'actionpack') diff --git a/actionpack/test/template/translation_helper_test.rb b/actionpack/test/template/translation_helper_test.rb index 1a9c9fa35c..699fb2f5bc 100644 --- a/actionpack/test/template/translation_helper_test.rb +++ b/actionpack/test/template/translation_helper_test.rb @@ -17,11 +17,6 @@ class TranslationHelperTest < ActiveSupport::TestCase expected = 'en, foo' assert_equal expected, translate(:foo) end - - def test_translation_of_an_array - I18n.expects(:translate).with(["foo", "bar"], :raise => true).returns(["foo", "bar"]) - assert_equal ["foo", "bar"], translate(["foo", "bar"]) - end def test_translation_of_an_array I18n.expects(:translate).with(["foo", "bar"], :raise => true).returns(["foo", "bar"]) -- cgit v1.2.3 From a3c6ad7d5e567cf4d688147357c5de134763599d Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Fri, 19 Feb 2010 19:19:20 -0800 Subject: Fix a bunch of pending tests by providing an introspection mode for the Response object that does up-front parsing of the headers to populate things like @etag --- actionpack/lib/action_dispatch/http/cache.rb | 21 +++++++++++-- actionpack/lib/action_dispatch/http/response.rb | 36 +++++++++++++--------- .../lib/action_dispatch/testing/integration.rb | 3 +- actionpack/test/controller/send_file_test.rb | 3 +- 4 files changed, 42 insertions(+), 21 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/http/cache.rb b/actionpack/lib/action_dispatch/http/cache.rb index 428e62dc6b..d2404e63c5 100644 --- a/actionpack/lib/action_dispatch/http/cache.rb +++ b/actionpack/lib/action_dispatch/http/cache.rb @@ -37,8 +37,21 @@ module ActionDispatch end module Response - def cache_control - @cache_control ||= {} + attr_reader :cache_control + + def initialize(*) + status, header, body = super + + @cache_control = {} + @etag = self["ETag"] + + if cache_control = self["Cache-Control"] + cache_control.split(/,\s*/).each do |segment| + first, last = segment.split("=") + last ||= true + @cache_control[first.to_sym] = last + end + end end def last_modified @@ -65,7 +78,7 @@ module ActionDispatch def etag=(etag) key = ActiveSupport::Cache.expand_cache_key(etag) - @etag = %("#{Digest::MD5.hexdigest(key)}") + @etag = self["ETag"] = %("#{Digest::MD5.hexdigest(key)}") end private @@ -100,6 +113,8 @@ module ActionDispatch def set_conditional_cache_control! control = @cache_control + return if self["Cache-Control"].present? + if control.empty? headers["Cache-Control"] = DEFAULT_CACHE_CONTROL elsif @cache_control[:no_cache] diff --git a/actionpack/lib/action_dispatch/http/response.rb b/actionpack/lib/action_dispatch/http/response.rb index f299306ff4..1b8dd9abfd 100644 --- a/actionpack/lib/action_dispatch/http/response.rb +++ b/actionpack/lib/action_dispatch/http/response.rb @@ -32,31 +32,37 @@ module ActionDispatch # :nodoc: # end # end class Response < Rack::Response - include ActionDispatch::Http::Cache::Response - attr_accessor :request, :blank attr_writer :header, :sending_file alias_method :headers=, :header= - def initialize - @status = 200 - @header = {} - @cache_control = {} + module Setup + def initialize(status = 200, header = {}, body = []) + @writer = lambda { |x| @body << x } + @block = nil + @length = 0 - @writer = lambda { |x| @body << x } - @block = nil - @length = 0 + @status, @header, @body = status, header, body - @body, @cookie = [], [] - @sending_file = false + @cookie = [] + @sending_file = false - @blank = false - @etag = nil + @blank = false + + if content_type = self["Content-Type"] + type, charset = content_type.split(/;\s*charset=/) + @content_type = Mime::Type.lookup(type) + @charset = charset || "UTF-8" + end - yield self if block_given? + yield self if block_given? + end end + include Setup + include ActionDispatch::Http::Cache::Response + def status=(status) @status = Rack::Utils.status_code(status) end @@ -120,7 +126,7 @@ module ActionDispatch # :nodoc: assign_default_content_type_and_charset! handle_conditional_get! self["Set-Cookie"] = @cookie.join("\n") unless @cookie.blank? - self["ETag"] = @etag if @etag + self["ETag"] = @_etag if @_etag super end diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb index 2093bb3a0e..d179af47d9 100644 --- a/actionpack/lib/action_dispatch/testing/integration.rb +++ b/actionpack/lib/action_dispatch/testing/integration.rb @@ -273,7 +273,8 @@ module ActionDispatch @request_count += 1 @request = ActionDispatch::Request.new(session.last_request.env) - @response = ActionDispatch::TestResponse.from_response(@mock_session.last_response) + response = @mock_session.last_response + @response = ActionDispatch::TestResponse.new(response.status, response.headers, response.body) @html_document = nil @controller = session.last_request.env['action_controller.instance'] diff --git a/actionpack/test/controller/send_file_test.rb b/actionpack/test/controller/send_file_test.rb index aebbd893a8..31177223e4 100644 --- a/actionpack/test/controller/send_file_test.rb +++ b/actionpack/test/controller/send_file_test.rb @@ -102,7 +102,7 @@ class SendFileTest < ActionController::TestCase end # Test that send_file_headers! is setting the correct HTTP headers. - def test_send_file_headers! + def test_send_file_headers_bang options = { :length => 1, :type => Mime::PNG, @@ -125,7 +125,6 @@ class SendFileTest < ActionController::TestCase assert_equal 'binary', h['Content-Transfer-Encoding'] # test overriding Cache-Control: no-cache header to fix IE open/save dialog - @controller.headers = { 'Cache-Control' => 'no-cache' } @controller.send(:send_file_headers!, options) @controller.response.prepare! assert_equal 'private', h['Cache-Control'] -- cgit v1.2.3 From 9acd686753c43612984aaa4002e80113fda2b255 Mon Sep 17 00:00:00 2001 From: snusnu Date: Sat, 20 Feb 2010 08:24:10 +0100 Subject: Adds #key and #to_param to the AMo interface This commit introduces two new methods that every AMo compliant object must implement. Below are the default implementations along with the implied interface contract. # Returns an Enumerable of all (primary) key # attributes or nil if new_record? is true def key new_record? ? nil : [1] end # Returns a string representing the object's key # suitable for use in URLs, or nil if new_record? # is true def to_param key ? key.first.to_s : nil end 1) The #key method Previously rails' record_identifier code, which is used in the #dom_id helper, relied on calling #id on the record to provide a reasonable DOM id. Now with rails3 being all ORM agnostic, it's not safe anymore to assume that every record ever will have an #id as its primary key attribute. Having a #key method available on every AMo object means that #dom_id can be implemented using record.to_model.key # instead of record.id Using this we're able to take composite primary keys into account (e.g. available in datamapper) by implementing #dom_id using a newly added record_key_for_dom_id(record) method. The user can overwrite this method to provide customized versions of the object's key used in #dom_id. Also, dealing with more complex keys that can contain arbitrary strings, means that we need to make sure that we only provide DOM ids that are valid according to the spec. For this reason, this patch sends the key provided through a newly added sanitize_dom_id(candidate_id) method, that makes sure we only produce valid HTML The reason to not just add #dom_id to the AMo interface was that it feels like providing a DOM id should not be a model concern. Adding #dom_id to the AMo interface would force these concern on the model, while it's better left to be implemented in a helper. Now one could say the same is true for #to_param, and actually I think that it doesn't really fit into the model either, but it's used in AR and it's a main part of integrating into the rails router. This is different from #dom_id which is only used in view helpers and can be implemented on top of a semantically more meaningful method like #key. 2) The #to_param method Since the rails router relies on #to_param to be present, AR::Base implements it and returns the id by default, allowing the user to overwrite the method if desired. Now with different ORMs integrating into rails, every ORM railtie needs to implement it's own #to_param implementation while already providing code to be AMo compliant. Since the whole point of AMo compliance seems to be to integrate any ORM seamlessly into rails, it seems fair that all we really need to do as another ORM, is to be AMo compliant. By including #to_param into the official interface, we can make sure that this code can be centralized in the various AMo compliance layers, and not be added separately by every ORM railtie. 3) All specs pass --- .../lib/action_controller/record_identifier.rb | 21 ++++++++++++++++++++- actionpack/test/lib/controller/fake_models.rb | 16 ++++++++++++++++ actionpack/test/template/prototype_helper_test.rb | 3 +++ 3 files changed, 39 insertions(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/record_identifier.rb b/actionpack/lib/action_controller/record_identifier.rb index 1165c3b7c5..9c35c5b0c3 100644 --- a/actionpack/lib/action_controller/record_identifier.rb +++ b/actionpack/lib/action_controller/record_identifier.rb @@ -60,13 +60,32 @@ module ActionController # # dom_id(Post.find(45), :edit) # => "edit_post_45" def dom_id(record, prefix = nil) - if record_id = record.id + if record_id = record_key_for_dom_id(record) "#{dom_class(record, prefix)}#{JOIN}#{record_id}" else dom_class(record, prefix || NEW) end end + # Returns a string representation of the key attribute(s) that is suitable for use in an HTML DOM id. + # This can be overwritten to customize the default generated string representation if desired. + # If you need to read back a key from a dom_id in order to query for the underlying database record, + # you should write a helper like 'person_record_from_dom_id' that will extract the key either based + # on the default implementation (which just joins all key attributes with '-') or on your own + # overwritten version of the method. By default, this implementation passes the key string through a + # method that replaces all characters that are invalid inside DOM ids, with valid ones. You need to + # make sure yourself that your dom ids are valid, in case you overwrite this method. + def record_key_for_dom_id(record) + return record.id unless record.respond_to?(:to_model) + key = record.to_model.key + key ? sanitize_dom_id(key.join('-')) : key + end + + # Replaces characters that are invalid in HTML DOM ids with valid ones. + def sanitize_dom_id(candidate_id) + candidate_id # TODO implement conversion to valid DOM id values + end + # Returns the plural class name of a record or class. Examples: # # plural_class_name(post) # => "posts" diff --git a/actionpack/test/lib/controller/fake_models.rb b/actionpack/test/lib/controller/fake_models.rb index a8c86f70b6..e4aed14dc0 100644 --- a/actionpack/test/lib/controller/fake_models.rb +++ b/actionpack/test/lib/controller/fake_models.rb @@ -6,6 +6,10 @@ class Customer < Struct.new(:name, :id) undef_method :to_json + def key + id ? [id] : nil + end + def to_param id.to_s end @@ -43,6 +47,10 @@ module Quiz extend ActiveModel::Naming include ActiveModel::Conversion + def key + id ? [id] : nil + end + def to_param id.to_s end @@ -59,6 +67,10 @@ class Post < Struct.new(:title, :author_name, :body, :secret, :written_on, :cost alias_method :secret?, :secret + def key + id ? [id] : nil + end + def new_record=(boolean) @new_record = boolean end @@ -84,6 +96,7 @@ class Comment attr_reader :id attr_reader :post_id def initialize(id = nil, post_id = nil); @id, @post_id = id, post_id end + def key; id ? [id] : nil end def save; @id = 1; @post_id = 1 end def new_record?; @id.nil? end def to_param; @id; end @@ -103,6 +116,7 @@ class Tag attr_reader :id attr_reader :post_id def initialize(id = nil, post_id = nil); @id, @post_id = id, post_id end + def key; id ? [id] : nil end def save; @id = 1; @post_id = 1 end def new_record?; @id.nil? end def to_param; @id; end @@ -122,6 +136,7 @@ class CommentRelevance attr_reader :id attr_reader :comment_id def initialize(id = nil, comment_id = nil); @id, @comment_id = id, comment_id end + def key; id ? [id] : nil end def save; @id = 1; @comment_id = 1 end def new_record?; @id.nil? end def to_param; @id; end @@ -137,6 +152,7 @@ class TagRelevance attr_reader :id attr_reader :tag_id def initialize(id = nil, tag_id = nil); @id, @tag_id = id, tag_id end + def key; id ? [id] : nil end def save; @id = 1; @tag_id = 1 end def new_record?; @id.nil? end def to_param; @id; end diff --git a/actionpack/test/template/prototype_helper_test.rb b/actionpack/test/template/prototype_helper_test.rb index d95bdc2b90..dab34f1201 100644 --- a/actionpack/test/template/prototype_helper_test.rb +++ b/actionpack/test/template/prototype_helper_test.rb @@ -4,6 +4,7 @@ require 'active_model' class Bunny < Struct.new(:Bunny, :id) extend ActiveModel::Naming include ActiveModel::Conversion + def key() id ? [id] : nil end end class Author @@ -11,6 +12,7 @@ class Author include ActiveModel::Conversion attr_reader :id + def key() id ? [id] : nil end def save; @id = 1 end def new_record?; @id.nil? end def name @@ -23,6 +25,7 @@ class Article include ActiveModel::Conversion attr_reader :id attr_reader :author_id + def key() id ? [id] : nil end def save; @id = 1; @author_id = 1 end def new_record?; @id.nil? end def name -- cgit v1.2.3 From f81c6bc0404ba2a03eed0ec6c08bbac45661305f Mon Sep 17 00:00:00 2001 From: snusnu Date: Sun, 21 Feb 2010 03:05:28 +0100 Subject: AMo #key is now #to_key and CI is probably happy Obviously #key is a too common name to be included in the AMo interface, #to_key fits better and also relates nicely to #to_param. Thx wycats, koz and josevalim for the suggestion. AR's #to_key implementation now takes customized primary keys into account and there's a testcase for that too. The #to_param AMo lint makes no assumptions on how the method behaves in the presence of composite primary keys. It leaves the decision wether to provide a default, or to raise and thus signal to the user that implementing this method will need his special attention, up to the implementers. All AMo cares about is that #to_param is implemented and returns nil in case of a new_record?. The default CompliantObject used in lint_test provides a naive default implementation that just joins all key attributes with '-'. The #to_key default implementation in lint_test's CompliantObject now returns [id] instead of [1]. This was previously causing the (wrong) tests I added for AR's #to_key implementation to pass. The #to_key tests added with this patch should be better. The CI failure was caused by my lack of knowledge about the test:isolated task. The tests for the record_identifier code in action_controller are using fake non AR models and I forgot to stub the #to_key method over there. This issue didn't come up when running the test task, only test:isolated revealed it. This patch fixes that. All tests pass isolated or not, well, apart from one previously unpended test in action_controller that is unrelated to my patch. --- actionpack/lib/action_controller/record_identifier.rb | 4 ++-- actionpack/test/controller/record_identifier_test.rb | 1 + actionpack/test/lib/controller/fake_models.rb | 14 +++++++------- actionpack/test/template/prototype_helper_test.rb | 6 +++--- 4 files changed, 13 insertions(+), 12 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/record_identifier.rb b/actionpack/lib/action_controller/record_identifier.rb index 9c35c5b0c3..3f966b1b64 100644 --- a/actionpack/lib/action_controller/record_identifier.rb +++ b/actionpack/lib/action_controller/record_identifier.rb @@ -77,8 +77,8 @@ module ActionController # make sure yourself that your dom ids are valid, in case you overwrite this method. def record_key_for_dom_id(record) return record.id unless record.respond_to?(:to_model) - key = record.to_model.key - key ? sanitize_dom_id(key.join('-')) : key + key = record.to_model.to_key + key ? sanitize_dom_id(key.join('_')) : key end # Replaces characters that are invalid in HTML DOM ids with valid ones. diff --git a/actionpack/test/controller/record_identifier_test.rb b/actionpack/test/controller/record_identifier_test.rb index 6b6d154faa..813dedc80d 100644 --- a/actionpack/test/controller/record_identifier_test.rb +++ b/actionpack/test/controller/record_identifier_test.rb @@ -5,6 +5,7 @@ class Comment include ActiveModel::Conversion attr_reader :id + def to_key; id ? [id] : nil end def save; @id = 1 end def new_record?; @id.nil? end def name diff --git a/actionpack/test/lib/controller/fake_models.rb b/actionpack/test/lib/controller/fake_models.rb index e4aed14dc0..4475d40f63 100644 --- a/actionpack/test/lib/controller/fake_models.rb +++ b/actionpack/test/lib/controller/fake_models.rb @@ -6,7 +6,7 @@ class Customer < Struct.new(:name, :id) undef_method :to_json - def key + def to_key id ? [id] : nil end @@ -47,7 +47,7 @@ module Quiz extend ActiveModel::Naming include ActiveModel::Conversion - def key + def to_key id ? [id] : nil end @@ -67,7 +67,7 @@ class Post < Struct.new(:title, :author_name, :body, :secret, :written_on, :cost alias_method :secret?, :secret - def key + def to_key id ? [id] : nil end @@ -96,7 +96,7 @@ class Comment attr_reader :id attr_reader :post_id def initialize(id = nil, post_id = nil); @id, @post_id = id, post_id end - def key; id ? [id] : nil end + def to_key; id ? [id] : nil end def save; @id = 1; @post_id = 1 end def new_record?; @id.nil? end def to_param; @id; end @@ -116,7 +116,7 @@ class Tag attr_reader :id attr_reader :post_id def initialize(id = nil, post_id = nil); @id, @post_id = id, post_id end - def key; id ? [id] : nil end + def to_key; id ? [id] : nil end def save; @id = 1; @post_id = 1 end def new_record?; @id.nil? end def to_param; @id; end @@ -136,7 +136,7 @@ class CommentRelevance attr_reader :id attr_reader :comment_id def initialize(id = nil, comment_id = nil); @id, @comment_id = id, comment_id end - def key; id ? [id] : nil end + def to_key; id ? [id] : nil end def save; @id = 1; @comment_id = 1 end def new_record?; @id.nil? end def to_param; @id; end @@ -152,7 +152,7 @@ class TagRelevance attr_reader :id attr_reader :tag_id def initialize(id = nil, tag_id = nil); @id, @tag_id = id, tag_id end - def key; id ? [id] : nil end + def to_key; id ? [id] : nil end def save; @id = 1; @tag_id = 1 end def new_record?; @id.nil? end def to_param; @id; end diff --git a/actionpack/test/template/prototype_helper_test.rb b/actionpack/test/template/prototype_helper_test.rb index dab34f1201..45f9d85e32 100644 --- a/actionpack/test/template/prototype_helper_test.rb +++ b/actionpack/test/template/prototype_helper_test.rb @@ -4,7 +4,7 @@ require 'active_model' class Bunny < Struct.new(:Bunny, :id) extend ActiveModel::Naming include ActiveModel::Conversion - def key() id ? [id] : nil end + def to_key() id ? [id] : nil end end class Author @@ -12,7 +12,7 @@ class Author include ActiveModel::Conversion attr_reader :id - def key() id ? [id] : nil end + def to_key() id ? [id] : nil end def save; @id = 1 end def new_record?; @id.nil? end def name @@ -25,7 +25,7 @@ class Article include ActiveModel::Conversion attr_reader :id attr_reader :author_id - def key() id ? [id] : nil end + def to_key() id ? [id] : nil end def save; @id = 1; @author_id = 1 end def new_record?; @id.nil? end def name -- cgit v1.2.3 From 250c8092461f5e6bf62751b313f6605a37fd1b2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sun, 21 Feb 2010 11:09:21 +0100 Subject: Require persisted? in ActiveModel::Lint and remove new_record? and destroyed? methods. ActionPack does not care if the resource is new or if it was destroyed, it cares only if it's persisted somewhere or not. --- .../lib/action_controller/polymorphic_routes.rb | 3 +- .../lib/action_view/helpers/active_model_helper.rb | 4 +-- actionpack/lib/action_view/helpers/form_helper.rb | 17 +++++---- actionpack/lib/action_view/helpers/url_helper.rb | 2 +- actionpack/test/controller/mime_responds_test.rb | 4 +-- actionpack/test/controller/redirect_test.rb | 18 +++++----- actionpack/test/lib/controller/fake_models.rb | 40 +++++++--------------- .../test/template/active_model_helper_test.rb | 4 +-- actionpack/test/template/atom_feed_helper_test.rb | 8 ++--- actionpack/test/template/form_helper_test.rb | 13 ++----- actionpack/test/template/record_tag_helper_test.rb | 1 + actionpack/test/template/url_helper_test.rb | 36 +++++++++---------- 12 files changed, 63 insertions(+), 87 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/polymorphic_routes.rb b/actionpack/lib/action_controller/polymorphic_routes.rb index eaed00cfb7..ae363e300c 100644 --- a/actionpack/lib/action_controller/polymorphic_routes.rb +++ b/actionpack/lib/action_controller/polymorphic_routes.rb @@ -92,8 +92,7 @@ module ActionController inflection = if options[:action].to_s == "new" args.pop :singular - elsif (record.respond_to?(:new_record?) && record.new_record?) || - (record.respond_to?(:destroyed?) && record.destroyed?) + elsif (record.respond_to?(:persisted?) && !record.persisted?) args.pop :plural elsif record.is_a?(Class) diff --git a/actionpack/lib/action_view/helpers/active_model_helper.rb b/actionpack/lib/action_view/helpers/active_model_helper.rb index 2f309fcca0..ed83b8a8b2 100644 --- a/actionpack/lib/action_view/helpers/active_model_helper.rb +++ b/actionpack/lib/action_view/helpers/active_model_helper.rb @@ -80,13 +80,13 @@ module ActionView record = convert_to_model(record) options = options.symbolize_keys - options[:action] ||= record.new_record? ? "create" : "update" + options[:action] ||= record.persisted? ? "update" : "create" action = url_for(:action => options[:action], :id => record) submit_value = options[:submit_value] || options[:action].gsub(/[^\w]/, '').capitalize contents = form_tag({:action => action}, :method =>(options[:method] || 'post'), :enctype => options[:multipart] ? 'multipart/form-data': nil) - contents.safe_concat hidden_field(record_name, :id) unless record.new_record? + contents.safe_concat hidden_field(record_name, :id) if record.persisted? contents.safe_concat all_input_tags(record, record_name, options) yield contents if block_given? contents.safe_concat submit_tag(submit_value) diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index ce21af9923..ace3bcfde3 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -316,14 +316,13 @@ module ActionView def apply_form_for_options!(object_or_array, options) #:nodoc: object = object_or_array.is_a?(Array) ? object_or_array.last : object_or_array - object = convert_to_model(object) html_options = - if object.respond_to?(:new_record?) && object.new_record? - { :class => dom_class(object, :new), :id => dom_id(object), :method => :post } - else + if object.respond_to?(:persisted?) && object.persisted? { :class => dom_class(object, :edit), :id => dom_id(object, :edit), :method => :put } + else + { :class => dom_class(object, :new), :id => dom_id(object), :method => :post } end options[:html] ||= {} @@ -1150,7 +1149,7 @@ module ActionView def submit_default_value object = @object.respond_to?(:to_model) ? @object.to_model : @object - key = object ? (object.new_record? ? :create : :update) : :submit + key = object ? (object.persisted? ? :update : :create) : :submit model = if object.class.respond_to?(:model_name) object.class.model_name.human @@ -1176,7 +1175,7 @@ module ActionView association = args.shift association = association.to_model if association.respond_to?(:to_model) - if association.respond_to?(:new_record?) + if association.respond_to?(:persisted?) association = [association] if @object.send(association_name).is_a?(Array) elsif !association.is_a?(Array) association = @object.send(association_name) @@ -1195,13 +1194,13 @@ module ActionView def fields_for_nested_model(name, object, options, block) object = object.to_model if object.respond_to?(:to_model) - if object.new_record? - @template.fields_for(name, object, options, &block) - else + if object.persisted? @template.fields_for(name, object, options) do |builder| block.call(builder) @template.concat builder.hidden_field(:id) unless builder.emitted_hidden_id? end + else + @template.fields_for(name, object, options, &block) end end diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb index 6ca1a5d730..e121472fe3 100644 --- a/actionpack/lib/action_view/helpers/url_helper.rb +++ b/actionpack/lib/action_view/helpers/url_helper.rb @@ -63,7 +63,7 @@ module ActionView # # => /testing/jump/#tax&ship # # <%= url_for(Workshop.new) %> - # # relies on Workshop answering a new_record? call (and in this case returning true) + # # relies on Workshop answering a persisted? call (and in this case returning false) # # => /workshops # # <%= url_for(@workshop) %> diff --git a/actionpack/test/controller/mime_responds_test.rb b/actionpack/test/controller/mime_responds_test.rb index 3bd3369242..5e34773899 100644 --- a/actionpack/test/controller/mime_responds_test.rb +++ b/actionpack/test/controller/mime_responds_test.rb @@ -513,7 +513,7 @@ class RespondWithController < ActionController::Base protected def resource - Customer.new("david", 13) + Customer.new("david", request.delete? ? nil : 13) end def _render_js(js, options) @@ -717,7 +717,7 @@ class RespondWithControllerTest < ActionController::TestCase delete :using_resource assert_equal "text/html", @response.content_type assert_equal 302, @response.status - assert_equal "http://www.example.com/customers/13", @response.location + assert_equal "http://www.example.com/customers", @response.location end end diff --git a/actionpack/test/controller/redirect_test.rb b/actionpack/test/controller/redirect_test.rb index 570ff4a41b..441bc47908 100644 --- a/actionpack/test/controller/redirect_test.rb +++ b/actionpack/test/controller/redirect_test.rb @@ -6,14 +6,14 @@ end class Workshop extend ActiveModel::Naming include ActiveModel::Conversion - attr_accessor :id, :new_record + attr_accessor :id - def initialize(id, new_record) - @id, @new_record = id, new_record + def initialize(id) + @id = id end - def new_record? - @new_record + def persisted? + id.present? end def to_s @@ -88,11 +88,11 @@ class RedirectController < ActionController::Base end def redirect_to_existing_record - redirect_to Workshop.new(5, false) + redirect_to Workshop.new(5) end def redirect_to_new_record - redirect_to Workshop.new(5, true) + redirect_to Workshop.new(nil) end def redirect_to_nil @@ -239,11 +239,11 @@ class RedirectTest < ActionController::TestCase get :redirect_to_existing_record assert_equal "http://test.host/workshops/5", redirect_to_url - assert_redirected_to Workshop.new(5, false) + assert_redirected_to Workshop.new(5) get :redirect_to_new_record assert_equal "http://test.host/workshops", redirect_to_url - assert_redirected_to Workshop.new(5, true) + assert_redirected_to Workshop.new(nil) end end diff --git a/actionpack/test/lib/controller/fake_models.rb b/actionpack/test/lib/controller/fake_models.rb index 4475d40f63..bf3e175f1f 100644 --- a/actionpack/test/lib/controller/fake_models.rb +++ b/actionpack/test/lib/controller/fake_models.rb @@ -6,14 +6,6 @@ class Customer < Struct.new(:name, :id) undef_method :to_json - def to_key - id ? [id] : nil - end - - def to_param - id.to_s - end - def to_xml(options={}) if options[:builder] options[:builder].name name @@ -31,8 +23,8 @@ class Customer < Struct.new(:name, :id) [] end - def destroyed? - false + def persisted? + id.present? end end @@ -47,12 +39,8 @@ module Quiz extend ActiveModel::Naming include ActiveModel::Conversion - def to_key - id ? [id] : nil - end - - def to_param - id.to_s + def persisted? + id.present? end end @@ -67,16 +55,12 @@ class Post < Struct.new(:title, :author_name, :body, :secret, :written_on, :cost alias_method :secret?, :secret - def to_key - id ? [id] : nil - end - - def new_record=(boolean) - @new_record = boolean + def persisted=(boolean) + @persisted = boolean end - def new_record? - @new_record + def persisted? + @persisted end attr_accessor :author @@ -98,7 +82,7 @@ class Comment def initialize(id = nil, post_id = nil); @id, @post_id = id, post_id end def to_key; id ? [id] : nil end def save; @id = 1; @post_id = 1 end - def new_record?; @id.nil? end + def persisted?; @id.present? end def to_param; @id; end def name @id.nil? ? "new #{self.class.name.downcase}" : "#{self.class.name.downcase} ##{@id}" @@ -118,7 +102,7 @@ class Tag def initialize(id = nil, post_id = nil); @id, @post_id = id, post_id end def to_key; id ? [id] : nil end def save; @id = 1; @post_id = 1 end - def new_record?; @id.nil? end + def persisted?; @id.present? end def to_param; @id; end def value @id.nil? ? "new #{self.class.name.downcase}" : "#{self.class.name.downcase} ##{@id}" @@ -138,7 +122,7 @@ class CommentRelevance def initialize(id = nil, comment_id = nil); @id, @comment_id = id, comment_id end def to_key; id ? [id] : nil end def save; @id = 1; @comment_id = 1 end - def new_record?; @id.nil? end + def persisted?; @id.present? end def to_param; @id; end def value @id.nil? ? "new #{self.class.name.downcase}" : "#{self.class.name.downcase} ##{@id}" @@ -154,7 +138,7 @@ class TagRelevance def initialize(id = nil, tag_id = nil); @id, @tag_id = id, tag_id end def to_key; id ? [id] : nil end def save; @id = 1; @tag_id = 1 end - def new_record?; @id.nil? end + def persisted?; @id.present? end def to_param; @id; end def value @id.nil? ? "new #{self.class.name.downcase}" : "#{self.class.name.downcase} ##{@id}" diff --git a/actionpack/test/template/active_model_helper_test.rb b/actionpack/test/template/active_model_helper_test.rb index 3e01ae78c3..371aa53c68 100644 --- a/actionpack/test/template/active_model_helper_test.rb +++ b/actionpack/test/template/active_model_helper_test.rb @@ -64,7 +64,7 @@ class ActiveModelHelperTest < ActionView::TestCase }.new end - def @post.new_record?() true end + def @post.persisted?() false end def @post.to_param() nil end def @post.column_for_attribute(attr_name) @@ -155,7 +155,7 @@ class ActiveModelHelperTest < ActionView::TestCase silence_warnings do class << @post - def new_record?() false end + def persisted?() true end def to_param() id end def id() 1 end end diff --git a/actionpack/test/template/atom_feed_helper_test.rb b/actionpack/test/template/atom_feed_helper_test.rb index 347cb98303..869ea22469 100644 --- a/actionpack/test/template/atom_feed_helper_test.rb +++ b/actionpack/test/template/atom_feed_helper_test.rb @@ -4,8 +4,8 @@ class Scroll < Struct.new(:id, :to_param, :title, :body, :updated_at, :created_a extend ActiveModel::Naming include ActiveModel::Conversion - def new_record? - true + def persisted? + false end end @@ -34,7 +34,7 @@ class ScrollsController < ActionController::Base feed.updated((@scrolls.first.created_at)) for scroll in @scrolls - feed.entry(scroll, :url => "/otherstuff/" + scroll.to_param, :updated => Time.utc(2007, 1, scroll.id)) do |entry| + feed.entry(scroll, :url => "/otherstuff/" + scroll.to_param.to_s, :updated => Time.utc(2007, 1, scroll.id)) do |entry| entry.title(scroll.title) entry.content(scroll.body, :type => 'html') @@ -55,7 +55,7 @@ class ScrollsController < ActionController::Base end for scroll in @scrolls - feed.entry(scroll, :url => "/otherstuff/" + scroll.to_param, :updated => Time.utc(2007, 1, scroll.id)) do |entry| + feed.entry(scroll, :url => "/otherstuff/" + scroll.to_param.to_s, :updated => Time.utc(2007, 1, scroll.id)) do |entry| entry.title(scroll.title) entry.content(scroll.body, :type => 'html') end diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb index 7b909fff82..d143c39c9c 100644 --- a/actionpack/test/template/form_helper_test.rb +++ b/actionpack/test/template/form_helper_test.rb @@ -53,6 +53,7 @@ class FormHelperTest < ActionView::TestCase def @post.id_before_type_cast; 123; end def @post.to_param; '123'; end + @post.persisted = true @post.title = "Hello World" @post.author_name = "" @post.body = "Back to the hill and over it again!" @@ -529,7 +530,7 @@ class FormHelperTest < ActionView::TestCase def test_submit_with_object_as_new_record_and_locale_strings old_locale, I18n.locale = I18n.locale, :submit - def @post.new_record?() true; end + @post.persisted = false form_for(:post, @post) do |f| concat f.submit end @@ -1363,7 +1364,7 @@ class FormHelperTest < ActionView::TestCase def test_form_for_with_new_object post = Post.new - post.new_record = true + post.persisted = false def post.id() nil end form_for(post) do |f| end @@ -1373,9 +1374,7 @@ class FormHelperTest < ActionView::TestCase end def test_form_for_with_existing_object_in_list - @post.new_record = false @comment.save - form_for([@post, @comment]) {} expected = %(
) @@ -1383,8 +1382,6 @@ class FormHelperTest < ActionView::TestCase end def test_form_for_with_new_object_in_list - @post.new_record = false - form_for([@post, @comment]) {} expected = %(
) @@ -1392,9 +1389,7 @@ class FormHelperTest < ActionView::TestCase end def test_form_for_with_existing_object_and_namespace_in_list - @post.new_record = false @comment.save - form_for([:admin, @post, @comment]) {} expected = %(
) @@ -1402,8 +1397,6 @@ class FormHelperTest < ActionView::TestCase end def test_form_for_with_new_object_and_namespace_in_list - @post.new_record = false - form_for([:admin, @post, @comment]) {} expected = %(
) diff --git a/actionpack/test/template/record_tag_helper_test.rb b/actionpack/test/template/record_tag_helper_test.rb index 1cd18c0692..74d7bba4fe 100644 --- a/actionpack/test/template/record_tag_helper_test.rb +++ b/actionpack/test/template/record_tag_helper_test.rb @@ -18,6 +18,7 @@ class RecordTagHelperTest < ActionView::TestCase def setup super @post = Post.new + @post.persisted = true end def test_content_tag_for diff --git a/actionpack/test/template/url_helper_test.rb b/actionpack/test/template/url_helper_test.rb index 418c050906..c917ca9d2b 100644 --- a/actionpack/test/template/url_helper_test.rb +++ b/actionpack/test/template/url_helper_test.rb @@ -499,14 +499,14 @@ end class Workshop extend ActiveModel::Naming include ActiveModel::Conversion - attr_accessor :id, :new_record + attr_accessor :id - def initialize(id, new_record) - @id, @new_record = id, new_record + def initialize(id) + @id = id end - def new_record? - @new_record + def persisted? + id.present? end def to_s @@ -517,14 +517,14 @@ end class Session extend ActiveModel::Naming include ActiveModel::Conversion - attr_accessor :id, :workshop_id, :new_record + attr_accessor :id, :workshop_id - def initialize(id, new_record) - @id, @new_record = id, new_record + def initialize(id) + @id = id end - def new_record? - @new_record + def persisted? + id.present? end def to_s @@ -534,12 +534,12 @@ end class WorkshopsController < ActionController::Base def index - @workshop = Workshop.new(1, true) + @workshop = Workshop.new(nil) render :inline => "<%= url_for(@workshop) %>\n<%= link_to('Workshop', @workshop) %>" end def show - @workshop = Workshop.new(params[:id], false) + @workshop = Workshop.new(params[:id]) render :inline => "<%= url_for(@workshop) %>\n<%= link_to('Workshop', @workshop) %>" end @@ -548,14 +548,14 @@ end class SessionsController < ActionController::Base def index - @workshop = Workshop.new(params[:workshop_id], false) - @session = Session.new(1, true) + @workshop = Workshop.new(params[:workshop_id]) + @session = Session.new(nil) render :inline => "<%= url_for([@workshop, @session]) %>\n<%= link_to('Session', [@workshop, @session]) %>" end def show - @workshop = Workshop.new(params[:workshop_id], false) - @session = Session.new(params[:id], false) + @workshop = Workshop.new(params[:workshop_id]) + @session = Session.new(params[:id]) render :inline => "<%= url_for([@workshop, @session]) %>\n<%= link_to('Session', [@workshop, @session]) %>" end @@ -565,8 +565,8 @@ end class PolymorphicControllerTest < ActionController::TestCase def setup super - @request = ActionController::TestRequest.new - @response = ActionController::TestResponse.new + @request = ActionController::TestRequest.new + @response = ActionController::TestResponse.new end def test_new_resource -- cgit v1.2.3 From 55ae903c3fd2965f85a6e2e45ddd6b5b1156be91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sun, 21 Feb 2010 14:29:40 +0100 Subject: Store compiled parameter filters so we don't have to compile them in each request. --- .../lib/action_dispatch/http/filter_parameters.rb | 65 +++++++++++++--------- 1 file changed, 40 insertions(+), 25 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/http/filter_parameters.rb b/actionpack/lib/action_dispatch/http/filter_parameters.rb index 1958e1668d..451b79b190 100644 --- a/actionpack/lib/action_dispatch/http/filter_parameters.rb +++ b/actionpack/lib/action_dispatch/http/filter_parameters.rb @@ -25,9 +25,16 @@ module ActionDispatch module FilterParameters extend ActiveSupport::Concern + mattr_reader :compiled_parameter_filter_for + @@compiled_parameter_filter_for = {} + # Return a hash of parameters with all sensitive data replaced. def filtered_parameters - @filtered_parameters ||= process_parameter_filter(parameters) + @filtered_parameters ||= if filtering_parameters? + process_parameter_filter(parameters) + else + parameters.dup + end end alias :fitered_params :filtered_parameters @@ -46,10 +53,18 @@ module ActionDispatch protected - def compile_parameter_filter #:nodoc: + def filtering_parameters? #:nodoc: + @env["action_dispatch.parameter_filter"].present? + end + + def process_parameter_filter(params) #:nodoc: + compiled_parameter_filter_for(@env["action_dispatch.parameter_filter"]).call(params) + end + + def compile_parameter_filter(filters) #:nodoc: strings, regexps, blocks = [], [], [] - Array(@env["action_dispatch.parameter_filter"]).each do |item| + filters.each do |item| case item when NilClass when Proc @@ -65,34 +80,34 @@ module ActionDispatch [regexps, blocks] end - def filtering_parameters? #:nodoc: - @env["action_dispatch.parameter_filter"].present? - end + def compiled_parameter_filter_for(filters) #:nodoc: + @@compiled_parameter_filter_for[filters] ||= begin + regexps, blocks = compile_parameter_filter(filters) - def process_parameter_filter(original_params) #:nodoc: - return original_params.dup unless filtering_parameters? + lambda do |original_params| + filtered_params = {} - filtered_params = {} - regexps, blocks = compile_parameter_filter + original_params.each do |key, value| + if regexps.find { |r| key =~ r } + value = '[FILTERED]' + elsif value.is_a?(Hash) + value = process_parameter_filter(value) + elsif value.is_a?(Array) + value = value.map { |v| v.is_a?(Hash) ? process_parameter_filter(v) : v } + elsif blocks.present? + key = key.dup + value = value.dup if value.duplicable? + blocks.each { |b| b.call(key, value) } + end - original_params.each do |key, value| - if regexps.find { |r| key =~ r } - value = '[FILTERED]' - elsif value.is_a?(Hash) - value = process_parameter_filter(value) - elsif value.is_a?(Array) - value = value.map { |i| process_parameter_filter(i) } - elsif blocks.present? - key = key.dup - value = value.dup if value.duplicable? - blocks.each { |b| b.call(key, value) } - end + filtered_params[key] = value + end - filtered_params[key] = value + filtered_params + end end - - filtered_params end + end end end \ No newline at end of file -- cgit v1.2.3 From a7b78e86b3b78cf4f461cd372d914ff3a6295c1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sun, 21 Feb 2010 14:40:48 +0100 Subject: Add a tests which ensures filtered_parameters does not raise an error for a mixed array [#3928 status:resolved] --- actionpack/test/dispatch/request_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/test/dispatch/request_test.rb b/actionpack/test/dispatch/request_test.rb index 2b5c19361a..cc6acead6e 100644 --- a/actionpack/test/dispatch/request_test.rb +++ b/actionpack/test/dispatch/request_test.rb @@ -462,7 +462,7 @@ class RequestTest < ActiveSupport::TestCase [{'foo'=>'bar', 'baz'=>'foo'},{'foo'=>'[FILTERED]', 'baz'=>'[FILTERED]'},%w'foo baz'], [{'bar'=>{'foo'=>'bar','bar'=>'foo'}},{'bar'=>{'foo'=>'[FILTERED]','bar'=>'foo'}},%w'fo'], [{'foo'=>{'foo'=>'bar','bar'=>'foo'}},{'foo'=>'[FILTERED]'},%w'f banana'], - [{'baz'=>[{'foo'=>'baz'}]}, {'baz'=>[{'foo'=>'[FILTERED]'}]}, [/foo/]]] + [{'baz'=>[{'foo'=>'baz'}, "1"]}, {'baz'=>[{'foo'=>'[FILTERED]'}, "1"]}, [/foo/]]] test_hashes.each do |before_filter, after_filter, filter_words| request = stub_request('action_dispatch.parameter_filter' => filter_words) -- cgit v1.2.3 From 6bc24d40d56332593bc22612d4618a2f80b1d91b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sch=C3=BCrrer?= Date: Sun, 21 Feb 2010 17:21:25 +0100 Subject: Use ActionDispatch::Routing everywhere --- actionpack/lib/action_controller/deprecated.rb | 1 - .../lib/action_controller/metal/compatibility.rb | 4 ++-- actionpack/lib/action_controller/metal/url_for.rb | 4 ++-- actionpack/lib/action_controller/test_case.rb | 2 +- actionpack/lib/action_dispatch/routing.rb | 1 + actionpack/lib/action_dispatch/routing/routes.rb | 5 +++++ .../action_dispatch/testing/assertions/routing.rb | 22 +++++++++++----------- .../lib/action_dispatch/testing/integration.rb | 4 ++-- .../lib/action_view/helpers/atom_feed_helper.rb | 2 +- actionpack/lib/action_view/helpers/url_helper.rb | 2 +- actionpack/lib/action_view/test_case.rb | 2 +- actionpack/test/abstract_unit.rb | 18 +++++++++--------- .../test/activerecord/polymorphic_routes_test.rb | 6 +++--- actionpack/test/controller/rescue_test.rb | 4 ++-- actionpack/test/controller/resources_test.rb | 4 ++-- actionpack/test/controller/test_test.rb | 8 ++++---- actionpack/test/controller/webservice_test.rb | 2 +- actionpack/test/dispatch/routing_test.rb | 10 +++++----- 18 files changed, 53 insertions(+), 48 deletions(-) create mode 100644 actionpack/lib/action_dispatch/routing/routes.rb (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/deprecated.rb b/actionpack/lib/action_controller/deprecated.rb index a4eef07841..50c4058845 100644 --- a/actionpack/lib/action_controller/deprecated.rb +++ b/actionpack/lib/action_controller/deprecated.rb @@ -1,5 +1,4 @@ ActionController::AbstractRequest = ActionController::Request = ActionDispatch::Request ActionController::AbstractResponse = ActionController::Response = ActionDispatch::Response ActionController::Routing = ActionDispatch::Routing -ActionController::Routing::Routes = ActionDispatch::Routing::RouteSet.new ActionController::UrlWriter = ActionController::UrlFor diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb index a1cfa32d4d..136b024d9e 100644 --- a/actionpack/lib/action_controller/metal/compatibility.rb +++ b/actionpack/lib/action_controller/metal/compatibility.rb @@ -20,8 +20,8 @@ module ActionController class << self delegate :default_charset=, :to => "ActionDispatch::Response" - delegate :resources_path_names, :to => "ActionController::Routing::Routes" - delegate :resources_path_names=, :to => "ActionController::Routing::Routes" + delegate :resources_path_names, :to => "ActionDispatch::Routing::Routes" + delegate :resources_path_names=, :to => "ActionDispatch::Routing::Routes" end # cattr_reader :protected_instance_variables diff --git a/actionpack/lib/action_controller/metal/url_for.rb b/actionpack/lib/action_controller/metal/url_for.rb index 4f3ad07be5..0a9ea7fe1a 100644 --- a/actionpack/lib/action_controller/metal/url_for.rb +++ b/actionpack/lib/action_controller/metal/url_for.rb @@ -6,7 +6,7 @@ module ActionController # is also possible: an URL can be generated from one of your routing definitions. # URL generation functionality is centralized in this module. # - # See ActionController::Routing and ActionController::Resources for general + # See ActionDispatch::Routing and ActionController::Resources for general # information about routing and routes.rb. # # Tip: If you need to generate URLs from your models or some other place, @@ -87,7 +87,7 @@ module ActionController extend ActiveSupport::Concern included do - ActionController::Routing::Routes.install_helpers(self) + ActionDispatch::Routing::Routes.install_helpers(self) # Including in a class uses an inheritable hash. Modules get a plain hash. if respond_to?(:class_attribute) diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb index 14557ca782..99924205dd 100644 --- a/actionpack/lib/action_controller/test_case.rb +++ b/actionpack/lib/action_controller/test_case.rb @@ -19,7 +19,7 @@ module ActionController def assign_parameters(controller_path, action, parameters = {}) parameters = parameters.symbolize_keys.merge(:controller => controller_path, :action => action) - extra_keys = ActionController::Routing::Routes.extra_keys(parameters) + extra_keys = ActionDispatch::Routing::Routes.extra_keys(parameters) non_path_parameters = get? ? query_parameters : request_parameters parameters.each do |key, value| if value.is_a? Fixnum diff --git a/actionpack/lib/action_dispatch/routing.rb b/actionpack/lib/action_dispatch/routing.rb index 335c9edb98..325d2f7f04 100644 --- a/actionpack/lib/action_dispatch/routing.rb +++ b/actionpack/lib/action_dispatch/routing.rb @@ -204,6 +204,7 @@ module ActionDispatch autoload :DeprecatedMapper, 'action_dispatch/routing/deprecated_mapper' autoload :Mapper, 'action_dispatch/routing/mapper' autoload :Route, 'action_dispatch/routing/route' + autoload :Routes, 'action_dispatch/routing/routes' autoload :RouteSet, 'action_dispatch/routing/route_set' SEPARATORS = %w( / . ? ) diff --git a/actionpack/lib/action_dispatch/routing/routes.rb b/actionpack/lib/action_dispatch/routing/routes.rb new file mode 100644 index 0000000000..4714556d36 --- /dev/null +++ b/actionpack/lib/action_dispatch/routing/routes.rb @@ -0,0 +1,5 @@ +# A singleton that stores the current route set +ActionDispatch::Routing::Routes = ActionDispatch::Routing::RouteSet.new + +# To preserve compatibility with pre-3.0 Rails action_controller/deprecated.rb +# defines ActionDispatch::Routing::Routes as an alias diff --git a/actionpack/lib/action_dispatch/testing/assertions/routing.rb b/actionpack/lib/action_dispatch/testing/assertions/routing.rb index 0c33539b4a..ada749bfe2 100644 --- a/actionpack/lib/action_dispatch/testing/assertions/routing.rb +++ b/actionpack/lib/action_dispatch/testing/assertions/routing.rb @@ -80,7 +80,7 @@ module ActionDispatch expected_path = "/#{expected_path}" unless expected_path[0] == ?/ # Load routes.rb if it hasn't been loaded. - generated_path, extra_keys = ActionController::Routing::Routes.generate_extras(options, defaults) + generated_path, extra_keys = ActionDispatch::Routing::Routes.generate_extras(options, defaults) found_extras = options.reject {|k, v| ! extra_keys.include? k} msg = build_message(message, "found extras , not ", found_extras, extras) @@ -125,7 +125,7 @@ module ActionDispatch end # A helper to make it easier to test different route configurations. - # This method temporarily replaces ActionController::Routing::Routes + # This method temporarily replaces ActionDispatch::Routing::Routes # with a new RouteSet instance. # # The new instance is yielded to the passed block. Typically the block @@ -142,22 +142,22 @@ module ActionDispatch # end # def with_routing - real_routes = ActionController::Routing::Routes - ActionController::Routing.module_eval { remove_const :Routes } + real_routes = ActionDispatch::Routing::Routes + ActionDispatch::Routing.module_eval { remove_const :Routes } - temporary_routes = ActionController::Routing::RouteSet.new - ActionController::Routing.module_eval { const_set :Routes, temporary_routes } + temporary_routes = ActionDispatch::Routing::RouteSet.new + ActionDispatch::Routing.module_eval { const_set :Routes, temporary_routes } yield temporary_routes ensure - if ActionController::Routing.const_defined? :Routes - ActionController::Routing.module_eval { remove_const :Routes } + if ActionDispatch::Routing.const_defined? :Routes + ActionDispatch::Routing.module_eval { remove_const :Routes } end - ActionController::Routing.const_set(:Routes, real_routes) if real_routes + ActionDispatch::Routing.const_set(:Routes, real_routes) if real_routes end def method_missing(selector, *args, &block) - if @controller && ActionController::Routing::Routes.named_routes.helpers.include?(selector) + if @controller && ActionDispatch::Routing::Routes.named_routes.helpers.include?(selector) @controller.send(selector, *args, &block) else super @@ -174,7 +174,7 @@ module ActionDispatch request.env["REQUEST_METHOD"] = request_method.to_s.upcase if request_method request.path = path - params = ActionController::Routing::Routes.recognize_path(path, { :method => request.method }) + params = ActionDispatch::Routing::Routes.recognize_path(path, { :method => request.method }) request.path_parameters = params.with_indifferent_access request diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb index d179af47d9..f93059759b 100644 --- a/actionpack/lib/action_dispatch/testing/integration.rb +++ b/actionpack/lib/action_dispatch/testing/integration.rb @@ -188,11 +188,11 @@ module ActionDispatch unless defined? @named_routes_configured # install the named routes in this session instance. klass = metaclass - ActionController::Routing::Routes.install_helpers(klass) + ActionDispatch::Routing::Routes.install_helpers(klass) # the helpers are made protected by default--we make them public for # easier access during testing and troubleshooting. - klass.module_eval { public *ActionController::Routing::Routes.named_routes.helpers } + klass.module_eval { public *ActionDispatch::Routing::Routes.named_routes.helpers } @named_routes_configured = true end end diff --git a/actionpack/lib/action_view/helpers/atom_feed_helper.rb b/actionpack/lib/action_view/helpers/atom_feed_helper.rb index 9951e11a37..4305a0d5f5 100644 --- a/actionpack/lib/action_view/helpers/atom_feed_helper.rb +++ b/actionpack/lib/action_view/helpers/atom_feed_helper.rb @@ -8,7 +8,7 @@ module ActionView # Full usage example: # # config/routes.rb: - # ActionController::Routing::Routes.draw do |map| + # ActionDispatch::Routing::Routes.draw do |map| # map.resources :posts # map.root :controller => "posts" # end diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb index e121472fe3..d9607c0095 100644 --- a/actionpack/lib/action_view/helpers/url_helper.rb +++ b/actionpack/lib/action_view/helpers/url_helper.rb @@ -5,7 +5,7 @@ require 'active_support/core_ext/hash/keys' module ActionView module Helpers #:nodoc: # Provides a set of methods for making links and getting URLs that - # depend on the routing subsystem (see ActionController::Routing). + # depend on the routing subsystem (see ActionDispatch::Routing). # This allows you to use the same format for links in views # and controllers. module UrlHelper diff --git a/actionpack/lib/action_view/test_case.rb b/actionpack/lib/action_view/test_case.rb index fc29acea6d..af2ed33f3f 100644 --- a/actionpack/lib/action_view/test_case.rb +++ b/actionpack/lib/action_view/test_case.rb @@ -152,7 +152,7 @@ module ActionView end def method_missing(selector, *args) - if ActionController::Routing::Routes.named_routes.helpers.include?(selector) + if ActionDispatch::Routing::Routes.named_routes.helpers.include?(selector) @controller.__send__(selector, *args) else super diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb index 655a133c96..7b41db3fea 100644 --- a/actionpack/test/abstract_unit.rb +++ b/actionpack/test/abstract_unit.rb @@ -76,7 +76,7 @@ class ActiveSupport::TestCase # Hold off drawing routes until all the possible controller classes # have been loaded. setup_once do - ActionController::Routing::Routes.draw do |map| + ActionDispatch::Routing::Routes.draw do |map| match ':controller(/:action(/:id))' end end @@ -92,7 +92,7 @@ class ActionController::IntegrationTest < ActiveSupport::TestCase middleware.use "ActionDispatch::Cookies" middleware.use "ActionDispatch::Flash" middleware.use "ActionDispatch::Head" - }.build(routes || ActionController::Routing::Routes) + }.build(routes || ActionDispatch::Routing::Routes) end self.app = build_app @@ -118,19 +118,19 @@ class ActionController::IntegrationTest < ActiveSupport::TestCase end def with_routing(&block) - real_routes = ActionController::Routing::Routes - ActionController::Routing.module_eval { remove_const :Routes } + real_routes = ActionDispatch::Routing::Routes + ActionDispatch::Routing.module_eval { remove_const :Routes } - temporary_routes = ActionController::Routing::RouteSet.new + temporary_routes = ActionDispatch::Routing::RouteSet.new self.class.app = self.class.build_app(temporary_routes) - ActionController::Routing.module_eval { const_set :Routes, temporary_routes } + ActionDispatch::Routing.module_eval { const_set :Routes, temporary_routes } yield temporary_routes ensure - if ActionController::Routing.const_defined? :Routes - ActionController::Routing.module_eval { remove_const :Routes } + if ActionDispatch::Routing.const_defined? :Routes + ActionDispatch::Routing.module_eval { remove_const :Routes } end - ActionController::Routing.const_set(:Routes, real_routes) if real_routes + ActionDispatch::Routing.const_set(:Routes, real_routes) if real_routes self.class.app = self.class.build_app end end diff --git a/actionpack/test/activerecord/polymorphic_routes_test.rb b/actionpack/test/activerecord/polymorphic_routes_test.rb index ea82758cf5..7be2ef7e29 100644 --- a/actionpack/test/activerecord/polymorphic_routes_test.rb +++ b/actionpack/test/activerecord/polymorphic_routes_test.rb @@ -400,7 +400,7 @@ class PolymorphicRoutesTest < ActionController::TestCase map.resources :series end - ActionController::Routing::Routes.install_helpers(self.class) + ActionDispatch::Routing::Routes.install_helpers(self.class) yield end end @@ -422,7 +422,7 @@ class PolymorphicRoutesTest < ActionController::TestCase end end - ActionController::Routing::Routes.install_helpers(self.class) + ActionDispatch::Routing::Routes.install_helpers(self.class) yield end end @@ -441,7 +441,7 @@ class PolymorphicRoutesTest < ActionController::TestCase end end - ActionController::Routing::Routes.install_helpers(self.class) + ActionDispatch::Routing::Routes.install_helpers(self.class) yield end end diff --git a/actionpack/test/controller/rescue_test.rb b/actionpack/test/controller/rescue_test.rb index 37367eaafc..118b563a72 100644 --- a/actionpack/test/controller/rescue_test.rb +++ b/actionpack/test/controller/rescue_test.rb @@ -326,7 +326,7 @@ class RescueTest < ActionController::IntegrationTest end test 'rescue routing exceptions' do - @app = ActionDispatch::Rescue.new(ActionController::Routing::Routes) do + @app = ActionDispatch::Rescue.new(ActionDispatch::Routing::Routes) do rescue_from ActionController::RoutingError, lambda { |env| [200, {"Content-Type" => "text/html"}, ["Gotcha!"]] } end @@ -335,7 +335,7 @@ class RescueTest < ActionController::IntegrationTest end test 'unrescued exception' do - @app = ActionDispatch::Rescue.new(ActionController::Routing::Routes) + @app = ActionDispatch::Rescue.new(ActionDispatch::Routing::Routes) assert_raise(ActionController::RoutingError) { get '/b00m' } end diff --git a/actionpack/test/controller/resources_test.rb b/actionpack/test/controller/resources_test.rb index 01ed491732..9b3f466e44 100644 --- a/actionpack/test/controller/resources_test.rb +++ b/actionpack/test/controller/resources_test.rb @@ -394,7 +394,7 @@ class ResourcesTest < ActionController::TestCase assert_restful_routes_for :messages do |options| assert_recognizes(options.merge(:action => "new"), :path => "/messages/new", :method => :get) assert_raise(ActionController::RoutingError) do - ActionController::Routing::Routes.recognize_path("/messages/new", :method => :post) + ActionDispatch::Routing::Routes.recognize_path("/messages/new", :method => :post) end end end @@ -504,7 +504,7 @@ class ResourcesTest < ActionController::TestCase def test_restful_routes_dont_generate_duplicates with_restful_routing :messages do - routes = ActionController::Routing::Routes.routes + routes = ActionDispatch::Routing::Routes.routes routes.each do |route| routes.each do |r| next if route === r # skip the comparison instance diff --git a/actionpack/test/controller/test_test.rb b/actionpack/test/controller/test_test.rb index 0f074b32e6..3f5d60540f 100644 --- a/actionpack/test/controller/test_test.rb +++ b/actionpack/test/controller/test_test.rb @@ -476,8 +476,8 @@ XML end def test_with_routing_places_routes_back - assert ActionController::Routing::Routes - routes_id = ActionController::Routing::Routes.object_id + assert ActionDispatch::Routing::Routes + routes_id = ActionDispatch::Routing::Routes.object_id begin with_routing { raise 'fail' } @@ -485,8 +485,8 @@ XML rescue RuntimeError end - assert ActionController::Routing::Routes - assert_equal routes_id, ActionController::Routing::Routes.object_id + assert ActionDispatch::Routing::Routes + assert_equal routes_id, ActionDispatch::Routing::Routes.object_id end def test_remote_addr diff --git a/actionpack/test/controller/webservice_test.rb b/actionpack/test/controller/webservice_test.rb index 5882a8cfa3..ede48017cf 100644 --- a/actionpack/test/controller/webservice_test.rb +++ b/actionpack/test/controller/webservice_test.rb @@ -245,7 +245,7 @@ class WebServiceTest < ActionController::IntegrationTest private def with_params_parsers(parsers = {}) old_session = @integration_session - @app = ActionDispatch::ParamsParser.new(ActionController::Routing::Routes, parsers) + @app = ActionDispatch::ParamsParser.new(ActionDispatch::Routing::Routes, parsers) reset! yield ensure diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb index 0cd1fddff1..e29127f78f 100644 --- a/actionpack/test/dispatch/routing_test.rb +++ b/actionpack/test/dispatch/routing_test.rb @@ -728,14 +728,14 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest private def with_test_routes - real_routes, temp_routes = ActionController::Routing::Routes, Routes + real_routes, temp_routes = ActionDispatch::Routing::Routes, Routes - ActionController::Routing.module_eval { remove_const :Routes } - ActionController::Routing.module_eval { const_set :Routes, temp_routes } + ActionDispatch::Routing.module_eval { remove_const :Routes } + ActionDispatch::Routing.module_eval { const_set :Routes, temp_routes } yield ensure - ActionController::Routing.module_eval { remove_const :Routes } - ActionController::Routing.const_set(:Routes, real_routes) + ActionDispatch::Routing.module_eval { remove_const :Routes } + ActionDispatch::Routing.const_set(:Routes, real_routes) end end -- cgit v1.2.3 From d92e8554921b7ab1906fd657325f395413cbdb30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Mon, 22 Feb 2010 13:13:26 +0100 Subject: Include missing modules. --- actionpack/lib/action_controller/metal/redirecting.rb | 1 + actionpack/lib/action_controller/metal/rendering.rb | 2 +- actionpack/lib/action_view/base.rb | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/redirecting.rb b/actionpack/lib/action_controller/metal/redirecting.rb index faf0589fd2..25e4e18493 100644 --- a/actionpack/lib/action_controller/metal/redirecting.rb +++ b/actionpack/lib/action_controller/metal/redirecting.rb @@ -11,6 +11,7 @@ module ActionController extend ActiveSupport::Concern include AbstractController::Logger + include ActionController::RackDelegation include ActionController::UrlFor # Redirects the browser to the target specified in +options+. This parameter can take one of three forms: diff --git a/actionpack/lib/action_controller/metal/rendering.rb b/actionpack/lib/action_controller/metal/rendering.rb index b1dab8497b..6518a464e2 100644 --- a/actionpack/lib/action_controller/metal/rendering.rb +++ b/actionpack/lib/action_controller/metal/rendering.rb @@ -2,7 +2,7 @@ module ActionController module Rendering extend ActiveSupport::Concern - include RackDelegation + include ActionController::RackDelegation include AbstractController::Rendering include AbstractController::LocalizedCache diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 4096c296c3..44e5870131 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -11,7 +11,7 @@ module ActionView #:nodoc: def initialize(paths, path, details, partial) @path = path - display_paths = paths.compact.join(":") + display_paths = paths.compact.map{ |p| p.to_s.inspect }.join(", ") template_type = if partial "partial" elsif path =~ /layouts/i @@ -20,7 +20,7 @@ module ActionView #:nodoc: 'template' end - super("Missing #{template_type} #{path} with #{details.inspect} in view path #{display_paths}") + super("Missing #{template_type} #{path} with #{details.inspect} in view paths #{display_paths}") end end -- cgit v1.2.3 From 35e0975af8b6b50b16de4d0bf96559f46b1d1155 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Mon, 22 Feb 2010 13:58:29 +0100 Subject: Rename erubis_implementation to erb_implementation. --- actionpack/lib/action_view/template/handlers/erb.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/template/handlers/erb.rb b/actionpack/lib/action_view/template/handlers/erb.rb index 4573a440d1..4b7cec50f3 100644 --- a/actionpack/lib/action_view/template/handlers/erb.rb +++ b/actionpack/lib/action_view/template/handlers/erb.rb @@ -43,13 +43,13 @@ module ActionView self.default_format = Mime::HTML - cattr_accessor :erubis_implementation - self.erubis_implementation = Erubis + cattr_accessor :erb_implementation + self.erb_implementation = Erubis def compile(template) source = template.source.gsub(/\A(<%(#.*coding[:=]\s*(\S+)\s*)-?%>)\s*\n?/, '') erb = "<% __in_erb_template=true %>#{source}" - result = self.class.erubis_implementation.new(erb, :trim=>(self.class.erb_trim_mode == "-")).src + result = self.class.erb_implementation.new(erb, :trim=>(self.class.erb_trim_mode == "-")).src result = "#{$2}\n#{result}" if $2 result end -- cgit v1.2.3 From 3345af61fb128d0a70793b235e3cb878781d6f40 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Tue, 23 Feb 2010 15:37:17 -0800 Subject: Fix streaming by having it create a File object, which can be handled by Rack servers as appropriate --- actionpack/lib/action_controller/metal/streaming.rb | 20 ++++++-------------- actionpack/lib/action_controller/metal/testing.rb | 1 - actionpack/test/controller/send_file_test.rb | 14 +++++++++++--- 3 files changed, 17 insertions(+), 18 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/streaming.rb b/actionpack/lib/action_controller/metal/streaming.rb index 8f03b8bb17..0d6fdafe0a 100644 --- a/actionpack/lib/action_controller/metal/streaming.rb +++ b/actionpack/lib/action_controller/metal/streaming.rb @@ -79,6 +79,8 @@ module ActionController #:nodoc: # http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9 # for the Cache-Control header spec. def send_file(path, options = {}) #:doc: + # self.response_body = File.open(path) + raise MissingFile, "Cannot read file #{path}" unless File.file?(path) and File.readable?(path) options[:length] ||= File.size(path) @@ -90,19 +92,9 @@ module ActionController #:nodoc: if options[:x_sendfile] head options[:status], X_SENDFILE_HEADER => path else - if options[:stream] - # TODO : Make render :text => proc {} work with the new base - render :status => options[:status], :text => Proc.new { |response, output| - len = options[:buffer_size] || 4096 - File.open(path, 'rb') do |file| - while buf = file.read(len) - output.write(buf) - end - end - } - else - File.open(path, 'rb') { |file| render :status => options[:status], :text => file.read } - end + self.status = options[:status] || 200 + self.content_type = options[:content_type] if options.key?(:content_type) + self.response_body = File.open(path, "rb") end end @@ -139,7 +131,7 @@ module ActionController #:nodoc: # instead. See ActionController::Base#render for more information. def send_data(data, options = {}) #:doc: send_file_headers! options.merge(:length => data.bytesize) - render :status => options[:status], :text => data + render options.slice(:status, :content_type).merge(:text => data) end private diff --git a/actionpack/lib/action_controller/metal/testing.rb b/actionpack/lib/action_controller/metal/testing.rb index 707ad968f4..4b8c452d50 100644 --- a/actionpack/lib/action_controller/metal/testing.rb +++ b/actionpack/lib/action_controller/metal/testing.rb @@ -13,7 +13,6 @@ module ActionController if cookies = @_request.env['action_dispatch.cookies'] cookies.write(@_response) end - @_response.body ||= self.response_body @_response.prepare! set_test_assigns ret diff --git a/actionpack/test/controller/send_file_test.rb b/actionpack/test/controller/send_file_test.rb index 31177223e4..ce144cc24b 100644 --- a/actionpack/test/controller/send_file_test.rb +++ b/actionpack/test/controller/send_file_test.rb @@ -46,15 +46,17 @@ class SendFileTest < ActionController::TestCase response = nil assert_nothing_raised { response = process('file') } assert_not_nil response - assert_kind_of String, response.body - assert_equal file_data, response.body + body = response.body + assert_kind_of String, body + assert_equal file_data, body end def test_file_stream response = nil assert_nothing_raised { response = process('file') } assert_not_nil response - assert_kind_of Array, response.body_parts + assert response.body_parts.respond_to?(:each) + assert response.body_parts.respond_to?(:to_path) require 'stringio' output = StringIO.new @@ -160,6 +162,12 @@ class SendFileTest < ActionController::TestCase assert_equal 500, @response.status end + define_method "test_send_#{method}_content_type" do + @controller.options = { :stream => false, :content_type => "application/x-ruby" } + assert_nothing_raised { assert_not_nil process(method) } + assert_equal "application/x-ruby", @response.content_type + end + define_method "test_default_send_#{method}_status" do @controller.options = { :stream => false } assert_nothing_raised { assert_not_nil process(method) } -- cgit v1.2.3 From a73f682e43016de520510e015802c48c9947a05c Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Tue, 23 Feb 2010 16:29:29 -0800 Subject: Make AD::Response correctly handle bodies that respond_to?(:to_path) as per the Rack spec --- actionpack/lib/action_dispatch/http/response.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/http/response.rb b/actionpack/lib/action_dispatch/http/response.rb index 1b8dd9abfd..e6ed28742f 100644 --- a/actionpack/lib/action_dispatch/http/response.rb +++ b/actionpack/lib/action_dispatch/http/response.rb @@ -82,6 +82,18 @@ module ActionDispatch # :nodoc: end alias_method :status_message, :message + def respond_to?(method) + if method.to_sym == :to_path + @body.respond_to?(:to_path) + else + super + end + end + + def to_path + @body.to_path + end + def body str = '' each { |part| str << part.to_s } -- cgit v1.2.3 From 5e2bd08023344f3fd4675e80203a10967ffe9000 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Tue, 23 Feb 2010 17:03:06 -0800 Subject: Makes send_file work again by deferring to Rack::Sendfile. * Add the Rack::Sendfile middleware * Make the header to use configurable via config.action_dispatch.x_sendfile_header (default to "X-Sendfile"). * Add Railties tests to confirm that these work * Remove the :stream, :buffer_size, and :x_senfile default options to send_file * Change the log subscriber to always say "Sent file" * Add deprecation warnings for options that are now no-ops Note that servers can configure this by setting X-Sendfile-Type. Hosting companies and those creating packages of servers specially designed for Rails applications are encouraged to specify this header so that this can work transparently. --- .../lib/action_controller/metal/streaming.rb | 57 ++++++++-------------- .../action_controller/railties/log_subscriber.rb | 10 +--- actionpack/lib/action_dispatch/railtie.rb | 2 + actionpack/test/controller/log_subscriber_test.rb | 4 +- actionpack/test/controller/send_file_test.rb | 23 --------- 5 files changed, 24 insertions(+), 72 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/streaming.rb b/actionpack/lib/action_controller/metal/streaming.rb index 0d6fdafe0a..753af3dc58 100644 --- a/actionpack/lib/action_controller/metal/streaming.rb +++ b/actionpack/lib/action_controller/metal/streaming.rb @@ -9,18 +9,13 @@ module ActionController #:nodoc: DEFAULT_SEND_FILE_OPTIONS = { :type => 'application/octet-stream'.freeze, :disposition => 'attachment'.freeze, - :stream => true, - :buffer_size => 4096, - :x_sendfile => false }.freeze - X_SENDFILE_HEADER = 'X-Sendfile'.freeze - protected - # Sends the file, by default streaming it 4096 bytes at a time. This way the - # whole file doesn't need to be read into memory at once. This makes it - # feasible to send even large files. You can optionally turn off streaming - # and send the whole file at once. + # Sends the file. This uses a server-appropriate method (such as X-Sendfile) + # via the Rack::Sendfile middleware. The header to use is set via + # config.action_dispatch.x_sendfile_header, and defaults to "X-Sendfile". + # Your server can also configure this for you by setting the X-Sendfile-Type header. # # Be careful to sanitize the path parameter if it is coming from a web # page. send_file(params[:path]) allows a malicious user to @@ -31,24 +26,12 @@ module ActionController #:nodoc: # Defaults to File.basename(path). # * :type - specifies an HTTP content type. Defaults to 'application/octet-stream'. You can specify # either a string or a symbol for a registered type register with Mime::Type.register, for example :json - # * :length - used to manually override the length (in bytes) of the content that - # is going to be sent to the client. Defaults to File.size(path). # * :disposition - specifies whether the file will be shown inline or downloaded. # Valid values are 'inline' and 'attachment' (default). - # * :stream - whether to send the file to the user agent as it is read (+true+) - # or to read the entire file before sending (+false+). Defaults to +true+. - # * :buffer_size - specifies size (in bytes) of the buffer used to stream the file. - # Defaults to 4096. # * :status - specifies the status code to send with the response. Defaults to '200 OK'. # * :url_based_filename - set to +true+ if you want the browser guess the filename from # the URL, which is necessary for i18n filenames on certain browsers # (setting :filename overrides this option). - # * :x_sendfile - uses X-Sendfile to send the file when set to +true+. This is currently - # only available with Lighttpd/Apache2 and specific modules installed and activated. Since this - # uses the web server to send the file, this may lower memory consumption on your server and - # it will not block your application for further requests. - # See http://blog.lighttpd.net/articles/2006/07/02/x-sendfile and - # http://tn123.ath.cx/mod_xsendfile/ for details. Defaults to +false+. # # The default Content-Type and Content-Disposition headers are # set to download arbitrary binary files in as many browsers as @@ -79,23 +62,18 @@ module ActionController #:nodoc: # http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9 # for the Cache-Control header spec. def send_file(path, options = {}) #:doc: - # self.response_body = File.open(path) - raise MissingFile, "Cannot read file #{path}" unless File.file?(path) and File.readable?(path) - options[:length] ||= File.size(path) options[:filename] ||= File.basename(path) unless options[:url_based_filename] send_file_headers! options - @performed_render = false - if options[:x_sendfile] - head options[:status], X_SENDFILE_HEADER => path - else - self.status = options[:status] || 200 - self.content_type = options[:content_type] if options.key?(:content_type) - self.response_body = File.open(path, "rb") + ActiveSupport::Deprecation.warn(":x_sendfile is no longer needed in send_file", caller) end + + self.status = options[:status] || 200 + self.content_type = options[:content_type] if options.key?(:content_type) + self.response_body = File.open(path, "rb") end # Sends the given binary data to the browser. This method is similar to @@ -130,32 +108,35 @@ module ActionController #:nodoc: # data to the browser, then use render :text => proc { ... } # instead. See ActionController::Base#render for more information. def send_data(data, options = {}) #:doc: - send_file_headers! options.merge(:length => data.bytesize) + send_file_headers! options.dup render options.slice(:status, :content_type).merge(:text => data) end private def send_file_headers!(options) options.update(DEFAULT_SEND_FILE_OPTIONS.merge(options)) - [:length, :type, :disposition].each do |arg| + [:type, :disposition].each do |arg| raise ArgumentError, ":#{arg} option required" if options[arg].nil? end - disposition = options[:disposition].dup || 'attachment' + if options.key?(:length) + ActiveSupport::Deprecation.warn("You do not need to provide the file's length", caller) + end - disposition <<= %(; filename="#{options[:filename]}") if options[:filename] + disposition = options[:disposition] + disposition += %(; filename="#{options[:filename]}") if options[:filename] content_type = options[:type] if content_type.is_a?(Symbol) - raise ArgumentError, "Unknown MIME type #{options[:type]}" unless Mime::EXTENSION_LOOKUP.key?(content_type.to_s) - self.content_type = Mime::Type.lookup_by_extension(content_type.to_s) + extension = Mime[content_type] + raise ArgumentError, "Unknown MIME type #{options[:type]}" unless extension + self.content_type = extension else self.content_type = content_type end headers.merge!( - 'Content-Length' => options[:length].to_s, 'Content-Disposition' => disposition, 'Content-Transfer-Encoding' => 'binary' ) diff --git a/actionpack/lib/action_controller/railties/log_subscriber.rb b/actionpack/lib/action_controller/railties/log_subscriber.rb index df9ffa1717..c2299d0b05 100644 --- a/actionpack/lib/action_controller/railties/log_subscriber.rb +++ b/actionpack/lib/action_controller/railties/log_subscriber.rb @@ -22,15 +22,7 @@ module ActionController end def send_file(event) - message = if event.payload[:x_sendfile] - header = ActionController::Streaming::X_SENDFILE_HEADER - "Sent #{header} header %s" - elsif event.payload[:stream] - "Streamed file %s" - else - "Sent file %s" - end - + message = "Sent file %s" message << " (%.1fms)" info(message % [event.payload[:path], event.duration]) end diff --git a/actionpack/lib/action_dispatch/railtie.rb b/actionpack/lib/action_dispatch/railtie.rb index 335daafc01..79e9464337 100644 --- a/actionpack/lib/action_dispatch/railtie.rb +++ b/actionpack/lib/action_dispatch/railtie.rb @@ -5,6 +5,8 @@ module ActionDispatch class Railtie < Rails::Railtie railtie_name :action_dispatch + config.action_dispatch.x_sendfile_header = "X-Sendfile" + # Prepare dispatcher callbacks and run 'prepare' callbacks initializer "action_dispatch.prepare_dispatcher" do |app| # TODO: This used to say unless defined?(Dispatcher). Find out why and fix. diff --git a/actionpack/test/controller/log_subscriber_test.rb b/actionpack/test/controller/log_subscriber_test.rb index 0659a4520e..5a3a2dd3ea 100644 --- a/actionpack/test/controller/log_subscriber_test.rb +++ b/actionpack/test/controller/log_subscriber_test.rb @@ -137,11 +137,11 @@ class ACLogSubscriberTest < ActionController::TestCase end def test_send_xfile - get :xfile_sender + assert_deprecated { get :xfile_sender } wait assert_equal 3, logs.size - assert_match /Sent X\-Sendfile header/, logs[1] + assert_match /Sent file/, logs[1] assert_match /test\/fixtures\/company\.rb/, logs[1] end diff --git a/actionpack/test/controller/send_file_test.rb b/actionpack/test/controller/send_file_test.rb index ce144cc24b..30c9a65b7c 100644 --- a/actionpack/test/controller/send_file_test.rb +++ b/actionpack/test/controller/send_file_test.rb @@ -74,18 +74,6 @@ class SendFileTest < ActionController::TestCase assert_equal "attachment", response.headers["Content-Disposition"] end - def test_x_sendfile_header - @controller.options = { :x_sendfile => true } - - response = nil - assert_nothing_raised { response = process('file') } - assert_not_nil response - - assert_equal @controller.file_path, response.headers['X-Sendfile'] - assert response.body.blank? - assert !response.etag? - end - def test_data response = nil assert_nothing_raised { response = process('data') } @@ -106,7 +94,6 @@ class SendFileTest < ActionController::TestCase # Test that send_file_headers! is setting the correct HTTP headers. def test_send_file_headers_bang options = { - :length => 1, :type => Mime::PNG, :disposition => 'disposition', :filename => 'filename' @@ -121,7 +108,6 @@ class SendFileTest < ActionController::TestCase @controller.send(:send_file_headers!, options) h = @controller.headers - assert_equal '1', h['Content-Length'] assert_equal 'image/png', @controller.content_type assert_equal 'disposition; filename="filename"', h['Content-Disposition'] assert_equal 'binary', h['Content-Transfer-Encoding'] @@ -134,7 +120,6 @@ class SendFileTest < ActionController::TestCase def test_send_file_headers_with_mime_lookup_with_symbol options = { - :length => 1, :type => :png } @@ -147,7 +132,6 @@ class SendFileTest < ActionController::TestCase def test_send_file_headers_with_bad_symbol options = { - :length => 1, :type => :this_type_is_not_registered } @@ -174,11 +158,4 @@ class SendFileTest < ActionController::TestCase assert_equal 200, @response.status end end - - def test_send_data_content_length_header - @controller.headers = {} - @controller.options = { :type => :text, :filename => 'file_with_utf8_text' } - process('multibyte_text_data') - assert_equal '29', @controller.headers['Content-Length'] - end end -- cgit v1.2.3 From 24ab5665b2f12a589e96a4b742cc49c08bf0e9df Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Tue, 23 Feb 2010 17:31:17 -0800 Subject: Revert "Fix test load paths for those not using bundler" This reverts commit eec2d301d4ce9df9c71c1a5aa63053eb970b6818. This commit broke tests. You cannot have a file called "bundler" on the load path. --- actionpack/test/abstract_unit.rb | 8 +------- actionpack/test/activerecord/controller_runtime_test.rb | 7 ++----- actionpack/test/controller/log_subscriber_test.rb | 3 --- actionpack/test/template/log_subscriber_test.rb | 5 +---- 4 files changed, 4 insertions(+), 19 deletions(-) (limited to 'actionpack') diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb index 7b41db3fea..8be212c8ab 100644 --- a/actionpack/test/abstract_unit.rb +++ b/actionpack/test/abstract_unit.rb @@ -1,10 +1,4 @@ -require File.expand_path('../../../bundler', __FILE__) - -lib = File.expand_path("#{File.dirname(__FILE__)}/../lib") -$:.unshift(lib) unless $:.include?('lib') || $:.include?(lib) - -activemodel_path = File.expand_path('../../../activemodel/lib', __FILE__) -$:.unshift(activemodel_path) if File.directory?(activemodel_path) && !$:.include?(activemodel_path) +require File.expand_path('../../../load_paths', __FILE__) $:.unshift(File.dirname(__FILE__) + '/lib') $:.unshift(File.dirname(__FILE__) + '/fixtures/helpers') diff --git a/actionpack/test/activerecord/controller_runtime_test.rb b/actionpack/test/activerecord/controller_runtime_test.rb index ee5fbdb0ae..d089830857 100644 --- a/actionpack/test/activerecord/controller_runtime_test.rb +++ b/actionpack/test/activerecord/controller_runtime_test.rb @@ -1,6 +1,3 @@ -railties_path = File.expand_path('../../../../railties/lib', __FILE__) -$:.unshift(railties_path) if File.directory?(railties_path) && !$:.include?(railties_path) - require 'active_record_unit' require 'active_record/railties/controller_runtime' require 'fixtures/project' @@ -15,7 +12,7 @@ class ControllerRuntimeLogSubscriberTest < ActionController::TestCase render :inline => "<%= Project.all %>" end end - + include Rails::LogSubscriber::TestHelper tests LogSubscriberController @@ -42,4 +39,4 @@ class ControllerRuntimeLogSubscriberTest < ActionController::TestCase assert_equal 2, @logger.logged(:info).size assert_match /\(Views: [\d\.]+ms | ActiveRecord: [\d\.]+ms\)/, @logger.logged(:info)[1] end -end +end \ No newline at end of file diff --git a/actionpack/test/controller/log_subscriber_test.rb b/actionpack/test/controller/log_subscriber_test.rb index 5a3a2dd3ea..668d6ae5ea 100644 --- a/actionpack/test/controller/log_subscriber_test.rb +++ b/actionpack/test/controller/log_subscriber_test.rb @@ -1,6 +1,3 @@ -railties_path = File.expand_path('../../../../railties/lib', __FILE__) -$:.unshift(railties_path) if File.directory?(railties_path) && !$:.include?(railties_path) - require "abstract_unit" require "rails/log_subscriber/test_helper" require "action_controller/railties/log_subscriber" diff --git a/actionpack/test/template/log_subscriber_test.rb b/actionpack/test/template/log_subscriber_test.rb index f370810e81..2eb2484cf5 100644 --- a/actionpack/test/template/log_subscriber_test.rb +++ b/actionpack/test/template/log_subscriber_test.rb @@ -1,6 +1,3 @@ -railties_path = File.expand_path('../../../../railties/lib', __FILE__) -$:.unshift(railties_path) if File.directory?(railties_path) && !$:.include?(railties_path) - require "abstract_unit" require "rails/log_subscriber/test_helper" require "action_view/railties/log_subscriber" @@ -93,4 +90,4 @@ class AVLogSubscriberTest < ActiveSupport::TestCase assert_equal 1, @logger.logged(:info).size assert_match /Rendered collection/, @logger.logged(:info).last end -end +end \ No newline at end of file -- cgit v1.2.3 From ae933a093db93c22b9facd3411afd9ef69719193 Mon Sep 17 00:00:00 2001 From: Yehuda Katz Date: Tue, 23 Feb 2010 22:45:42 -0800 Subject: Fix render :file => "#{Rails.root}/public/404.html", :status => :not_found. Closes #8994 --- actionpack/lib/action_view/template/resolver.rb | 2 +- actionpack/test/controller/render_test.rb | 9 +++++++++ actionpack/test/fixtures/hello.html | 1 + 3 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 actionpack/test/fixtures/hello.html (limited to 'actionpack') diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb index 8acfe6cad0..20402f9d6d 100644 --- a/actionpack/lib/action_view/template/resolver.rb +++ b/actionpack/lib/action_view/template/resolver.rb @@ -20,7 +20,7 @@ module ActionView register_detail(:locale) { [I18n.locale] } register_detail(:formats) { Mime::SET.symbols } - register_detail(:handlers, :allow_nil => false) do + register_detail(:handlers) do Template::Handlers.extensions end diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb index 3cc22cc316..ecfe14b797 100644 --- a/actionpack/test/controller/render_test.rb +++ b/actionpack/test/controller/render_test.rb @@ -21,6 +21,10 @@ class TestController < ActionController::Base def hello_world end + def hello_world_file + render :file => File.expand_path("../../fixtures/hello.html", __FILE__) + end + def conditional_hello if stale?(:last_modified => Time.now.utc.beginning_of_day, :etag => [:foo, 123]) render :action => 'hello_world' @@ -751,6 +755,11 @@ class RenderTest < ActionController::TestCase assert_equal "The secret is in the sauce\n", @response.body end + def test_render_file + get :hello_world_file + assert_equal "Hello world!", @response.body + end + # :ported: def test_render_file_as_string_with_instance_variables get :render_file_as_string_with_instance_variables diff --git a/actionpack/test/fixtures/hello.html b/actionpack/test/fixtures/hello.html new file mode 100644 index 0000000000..6769dd60bd --- /dev/null +++ b/actionpack/test/fixtures/hello.html @@ -0,0 +1 @@ +Hello world! \ No newline at end of file -- cgit v1.2.3 From 60ca754b97f1254eebd61da08fb2f58f298fec31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 24 Feb 2010 15:45:33 +0100 Subject: Remove the renderer option from the hash. --- actionpack/lib/action_controller/metal/renderers.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/renderers.rb b/actionpack/lib/action_controller/metal/renderers.rb index 639b508746..49d3d6b466 100644 --- a/actionpack/lib/action_controller/metal/renderers.rb +++ b/actionpack/lib/action_controller/metal/renderers.rb @@ -19,7 +19,7 @@ module ActionController <<-RUBY_EVAL if options.key?(:#{name}) _process_options(options) - return _render_option_#{name}(options[:#{name}], options) + return _render_option_#{name}(options.delete(:#{name}), options) end RUBY_EVAL end -- cgit v1.2.3 From 6a061187e26f0942c458a859c8e941ed092a48c1 Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Tue, 23 Feb 2010 19:53:52 -0800 Subject: Remove ActionController::Base.resources_path_names --- .../lib/action_controller/metal/compatibility.rb | 2 -- .../lib/action_dispatch/routing/deprecated_mapper.rb | 15 ++++++++------- actionpack/test/controller/resources_test.rb | 19 ++++++++++--------- 3 files changed, 18 insertions(+), 18 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb index 136b024d9e..2b1ada1426 100644 --- a/actionpack/lib/action_controller/metal/compatibility.rb +++ b/actionpack/lib/action_controller/metal/compatibility.rb @@ -20,8 +20,6 @@ module ActionController class << self delegate :default_charset=, :to => "ActionDispatch::Response" - delegate :resources_path_names, :to => "ActionDispatch::Routing::Routes" - delegate :resources_path_names=, :to => "ActionDispatch::Routing::Routes" end # cattr_reader :protected_instance_variables diff --git a/actionpack/lib/action_dispatch/routing/deprecated_mapper.rb b/actionpack/lib/action_dispatch/routing/deprecated_mapper.rb index 8ce6b2f6d5..1417a9d8c0 100644 --- a/actionpack/lib/action_dispatch/routing/deprecated_mapper.rb +++ b/actionpack/lib/action_dispatch/routing/deprecated_mapper.rb @@ -244,14 +244,15 @@ module ActionDispatch attr_reader :collection_methods, :member_methods, :new_methods attr_reader :path_prefix, :name_prefix, :path_segment attr_reader :plural, :singular - attr_reader :options + attr_reader :options, :defaults - def initialize(entities, options) + def initialize(entities, options, defaults) @plural ||= entities @singular ||= options[:singular] || plural.to_s.singularize @path_segment = options.delete(:as) || @plural @options = options + @defaults = defaults arrange_actions add_default_actions @@ -280,7 +281,7 @@ module ActionDispatch def new_path new_action = self.options[:path_names][:new] if self.options[:path_names] - new_action ||= ActionController::Base.resources_path_names[:new] + new_action ||= self.defaults[:path_names][:new] @new_path ||= "#{path}/#{new_action}" end @@ -370,7 +371,7 @@ module ActionDispatch end class SingletonResource < Resource #:nodoc: - def initialize(entity, options) + def initialize(entity, options, defaults) @singular = @plural = entity options[:controller] ||= @singular.to_s.pluralize super @@ -717,7 +718,7 @@ module ActionDispatch private def map_resource(entities, options = {}, &block) - resource = Resource.new(entities, options) + resource = Resource.new(entities, options, :path_names => @set.resources_path_names) with_options :controller => resource.controller do |map| map_associations(resource, options) @@ -734,7 +735,7 @@ module ActionDispatch end def map_singleton_resource(entities, options = {}, &block) - resource = SingletonResource.new(entities, options) + resource = SingletonResource.new(entities, options, :path_names => @set.resources_path_names) with_options :controller => resource.controller do |map| map_associations(resource, options) @@ -826,7 +827,7 @@ module ActionDispatch actions.each do |action| [method].flatten.each do |m| action_path = resource.options[:path_names][action] if resource.options[:path_names].is_a?(Hash) - action_path ||= ActionController::Base.resources_path_names[action] || action + action_path ||= @set.resources_path_names[action] || action map_resource_routes(map, resource, action, "#{resource.member_path}#{resource.action_separator}#{action_path}", "#{action}_#{resource.shallow_name_prefix}#{resource.singular}", m, { :force_id => true }) end diff --git a/actionpack/test/controller/resources_test.rb b/actionpack/test/controller/resources_test.rb index 9b3f466e44..cce98ac482 100644 --- a/actionpack/test/controller/resources_test.rb +++ b/actionpack/test/controller/resources_test.rb @@ -31,10 +31,10 @@ end class ResourcesTest < ActionController::TestCase def test_should_arrange_actions - resource = ActionDispatch::Routing::DeprecatedMapper::Resource.new(:messages, + resource = ActionDispatch::Routing::DeprecatedMapper::Resource.new(:messages, { :collection => { :rss => :get, :reorder => :post, :csv => :post }, :member => { :rss => :get, :atom => :get, :upload => :post, :fix => :post }, - :new => { :preview => :get, :draft => :get }) + :new => { :preview => :get, :draft => :get }}, {}) assert_resource_methods [:rss], resource, :collection, :get assert_resource_methods [:csv, :reorder], resource, :collection, :post @@ -44,18 +44,18 @@ class ResourcesTest < ActionController::TestCase end def test_should_resource_controller_name_equal_resource_name_by_default - resource = ActionDispatch::Routing::DeprecatedMapper::Resource.new(:messages, {}) + resource = ActionDispatch::Routing::DeprecatedMapper::Resource.new(:messages, {}, {}) assert_equal 'messages', resource.controller end def test_should_resource_controller_name_equal_controller_option - resource = ActionDispatch::Routing::DeprecatedMapper::Resource.new(:messages, :controller => 'posts') + resource = ActionDispatch::Routing::DeprecatedMapper::Resource.new(:messages, {:controller => 'posts'}, {}) assert_equal 'posts', resource.controller end def test_should_all_singleton_paths_be_the_same [ :path, :nesting_path_prefix, :member_path ].each do |method| - resource = ActionDispatch::Routing::DeprecatedMapper::SingletonResource.new(:messages, :path_prefix => 'admin') + resource = ActionDispatch::Routing::DeprecatedMapper::SingletonResource.new(:messages, {:path_prefix => 'admin'}, {}) assert_equal 'admin/messages', resource.send(method) end end @@ -111,8 +111,8 @@ class ResourcesTest < ActionController::TestCase end def test_override_paths_for_default_restful_actions - resource = ActionDispatch::Routing::DeprecatedMapper::Resource.new(:messages, - :path_names => {:new => 'nuevo', :edit => 'editar'}) + resource = ActionDispatch::Routing::DeprecatedMapper::Resource.new(:messages, { + :path_names => {:new => 'nuevo', :edit => 'editar'}}, {}) assert_equal resource.new_path, "#{resource.path}/nuevo" end @@ -1162,8 +1162,9 @@ class ResourcesTest < ActionController::TestCase options[:shallow_options] = options[:options] end - new_action = ActionController::Base.resources_path_names[:new] || "new" - edit_action = ActionController::Base.resources_path_names[:edit] || "edit" + new_action = ActionDispatch::Routing::Routes.resources_path_names[:new] || "new" + edit_action = ActionDispatch::Routing::Routes.resources_path_names[:edit] || "edit" + if options[:path_names] new_action = options[:path_names][:new] if options[:path_names][:new] edit_action = options[:path_names][:edit] if options[:path_names][:edit] -- cgit v1.2.3 From a39c7505bd69e9da0a122fbb8fe20612390c57ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 24 Feb 2010 19:17:24 +0100 Subject: Cleanup render callstack and make render(:json => {}, :status => 401) work again. --- .../lib/action_controller/metal/rendering.rb | 37 ++++++++-------------- actionpack/test/controller/render_json_test.rb | 10 ++++++ 2 files changed, 24 insertions(+), 23 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/rendering.rb b/actionpack/lib/action_controller/metal/rendering.rb index 6518a464e2..b90c054e98 100644 --- a/actionpack/lib/action_controller/metal/rendering.rb +++ b/actionpack/lib/action_controller/metal/rendering.rb @@ -12,21 +12,13 @@ module ActionController end def render(*args) - if response_body - raise ::AbstractController::DoubleRenderError - end - + raise ::AbstractController::DoubleRenderError if response_body args << {} unless args.last.is_a?(Hash) super(*args) self.content_type ||= args.last[:_template].mime_type.to_s response_body end - def render_to_body(options) - _process_options(options) - super - end - private def _render_partial(options) @@ -35,24 +27,10 @@ module ActionController super end - def _determine_template(options) - if options.key?(:text) && options[:text].respond_to?(:to_text) - options[:text] = options[:text].to_text - end - super - end - def format_for_text formats.first end - def _process_options(options) - status, content_type, location = options.values_at(:status, :content_type, :location) - self.status = status if status - self.content_type = content_type if content_type - self.headers["Location"] = url_for(location) if location - end - def _normalize_options(action=nil, options={}, &blk) case action when NilClass @@ -64,12 +42,25 @@ module ActionController options.merge! :partial => action end + if options.key?(:text) && options[:text].respond_to?(:to_text) + options[:text] = options[:text].to_text + end + if options[:status] options[:status] = Rack::Utils.status_code(options[:status]) end options[:update] = blk if block_given? + + _process_options(options) options end + + def _process_options(options) + status, content_type, location = options.values_at(:status, :content_type, :location) + self.status = status if status + self.content_type = content_type if content_type + self.headers["Location"] = url_for(location) if location + end end end diff --git a/actionpack/test/controller/render_json_test.rb b/actionpack/test/controller/render_json_test.rb index 3938fc7061..2580ada88b 100644 --- a/actionpack/test/controller/render_json_test.rb +++ b/actionpack/test/controller/render_json_test.rb @@ -18,6 +18,10 @@ class RenderJsonTest < ActionController::TestCase render :json => ActiveSupport::JSON.encode(:hello => 'world') end + def render_json_hello_world_with_status + render :json => ActiveSupport::JSON.encode(:hello => 'world'), :status => 401 + end + def render_json_hello_world_with_callback render :json => ActiveSupport::JSON.encode(:hello => 'world'), :callback => 'alert' end @@ -58,6 +62,12 @@ class RenderJsonTest < ActionController::TestCase assert_equal 'application/json', @response.content_type end + def test_render_json_with_status + get :render_json_hello_world_with_status + assert_equal '{"hello":"world"}', @response.body + assert_equal 401, @response.status + end + def test_render_json_with_callback get :render_json_hello_world_with_callback assert_equal 'alert({"hello":"world"})', @response.body -- cgit v1.2.3 From df85ab41c1ff6992dd462a0e63dac9dcdcee0348 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 24 Feb 2010 22:06:24 +0100 Subject: Renamed LocalizedCache to DetailsCache. --- actionpack/lib/abstract_controller.rb | 2 +- .../lib/abstract_controller/details_cache.rb | 48 ++++++++++++++++++ .../lib/abstract_controller/localized_cache.rb | 49 ------------------- actionpack/lib/abstract_controller/rendering.rb | 10 ++-- .../lib/action_controller/metal/rendering.rb | 2 +- actionpack/lib/action_view/base.rb | 2 +- actionpack/test/abstract/details_cache_test.rb | 57 ++++++++++++++++++++++ actionpack/test/abstract/localized_cache_test.rb | 57 ---------------------- 8 files changed, 115 insertions(+), 112 deletions(-) create mode 100644 actionpack/lib/abstract_controller/details_cache.rb delete mode 100644 actionpack/lib/abstract_controller/localized_cache.rb create mode 100644 actionpack/test/abstract/details_cache_test.rb delete mode 100644 actionpack/test/abstract/localized_cache_test.rb (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller.rb b/actionpack/lib/abstract_controller.rb index 1e15ab090c..1944e42ef1 100644 --- a/actionpack/lib/abstract_controller.rb +++ b/actionpack/lib/abstract_controller.rb @@ -13,9 +13,9 @@ module AbstractController autoload :Callbacks autoload :Collector autoload :Compatibility + autoload :DetailsCache autoload :Helpers autoload :Layouts - autoload :LocalizedCache autoload :Logger autoload :Rendering autoload :Translation diff --git a/actionpack/lib/abstract_controller/details_cache.rb b/actionpack/lib/abstract_controller/details_cache.rb new file mode 100644 index 0000000000..5b87b41e7d --- /dev/null +++ b/actionpack/lib/abstract_controller/details_cache.rb @@ -0,0 +1,48 @@ +module AbstractController + class HashKey + @hash_keys = Hash.new {|h,k| h[k] = {} } + + def self.get(klass, details) + @hash_keys[klass][details] ||= new(klass, details) + end + + attr_reader :hash + alias_method :eql?, :equal? + + def initialize(klass, details) + @details, @hash = details, details.hash + end + + def inspect + "#" + end + end + + module DetailsCache + extend ActiveSupport::Concern + + module ClassMethods + def clear_template_caches! + ActionView::Partials::PartialRenderer::TEMPLATES.clear + template_cache.clear + super + end + + def template_cache + @template_cache ||= Hash.new {|h,k| h[k] = {} } + end + end + + def render_to_body(*args) + Thread.current[:format_locale_key] = HashKey.get(self.class, _details_defaults) + super + end + + private + + def with_template_cache(name, details) + self.class.template_cache[HashKey.get(self.class, details)][name] ||= super + end + + end +end diff --git a/actionpack/lib/abstract_controller/localized_cache.rb b/actionpack/lib/abstract_controller/localized_cache.rb deleted file mode 100644 index 5e3efa002c..0000000000 --- a/actionpack/lib/abstract_controller/localized_cache.rb +++ /dev/null @@ -1,49 +0,0 @@ -module AbstractController - class HashKey - @hash_keys = Hash.new {|h,k| h[k] = Hash.new {|sh,sk| sh[sk] = {} } } - - def self.get(klass, formats, locale) - @hash_keys[klass][formats][locale] ||= new(klass, formats, locale) - end - - attr_accessor :hash - def initialize(klass, formats, locale) - @formats, @locale = formats, locale - @hash = [formats, locale].hash - end - - alias_method :eql?, :equal? - - def inspect - "#" - end - end - - module LocalizedCache - extend ActiveSupport::Concern - - module ClassMethods - def clear_template_caches! - ActionView::Partials::PartialRenderer::TEMPLATES.clear - template_cache.clear - super - end - - def template_cache - @template_cache ||= Hash.new {|h,k| h[k] = {} } - end - end - - def render(*args) - Thread.current[:format_locale_key] = HashKey.get(self.class, formats, I18n.locale) - super - end - - private - - def with_template_cache(name) - self.class.template_cache[Thread.current[:format_locale_key]][name] ||= super - end - - end -end diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb index f5c20e8013..14f51ae1bf 100644 --- a/actionpack/lib/abstract_controller/rendering.rb +++ b/actionpack/lib/abstract_controller/rendering.rb @@ -165,13 +165,17 @@ module AbstractController details = _normalize_details(options) - options[:_template] ||= with_template_cache(name) do + options[:_template] ||= with_template_cache(name, details) do find_template(name, details, options) end end + def _details_defaults + { :formats => formats, :locale => [I18n.locale] } + end + def _normalize_details(options) - details = { :formats => formats } + details = _details_defaults details[:formats] = Array(options[:format]) if options[:format] details[:locale] = Array(options[:locale]) if options[:locale] details @@ -185,7 +189,7 @@ module AbstractController view_paths.exists?(name, details, options[:_prefix], options[:_partial]) end - def with_template_cache(name) + def with_template_cache(name, details) yield end diff --git a/actionpack/lib/action_controller/metal/rendering.rb b/actionpack/lib/action_controller/metal/rendering.rb index b90c054e98..a026289ee5 100644 --- a/actionpack/lib/action_controller/metal/rendering.rb +++ b/actionpack/lib/action_controller/metal/rendering.rb @@ -4,7 +4,7 @@ module ActionController include ActionController::RackDelegation include AbstractController::Rendering - include AbstractController::LocalizedCache + include AbstractController::DetailsCache def process_action(*) self.formats = request.formats.map {|x| x.to_sym } diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 44e5870131..a61017ae11 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -196,7 +196,7 @@ module ActionView #:nodoc: # This is expensive, but we need to reset this when the format is updated, # which currently only happens Thread.current[:format_locale_key] = - AbstractController::HashKey.get(self.class, formats, I18n.locale) + AbstractController::HashKey.get(self.class, :formats => formats, :locale => [I18n.locale]) end end diff --git a/actionpack/test/abstract/details_cache_test.rb b/actionpack/test/abstract/details_cache_test.rb new file mode 100644 index 0000000000..ee746c1bb0 --- /dev/null +++ b/actionpack/test/abstract/details_cache_test.rb @@ -0,0 +1,57 @@ +require 'abstract_unit' + +module AbstractController + module Testing + + class CachedController < AbstractController::Base + include AbstractController::Rendering + include AbstractController::DetailsCache + + self.view_paths = [ActionView::FixtureResolver.new( + "default.erb" => "With Default", + "template.erb" => "With Template", + "some/file.erb" => "With File", + "template_name.erb" => "With Template Name" + )] + end + + class TestLocalizedCache < ActiveSupport::TestCase + + def setup + @controller = CachedController.new + CachedController.clear_template_caches! + end + + def test_templates_are_cached + @controller.render :template => "default.erb" + assert_equal "With Default", @controller.response_body + + cached = @controller.class.template_cache + assert_equal 1, cached.size + assert_kind_of ActionView::Template, cached.values.first["default.erb"] + end + + def test_cache_is_used + CachedController.new.render :template => "default.erb" + + @controller.expects(:find_template).never + @controller.render :template => "default.erb" + + assert_equal 1, @controller.class.template_cache.size + end + + def test_cache_changes_with_locale + CachedController.new.render :template => "default.erb" + + I18n.locale = :es + @controller.render :template => "default.erb" + + assert_equal 2, @controller.class.template_cache.size + ensure + I18n.locale = :en + end + + end + + end +end diff --git a/actionpack/test/abstract/localized_cache_test.rb b/actionpack/test/abstract/localized_cache_test.rb deleted file mode 100644 index 8b0b0fff03..0000000000 --- a/actionpack/test/abstract/localized_cache_test.rb +++ /dev/null @@ -1,57 +0,0 @@ -require 'abstract_unit' - -module AbstractController - module Testing - - class CachedController < AbstractController::Base - include AbstractController::Rendering - include AbstractController::LocalizedCache - - self.view_paths = [ActionView::FixtureResolver.new( - "default.erb" => "With Default", - "template.erb" => "With Template", - "some/file.erb" => "With File", - "template_name.erb" => "With Template Name" - )] - end - - class TestLocalizedCache < ActiveSupport::TestCase - - def setup - @controller = CachedController.new - CachedController.clear_template_caches! - end - - def test_templates_are_cached - @controller.render :template => "default.erb" - assert_equal "With Default", @controller.response_body - - cached = @controller.class.template_cache - assert_equal 1, cached.size - assert_kind_of ActionView::Template, cached.values.first["default.erb"] - end - - def test_cache_is_used - CachedController.new.render :template => "default.erb" - - @controller.expects(:find_template).never - @controller.render :template => "default.erb" - - assert_equal 1, @controller.class.template_cache.size - end - - def test_cache_changes_with_locale - CachedController.new.render :template => "default.erb" - - I18n.locale = :es - @controller.render :template => "default.erb" - - assert_equal 2, @controller.class.template_cache.size - ensure - I18n.locale = :en - end - - end - - end -end -- cgit v1.2.3 From f76eaa4b7c44e5793bb73f10f47989cff6be6ea3 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 24 Feb 2010 22:28:40 -0200 Subject: add time_separator for minutes only if minutes aren't hidden Signed-off-by: Jeremy Kemper --- actionpack/lib/action_view/helpers/date_helper.rb | 2 +- actionpack/test/template/date_helper_test.rb | 41 +++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb index c2810b3190..89ac682c18 100644 --- a/actionpack/lib/action_view/helpers/date_helper.rb +++ b/actionpack/lib/action_view/helpers/date_helper.rb @@ -907,7 +907,7 @@ module ActionView when :hour (@options[:discard_year] && @options[:discard_day]) ? "" : @options[:datetime_separator] when :minute - @options[:time_separator] + @options[:discard_minute] ? "" : @options[:time_separator] when :second @options[:include_seconds] ? @options[:time_separator] : "" end diff --git a/actionpack/test/template/date_helper_test.rb b/actionpack/test/template/date_helper_test.rb index fb51b67185..7d3075d232 100644 --- a/actionpack/test/template/date_helper_test.rb +++ b/actionpack/test/template/date_helper_test.rb @@ -2173,6 +2173,47 @@ class DateHelperTest < ActionView::TestCase assert_dom_equal expected, datetime_select("post", "updated_at", :discard_year => true, :discard_month => true) end + def test_datetime_select_discard_hour + @post = Post.new + @post.updated_at = Time.local(2004, 6, 15, 15, 16, 35) + + expected = %{\n" + expected << %{\n" + expected << %{\n" + + assert_dom_equal expected, datetime_select("post", "updated_at", :discard_hour => true) + end + + def test_datetime_select_discard_minute + @post = Post.new + @post.updated_at = Time.local(2004, 6, 15, 15, 16, 35) + + expected = %{\n" + expected << %{\n" + expected << %{\n" + + expected << " — " + + expected << %{\n" + expected << %{\n} + + assert_dom_equal expected, datetime_select("post", "updated_at", :discard_minute => true) + end + def test_datetime_select_invalid_order @post = Post.new @post.updated_at = Time.local(2004, 6, 15, 15, 16, 35) -- cgit v1.2.3 From f7b0a857e97304a5daeb47313759b9bf0d7e2fc9 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Thu, 25 Feb 2010 09:32:29 -0800 Subject: Use Object#singleton_class instead of #metaclass. Prefer Ruby's choice. --- actionpack/lib/action_dispatch/testing/integration.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb index f93059759b..14c7ff642b 100644 --- a/actionpack/lib/action_dispatch/testing/integration.rb +++ b/actionpack/lib/action_dispatch/testing/integration.rb @@ -1,6 +1,6 @@ require 'stringio' require 'uri' -require 'active_support/core_ext/object/metaclass' +require 'active_support/core_ext/object/singleton_class' require 'rack/test' module ActionDispatch @@ -187,7 +187,7 @@ module ActionDispatch unless defined? @named_routes_configured # install the named routes in this session instance. - klass = metaclass + klass = singleton_class ActionDispatch::Routing::Routes.install_helpers(klass) # the helpers are made protected by default--we make them public for -- cgit v1.2.3 From 66d537852b6c0357f391069c6d3b0b62c0722283 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Thu, 25 Feb 2010 15:06:11 -0800 Subject: Bump i18n for new public I18n.normalize_keys --- actionpack/lib/action_view/helpers/translation_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/translation_helper.rb b/actionpack/lib/action_view/helpers/translation_helper.rb index 7d954b3a2f..8a89ee58a0 100644 --- a/actionpack/lib/action_view/helpers/translation_helper.rb +++ b/actionpack/lib/action_view/helpers/translation_helper.rb @@ -15,7 +15,7 @@ module ActionView translation = I18n.translate(scope_key_by_partial(key), options) translation.is_a?(Array) ? translation.map { |entry| entry.html_safe } : translation.html_safe rescue I18n::MissingTranslationData => e - keys = I18n.send(:normalize_translation_keys, e.locale, e.key, e.options[:scope]) + keys = I18n.normalize_keys(e.locale, e.key, e.options[:scope]) content_tag('span', keys.join(', '), :class => 'translation_missing') end alias :t :translate -- cgit v1.2.3 From 226dfc2681c98deaf14e4ae82e973d1d5caedd68 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Wed, 24 Feb 2010 16:01:03 -0800 Subject: WIP: Remove the global router --- actionpack/lib/action_controller.rb | 2 +- actionpack/lib/action_controller/base.rb | 2 +- actionpack/lib/action_controller/deprecated.rb | 3 +- actionpack/lib/action_controller/metal/head.rb | 4 +- .../lib/action_controller/metal/redirecting.rb | 4 +- actionpack/lib/action_controller/metal/url_for.rb | 165 -------------------- actionpack/lib/action_controller/test_case.rb | 10 +- actionpack/lib/action_controller/url_rewriter.rb | 9 +- actionpack/lib/action_dispatch/routing.rb | 1 + .../lib/action_dispatch/routing/route_set.rb | 30 ++++ actionpack/lib/action_dispatch/routing/routes.rb | 2 +- actionpack/lib/action_dispatch/routing/url_for.rb | 167 +++++++++++++++++++++ .../action_dispatch/testing/assertions/routing.rb | 27 ++-- .../lib/action_dispatch/testing/integration.rb | 10 +- actionpack/lib/action_view/test_case.rb | 3 +- actionpack/test/abstract_unit.rb | 71 ++++++--- .../test/controller/action_pack_assertions_test.rb | 9 +- actionpack/test/controller/base_test.rb | 4 +- actionpack/test/controller/integration_test.rb | 11 +- actionpack/test/controller/rescue_test.rb | 4 +- actionpack/test/controller/resources_test.rb | 13 +- actionpack/test/controller/test_test.rb | 8 +- actionpack/test/controller/url_for_test.rb | 2 +- actionpack/test/controller/url_rewriter_test.rb | 32 ++-- actionpack/test/dispatch/routing_test.rb | 10 +- actionpack/test/template/test_case_test.rb | 2 +- 26 files changed, 342 insertions(+), 263 deletions(-) delete mode 100644 actionpack/lib/action_controller/metal/url_for.rb create mode 100644 actionpack/lib/action_dispatch/routing/url_for.rb (limited to 'actionpack') diff --git a/actionpack/lib/action_controller.rb b/actionpack/lib/action_controller.rb index 759e52b135..93d8fb612f 100644 --- a/actionpack/lib/action_controller.rb +++ b/actionpack/lib/action_controller.rb @@ -32,7 +32,7 @@ module ActionController autoload :SessionManagement autoload :Streaming autoload :Testing - autoload :UrlFor + # ROUTES TODO: Proxy UrlFor to Rails.application.routes.url_helpers autoload :Verification end diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index 7f1aa95f6f..0777d9dc16 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -9,7 +9,7 @@ module ActionController include ActionController::Helpers include ActionController::HideActions - include ActionController::UrlFor + # include ActionController::UrlFor include ActionController::Redirecting include ActionController::Rendering include ActionController::Renderers::All diff --git a/actionpack/lib/action_controller/deprecated.rb b/actionpack/lib/action_controller/deprecated.rb index 50c4058845..6088d97abe 100644 --- a/actionpack/lib/action_controller/deprecated.rb +++ b/actionpack/lib/action_controller/deprecated.rb @@ -1,4 +1,5 @@ ActionController::AbstractRequest = ActionController::Request = ActionDispatch::Request ActionController::AbstractResponse = ActionController::Response = ActionDispatch::Response ActionController::Routing = ActionDispatch::Routing -ActionController::UrlWriter = ActionController::UrlFor +# ROUTES TODO: Figure out how to deprecate this. +# ActionController::UrlWriter = ActionController::UrlFor diff --git a/actionpack/lib/action_controller/metal/head.rb b/actionpack/lib/action_controller/metal/head.rb index 37be8b3999..fe6e6186a5 100644 --- a/actionpack/lib/action_controller/metal/head.rb +++ b/actionpack/lib/action_controller/metal/head.rb @@ -1,7 +1,6 @@ module ActionController module Head extend ActiveSupport::Concern - include ActionController::UrlFor # Return a response that has no content (merely headers). The options # argument is interpreted to be a hash of header names and values. @@ -25,6 +24,9 @@ module ActionController end self.status = status + # ROUTES TODO: Figure out how to rescue from a no method error + # This is needed only if you wire up a controller yourself, and + # this not working would be baffling without a better error self.location = url_for(location) if location self.content_type = Mime[formats.first] self.response_body = " " diff --git a/actionpack/lib/action_controller/metal/redirecting.rb b/actionpack/lib/action_controller/metal/redirecting.rb index 25e4e18493..de40ea77b1 100644 --- a/actionpack/lib/action_controller/metal/redirecting.rb +++ b/actionpack/lib/action_controller/metal/redirecting.rb @@ -12,7 +12,6 @@ module ActionController include AbstractController::Logger include ActionController::RackDelegation - include ActionController::UrlFor # Redirects the browser to the target specified in +options+. This parameter can take one of three forms: # @@ -84,6 +83,9 @@ module ActionController raise RedirectBackError unless refer = request.headers["Referer"] refer else + # ROUTES TODO: Figure out how to rescue from a no method error + # This is needed only if you wire up a controller yourself, and + # this not working would be baffling without a better error url_for(options) end.gsub(/[\r\n]/, '') end diff --git a/actionpack/lib/action_controller/metal/url_for.rb b/actionpack/lib/action_controller/metal/url_for.rb deleted file mode 100644 index 0a9ea7fe1a..0000000000 --- a/actionpack/lib/action_controller/metal/url_for.rb +++ /dev/null @@ -1,165 +0,0 @@ -require 'active_support/core_ext/class/attribute' -require 'active_support/core_ext/module/attribute_accessors' - -module ActionController - # In routes.rb one defines URL-to-controller mappings, but the reverse - # is also possible: an URL can be generated from one of your routing definitions. - # URL generation functionality is centralized in this module. - # - # See ActionDispatch::Routing and ActionController::Resources for general - # information about routing and routes.rb. - # - # Tip: If you need to generate URLs from your models or some other place, - # then ActionController::UrlFor is what you're looking for. Read on for - # an introduction. - # - # == URL generation from parameters - # - # As you may know, some functions - such as ActionController::Base#url_for - # and ActionView::Helpers::UrlHelper#link_to, can generate URLs given a set - # of parameters. For example, you've probably had the chance to write code - # like this in one of your views: - # - # <%= link_to('Click here', :controller => 'users', - # :action => 'new', :message => 'Welcome!') %> - # - # #=> Generates a link to: /users/new?message=Welcome%21 - # - # link_to, and all other functions that require URL generation functionality, - # actually use ActionController::UrlFor under the hood. And in particular, - # they use the ActionController::UrlFor#url_for method. One can generate - # the same path as the above example by using the following code: - # - # include UrlFor - # url_for(:controller => 'users', - # :action => 'new', - # :message => 'Welcome!', - # :only_path => true) - # # => "/users/new?message=Welcome%21" - # - # Notice the :only_path => true part. This is because UrlFor has no - # information about the website hostname that your Rails app is serving. So if you - # want to include the hostname as well, then you must also pass the :host - # argument: - # - # include UrlFor - # url_for(:controller => 'users', - # :action => 'new', - # :message => 'Welcome!', - # :host => 'www.example.com') # Changed this. - # # => "http://www.example.com/users/new?message=Welcome%21" - # - # By default, all controllers and views have access to a special version of url_for, - # that already knows what the current hostname is. So if you use url_for in your - # controllers or your views, then you don't need to explicitly pass the :host - # argument. - # - # For convenience reasons, mailers provide a shortcut for ActionController::UrlFor#url_for. - # So within mailers, you only have to type 'url_for' instead of 'ActionController::UrlFor#url_for' - # in full. However, mailers don't have hostname information, and what's why you'll still - # have to specify the :host argument when generating URLs in mailers. - # - # - # == URL generation for named routes - # - # UrlFor also allows one to access methods that have been auto-generated from - # named routes. For example, suppose that you have a 'users' resource in your - # routes.rb: - # - # map.resources :users - # - # This generates, among other things, the method users_path. By default, - # this method is accessible from your controllers, views and mailers. If you need - # to access this auto-generated method from other places (such as a model), then - # you can do that by including ActionController::UrlFor in your class: - # - # class User < ActiveRecord::Base - # include ActionController::UrlFor - # - # def base_uri - # user_path(self) - # end - # end - # - # User.find(1).base_uri # => "/users/1" - # - module UrlFor - extend ActiveSupport::Concern - - included do - ActionDispatch::Routing::Routes.install_helpers(self) - - # Including in a class uses an inheritable hash. Modules get a plain hash. - if respond_to?(:class_attribute) - class_attribute :default_url_options - else - mattr_accessor :default_url_options - end - - self.default_url_options = {} - end - - # Overwrite to implement a number of default options that all url_for-based methods will use. The default options should come in - # the form of a hash, just like the one you would use for url_for directly. Example: - # - # def default_url_options(options) - # { :project => @project.active? ? @project.url_name : "unknown" } - # end - # - # As you can infer from the example, this is mostly useful for situations where you want to centralize dynamic decisions about the - # urls as they stem from the business domain. Please note that any individual url_for call can always override the defaults set - # by this method. - def default_url_options(options = nil) - self.class.default_url_options - end - - def rewrite_options(options) #:nodoc: - if options.delete(:use_defaults) != false && (defaults = default_url_options(options)) - defaults.merge(options) - else - options - end - end - - # Generate a url based on the options provided, default_url_options and the - # routes defined in routes.rb. The following options are supported: - # - # * :only_path - If true, the relative url is returned. Defaults to +false+. - # * :protocol - The protocol to connect to. Defaults to 'http'. - # * :host - Specifies the host the link should be targeted at. - # If :only_path is false, this option must be - # provided either explicitly, or via +default_url_options+. - # * :port - Optionally specify the port to connect to. - # * :anchor - An anchor name to be appended to the path. - # * :skip_relative_url_root - If true, the url is not constructed using the - # +relative_url_root+ set in ActionController::Base.relative_url_root. - # * :trailing_slash - If true, adds a trailing slash, as in "/archive/2009/" - # - # Any other key (:controller, :action, etc.) given to - # +url_for+ is forwarded to the Routes module. - # - # Examples: - # - # url_for :controller => 'tasks', :action => 'testing', :host=>'somehost.org', :port=>'8080' # => 'http://somehost.org:8080/tasks/testing' - # url_for :controller => 'tasks', :action => 'testing', :host=>'somehost.org', :anchor => 'ok', :only_path => true # => '/tasks/testing#ok' - # url_for :controller => 'tasks', :action => 'testing', :trailing_slash=>true # => 'http://somehost.org/tasks/testing/' - # url_for :controller => 'tasks', :action => 'testing', :host=>'somehost.org', :number => '33' # => 'http://somehost.org/tasks/testing?number=33' - def url_for(options = {}) - options ||= {} - case options - when String - options - when Hash - _url_rewriter.rewrite(rewrite_options(options)) - else - polymorphic_url(options) - end - end - - protected - - def _url_rewriter - ActionController::UrlRewriter - end - end -end diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb index 99924205dd..5f8bc6f325 100644 --- a/actionpack/lib/action_controller/test_case.rb +++ b/actionpack/lib/action_controller/test_case.rb @@ -17,9 +17,9 @@ module ActionController end end - def assign_parameters(controller_path, action, parameters = {}) + def assign_parameters(router, controller_path, action, parameters = {}) parameters = parameters.symbolize_keys.merge(:controller => controller_path, :action => action) - extra_keys = ActionDispatch::Routing::Routes.extra_keys(parameters) + extra_keys = router.extra_keys(parameters) non_path_parameters = get? ? query_parameters : request_parameters parameters.each do |key, value| if value.is_a? Fixnum @@ -220,7 +220,7 @@ module ActionController def process(action, parameters = nil, session = nil, flash = nil, http_method = 'GET') # Sanity check for required instance variables so we can give an # understandable error message. - %w(@controller @request @response).each do |iv_name| + %w(@router @controller @request @response).each do |iv_name| if !(instance_variable_names.include?(iv_name) || instance_variable_names.include?(iv_name.to_sym)) || instance_variable_get(iv_name).nil? raise "#{iv_name} is nil: make sure you set it in your test's setup method." end @@ -236,7 +236,7 @@ module ActionController @request.env['REQUEST_METHOD'] = http_method parameters ||= {} - @request.assign_parameters(@controller.class.name.underscore.sub(/_controller$/, ''), action.to_s, parameters) + @request.assign_parameters(@router, @controller.class.name.underscore.sub(/_controller$/, ''), action.to_s, parameters) @request.session = ActionController::TestSession.new(session) unless session.nil? @request.session["flash"] = @request.flash.update(flash || {}) @@ -340,7 +340,7 @@ module ActionController options.update(:only_path => true, :action => action) url = ActionController::UrlRewriter.new(@request, parameters) - @request.request_uri = url.rewrite(options) + @request.request_uri = url.rewrite(@router, options) end end end diff --git a/actionpack/lib/action_controller/url_rewriter.rb b/actionpack/lib/action_controller/url_rewriter.rb index 933a1fa8f9..272465d4f5 100644 --- a/actionpack/lib/action_controller/url_rewriter.rb +++ b/actionpack/lib/action_controller/url_rewriter.rb @@ -9,11 +9,11 @@ module ActionController @request, @parameters = request, parameters end - def rewrite(options = {}) + def rewrite(router, options = {}) options[:host] ||= @request.host_with_port options[:protocol] ||= @request.protocol - self.class.rewrite(options, @request.symbolized_path_parameters) do |options| + self.class.rewrite(router, options, @request.symbolized_path_parameters) do |options| process_path_options(options) end end @@ -24,7 +24,8 @@ module ActionController alias_method :to_s, :to_str - def self.rewrite(options, path_segments=nil) + # ROUTES TODO: Class method code smell + def self.rewrite(router, options, path_segments=nil) rewritten_url = "" unless options[:only_path] @@ -40,7 +41,7 @@ module ActionController path_options = options.except(*RESERVED_OPTIONS) path_options = yield(path_options) if block_given? - path = Routing::Routes.generate(path_options, path_segments || {}) + path = router.generate(path_options, path_segments || {}) rewritten_url << ActionController::Base.relative_url_root.to_s unless options[:skip_relative_url_root] rewritten_url << (options[:trailing_slash] ? path.sub(/\?|\z/) { "/" + $& } : path) diff --git a/actionpack/lib/action_dispatch/routing.rb b/actionpack/lib/action_dispatch/routing.rb index 325d2f7f04..2cc7fe5344 100644 --- a/actionpack/lib/action_dispatch/routing.rb +++ b/actionpack/lib/action_dispatch/routing.rb @@ -206,6 +206,7 @@ module ActionDispatch autoload :Route, 'action_dispatch/routing/route' autoload :Routes, 'action_dispatch/routing/routes' autoload :RouteSet, 'action_dispatch/routing/route_set' + autoload :UrlFor, 'action_dispatch/routing/url_for' SEPARATORS = %w( / . ? ) HTTP_METHODS = [:get, :head, :post, :put, :delete, :options] diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 8778fd2932..8b761d393f 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -272,6 +272,36 @@ module ActionDispatch named_routes.install(destinations, regenerate_code) end + # ROUTES TODO: Revisit the name of these methods + def url_helpers + @url_helpers ||= begin + router = self + Module.new do + extend ActiveSupport::Concern + include UrlFor + + define_method(:_router) { router } + end + end + end + + def named_url_helpers + @named_url_helpers ||= begin + router = self + + Module.new do + extend ActiveSupport::Concern + include router.url_helpers + + # ROUTES TODO: install_helpers isn't great... can we make a module with the stuff that + # we can include? + included do + router.install_helpers(self) + end + end + end + end + def empty? routes.empty? end diff --git a/actionpack/lib/action_dispatch/routing/routes.rb b/actionpack/lib/action_dispatch/routing/routes.rb index 4714556d36..34afada9c9 100644 --- a/actionpack/lib/action_dispatch/routing/routes.rb +++ b/actionpack/lib/action_dispatch/routing/routes.rb @@ -1,5 +1,5 @@ # A singleton that stores the current route set -ActionDispatch::Routing::Routes = ActionDispatch::Routing::RouteSet.new +# ActionDispatch::Routing::Routes = ActionDispatch::Routing::RouteSet.new # To preserve compatibility with pre-3.0 Rails action_controller/deprecated.rb # defines ActionDispatch::Routing::Routes as an alias diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb new file mode 100644 index 0000000000..64c695fe13 --- /dev/null +++ b/actionpack/lib/action_dispatch/routing/url_for.rb @@ -0,0 +1,167 @@ +module ActionDispatch + module Routing + # In routes.rb one defines URL-to-controller mappings, but the reverse + # is also possible: an URL can be generated from one of your routing definitions. + # URL generation functionality is centralized in this module. + # + # See ActionDispatch::Routing and ActionController::Resources for general + # information about routing and routes.rb. + # + # Tip: If you need to generate URLs from your models or some other place, + # then ActionController::UrlFor is what you're looking for. Read on for + # an introduction. + # + # == URL generation from parameters + # + # As you may know, some functions - such as ActionController::Base#url_for + # and ActionView::Helpers::UrlHelper#link_to, can generate URLs given a set + # of parameters. For example, you've probably had the chance to write code + # like this in one of your views: + # + # <%= link_to('Click here', :controller => 'users', + # :action => 'new', :message => 'Welcome!') %> + # + # #=> Generates a link to: /users/new?message=Welcome%21 + # + # link_to, and all other functions that require URL generation functionality, + # actually use ActionController::UrlFor under the hood. And in particular, + # they use the ActionController::UrlFor#url_for method. One can generate + # the same path as the above example by using the following code: + # + # include UrlFor + # url_for(:controller => 'users', + # :action => 'new', + # :message => 'Welcome!', + # :only_path => true) + # # => "/users/new?message=Welcome%21" + # + # Notice the :only_path => true part. This is because UrlFor has no + # information about the website hostname that your Rails app is serving. So if you + # want to include the hostname as well, then you must also pass the :host + # argument: + # + # include UrlFor + # url_for(:controller => 'users', + # :action => 'new', + # :message => 'Welcome!', + # :host => 'www.example.com') # Changed this. + # # => "http://www.example.com/users/new?message=Welcome%21" + # + # By default, all controllers and views have access to a special version of url_for, + # that already knows what the current hostname is. So if you use url_for in your + # controllers or your views, then you don't need to explicitly pass the :host + # argument. + # + # For convenience reasons, mailers provide a shortcut for ActionController::UrlFor#url_for. + # So within mailers, you only have to type 'url_for' instead of 'ActionController::UrlFor#url_for' + # in full. However, mailers don't have hostname information, and what's why you'll still + # have to specify the :host argument when generating URLs in mailers. + # + # + # == URL generation for named routes + # + # UrlFor also allows one to access methods that have been auto-generated from + # named routes. For example, suppose that you have a 'users' resource in your + # routes.rb: + # + # map.resources :users + # + # This generates, among other things, the method users_path. By default, + # this method is accessible from your controllers, views and mailers. If you need + # to access this auto-generated method from other places (such as a model), then + # you can do that by including ActionController::UrlFor in your class: + # + # class User < ActiveRecord::Base + # include ActionController::UrlFor + # + # def base_uri + # user_path(self) + # end + # end + # + # User.find(1).base_uri # => "/users/1" + # + module UrlFor + extend ActiveSupport::Concern + + included do + # ActionDispatch::Routing::Routes.install_helpers(self) + + # Including in a class uses an inheritable hash. Modules get a plain hash. + if respond_to?(:class_attribute) + class_attribute :default_url_options + else + mattr_accessor :default_url_options + end + + self.default_url_options = {} + end + + # Overwrite to implement a number of default options that all url_for-based methods will use. The default options should come in + # the form of a hash, just like the one you would use for url_for directly. Example: + # + # def default_url_options(options) + # { :project => @project.active? ? @project.url_name : "unknown" } + # end + # + # As you can infer from the example, this is mostly useful for situations where you want to centralize dynamic decisions about the + # urls as they stem from the business domain. Please note that any individual url_for call can always override the defaults set + # by this method. + def default_url_options(options = nil) + # ROUTES TODO: This should probably be an instance method + self.class.default_url_options + end + + def rewrite_options(options) #:nodoc: + if options.delete(:use_defaults) != false && (defaults = default_url_options(options)) + defaults.merge(options) + else + options + end + end + + # Generate a url based on the options provided, default_url_options and the + # routes defined in routes.rb. The following options are supported: + # + # * :only_path - If true, the relative url is returned. Defaults to +false+. + # * :protocol - The protocol to connect to. Defaults to 'http'. + # * :host - Specifies the host the link should be targeted at. + # If :only_path is false, this option must be + # provided either explicitly, or via +default_url_options+. + # * :port - Optionally specify the port to connect to. + # * :anchor - An anchor name to be appended to the path. + # * :skip_relative_url_root - If true, the url is not constructed using the + # +relative_url_root+ set in ActionController::Base.relative_url_root. + # * :trailing_slash - If true, adds a trailing slash, as in "/archive/2009/" + # + # Any other key (:controller, :action, etc.) given to + # +url_for+ is forwarded to the Routes module. + # + # Examples: + # + # url_for :controller => 'tasks', :action => 'testing', :host=>'somehost.org', :port=>'8080' # => 'http://somehost.org:8080/tasks/testing' + # url_for :controller => 'tasks', :action => 'testing', :host=>'somehost.org', :anchor => 'ok', :only_path => true # => '/tasks/testing#ok' + # url_for :controller => 'tasks', :action => 'testing', :trailing_slash=>true # => 'http://somehost.org/tasks/testing/' + # url_for :controller => 'tasks', :action => 'testing', :host=>'somehost.org', :number => '33' # => 'http://somehost.org/tasks/testing?number=33' + def url_for(options = {}) + options ||= {} + case options + when String + options + when Hash + _url_rewriter.rewrite(_router, rewrite_options(options)) + else + polymorphic_url(options) + end + end + + protected + + # ROUTES TODO: Figure out why _url_rewriter is sometimes the class and + # sometimes an instance. + def _url_rewriter + ActionController::UrlRewriter + end + end + end +end \ No newline at end of file diff --git a/actionpack/lib/action_dispatch/testing/assertions/routing.rb b/actionpack/lib/action_dispatch/testing/assertions/routing.rb index ada749bfe2..f281febbc5 100644 --- a/actionpack/lib/action_dispatch/testing/assertions/routing.rb +++ b/actionpack/lib/action_dispatch/testing/assertions/routing.rb @@ -80,7 +80,7 @@ module ActionDispatch expected_path = "/#{expected_path}" unless expected_path[0] == ?/ # Load routes.rb if it hasn't been loaded. - generated_path, extra_keys = ActionDispatch::Routing::Routes.generate_extras(options, defaults) + generated_path, extra_keys = @router.generate_extras(options, defaults) found_extras = options.reject {|k, v| ! extra_keys.include? k} msg = build_message(message, "found extras , not ", found_extras, extras) @@ -142,22 +142,21 @@ module ActionDispatch # end # def with_routing - real_routes = ActionDispatch::Routing::Routes - ActionDispatch::Routing.module_eval { remove_const :Routes } - - temporary_routes = ActionDispatch::Routing::RouteSet.new - ActionDispatch::Routing.module_eval { const_set :Routes, temporary_routes } - - yield temporary_routes + old_routes, @router = @router, ActionDispatch::Routing::RouteSet.new + old_controller, @controller = @controller, @controller.clone if @controller + # ROUTES TODO: Figure out this insanity + silence_warnings { ::ActionController.const_set(:UrlFor, @router.named_url_helpers) } + _router = @router + @controller.metaclass.send(:send, :include, @router.named_url_helpers) if @controller + yield @router ensure - if ActionDispatch::Routing.const_defined? :Routes - ActionDispatch::Routing.module_eval { remove_const :Routes } - end - ActionDispatch::Routing.const_set(:Routes, real_routes) if real_routes + @router = old_routes + @controller = old_controller if @controller + silence_warnings { ::ActionController.const_set(:UrlFor, @router.named_url_helpers) } if @router end def method_missing(selector, *args, &block) - if @controller && ActionDispatch::Routing::Routes.named_routes.helpers.include?(selector) + if @controller && @router.named_routes.helpers.include?(selector) @controller.send(selector, *args, &block) else super @@ -174,7 +173,7 @@ module ActionDispatch request.env["REQUEST_METHOD"] = request_method.to_s.upcase if request_method request.path = path - params = ActionDispatch::Routing::Routes.recognize_path(path, { :method => request.method }) + params = @router.recognize_path(path, { :method => request.method }) request.path_parameters = params.with_indifferent_access request diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb index 14c7ff642b..3b9d8b0318 100644 --- a/actionpack/lib/action_dispatch/testing/integration.rb +++ b/actionpack/lib/action_dispatch/testing/integration.rb @@ -188,11 +188,11 @@ module ActionDispatch unless defined? @named_routes_configured # install the named routes in this session instance. klass = singleton_class - ActionDispatch::Routing::Routes.install_helpers(klass) + # ActionDispatch::Routing::Routes.install_helpers(klass) # the helpers are made protected by default--we make them public for # easier access during testing and troubleshooting. - klass.module_eval { public *ActionDispatch::Routing::Routes.named_routes.helpers } + # klass.module_eval { public *ActionDispatch::Routing::Routes.named_routes.helpers } @named_routes_configured = true end end @@ -224,9 +224,13 @@ module ActionDispatch # Returns the URL for the given options, according to the rules specified # in the application's routes. def url_for(options) + # ROUTES TODO: @app.router is not guaranteed to exist, so a generic Rack + # application will not work here. This means that a generic Rack application + # integration test cannot call url_for, since the application will not have + # #router on it. controller ? controller.url_for(options) : - generic_url_rewriter.rewrite(options) + generic_url_rewriter.rewrite(SharedTestRoutes, options) end private diff --git a/actionpack/lib/action_view/test_case.rb b/actionpack/lib/action_view/test_case.rb index af2ed33f3f..f6f4e18a4a 100644 --- a/actionpack/lib/action_view/test_case.rb +++ b/actionpack/lib/action_view/test_case.rb @@ -53,6 +53,7 @@ module ActionView setup :setup_with_controller def setup_with_controller @controller = TestController.new + @router = SharedTestRoutes @output_buffer = ActiveSupport::SafeBuffer.new @rendered = '' @@ -152,7 +153,7 @@ module ActionView end def method_missing(selector, *args) - if ActionDispatch::Routing::Routes.named_routes.helpers.include?(selector) + if @router.named_routes.helpers.include?(selector) @controller.__send__(selector, *args) else super diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb index 8be212c8ab..846ac5f0d7 100644 --- a/actionpack/test/abstract_unit.rb +++ b/actionpack/test/abstract_unit.rb @@ -64,29 +64,50 @@ module SetupOnce end end -class ActiveSupport::TestCase - include SetupOnce - - # Hold off drawing routes until all the possible controller classes - # have been loaded. - setup_once do - ActionDispatch::Routing::Routes.draw do |map| - match ':controller(/:action(/:id))' +SharedTestRoutes = ActionDispatch::Routing::RouteSet.new + +module ActiveSupport + class TestCase + include SetupOnce + # Hold off drawing routes until all the possible controller classes + # have been loaded. + setup_once do + SharedTestRoutes.draw do |map| + match ':controller(/:action(/:id))' + end + + # ROUTES TODO: Don't do this here + # brodel :'( + ActionController::IntegrationTest.app.router.draw do + match ':controller(/:action(/:id))' + end end end end +class RoutedRackApp + attr_reader :router + + def initialize(router, &blk) + @router = router + @stack = ActionDispatch::MiddlewareStack.new(&blk).build(@router) + end + + def call(env) + @stack.call(env) + end +end + class ActionController::IntegrationTest < ActiveSupport::TestCase def self.build_app(routes = nil) - ActionDispatch::Flash - ActionDispatch::MiddlewareStack.new { |middleware| + RoutedRackApp.new(routes || ActionDispatch::Routing::RouteSet.new) do |middleware| middleware.use "ActionDispatch::ShowExceptions" middleware.use "ActionDispatch::Callbacks" middleware.use "ActionDispatch::ParamsParser" middleware.use "ActionDispatch::Cookies" middleware.use "ActionDispatch::Flash" middleware.use "ActionDispatch::Head" - }.build(routes || ActionDispatch::Routing::Routes) + end end self.app = build_app @@ -112,20 +133,15 @@ class ActionController::IntegrationTest < ActiveSupport::TestCase end def with_routing(&block) - real_routes = ActionDispatch::Routing::Routes - ActionDispatch::Routing.module_eval { remove_const :Routes } - temporary_routes = ActionDispatch::Routing::RouteSet.new - self.class.app = self.class.build_app(temporary_routes) - ActionDispatch::Routing.module_eval { const_set :Routes, temporary_routes } + old_app, self.class.app = self.class.app, self.class.build_app(temporary_routes) + old_routes = SharedTestRoutes + silence_warnings { Object.const_set(:SharedTestRoutes, temporary_routes) } yield temporary_routes ensure - if ActionDispatch::Routing.const_defined? :Routes - ActionDispatch::Routing.module_eval { remove_const :Routes } - end - ActionDispatch::Routing.const_set(:Routes, real_routes) if real_routes - self.class.app = self.class.build_app + self.class.app = old_app + silence_warnings { Object.const_set(:SharedTestRoutes, old_routes) } end end @@ -190,6 +206,11 @@ module ActionController class TestCase include ActionDispatch::TestProcess + setup do + # ROUTES TODO: The router object should come from somewhere sane + @router = SharedTestRoutes + end + def assert_template(options = {}, message = nil) validate_request! @@ -232,3 +253,11 @@ module ActionController end end end + +# ROUTES TODO: Cleaner way to do this? +module ActionController + UrlFor = SharedTestRoutes.named_url_helpers + class Base + include UrlFor + end +end \ No newline at end of file diff --git a/actionpack/test/controller/action_pack_assertions_test.rb b/actionpack/test/controller/action_pack_assertions_test.rb index d54be9bdc0..7c83a91f4d 100644 --- a/actionpack/test/controller/action_pack_assertions_test.rb +++ b/actionpack/test/controller/action_pack_assertions_test.rb @@ -253,12 +253,13 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase end def test_assert_redirect_to_nested_named_route + @controller = Admin::InnerModuleController.new + with_routing do |set| set.draw do |map| match 'admin/inner_module', :to => 'admin/inner_module#index', :as => :admin_inner_module match ':controller/:action' end - @controller = Admin::InnerModuleController.new process :redirect_to_index # redirection is <{"action"=>"index", "controller"=>"admin/admin/inner_module"}> assert_redirected_to admin_inner_module_path @@ -266,12 +267,13 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase end def test_assert_redirected_to_top_level_named_route_from_nested_controller + @controller = Admin::InnerModuleController.new + with_routing do |set| set.draw do |map| match '/action_pack_assertions/:id', :to => 'action_pack_assertions#index', :as => :top_level match ':controller/:action' end - @controller = Admin::InnerModuleController.new process :redirect_to_top_level_named_route # assert_redirected_to "http://test.host/action_pack_assertions/foo" would pass because of exact match early return assert_redirected_to "/action_pack_assertions/foo" @@ -279,13 +281,14 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase end def test_assert_redirected_to_top_level_named_route_with_same_controller_name_in_both_namespaces + @controller = Admin::InnerModuleController.new + with_routing do |set| set.draw do |map| # this controller exists in the admin namespace as well which is the only difference from previous test match '/user/:id', :to => 'user#index', :as => :top_level match ':controller/:action' end - @controller = Admin::InnerModuleController.new process :redirect_to_top_level_named_route # assert_redirected_to top_level_url('foo') would pass because of exact match early return assert_redirected_to top_level_path('foo') diff --git a/actionpack/test/controller/base_test.rb b/actionpack/test/controller/base_test.rb index 4fcfbacf4e..25006dda76 100644 --- a/actionpack/test/controller/base_test.rb +++ b/actionpack/test/controller/base_test.rb @@ -219,12 +219,14 @@ class EmptyUrlOptionsTest < ActionController::TestCase end def test_named_routes_with_path_without_doing_a_request_first + @controller = EmptyController.new + with_routing do |set| set.draw do |map| resources :things end - assert_equal '/things', EmptyController.new.send(:things_path) + assert_equal '/things', @controller.send(:things_path) end end end diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb index 683ab5236c..29531d237a 100644 --- a/actionpack/test/controller/integration_test.rb +++ b/actionpack/test/controller/integration_test.rb @@ -86,7 +86,7 @@ class SessionTest < Test::Unit::TestCase def test_url_for_without_controller options = {:action => 'show'} mock_rewriter = mock() - mock_rewriter.expects(:rewrite).with(options).returns('/show') + mock_rewriter.expects(:rewrite).with(SharedTestRoutes, options).returns('/show') @session.stubs(:generic_url_rewriter).returns(mock_rewriter) @session.stubs(:controller).returns(nil) assert_equal '/show', @session.url_for(options) @@ -401,9 +401,14 @@ class IntegrationProcessTest < ActionController::IntegrationTest private def with_test_route_set with_routing do |set| + controller = ::IntegrationProcessTest::IntegrationController.clone + controller.class_eval do + include set.named_url_helpers + end + set.draw do |map| - match ':action', :to => ::IntegrationProcessTest::IntegrationController - get 'get/:action', :to => ::IntegrationProcessTest::IntegrationController + match ':action', :to => controller + get 'get/:action', :to => controller end yield end diff --git a/actionpack/test/controller/rescue_test.rb b/actionpack/test/controller/rescue_test.rb index 118b563a72..dd991898a8 100644 --- a/actionpack/test/controller/rescue_test.rb +++ b/actionpack/test/controller/rescue_test.rb @@ -326,7 +326,7 @@ class RescueTest < ActionController::IntegrationTest end test 'rescue routing exceptions' do - @app = ActionDispatch::Rescue.new(ActionDispatch::Routing::Routes) do + @app = ActionDispatch::Rescue.new(SharedTestRoutes) do rescue_from ActionController::RoutingError, lambda { |env| [200, {"Content-Type" => "text/html"}, ["Gotcha!"]] } end @@ -335,7 +335,7 @@ class RescueTest < ActionController::IntegrationTest end test 'unrescued exception' do - @app = ActionDispatch::Rescue.new(ActionDispatch::Routing::Routes) + @app = ActionDispatch::Rescue.new(SharedTestRoutes) assert_raise(ActionController::RoutingError) { get '/b00m' } end diff --git a/actionpack/test/controller/resources_test.rb b/actionpack/test/controller/resources_test.rb index cce98ac482..6f3c16f588 100644 --- a/actionpack/test/controller/resources_test.rb +++ b/actionpack/test/controller/resources_test.rb @@ -125,7 +125,7 @@ class ResourcesTest < ActionController::TestCase def test_with_custom_conditions with_restful_routing :messages, :conditions => { :subdomain => 'app' } do - assert ActionDispatch::Routing::Routes.recognize_path("/messages", :method => :get, :subdomain => 'app') + assert @router.recognize_path("/messages", :method => :get, :subdomain => 'app') end end @@ -394,7 +394,7 @@ class ResourcesTest < ActionController::TestCase assert_restful_routes_for :messages do |options| assert_recognizes(options.merge(:action => "new"), :path => "/messages/new", :method => :get) assert_raise(ActionController::RoutingError) do - ActionDispatch::Routing::Routes.recognize_path("/messages/new", :method => :post) + @router.recognize_path("/messages/new", :method => :post) end end end @@ -504,7 +504,7 @@ class ResourcesTest < ActionController::TestCase def test_restful_routes_dont_generate_duplicates with_restful_routing :messages do - routes = ActionDispatch::Routing::Routes.routes + routes = @router.routes routes.each do |route| routes.each do |r| next if route === r # skip the comparison instance @@ -1162,8 +1162,8 @@ class ResourcesTest < ActionController::TestCase options[:shallow_options] = options[:options] end - new_action = ActionDispatch::Routing::Routes.resources_path_names[:new] || "new" - edit_action = ActionDispatch::Routing::Routes.resources_path_names[:edit] || "edit" + new_action = @router.resources_path_names[:new] || "new" + edit_action = @router.resources_path_names[:edit] || "edit" if options[:path_names] new_action = options[:path_names][:new] if options[:path_names][:new] @@ -1230,6 +1230,8 @@ class ResourcesTest < ActionController::TestCase end @controller = "#{options[:options][:controller].camelize}Controller".constantize.new + # ROUTES TODO: Figure out a way to not extend the routing helpers here + @controller.metaclass.send(:include, @router.named_url_helpers) @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new get :index, options[:options] @@ -1299,6 +1301,7 @@ class ResourcesTest < ActionController::TestCase def assert_singleton_named_routes_for(singleton_name, options = {}) (options[:options] ||= {})[:controller] ||= singleton_name.to_s.pluralize @controller = "#{options[:options][:controller].camelize}Controller".constantize.new + @controller.metaclass.send(:include, @router.named_url_helpers) @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new get :show, options[:options] diff --git a/actionpack/test/controller/test_test.rb b/actionpack/test/controller/test_test.rb index 3f5d60540f..d716dc2661 100644 --- a/actionpack/test/controller/test_test.rb +++ b/actionpack/test/controller/test_test.rb @@ -476,8 +476,8 @@ XML end def test_with_routing_places_routes_back - assert ActionDispatch::Routing::Routes - routes_id = ActionDispatch::Routing::Routes.object_id + assert @router + routes_id = @router.object_id begin with_routing { raise 'fail' } @@ -485,8 +485,8 @@ XML rescue RuntimeError end - assert ActionDispatch::Routing::Routes - assert_equal routes_id, ActionDispatch::Routing::Routes.object_id + assert @router + assert_equal routes_id, @router.object_id end def test_remote_addr diff --git a/actionpack/test/controller/url_for_test.rb b/actionpack/test/controller/url_for_test.rb index 749fa5861f..43e2f91693 100644 --- a/actionpack/test/controller/url_for_test.rb +++ b/actionpack/test/controller/url_for_test.rb @@ -5,7 +5,7 @@ module AbstractController class UrlForTests < ActionController::TestCase class W - include ActionController::UrlFor + include SharedTestRoutes.url_helpers end def teardown diff --git a/actionpack/test/controller/url_rewriter_test.rb b/actionpack/test/controller/url_rewriter_test.rb index c2b8cd85d8..199b824a7a 100644 --- a/actionpack/test/controller/url_rewriter_test.rb +++ b/actionpack/test/controller/url_rewriter_test.rb @@ -12,52 +12,52 @@ class UrlRewriterTests < ActionController::TestCase def test_port assert_equal('http://test.host:1271/c/a/i', - @rewriter.rewrite(:controller => 'c', :action => 'a', :id => 'i', :port => 1271) + @rewriter.rewrite(@router, :controller => 'c', :action => 'a', :id => 'i', :port => 1271) ) end def test_protocol_with_and_without_separator assert_equal('https://test.host/c/a/i', - @rewriter.rewrite(:protocol => 'https', :controller => 'c', :action => 'a', :id => 'i') + @rewriter.rewrite(@router, :protocol => 'https', :controller => 'c', :action => 'a', :id => 'i') ) assert_equal('https://test.host/c/a/i', - @rewriter.rewrite(:protocol => 'https://', :controller => 'c', :action => 'a', :id => 'i') + @rewriter.rewrite(@router, :protocol => 'https://', :controller => 'c', :action => 'a', :id => 'i') ) end def test_user_name_and_password assert_equal( 'http://david:secret@test.host/c/a/i', - @rewriter.rewrite(:user => "david", :password => "secret", :controller => 'c', :action => 'a', :id => 'i') + @rewriter.rewrite(@router, :user => "david", :password => "secret", :controller => 'c', :action => 'a', :id => 'i') ) end def test_user_name_and_password_with_escape_codes assert_equal( 'http://openid.aol.com%2Fnextangler:one+two%3F@test.host/c/a/i', - @rewriter.rewrite(:user => "openid.aol.com/nextangler", :password => "one two?", :controller => 'c', :action => 'a', :id => 'i') + @rewriter.rewrite(@router, :user => "openid.aol.com/nextangler", :password => "one two?", :controller => 'c', :action => 'a', :id => 'i') ) end def test_anchor assert_equal( 'http://test.host/c/a/i#anchor', - @rewriter.rewrite(:controller => 'c', :action => 'a', :id => 'i', :anchor => 'anchor') + @rewriter.rewrite(@router, :controller => 'c', :action => 'a', :id => 'i', :anchor => 'anchor') ) end def test_anchor_should_call_to_param assert_equal( 'http://test.host/c/a/i#anchor', - @rewriter.rewrite(:controller => 'c', :action => 'a', :id => 'i', :anchor => Struct.new(:to_param).new('anchor')) + @rewriter.rewrite(@router, :controller => 'c', :action => 'a', :id => 'i', :anchor => Struct.new(:to_param).new('anchor')) ) end def test_anchor_should_be_cgi_escaped assert_equal( 'http://test.host/c/a/i#anc%2Fhor', - @rewriter.rewrite(:controller => 'c', :action => 'a', :id => 'i', :anchor => Struct.new(:to_param).new('anc/hor')) + @rewriter.rewrite(@router, :controller => 'c', :action => 'a', :id => 'i', :anchor => Struct.new(:to_param).new('anc/hor')) ) end @@ -66,8 +66,8 @@ class UrlRewriterTests < ActionController::TestCase @params[:action] = 'bye' @params[:id] = '2' - assert_equal '/hi/hi/2', @rewriter.rewrite(:only_path => true, :overwrite_params => {:action => 'hi'}) - u = @rewriter.rewrite(:only_path => false, :overwrite_params => {:action => 'hi'}) + assert_equal '/hi/hi/2', @rewriter.rewrite(@router, :only_path => true, :overwrite_params => {:action => 'hi'}) + u = @rewriter.rewrite(@router, :only_path => false, :overwrite_params => {:action => 'hi'}) assert_match %r(/hi/hi/2$), u end @@ -76,8 +76,8 @@ class UrlRewriterTests < ActionController::TestCase @params[:action] = 'list' @params[:list_page] = 1 - assert_equal '/search/list?list_page=2', @rewriter.rewrite(:only_path => true, :overwrite_params => {"list_page" => 2}) - u = @rewriter.rewrite(:only_path => false, :overwrite_params => {:list_page => 2}) + assert_equal '/search/list?list_page=2', @rewriter.rewrite(@router, :only_path => true, :overwrite_params => {"list_page" => 2}) + u = @rewriter.rewrite(@router, :only_path => false, :overwrite_params => {:list_page => 2}) assert_equal 'http://test.host/search/list?list_page=2', u end @@ -91,12 +91,12 @@ class UrlRewriterTests < ActionController::TestCase def test_trailing_slash options = {:controller => 'foo', :action => 'bar', :id => '3', :only_path => true} - assert_equal '/foo/bar/3', @rewriter.rewrite(options) - assert_equal '/foo/bar/3?query=string', @rewriter.rewrite(options.merge({:query => 'string'})) + assert_equal '/foo/bar/3', @rewriter.rewrite(@router, options) + assert_equal '/foo/bar/3?query=string', @rewriter.rewrite(@router, options.merge({:query => 'string'})) options.update({:trailing_slash => true}) - assert_equal '/foo/bar/3/', @rewriter.rewrite(options) + assert_equal '/foo/bar/3/', @rewriter.rewrite(@router, options) options.update({:query => 'string'}) - assert_equal '/foo/bar/3/?query=string', @rewriter.rewrite(options) + assert_equal '/foo/bar/3/?query=string', @rewriter.rewrite(@router, options) end end diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb index e29127f78f..7cfc6ef3d7 100644 --- a/actionpack/test/dispatch/routing_test.rb +++ b/actionpack/test/dispatch/routing_test.rb @@ -164,6 +164,8 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest Routes end + include Routes.named_url_helpers + def test_logout with_test_routes do delete '/logout' @@ -728,14 +730,6 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest private def with_test_routes - real_routes, temp_routes = ActionDispatch::Routing::Routes, Routes - - ActionDispatch::Routing.module_eval { remove_const :Routes } - ActionDispatch::Routing.module_eval { const_set :Routes, temp_routes } - yield - ensure - ActionDispatch::Routing.module_eval { remove_const :Routes } - ActionDispatch::Routing.const_set(:Routes, real_routes) end end diff --git a/actionpack/test/template/test_case_test.rb b/actionpack/test/template/test_case_test.rb index be2c6b3108..12807baaa7 100644 --- a/actionpack/test/template/test_case_test.rb +++ b/actionpack/test/template/test_case_test.rb @@ -107,7 +107,7 @@ module ActionView end test "is able to use routes" do - controller.request.assign_parameters('foo', 'index') + controller.request.assign_parameters(@router, 'foo', 'index') assert_equal '/foo', url_for assert_equal '/bar', url_for(:controller => 'bar') end -- cgit v1.2.3 From 4b038f638d8c8969b2bccac82d0d7a370381680b Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Wed, 24 Feb 2010 16:01:32 -0800 Subject: Merge branch 'master' of github.com:rails/rails --- actionpack/test/controller/webservice_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/test/controller/webservice_test.rb b/actionpack/test/controller/webservice_test.rb index ede48017cf..05545395fb 100644 --- a/actionpack/test/controller/webservice_test.rb +++ b/actionpack/test/controller/webservice_test.rb @@ -245,7 +245,7 @@ class WebServiceTest < ActionController::IntegrationTest private def with_params_parsers(parsers = {}) old_session = @integration_session - @app = ActionDispatch::ParamsParser.new(ActionDispatch::Routing::Routes, parsers) + @app = ActionDispatch::ParamsParser.new(app.router, parsers) reset! yield ensure -- cgit v1.2.3 From a278f2331007411b190d65577082d2710ad9a996 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Wed, 24 Feb 2010 16:17:04 -0800 Subject: Fix all of AP's tests with the non global router --- actionpack/test/activerecord/polymorphic_routes_test.rb | 6 +++--- actionpack/test/controller/caching_test.rb | 6 ++++-- 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'actionpack') diff --git a/actionpack/test/activerecord/polymorphic_routes_test.rb b/actionpack/test/activerecord/polymorphic_routes_test.rb index 7be2ef7e29..a10bb4473e 100644 --- a/actionpack/test/activerecord/polymorphic_routes_test.rb +++ b/actionpack/test/activerecord/polymorphic_routes_test.rb @@ -400,7 +400,7 @@ class PolymorphicRoutesTest < ActionController::TestCase map.resources :series end - ActionDispatch::Routing::Routes.install_helpers(self.class) + self.class.send(:include, @router.named_url_helpers) yield end end @@ -422,7 +422,7 @@ class PolymorphicRoutesTest < ActionController::TestCase end end - ActionDispatch::Routing::Routes.install_helpers(self.class) + self.class.send(:include, @router.named_url_helpers) yield end end @@ -441,7 +441,7 @@ class PolymorphicRoutesTest < ActionController::TestCase end end - ActionDispatch::Routing::Routes.install_helpers(self.class) + self.class.send(:include, @router.named_url_helpers) yield end end diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index de92fc56fd..9c9d886f5d 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -74,9 +74,9 @@ class PageCachingTest < ActionController::TestCase match '/', :to => 'posts#index', :as => :main end @params[:format] = 'rss' - assert_equal '/posts.rss', @rewriter.rewrite(@params) + assert_equal '/posts.rss', @rewriter.rewrite(@router, @params) @params[:format] = nil - assert_equal '/', @rewriter.rewrite(@params) + assert_equal '/', @rewriter.rewrite(@router, @params) end end @@ -511,6 +511,8 @@ class ActionCacheTest < ActionController::TestCase @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new @controller = ActionCachingTestController.new + # ROUTES TODO: It seems bad to explicitly remix in the class + @controller.metaclass.send(:include, @router.named_url_helpers) @request.host = 'hostname.com' end -- cgit v1.2.3 From 36fd9efb5e4bfc9ac3acd4189d4dc457dea8102a Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Thu, 25 Feb 2010 15:05:10 -0800 Subject: Continued effort to deglobalize the router --- actionpack/lib/action_controller.rb | 2 +- actionpack/lib/action_controller/base.rb | 9 +----- actionpack/lib/action_controller/metal/url_for.rb | 21 +++++++++++++ actionpack/lib/action_controller/railtie.rb | 1 + actionpack/lib/action_controller/test_case.rb | 2 +- actionpack/lib/action_controller/url_rewriter.rb | 21 +++++++++++++ .../lib/action_dispatch/routing/route_set.rb | 23 ++++----------- actionpack/lib/action_dispatch/routing/url_for.rb | 31 +++++--------------- actionpack/test/controller/base_test.rb | 1 + actionpack/test/controller/routing_test.rb | 34 +++++----------------- 10 files changed, 66 insertions(+), 79 deletions(-) create mode 100644 actionpack/lib/action_controller/metal/url_for.rb (limited to 'actionpack') diff --git a/actionpack/lib/action_controller.rb b/actionpack/lib/action_controller.rb index 93d8fb612f..759e52b135 100644 --- a/actionpack/lib/action_controller.rb +++ b/actionpack/lib/action_controller.rb @@ -32,7 +32,7 @@ module ActionController autoload :SessionManagement autoload :Streaming autoload :Testing - # ROUTES TODO: Proxy UrlFor to Rails.application.routes.url_helpers + autoload :UrlFor autoload :Verification end diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index 0777d9dc16..f8ddc8da09 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -9,7 +9,7 @@ module ActionController include ActionController::Helpers include ActionController::HideActions - # include ActionController::UrlFor + include ActionController::UrlFor include ActionController::Redirecting include ActionController::Rendering include ActionController::Renderers::All @@ -82,12 +82,5 @@ module ActionController filter end - protected - - # Overwrite url rewriter to use request. - def _url_rewriter - return ActionController::UrlRewriter unless request - @_url_rewriter ||= ActionController::UrlRewriter.new(request, params) - end end end diff --git a/actionpack/lib/action_controller/metal/url_for.rb b/actionpack/lib/action_controller/metal/url_for.rb new file mode 100644 index 0000000000..013834ddee --- /dev/null +++ b/actionpack/lib/action_controller/metal/url_for.rb @@ -0,0 +1,21 @@ +module ActionController + module UrlFor + extend ActiveSupport::Concern + + include ActionDispatch::Routing::UrlFor + include ActionController::RackDelegation + + def merge_options(options) + super.reverse_merge( + :host => request.host_with_port, + :protocol => request.protocol, + :_path_segments => request.symbolized_path_parameters + ) + end + + def _router + raise "In order to use #url_for, you must include the helpers of a particular " \ + "router. For instance, `include Rails.application.router.named_url_helpers" + end + end +end \ No newline at end of file diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb index 015a8212c4..5a16d82e49 100644 --- a/actionpack/lib/action_controller/railtie.rb +++ b/actionpack/lib/action_controller/railtie.rb @@ -1,6 +1,7 @@ require "action_controller" require "rails" require "action_view/railtie" +require "active_support/core_ext/class/subclasses" module ActionController class Railtie < Rails::Railtie diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb index 5f8bc6f325..0fa2a8b90c 100644 --- a/actionpack/lib/action_controller/test_case.rb +++ b/actionpack/lib/action_controller/test_case.rb @@ -336,7 +336,7 @@ module ActionController private def build_request_uri(action, parameters) unless @request.env['REQUEST_URI'] - options = @controller.__send__(:rewrite_options, parameters) + options = @controller.__send__(:merge_options, parameters) options.update(:only_path => true, :action => action) url = ActionController::UrlRewriter.new(@request, parameters) diff --git a/actionpack/lib/action_controller/url_rewriter.rb b/actionpack/lib/action_controller/url_rewriter.rb index 272465d4f5..807b21cd0e 100644 --- a/actionpack/lib/action_controller/url_rewriter.rb +++ b/actionpack/lib/action_controller/url_rewriter.rb @@ -26,8 +26,14 @@ module ActionController # ROUTES TODO: Class method code smell def self.rewrite(router, options, path_segments=nil) + handle_positional_args(options) + rewritten_url = "" + # ROUTES TODO: Fix the tests + segments = options.delete(:_path_segments) + path_segments = path_segments ? path_segments.merge(segments || {}) : segments + unless options[:only_path] rewritten_url << (options[:protocol] || "http") rewritten_url << "://" unless rewritten_url.match("://") @@ -52,6 +58,21 @@ module ActionController protected + def self.handle_positional_args(options) + return unless args = options.delete(:_positional_args) + + keys = options.delete(:_positional_keys) + keys -= options.keys if args.size < keys.size - 1 # take format into account + + args = args.zip(keys).inject({}) do |h, (v, k)| + h[k] = v + h + end + + # Tell url_for to skip default_url_options + options.merge!(args) + end + def self.rewrite_authentication(options) if options[:user] && options[:password] "#{Rack::Utils.escape(options.delete(:user))}:#{Rack::Utils.escape(options.delete(:password))}@" diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 8b761d393f..7bfe4fa2bf 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -194,24 +194,11 @@ module ActionDispatch # end @module.module_eval <<-END_EVAL, __FILE__, __LINE__ + 1 def #{selector}(*args) - if args.empty? || Hash === args.first - options = #{hash_access_method}(args.first || {}) - else - options = #{hash_access_method}(args.extract_options!) - default = default_url_options(options) if self.respond_to?(:default_url_options, true) - options = (default ||= {}).merge(options) - - keys = #{route.segment_keys.inspect} - keys -= options.keys if args.size < keys.size - 1 # take format into account - - args = args.zip(keys).inject({}) do |h, (v, k)| - h[k] = v - h - end - - # Tell url_for to skip default_url_options - options[:use_defaults] = false - options.merge!(args) + options = #{hash_access_method}(args.extract_options!) + + if args.any? + options[:_positional_args] = args + options[:_positional_keys] = #{route.segment_keys.inspect} end url_for(options) diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb index 64c695fe13..1d6da817ed 100644 --- a/actionpack/lib/action_dispatch/routing/url_for.rb +++ b/actionpack/lib/action_dispatch/routing/url_for.rb @@ -85,8 +85,6 @@ module ActionDispatch extend ActiveSupport::Concern included do - # ActionDispatch::Routing::Routes.install_helpers(self) - # Including in a class uses an inheritable hash. Modules get a plain hash. if respond_to?(:class_attribute) class_attribute :default_url_options @@ -97,23 +95,16 @@ module ActionDispatch self.default_url_options = {} end - # Overwrite to implement a number of default options that all url_for-based methods will use. The default options should come in - # the form of a hash, just like the one you would use for url_for directly. Example: - # - # def default_url_options(options) - # { :project => @project.active? ? @project.url_name : "unknown" } - # end - # - # As you can infer from the example, this is mostly useful for situations where you want to centralize dynamic decisions about the - # urls as they stem from the business domain. Please note that any individual url_for call can always override the defaults set - # by this method. def default_url_options(options = nil) - # ROUTES TODO: This should probably be an instance method self.class.default_url_options end - def rewrite_options(options) #:nodoc: - if options.delete(:use_defaults) != false && (defaults = default_url_options(options)) + def url_options + self.class.default_url_options.merge + end + + def merge_options(options) #:nodoc: + if options.delete(:use_defaults) != false && respond_to?(:default_url_options) && (defaults = default_url_options(options)) defaults.merge(options) else options @@ -149,19 +140,11 @@ module ActionDispatch when String options when Hash - _url_rewriter.rewrite(_router, rewrite_options(options)) + ActionController::UrlRewriter.rewrite(_router, merge_options(options)) else polymorphic_url(options) end end - - protected - - # ROUTES TODO: Figure out why _url_rewriter is sometimes the class and - # sometimes an instance. - def _url_rewriter - ActionController::UrlRewriter - end end end end \ No newline at end of file diff --git a/actionpack/test/controller/base_test.rb b/actionpack/test/controller/base_test.rb index 25006dda76..436ee212c8 100644 --- a/actionpack/test/controller/base_test.rb +++ b/actionpack/test/controller/base_test.rb @@ -220,6 +220,7 @@ class EmptyUrlOptionsTest < ActionController::TestCase def test_named_routes_with_path_without_doing_a_request_first @controller = EmptyController.new + @controller.request = @request with_routing do |set| set.draw do |map| diff --git a/actionpack/test/controller/routing_test.rb b/actionpack/test/controller/routing_test.rb index f390bbdc89..f2fccfbcfc 100644 --- a/actionpack/test/controller/routing_test.rb +++ b/actionpack/test/controller/routing_test.rb @@ -52,29 +52,11 @@ class UriReservedCharactersRoutingTest < Test::Unit::TestCase end class MockController - attr_accessor :routes - - def initialize(routes) - self.routes = routes - end - def url_for(options) - only_path = options.delete(:only_path) - - port = options.delete(:port) || 80 - port_string = port == 80 ? '' : ":#{port}" - - protocol = options.delete(:protocol) || "http" - host = options.delete(:host) || "test.host" - anchor = "##{options.delete(:anchor)}" if options.key?(:anchor) + options[:protocol] ||= "http" + options[:host] ||= "test.host" - path = routes.generate(options) - - only_path ? "#{path}#{anchor}" : "#{protocol}://#{host}#{port_string}#{path}#{anchor}" - end - - def request - @request ||= ActionController::TestRequest.new + super(options) end end @@ -268,9 +250,9 @@ class LegacyRouteSetTests < Test::Unit::TestCase end def setup_for_named_route - klass = Class.new(MockController) - rs.install_helpers(klass) - klass.new(rs) + inst = MockController.clone.new + inst.class.send(:include, rs.named_url_helpers) + inst end def test_named_route_without_hash @@ -759,9 +741,7 @@ class RouteSetTest < ActiveSupport::TestCase map.users '/admin/users', :controller => 'admin/users', :action => 'index' end - klass = Class.new(MockController) - set.install_helpers(klass) - klass.new(set) + MockController.clone.new.tap { |inst| inst.class.send(:include, set.named_url_helpers)} end def test_named_route_hash_access_method -- cgit v1.2.3 From fc4582fb6684ce72f5628629ea7d061659b790f8 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Thu, 25 Feb 2010 16:48:36 -0800 Subject: Final pass at removing the router from a global constant --- actionpack/lib/action_controller/railtie.rb | 10 ++++++++-- actionpack/lib/action_controller/railties/url_helpers.rb | 14 ++++++++++++++ actionpack/lib/action_dispatch/routing.rb | 1 - actionpack/lib/action_dispatch/routing/routes.rb | 5 ----- .../lib/action_dispatch/testing/assertions/routing.rb | 2 +- actionpack/lib/action_dispatch/testing/integration.rb | 2 -- actionpack/lib/action_view/helpers/atom_feed_helper.rb | 2 +- 7 files changed, 24 insertions(+), 12 deletions(-) create mode 100644 actionpack/lib/action_controller/railties/url_helpers.rb delete mode 100644 actionpack/lib/action_dispatch/routing/routes.rb (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb index 5a16d82e49..3df70d4a4d 100644 --- a/actionpack/lib/action_controller/railtie.rb +++ b/actionpack/lib/action_controller/railtie.rb @@ -1,5 +1,5 @@ -require "action_controller" require "rails" +require "action_controller" require "action_view/railtie" require "active_support/core_ext/class/subclasses" @@ -8,6 +8,8 @@ module ActionController railtie_name :action_controller require "action_controller/railties/log_subscriber" + require "action_controller/railties/url_helpers" + log_subscriber ActionController::Railties::LogSubscriber.new initializer "action_controller.logger" do @@ -27,5 +29,9 @@ module ActionController initializer "action_controller.set_helpers_path" do |app| ActionController::Base.helpers_path = app.config.paths.app.helpers.to_a end + + initializer "action_controller.url_helpers" do |app| + ActionController::Base.extend ::ActionController::Railtie::UrlHelpers.with(app.routes) + end end -end +end \ No newline at end of file diff --git a/actionpack/lib/action_controller/railties/url_helpers.rb b/actionpack/lib/action_controller/railties/url_helpers.rb new file mode 100644 index 0000000000..354d3fa898 --- /dev/null +++ b/actionpack/lib/action_controller/railties/url_helpers.rb @@ -0,0 +1,14 @@ +module ActionController + class Railtie + module UrlHelpers + def self.with(router) + Module.new do + define_method(:inherited) do |klass| + super + klass.send(:include, router.named_url_helpers) + end + end + end + end + end +end \ No newline at end of file diff --git a/actionpack/lib/action_dispatch/routing.rb b/actionpack/lib/action_dispatch/routing.rb index 2cc7fe5344..5bc3205c51 100644 --- a/actionpack/lib/action_dispatch/routing.rb +++ b/actionpack/lib/action_dispatch/routing.rb @@ -204,7 +204,6 @@ module ActionDispatch autoload :DeprecatedMapper, 'action_dispatch/routing/deprecated_mapper' autoload :Mapper, 'action_dispatch/routing/mapper' autoload :Route, 'action_dispatch/routing/route' - autoload :Routes, 'action_dispatch/routing/routes' autoload :RouteSet, 'action_dispatch/routing/route_set' autoload :UrlFor, 'action_dispatch/routing/url_for' diff --git a/actionpack/lib/action_dispatch/routing/routes.rb b/actionpack/lib/action_dispatch/routing/routes.rb deleted file mode 100644 index 34afada9c9..0000000000 --- a/actionpack/lib/action_dispatch/routing/routes.rb +++ /dev/null @@ -1,5 +0,0 @@ -# A singleton that stores the current route set -# ActionDispatch::Routing::Routes = ActionDispatch::Routing::RouteSet.new - -# To preserve compatibility with pre-3.0 Rails action_controller/deprecated.rb -# defines ActionDispatch::Routing::Routes as an alias diff --git a/actionpack/lib/action_dispatch/testing/assertions/routing.rb b/actionpack/lib/action_dispatch/testing/assertions/routing.rb index f281febbc5..17caa2e030 100644 --- a/actionpack/lib/action_dispatch/testing/assertions/routing.rb +++ b/actionpack/lib/action_dispatch/testing/assertions/routing.rb @@ -125,7 +125,7 @@ module ActionDispatch end # A helper to make it easier to test different route configurations. - # This method temporarily replaces ActionDispatch::Routing::Routes + # This method temporarily replaces @router # with a new RouteSet instance. # # The new instance is yielded to the passed block. Typically the block diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb index 3b9d8b0318..3bd9502e91 100644 --- a/actionpack/lib/action_dispatch/testing/integration.rb +++ b/actionpack/lib/action_dispatch/testing/integration.rb @@ -188,11 +188,9 @@ module ActionDispatch unless defined? @named_routes_configured # install the named routes in this session instance. klass = singleton_class - # ActionDispatch::Routing::Routes.install_helpers(klass) # the helpers are made protected by default--we make them public for # easier access during testing and troubleshooting. - # klass.module_eval { public *ActionDispatch::Routing::Routes.named_routes.helpers } @named_routes_configured = true end end diff --git a/actionpack/lib/action_view/helpers/atom_feed_helper.rb b/actionpack/lib/action_view/helpers/atom_feed_helper.rb index 4305a0d5f5..a26a8c9b4b 100644 --- a/actionpack/lib/action_view/helpers/atom_feed_helper.rb +++ b/actionpack/lib/action_view/helpers/atom_feed_helper.rb @@ -8,7 +8,7 @@ module ActionView # Full usage example: # # config/routes.rb: - # ActionDispatch::Routing::Routes.draw do |map| + # Basecamp::Application.routes.draw do |map| # map.resources :posts # map.root :controller => "posts" # end -- cgit v1.2.3 From 8760add31a0415b4635059cf7fadabc26946c0c2 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Thu, 25 Feb 2010 17:51:56 -0800 Subject: Get URL helpers working again in integration tests. --- actionpack/lib/action_controller/railtie.rb | 2 + .../lib/action_dispatch/testing/integration.rb | 48 +++++++++++----------- actionpack/test/controller/integration_test.rb | 24 ++++------- 3 files changed, 33 insertions(+), 41 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb index 3df70d4a4d..268301da64 100644 --- a/actionpack/lib/action_controller/railtie.rb +++ b/actionpack/lib/action_controller/railtie.rb @@ -32,6 +32,8 @@ module ActionController initializer "action_controller.url_helpers" do |app| ActionController::Base.extend ::ActionController::Railtie::UrlHelpers.with(app.routes) + ActionController::Routing::Routes = app.routes + ::SharedTestRoutes = app.routes end end end \ No newline at end of file diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb index 3bd9502e91..fb067601c8 100644 --- a/actionpack/lib/action_dispatch/testing/integration.rb +++ b/actionpack/lib/action_dispatch/testing/integration.rb @@ -219,17 +219,17 @@ module ActionDispatch @host = name end - # Returns the URL for the given options, according to the rules specified - # in the application's routes. - def url_for(options) - # ROUTES TODO: @app.router is not guaranteed to exist, so a generic Rack - # application will not work here. This means that a generic Rack application - # integration test cannot call url_for, since the application will not have - # #router on it. - controller ? - controller.url_for(options) : - generic_url_rewriter.rewrite(SharedTestRoutes, options) - end + # # Returns the URL for the given options, according to the rules specified + # # in the application's routes. + # def url_for(options) + # # ROUTES TODO: @app.router is not guaranteed to exist, so a generic Rack + # # application will not work here. This means that a generic Rack application + # # integration test cannot call url_for, since the application will not have + # # #router on it. + # controller ? + # controller.url_for(options) : + # generic_url_rewriter.rewrite(SharedTestRoutes, options) + # end private @@ -283,19 +283,6 @@ module ActionDispatch return response.status end - - # Get a temporary URL writer object - def generic_url_rewriter - env = { - 'REQUEST_METHOD' => "GET", - 'QUERY_STRING' => "", - "REQUEST_URI" => "/", - "HTTP_HOST" => host, - "SERVER_PORT" => https? ? "443" : "80", - "HTTPS" => https? ? "on" : "off" - } - ActionController::UrlRewriter.new(ActionDispatch::Request.new(env), {}) - end end module Runner @@ -367,6 +354,19 @@ module ActionDispatch end end + extend ActiveSupport::Concern + include ActionDispatch::Routing::UrlFor + + def merge_options(options) + opts = super.reverse_merge( + :host => host, + :protocol => https? ? "https" : "http" + ) + + opts.merge!(:port => 443) if !opts.key?(:port) && https? + opts + end + # Delegate unhandled messages to the current session instance. def method_missing(sym, *args, &block) reset! unless @integration_session diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb index 29531d237a..1611a549fd 100644 --- a/actionpack/test/controller/integration_test.rb +++ b/actionpack/test/controller/integration_test.rb @@ -75,23 +75,6 @@ class SessionTest < Test::Unit::TestCase @session.delete_via_redirect(path, args, headers) end - def test_url_for_with_controller - options = {:action => 'show'} - mock_controller = mock() - mock_controller.expects(:url_for).with(options).returns('/show') - @session.stubs(:controller).returns(mock_controller) - assert_equal '/show', @session.url_for(options) - end - - def test_url_for_without_controller - options = {:action => 'show'} - mock_rewriter = mock() - mock_rewriter.expects(:rewrite).with(SharedTestRoutes, options).returns('/show') - @session.stubs(:generic_url_rewriter).returns(mock_rewriter) - @session.stubs(:controller).returns(nil) - assert_equal '/show', @session.url_for(options) - end - def test_get path = "/index"; params = "blah"; headers = {:location => 'blah'} @session.expects(:process).with(:get,path,params,headers) @@ -238,6 +221,8 @@ class IntegrationTestUsesCorrectClass < ActionController::IntegrationTest end class IntegrationProcessTest < ActionController::IntegrationTest + include SharedTestRoutes.named_url_helpers + class IntegrationController < ActionController::Base def get respond_to do |format| @@ -410,12 +395,17 @@ class IntegrationProcessTest < ActionController::IntegrationTest match ':action', :to => controller get 'get/:action', :to => controller end + + self.metaclass.send(:include, set.named_url_helpers) + yield end end end class MetalIntegrationTest < ActionController::IntegrationTest + include SharedTestRoutes.named_url_helpers + class Poller def self.call(env) if env["PATH_INFO"] =~ /^\/success/ -- cgit v1.2.3 From f863045c45fbbe5972f557c02b729441ffe81502 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Thu, 25 Feb 2010 17:56:58 -0800 Subject: Rename metaclass to singleton_class --- actionpack/lib/action_dispatch/testing/assertions/routing.rb | 2 +- actionpack/test/controller/caching_test.rb | 2 +- actionpack/test/controller/integration_test.rb | 2 +- actionpack/test/controller/resources_test.rb | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/testing/assertions/routing.rb b/actionpack/lib/action_dispatch/testing/assertions/routing.rb index 17caa2e030..5a3ff5a04c 100644 --- a/actionpack/lib/action_dispatch/testing/assertions/routing.rb +++ b/actionpack/lib/action_dispatch/testing/assertions/routing.rb @@ -147,7 +147,7 @@ module ActionDispatch # ROUTES TODO: Figure out this insanity silence_warnings { ::ActionController.const_set(:UrlFor, @router.named_url_helpers) } _router = @router - @controller.metaclass.send(:send, :include, @router.named_url_helpers) if @controller + @controller.singleton_class.send(:send, :include, @router.named_url_helpers) if @controller yield @router ensure @router = old_routes diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index 9c9d886f5d..98cea945a7 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -512,7 +512,7 @@ class ActionCacheTest < ActionController::TestCase @response = ActionController::TestResponse.new @controller = ActionCachingTestController.new # ROUTES TODO: It seems bad to explicitly remix in the class - @controller.metaclass.send(:include, @router.named_url_helpers) + @controller.singleton_class.send(:include, @router.named_url_helpers) @request.host = 'hostname.com' end diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb index 1611a549fd..437d26e4ed 100644 --- a/actionpack/test/controller/integration_test.rb +++ b/actionpack/test/controller/integration_test.rb @@ -396,7 +396,7 @@ class IntegrationProcessTest < ActionController::IntegrationTest get 'get/:action', :to => controller end - self.metaclass.send(:include, set.named_url_helpers) + self.singleton_class.send(:include, set.named_url_helpers) yield end diff --git a/actionpack/test/controller/resources_test.rb b/actionpack/test/controller/resources_test.rb index 6f3c16f588..b377e5bbbc 100644 --- a/actionpack/test/controller/resources_test.rb +++ b/actionpack/test/controller/resources_test.rb @@ -1231,7 +1231,7 @@ class ResourcesTest < ActionController::TestCase @controller = "#{options[:options][:controller].camelize}Controller".constantize.new # ROUTES TODO: Figure out a way to not extend the routing helpers here - @controller.metaclass.send(:include, @router.named_url_helpers) + @controller.singleton_class.send(:include, @router.named_url_helpers) @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new get :index, options[:options] @@ -1301,7 +1301,7 @@ class ResourcesTest < ActionController::TestCase def assert_singleton_named_routes_for(singleton_name, options = {}) (options[:options] ||= {})[:controller] ||= singleton_name.to_s.pluralize @controller = "#{options[:options][:controller].camelize}Controller".constantize.new - @controller.metaclass.send(:include, @router.named_url_helpers) + @controller.singleton_class.send(:include, @router.named_url_helpers) @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new get :show, options[:options] -- cgit v1.2.3 From b48beb6986ee3c533ccae6d54d70f3c28a80a942 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Fri, 26 Feb 2010 10:27:06 +0100 Subject: Add missing require on abstract_controller/collector [#4061 status:resolved] --- actionpack/lib/abstract_controller/collector.rb | 2 ++ 1 file changed, 2 insertions(+) (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller/collector.rb b/actionpack/lib/abstract_controller/collector.rb index d429333661..81fb514770 100644 --- a/actionpack/lib/abstract_controller/collector.rb +++ b/actionpack/lib/abstract_controller/collector.rb @@ -1,3 +1,5 @@ +require "action_dispatch/http/mime_type" + module AbstractController module Collector def self.generate_method_for_mime(mime) -- cgit v1.2.3 From bd36418c512acb62c5515a6cbde79ce59dd67b46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Fri, 26 Feb 2010 11:51:21 +0100 Subject: Fix controller_path returnsing an empty string in Ruby 1.8.7 [#4036 status:resolved] --- actionpack/lib/abstract_controller.rb | 2 ++ actionpack/lib/abstract_controller/base.rb | 2 +- actionpack/lib/abstract_controller/helpers.rb | 3 --- actionpack/lib/abstract_controller/layouts.rb | 3 --- actionpack/lib/abstract_controller/logger.rb | 4 ++-- actionpack/lib/abstract_controller/rendering.rb | 4 +--- actionpack/test/controller/base_test.rb | 9 +++++++++ 7 files changed, 15 insertions(+), 12 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller.rb b/actionpack/lib/abstract_controller.rb index 1944e42ef1..c1b035306b 100644 --- a/actionpack/lib/abstract_controller.rb +++ b/actionpack/lib/abstract_controller.rb @@ -3,8 +3,10 @@ $:.unshift(activesupport_path) if File.directory?(activesupport_path) && !$:.inc require 'active_support/ruby/shim' require 'active_support/dependencies/autoload' +require 'active_support/core_ext/class/attribute' require 'active_support/core_ext/module/attr_internal' require 'active_support/core_ext/module/delegation' +require 'active_support/core_ext/module/anonymous' module AbstractController extend ActiveSupport::Autoload diff --git a/actionpack/lib/abstract_controller/base.rb b/actionpack/lib/abstract_controller/base.rb index 3119ee498b..e14818e464 100644 --- a/actionpack/lib/abstract_controller/base.rb +++ b/actionpack/lib/abstract_controller/base.rb @@ -84,7 +84,7 @@ module AbstractController # ==== Returns # String def controller_path - @controller_path ||= name && name.sub(/Controller$/, '').underscore + @controller_path ||= name.sub(/Controller$/, '').underscore unless anonymous? end end diff --git a/actionpack/lib/abstract_controller/helpers.rb b/actionpack/lib/abstract_controller/helpers.rb index ca3a7550e5..f875213afb 100644 --- a/actionpack/lib/abstract_controller/helpers.rb +++ b/actionpack/lib/abstract_controller/helpers.rb @@ -1,7 +1,4 @@ require 'active_support/dependencies' -require 'active_support/core_ext/class/attribute' -require 'active_support/core_ext/module/delegation' -require 'active_support/core_ext/module/anonymous' module AbstractController module Helpers diff --git a/actionpack/lib/abstract_controller/layouts.rb b/actionpack/lib/abstract_controller/layouts.rb index 0d214396aa..beda4e633e 100644 --- a/actionpack/lib/abstract_controller/layouts.rb +++ b/actionpack/lib/abstract_controller/layouts.rb @@ -1,6 +1,3 @@ -require 'active_support/core_ext/class/attribute' -require 'active_support/core_ext/module/delegation' - module AbstractController # Layouts reverse the common pattern of including shared headers and footers in many templates to isolate changes in # repeated setups. The inclusion pattern has pages that look like this: diff --git a/actionpack/lib/abstract_controller/logger.rb b/actionpack/lib/abstract_controller/logger.rb index a23a13e1d6..9318f5e369 100644 --- a/actionpack/lib/abstract_controller/logger.rb +++ b/actionpack/lib/abstract_controller/logger.rb @@ -1,5 +1,5 @@ -require 'active_support/core_ext/logger' -require 'active_support/benchmarkable' +require "active_support/core_ext/logger" +require "active_support/benchmarkable" module AbstractController module Logger diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb index 14f51ae1bf..32fdf821a7 100644 --- a/actionpack/lib/abstract_controller/rendering.rb +++ b/actionpack/lib/abstract_controller/rendering.rb @@ -1,7 +1,5 @@ require "abstract_controller/base" -require 'active_support/core_ext/class/attribute' -require 'active_support/core_ext/module/delegation' -require 'active_support/core_ext/array/wrap' +require "active_support/core_ext/array/wrap" module AbstractController class DoubleRenderError < Error diff --git a/actionpack/test/controller/base_test.rb b/actionpack/test/controller/base_test.rb index 436ee212c8..207dc63d57 100644 --- a/actionpack/test/controller/base_test.rb +++ b/actionpack/test/controller/base_test.rb @@ -113,6 +113,15 @@ class ControllerInstanceTests < Test::Unit::TestCase assert_equal Set.new(%w(public_action)), c.class.__send__(:action_methods), "#{c.controller_path} should not be empty!" end end + + def test_temporary_anonymous_controllers + name = 'ExamplesController' + klass = Class.new(ActionController::Base) + Object.const_set(name, klass) + + controller = klass.new + assert_equal "examples", controller.controller_path + end end class PerformActionTest < ActionController::TestCase -- cgit v1.2.3 From 1e95f019bb0b2f1f37c5897562da691eb72c0f1c Mon Sep 17 00:00:00 2001 From: Yehuda Katz Date: Fri, 26 Feb 2010 14:31:29 -0800 Subject: Fix 1.9 issue --- actionpack/lib/action_controller/railties/url_helpers.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/railties/url_helpers.rb b/actionpack/lib/action_controller/railties/url_helpers.rb index 354d3fa898..e726535a4f 100644 --- a/actionpack/lib/action_controller/railties/url_helpers.rb +++ b/actionpack/lib/action_controller/railties/url_helpers.rb @@ -4,7 +4,7 @@ module ActionController def self.with(router) Module.new do define_method(:inherited) do |klass| - super + super(klass) klass.send(:include, router.named_url_helpers) end end -- cgit v1.2.3 From 98f77e08278658ec47c9eb2e8f819d781c1eaebf Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Fri, 26 Feb 2010 15:00:33 -0800 Subject: Rename named_url_helpers to url_helpers and url_helpers to url_for --- actionpack/lib/action_controller/metal/url_for.rb | 2 +- actionpack/lib/action_controller/railties/url_helpers.rb | 2 +- actionpack/lib/action_dispatch/routing/route_set.rb | 11 +++++------ actionpack/lib/action_dispatch/testing/assertions/routing.rb | 6 +++--- actionpack/test/abstract_unit.rb | 2 +- actionpack/test/activerecord/polymorphic_routes_test.rb | 6 +++--- actionpack/test/controller/caching_test.rb | 2 +- actionpack/test/controller/integration_test.rb | 8 ++++---- actionpack/test/controller/resources_test.rb | 4 ++-- actionpack/test/controller/routing_test.rb | 4 ++-- actionpack/test/dispatch/routing_test.rb | 2 +- 11 files changed, 24 insertions(+), 25 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/url_for.rb b/actionpack/lib/action_controller/metal/url_for.rb index 013834ddee..6748cb7bd4 100644 --- a/actionpack/lib/action_controller/metal/url_for.rb +++ b/actionpack/lib/action_controller/metal/url_for.rb @@ -15,7 +15,7 @@ module ActionController def _router raise "In order to use #url_for, you must include the helpers of a particular " \ - "router. For instance, `include Rails.application.router.named_url_helpers" + "router. For instance, `include Rails.application.routes.url_helpers" end end end \ No newline at end of file diff --git a/actionpack/lib/action_controller/railties/url_helpers.rb b/actionpack/lib/action_controller/railties/url_helpers.rb index e726535a4f..ad2a8d4ef3 100644 --- a/actionpack/lib/action_controller/railties/url_helpers.rb +++ b/actionpack/lib/action_controller/railties/url_helpers.rb @@ -5,7 +5,7 @@ module ActionController Module.new do define_method(:inherited) do |klass| super(klass) - klass.send(:include, router.named_url_helpers) + klass.send(:include, router.url_helpers) end end end diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 7bfe4fa2bf..47320883ac 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -259,9 +259,8 @@ module ActionDispatch named_routes.install(destinations, regenerate_code) end - # ROUTES TODO: Revisit the name of these methods - def url_helpers - @url_helpers ||= begin + def url_for + @url_for ||= begin router = self Module.new do extend ActiveSupport::Concern @@ -272,13 +271,13 @@ module ActionDispatch end end - def named_url_helpers - @named_url_helpers ||= begin + def url_helpers + @url_helpers ||= begin router = self Module.new do extend ActiveSupport::Concern - include router.url_helpers + include router.url_for # ROUTES TODO: install_helpers isn't great... can we make a module with the stuff that # we can include? diff --git a/actionpack/lib/action_dispatch/testing/assertions/routing.rb b/actionpack/lib/action_dispatch/testing/assertions/routing.rb index 5a3ff5a04c..5a9a20cc5b 100644 --- a/actionpack/lib/action_dispatch/testing/assertions/routing.rb +++ b/actionpack/lib/action_dispatch/testing/assertions/routing.rb @@ -145,14 +145,14 @@ module ActionDispatch old_routes, @router = @router, ActionDispatch::Routing::RouteSet.new old_controller, @controller = @controller, @controller.clone if @controller # ROUTES TODO: Figure out this insanity - silence_warnings { ::ActionController.const_set(:UrlFor, @router.named_url_helpers) } + silence_warnings { ::ActionController.const_set(:UrlFor, @router.url_helpers) } _router = @router - @controller.singleton_class.send(:send, :include, @router.named_url_helpers) if @controller + @controller.singleton_class.send(:send, :include, @router.url_helpers) if @controller yield @router ensure @router = old_routes @controller = old_controller if @controller - silence_warnings { ::ActionController.const_set(:UrlFor, @router.named_url_helpers) } if @router + silence_warnings { ::ActionController.const_set(:UrlFor, @router.url_helpers) } if @router end def method_missing(selector, *args, &block) diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb index 846ac5f0d7..9960f7af87 100644 --- a/actionpack/test/abstract_unit.rb +++ b/actionpack/test/abstract_unit.rb @@ -256,7 +256,7 @@ end # ROUTES TODO: Cleaner way to do this? module ActionController - UrlFor = SharedTestRoutes.named_url_helpers + UrlFor = SharedTestRoutes.url_helpers class Base include UrlFor end diff --git a/actionpack/test/activerecord/polymorphic_routes_test.rb b/actionpack/test/activerecord/polymorphic_routes_test.rb index a10bb4473e..6e406ecd15 100644 --- a/actionpack/test/activerecord/polymorphic_routes_test.rb +++ b/actionpack/test/activerecord/polymorphic_routes_test.rb @@ -400,7 +400,7 @@ class PolymorphicRoutesTest < ActionController::TestCase map.resources :series end - self.class.send(:include, @router.named_url_helpers) + self.class.send(:include, @router.url_helpers) yield end end @@ -422,7 +422,7 @@ class PolymorphicRoutesTest < ActionController::TestCase end end - self.class.send(:include, @router.named_url_helpers) + self.class.send(:include, @router.url_helpers) yield end end @@ -441,7 +441,7 @@ class PolymorphicRoutesTest < ActionController::TestCase end end - self.class.send(:include, @router.named_url_helpers) + self.class.send(:include, @router.url_helpers) yield end end diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index 98cea945a7..67b6a1d858 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -512,7 +512,7 @@ class ActionCacheTest < ActionController::TestCase @response = ActionController::TestResponse.new @controller = ActionCachingTestController.new # ROUTES TODO: It seems bad to explicitly remix in the class - @controller.singleton_class.send(:include, @router.named_url_helpers) + @controller.singleton_class.send(:include, @router.url_helpers) @request.host = 'hostname.com' end diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb index 437d26e4ed..5352243734 100644 --- a/actionpack/test/controller/integration_test.rb +++ b/actionpack/test/controller/integration_test.rb @@ -221,7 +221,7 @@ class IntegrationTestUsesCorrectClass < ActionController::IntegrationTest end class IntegrationProcessTest < ActionController::IntegrationTest - include SharedTestRoutes.named_url_helpers + include SharedTestRoutes.url_helpers class IntegrationController < ActionController::Base def get @@ -388,7 +388,7 @@ class IntegrationProcessTest < ActionController::IntegrationTest with_routing do |set| controller = ::IntegrationProcessTest::IntegrationController.clone controller.class_eval do - include set.named_url_helpers + include set.url_helpers end set.draw do |map| @@ -396,7 +396,7 @@ class IntegrationProcessTest < ActionController::IntegrationTest get 'get/:action', :to => controller end - self.singleton_class.send(:include, set.named_url_helpers) + self.singleton_class.send(:include, set.url_helpers) yield end @@ -404,7 +404,7 @@ class IntegrationProcessTest < ActionController::IntegrationTest end class MetalIntegrationTest < ActionController::IntegrationTest - include SharedTestRoutes.named_url_helpers + include SharedTestRoutes.url_helpers class Poller def self.call(env) diff --git a/actionpack/test/controller/resources_test.rb b/actionpack/test/controller/resources_test.rb index b377e5bbbc..cf0cab3690 100644 --- a/actionpack/test/controller/resources_test.rb +++ b/actionpack/test/controller/resources_test.rb @@ -1231,7 +1231,7 @@ class ResourcesTest < ActionController::TestCase @controller = "#{options[:options][:controller].camelize}Controller".constantize.new # ROUTES TODO: Figure out a way to not extend the routing helpers here - @controller.singleton_class.send(:include, @router.named_url_helpers) + @controller.singleton_class.send(:include, @router.url_helpers) @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new get :index, options[:options] @@ -1301,7 +1301,7 @@ class ResourcesTest < ActionController::TestCase def assert_singleton_named_routes_for(singleton_name, options = {}) (options[:options] ||= {})[:controller] ||= singleton_name.to_s.pluralize @controller = "#{options[:options][:controller].camelize}Controller".constantize.new - @controller.singleton_class.send(:include, @router.named_url_helpers) + @controller.singleton_class.send(:include, @router.url_helpers) @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new get :show, options[:options] diff --git a/actionpack/test/controller/routing_test.rb b/actionpack/test/controller/routing_test.rb index f2fccfbcfc..31f86d2dde 100644 --- a/actionpack/test/controller/routing_test.rb +++ b/actionpack/test/controller/routing_test.rb @@ -251,7 +251,7 @@ class LegacyRouteSetTests < Test::Unit::TestCase def setup_for_named_route inst = MockController.clone.new - inst.class.send(:include, rs.named_url_helpers) + inst.class.send(:include, rs.url_helpers) inst end @@ -741,7 +741,7 @@ class RouteSetTest < ActiveSupport::TestCase map.users '/admin/users', :controller => 'admin/users', :action => 'index' end - MockController.clone.new.tap { |inst| inst.class.send(:include, set.named_url_helpers)} + MockController.clone.new.tap { |inst| inst.class.send(:include, set.url_helpers)} end def test_named_route_hash_access_method diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb index 7cfc6ef3d7..37c2f1421b 100644 --- a/actionpack/test/dispatch/routing_test.rb +++ b/actionpack/test/dispatch/routing_test.rb @@ -164,7 +164,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest Routes end - include Routes.named_url_helpers + include Routes.url_helpers def test_logout with_test_routes do -- cgit v1.2.3 From 224c0318bdbaea354bc5ab5c70b267b2a9c3d1c9 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Fri, 26 Feb 2010 15:04:34 -0800 Subject: Remove the :use_defaults check in UrlFor#merge options --- actionpack/lib/action_dispatch/routing/url_for.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb index 1d6da817ed..7004c1aab3 100644 --- a/actionpack/lib/action_dispatch/routing/url_for.rb +++ b/actionpack/lib/action_dispatch/routing/url_for.rb @@ -104,7 +104,7 @@ module ActionDispatch end def merge_options(options) #:nodoc: - if options.delete(:use_defaults) != false && respond_to?(:default_url_options) && (defaults = default_url_options(options)) + if respond_to?(:default_url_options) && (defaults = default_url_options(options)) defaults.merge(options) else options -- cgit v1.2.3 From bae691f61ab8cf4a59adaee6406855e11d009c74 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Fri, 26 Feb 2010 15:20:41 -0800 Subject: Change the API for setting global options for #url_for to self.url_options = { ... } This attr_accessor can be set in a before filter or in the action itself. Overwriting default_url_options still works but will output a deprecation notice. --- actionpack/lib/action_controller/metal/url_for.rb | 2 +- actionpack/lib/action_controller/test_case.rb | 2 +- actionpack/lib/action_dispatch/routing/url_for.rb | 34 +++++++++++++++------- .../lib/action_dispatch/testing/integration.rb | 2 +- 4 files changed, 26 insertions(+), 14 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/url_for.rb b/actionpack/lib/action_controller/metal/url_for.rb index 6748cb7bd4..8a06f34d23 100644 --- a/actionpack/lib/action_controller/metal/url_for.rb +++ b/actionpack/lib/action_controller/metal/url_for.rb @@ -5,7 +5,7 @@ module ActionController include ActionDispatch::Routing::UrlFor include ActionController::RackDelegation - def merge_options(options) + def url_options super.reverse_merge( :host => request.host_with_port, :protocol => request.protocol, diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb index 0fa2a8b90c..64d9bdab2a 100644 --- a/actionpack/lib/action_controller/test_case.rb +++ b/actionpack/lib/action_controller/test_case.rb @@ -336,7 +336,7 @@ module ActionController private def build_request_uri(action, parameters) unless @request.env['REQUEST_URI'] - options = @controller.__send__(:merge_options, parameters) + options = @controller.__send__(:url_options).merge(parameters) options.update(:only_path => true, :action => action) url = ActionController::UrlRewriter.new(@request, parameters) diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb index 7004c1aab3..d467929561 100644 --- a/actionpack/lib/action_dispatch/routing/url_for.rb +++ b/actionpack/lib/action_dispatch/routing/url_for.rb @@ -95,22 +95,26 @@ module ActionDispatch self.default_url_options = {} end - def default_url_options(options = nil) - self.class.default_url_options - end + # def default_url_options(options = nil) + # self.class.default_url_options + # end def url_options - self.class.default_url_options.merge + self.class.default_url_options.merge(@url_options || {}) end - def merge_options(options) #:nodoc: - if respond_to?(:default_url_options) && (defaults = default_url_options(options)) - defaults.merge(options) - else - options - end + def url_options=(options) + @url_options = options end + # def merge_options(options) #:nodoc: + # if respond_to?(:default_url_options) && (defaults = default_url_options(options)) + # defaults.merge(options) + # else + # options + # end + # end + # Generate a url based on the options provided, default_url_options and the # routes defined in routes.rb. The following options are supported: # @@ -140,7 +144,15 @@ module ActionDispatch when String options when Hash - ActionController::UrlRewriter.rewrite(_router, merge_options(options)) + # Handle the deprecated instance level default_url_options + if respond_to?(:default_url_options, true) + ActiveSupport::Deprecation.warn "Overwriting #default_url_options is deprecated. Please set url options with self.url_options = { ... }" + if defaults = default_url_options(options) + options = defaults.merge(options) + end + end + + ActionController::UrlRewriter.rewrite(_router, url_options.merge(options)) else polymorphic_url(options) end diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb index fb067601c8..0bad9c37d6 100644 --- a/actionpack/lib/action_dispatch/testing/integration.rb +++ b/actionpack/lib/action_dispatch/testing/integration.rb @@ -357,7 +357,7 @@ module ActionDispatch extend ActiveSupport::Concern include ActionDispatch::Routing::UrlFor - def merge_options(options) + def url_options opts = super.reverse_merge( :host => host, :protocol => https? ? "https" : "http" -- cgit v1.2.3 From 47fe14bfcc553acfd4c44434636529f25054a751 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Fri, 26 Feb 2010 15:34:12 -0800 Subject: Silence test deprecation warnings --- actionpack/test/controller/base_test.rb | 71 ++++++++++++++++++++++------- actionpack/test/template/url_helper_test.rb | 2 +- 2 files changed, 56 insertions(+), 17 deletions(-) (limited to 'actionpack') diff --git a/actionpack/test/controller/base_test.rb b/actionpack/test/controller/base_test.rb index 207dc63d57..ade9a7fcba 100644 --- a/actionpack/test/controller/base_test.rb +++ b/actionpack/test/controller/base_test.rb @@ -66,6 +66,16 @@ class DefaultUrlOptionsController < ActionController::Base end end +class UrlOptionsController < ActionController::Base + def from_view + render :inline => "<%= #{params[:route]} %>" + end + + def url_options + super.merge(:host => 'www.override.com', :action => 'new', :locale => 'en') + end +end + class ControllerClassTests < ActiveSupport::TestCase def test_controller_path assert_equal 'empty', EmptyController.controller_path @@ -162,8 +172,8 @@ class PerformActionTest < ActionController::TestCase end end -class DefaultUrlOptionsTest < ActionController::TestCase - tests DefaultUrlOptionsController +class UrlOptionsTest < ActionController::TestCase + tests UrlOptionsController def setup super @@ -174,7 +184,7 @@ class DefaultUrlOptionsTest < ActionController::TestCase def test_default_url_options_are_used_if_set with_routing do |set| set.draw do |map| - match 'from_view', :to => 'default_url_options#from_view', :as => :from_view + match 'from_view', :to => 'url_options#from_view', :as => :from_view match ':controller/:action' end @@ -184,6 +194,33 @@ class DefaultUrlOptionsTest < ActionController::TestCase assert_equal 'http://www.override.com/from_view?locale=en', @controller.send(:from_view_url) assert_equal 'http://www.override.com/default_url_options/new?locale=en', @controller.url_for(:controller => 'default_url_options') end + end +end + +class DefaultUrlOptionsTest < ActionController::TestCase + tests DefaultUrlOptionsController + + def setup + super + @request.host = 'www.example.com' + rescue_action_in_public! + end + + def test_default_url_options_are_used_if_set + with_routing do |set| + set.draw do |map| + match 'from_view', :to => 'default_url_options#from_view', :as => :from_view + match ':controller/:action' + end + + assert_deprecated do + get :from_view, :route => "from_view_url" + + assert_equal 'http://www.override.com/from_view?locale=en', @response.body + assert_equal 'http://www.override.com/from_view?locale=en', @controller.send(:from_view_url) + assert_equal 'http://www.override.com/default_url_options/new?locale=en', @controller.url_for(:controller => 'default_url_options') + end + end end def test_default_url_options_are_used_in_non_positional_parameters @@ -195,19 +232,21 @@ class DefaultUrlOptionsTest < ActionController::TestCase match ':controller/:action' end - get :from_view, :route => "description_path(1)" - - assert_equal '/en/descriptions/1', @response.body - assert_equal '/en/descriptions', @controller.send(:descriptions_path) - assert_equal '/pl/descriptions', @controller.send(:descriptions_path, "pl") - assert_equal '/pl/descriptions', @controller.send(:descriptions_path, :locale => "pl") - assert_equal '/pl/descriptions.xml', @controller.send(:descriptions_path, "pl", "xml") - assert_equal '/en/descriptions.xml', @controller.send(:descriptions_path, :format => "xml") - assert_equal '/en/descriptions/1', @controller.send(:description_path, 1) - assert_equal '/pl/descriptions/1', @controller.send(:description_path, "pl", 1) - assert_equal '/pl/descriptions/1', @controller.send(:description_path, 1, :locale => "pl") - assert_equal '/pl/descriptions/1.xml', @controller.send(:description_path, "pl", 1, "xml") - assert_equal '/en/descriptions/1.xml', @controller.send(:description_path, 1, :format => "xml") + assert_deprecated do + get :from_view, :route => "description_path(1)" + + assert_equal '/en/descriptions/1', @response.body + assert_equal '/en/descriptions', @controller.send(:descriptions_path) + assert_equal '/pl/descriptions', @controller.send(:descriptions_path, "pl") + assert_equal '/pl/descriptions', @controller.send(:descriptions_path, :locale => "pl") + assert_equal '/pl/descriptions.xml', @controller.send(:descriptions_path, "pl", "xml") + assert_equal '/en/descriptions.xml', @controller.send(:descriptions_path, :format => "xml") + assert_equal '/en/descriptions/1', @controller.send(:description_path, 1) + assert_equal '/pl/descriptions/1', @controller.send(:description_path, "pl", 1) + assert_equal '/pl/descriptions/1', @controller.send(:description_path, 1, :locale => "pl") + assert_equal '/pl/descriptions/1.xml', @controller.send(:description_path, "pl", 1, "xml") + assert_equal '/en/descriptions/1.xml', @controller.send(:description_path, 1, :format => "xml") + end end end diff --git a/actionpack/test/template/url_helper_test.rb b/actionpack/test/template/url_helper_test.rb index c917ca9d2b..b047466aaf 100644 --- a/actionpack/test/template/url_helper_test.rb +++ b/actionpack/test/template/url_helper_test.rb @@ -426,7 +426,7 @@ class UrlHelperControllerTest < ActionController::TestCase end with_url_helper_routing do - get :show_named_route, :kind => 'url' + assert_deprecated { get :show_named_route, :kind => 'url' } assert_equal 'http://testtwo.host/url_helper_controller_test/url_helper/show_named_route', @response.body end end -- cgit v1.2.3 From 5797575bac580037e4a9ee686a8bcb7e56b65235 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Fri, 26 Feb 2010 15:40:36 -0800 Subject: Stop setting UrlFor using SharedTestHelpers --- actionpack/test/abstract_unit.rb | 6 +++--- actionpack/test/activerecord/polymorphic_routes_test.rb | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'actionpack') diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb index 9960f7af87..e0acbdd430 100644 --- a/actionpack/test/abstract_unit.rb +++ b/actionpack/test/abstract_unit.rb @@ -254,10 +254,10 @@ module ActionController end end -# ROUTES TODO: Cleaner way to do this? +# This stub emulates the Railtie including the URL helpers from a Rails application module ActionController - UrlFor = SharedTestRoutes.url_helpers class Base - include UrlFor + # ROUTES TODO: Rename SharedTestRoutes to something that reflects it's a standin for Rails.application + include SharedTestRoutes.url_helpers end end \ No newline at end of file diff --git a/actionpack/test/activerecord/polymorphic_routes_test.rb b/actionpack/test/activerecord/polymorphic_routes_test.rb index 6e406ecd15..5643ad5ad6 100644 --- a/actionpack/test/activerecord/polymorphic_routes_test.rb +++ b/actionpack/test/activerecord/polymorphic_routes_test.rb @@ -26,7 +26,7 @@ class Series < ActiveRecord::Base end class PolymorphicRoutesTest < ActionController::TestCase - include ActionController::UrlFor + include SharedTestRoutes.url_helpers self.default_url_options[:host] = 'example.com' def setup -- cgit v1.2.3 From 3bad24c85d973295df55a04272a4e1829eab4685 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Fri, 26 Feb 2010 15:44:22 -0800 Subject: Remove traces of SharedTestRoutes from user code; leave it as a standin for Rails.application.routes in Rails internal tests --- actionpack/lib/action_controller/railtie.rb | 1 - actionpack/lib/action_dispatch/testing/integration.rb | 12 ------------ actionpack/test/abstract_unit.rb | 1 - 3 files changed, 14 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb index 268301da64..69ee4b04ec 100644 --- a/actionpack/lib/action_controller/railtie.rb +++ b/actionpack/lib/action_controller/railtie.rb @@ -33,7 +33,6 @@ module ActionController initializer "action_controller.url_helpers" do |app| ActionController::Base.extend ::ActionController::Railtie::UrlHelpers.with(app.routes) ActionController::Routing::Routes = app.routes - ::SharedTestRoutes = app.routes end end end \ No newline at end of file diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb index 0bad9c37d6..88667d3570 100644 --- a/actionpack/lib/action_dispatch/testing/integration.rb +++ b/actionpack/lib/action_dispatch/testing/integration.rb @@ -219,18 +219,6 @@ module ActionDispatch @host = name end - # # Returns the URL for the given options, according to the rules specified - # # in the application's routes. - # def url_for(options) - # # ROUTES TODO: @app.router is not guaranteed to exist, so a generic Rack - # # application will not work here. This means that a generic Rack application - # # integration test cannot call url_for, since the application will not have - # # #router on it. - # controller ? - # controller.url_for(options) : - # generic_url_rewriter.rewrite(SharedTestRoutes, options) - # end - private # Performs the actual request. diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb index e0acbdd430..1213c9d99f 100644 --- a/actionpack/test/abstract_unit.rb +++ b/actionpack/test/abstract_unit.rb @@ -257,7 +257,6 @@ end # This stub emulates the Railtie including the URL helpers from a Rails application module ActionController class Base - # ROUTES TODO: Rename SharedTestRoutes to something that reflects it's a standin for Rails.application include SharedTestRoutes.url_helpers end end \ No newline at end of file -- cgit v1.2.3 From dae109a4632af702b8556ecf029a27d91476848b Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Fri, 26 Feb 2010 15:56:17 -0800 Subject: Including UrlFor in Redirecting and Head will warn usefully if a controller is wired up without a router included (and still support redirect_to "omg") --- actionpack/lib/action_controller/metal/head.rb | 5 ++--- actionpack/lib/action_controller/metal/redirecting.rb | 4 +--- 2 files changed, 3 insertions(+), 6 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/head.rb b/actionpack/lib/action_controller/metal/head.rb index fe6e6186a5..a5c9910d68 100644 --- a/actionpack/lib/action_controller/metal/head.rb +++ b/actionpack/lib/action_controller/metal/head.rb @@ -2,6 +2,8 @@ module ActionController module Head extend ActiveSupport::Concern + include ActionController::UrlFor + # Return a response that has no content (merely headers). The options # argument is interpreted to be a hash of header names and values. # This allows you to easily return a response that consists only of @@ -24,9 +26,6 @@ module ActionController end self.status = status - # ROUTES TODO: Figure out how to rescue from a no method error - # This is needed only if you wire up a controller yourself, and - # this not working would be baffling without a better error self.location = url_for(location) if location self.content_type = Mime[formats.first] self.response_body = " " diff --git a/actionpack/lib/action_controller/metal/redirecting.rb b/actionpack/lib/action_controller/metal/redirecting.rb index de40ea77b1..25e4e18493 100644 --- a/actionpack/lib/action_controller/metal/redirecting.rb +++ b/actionpack/lib/action_controller/metal/redirecting.rb @@ -12,6 +12,7 @@ module ActionController include AbstractController::Logger include ActionController::RackDelegation + include ActionController::UrlFor # Redirects the browser to the target specified in +options+. This parameter can take one of three forms: # @@ -83,9 +84,6 @@ module ActionController raise RedirectBackError unless refer = request.headers["Referer"] refer else - # ROUTES TODO: Figure out how to rescue from a no method error - # This is needed only if you wire up a controller yourself, and - # this not working would be baffling without a better error url_for(options) end.gsub(/[\r\n]/, '') end -- cgit v1.2.3 From ab0cc7286fdaed96ff03bf8a160ccc75c3a2916d Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Fri, 26 Feb 2010 15:56:38 -0800 Subject: Setting UrlFor in with_routing is no longer needed now that it's not global --- actionpack/lib/action_dispatch/testing/assertions/routing.rb | 3 --- actionpack/test/controller/url_for_test.rb | 9 +++++---- 2 files changed, 5 insertions(+), 7 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/testing/assertions/routing.rb b/actionpack/lib/action_dispatch/testing/assertions/routing.rb index 5a9a20cc5b..726da2ee07 100644 --- a/actionpack/lib/action_dispatch/testing/assertions/routing.rb +++ b/actionpack/lib/action_dispatch/testing/assertions/routing.rb @@ -144,15 +144,12 @@ module ActionDispatch def with_routing old_routes, @router = @router, ActionDispatch::Routing::RouteSet.new old_controller, @controller = @controller, @controller.clone if @controller - # ROUTES TODO: Figure out this insanity - silence_warnings { ::ActionController.const_set(:UrlFor, @router.url_helpers) } _router = @router @controller.singleton_class.send(:send, :include, @router.url_helpers) if @controller yield @router ensure @router = old_routes @controller = old_controller if @controller - silence_warnings { ::ActionController.const_set(:UrlFor, @router.url_helpers) } if @router end def method_missing(selector, *args, &block) diff --git a/actionpack/test/controller/url_for_test.rb b/actionpack/test/controller/url_for_test.rb index 43e2f91693..a7b77edc6e 100644 --- a/actionpack/test/controller/url_for_test.rb +++ b/actionpack/test/controller/url_for_test.rb @@ -132,7 +132,8 @@ module AbstractController end # We need to create a new class in order to install the new named route. - kls = Class.new { include ActionController::UrlFor } + kls = Class.new { include set.url_helpers } + controller = kls.new assert controller.respond_to?(:home_url) assert_equal 'http://www.basecamphq.com/home/sweet/home/again', @@ -153,7 +154,7 @@ module AbstractController match '/home/sweet/home/:user', :to => 'home#index', :as => :home end - kls = Class.new { include ActionController::UrlFor } + kls = Class.new { include set.url_helpers } controller = kls.new assert_equal 'http://www.basecamphq.com/subdir/home/sweet/home/again', @@ -171,7 +172,7 @@ module AbstractController end # We need to create a new class in order to install the new named route. - kls = Class.new { include ActionController::UrlFor } + kls = Class.new { include set.url_helpers } controller = kls.new assert controller.respond_to?(:home_url) assert_equal '/brave/new/world', @@ -239,7 +240,7 @@ module AbstractController end # We need to create a new class in order to install the new named route. - kls = Class.new { include ActionController::UrlFor } + kls = Class.new { include set.url_helpers } kls.default_url_options[:host] = 'www.basecamphq.com' controller = kls.new -- cgit v1.2.3 From 74df7795a836862df503aa23eda403c15b22ca3b Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Fri, 26 Feb 2010 15:58:24 -0800 Subject: Relatively speaking, it's not actually that bad... --- actionpack/test/abstract_unit.rb | 2 -- 1 file changed, 2 deletions(-) (limited to 'actionpack') diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb index 1213c9d99f..b09980cbba 100644 --- a/actionpack/test/abstract_unit.rb +++ b/actionpack/test/abstract_unit.rb @@ -76,8 +76,6 @@ module ActiveSupport match ':controller(/:action(/:id))' end - # ROUTES TODO: Don't do this here - # brodel :'( ActionController::IntegrationTest.app.router.draw do match ':controller(/:action(/:id))' end -- cgit v1.2.3 From be0bf10a3cf5783f8859f73659c5fe3c16bd1ccd Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Fri, 26 Feb 2010 16:06:54 -0800 Subject: Upon further reflection, we realized that SharedTestRoutes is not really a hack, but is instead a standin (in the Rails tests) for Rails.application.routes. * In a real application, action_controller/railties.rb does AC::Base.include(app.routes.url_helpers) * ActionController itself does not know about Rails.application, but instead can have named routes for any router * SharedTestRoutes are created in abstract_unit to stand in for Rails.application.routes, and is used in internal functional tests --- actionpack/test/abstract_unit.rb | 1 - 1 file changed, 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb index b09980cbba..c95673d97e 100644 --- a/actionpack/test/abstract_unit.rb +++ b/actionpack/test/abstract_unit.rb @@ -205,7 +205,6 @@ module ActionController include ActionDispatch::TestProcess setup do - # ROUTES TODO: The router object should come from somewhere sane @router = SharedTestRoutes end -- cgit v1.2.3 From 050831803a9e553ba392a73732b00528dfa8c6ad Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Fri, 26 Feb 2010 17:18:29 -0800 Subject: If IntegrationSession is initialized with an objects that responds to #routes, automatically extend the URL helpers from the RouteSet onto it --- .../lib/action_dispatch/routing/route_set.rb | 1 - .../lib/action_dispatch/testing/integration.rb | 28 ++++++++++++++++------ actionpack/test/abstract_unit.rb | 1 + actionpack/test/controller/caching_test.rb | 1 - actionpack/test/controller/integration_test.rb | 6 ++--- actionpack/test/controller/resources_test.rb | 1 - 6 files changed, 24 insertions(+), 14 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 47320883ac..6bc4303be3 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -203,7 +203,6 @@ module ActionDispatch url_for(options) end - protected :#{selector} END_EVAL helpers << selector end diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb index 88667d3570..0aff4250c1 100644 --- a/actionpack/lib/action_dispatch/testing/integration.rb +++ b/actionpack/lib/action_dispatch/testing/integration.rb @@ -162,12 +162,31 @@ module ActionDispatch # A running counter of the number of requests processed. attr_accessor :request_count + include ActionDispatch::Routing::UrlFor + # Create and initialize a new Session instance. def initialize(app) @app = app + + # If the app is a Rails app, make url_helpers available on the session + # This makes app.url_for and app.foo_path available in the console + if app.respond_to?(:routes) && app.routes.respond_to?(:url_helpers) + singleton_class.class_eval { include app.routes.url_helpers } + end + reset! end + def url_options + opts = super.reverse_merge( + :host => host, + :protocol => https? ? "https" : "http" + ) + + opts.merge!(:port => 443) if !opts.key?(:port) && https? + opts + end + # Resets the instance. This can be used to reset the state information # in an existing session instance, so it can be used from a clean-slate # condition. @@ -346,13 +365,8 @@ module ActionDispatch include ActionDispatch::Routing::UrlFor def url_options - opts = super.reverse_merge( - :host => host, - :protocol => https? ? "https" : "http" - ) - - opts.merge!(:port => 443) if !opts.key?(:port) && https? - opts + reset! unless @integration_session + @integration_session.url_options end # Delegate unhandled messages to the current session instance. diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb index c95673d97e..c178dc481c 100644 --- a/actionpack/test/abstract_unit.rb +++ b/actionpack/test/abstract_unit.rb @@ -85,6 +85,7 @@ end class RoutedRackApp attr_reader :router + alias routes router def initialize(router, &blk) @router = router diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index 67b6a1d858..80c968cc04 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -511,7 +511,6 @@ class ActionCacheTest < ActionController::TestCase @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new @controller = ActionCachingTestController.new - # ROUTES TODO: It seems bad to explicitly remix in the class @controller.singleton_class.send(:include, @router.url_helpers) @request.host = 'hostname.com' end diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb index 5352243734..c38348fa68 100644 --- a/actionpack/test/controller/integration_test.rb +++ b/actionpack/test/controller/integration_test.rb @@ -178,8 +178,8 @@ class IntegrationTestTest < Test::Unit::TestCase session1 = @test.open_session { |sess| } session2 = @test.open_session # implicit session - assert_equal ::ActionController::Integration::Session, session1.class - assert_equal ::ActionController::Integration::Session, session2.class + assert_kind_of ::ActionController::Integration::Session, session1 + assert_kind_of ::ActionController::Integration::Session, session2 assert_not_equal session1, session2 end @@ -221,8 +221,6 @@ class IntegrationTestUsesCorrectClass < ActionController::IntegrationTest end class IntegrationProcessTest < ActionController::IntegrationTest - include SharedTestRoutes.url_helpers - class IntegrationController < ActionController::Base def get respond_to do |format| diff --git a/actionpack/test/controller/resources_test.rb b/actionpack/test/controller/resources_test.rb index cf0cab3690..f60045bba6 100644 --- a/actionpack/test/controller/resources_test.rb +++ b/actionpack/test/controller/resources_test.rb @@ -1230,7 +1230,6 @@ class ResourcesTest < ActionController::TestCase end @controller = "#{options[:options][:controller].camelize}Controller".constantize.new - # ROUTES TODO: Figure out a way to not extend the routing helpers here @controller.singleton_class.send(:include, @router.url_helpers) @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new -- cgit v1.2.3 From 8689989a52fb673650c45322f060093678c6b91e Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Fri, 26 Feb 2010 17:31:32 -0800 Subject: Make ActionController::Routing::Routes a DeprecatedProxy --- actionpack/lib/action_controller/deprecated.rb | 2 -- actionpack/lib/action_controller/railtie.rb | 8 +++++++- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/deprecated.rb b/actionpack/lib/action_controller/deprecated.rb index 6088d97abe..9f2de57033 100644 --- a/actionpack/lib/action_controller/deprecated.rb +++ b/actionpack/lib/action_controller/deprecated.rb @@ -1,5 +1,3 @@ ActionController::AbstractRequest = ActionController::Request = ActionDispatch::Request ActionController::AbstractResponse = ActionController::Response = ActionDispatch::Response ActionController::Routing = ActionDispatch::Routing -# ROUTES TODO: Figure out how to deprecate this. -# ActionController::UrlWriter = ActionController::UrlFor diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb index 69ee4b04ec..07c6b8f2b6 100644 --- a/actionpack/lib/action_controller/railtie.rb +++ b/actionpack/lib/action_controller/railtie.rb @@ -2,6 +2,7 @@ require "rails" require "action_controller" require "action_view/railtie" require "active_support/core_ext/class/subclasses" +require "active_support/deprecation/proxy_wrappers" module ActionController class Railtie < Rails::Railtie @@ -32,7 +33,12 @@ module ActionController initializer "action_controller.url_helpers" do |app| ActionController::Base.extend ::ActionController::Railtie::UrlHelpers.with(app.routes) - ActionController::Routing::Routes = app.routes + + message = "ActionController::Routing::Routes is deprecated. " \ + "Instead, use Rails.application.routes" + + proxy = ActiveSupport::Deprecation::DeprecatedObjectProxy.new(app.routes, message) + ActionController::Routing::Routes = proxy end end end \ No newline at end of file -- cgit v1.2.3 From faf3c2f827e786bc06ea143b80bb98c9a1e18304 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Fri, 26 Feb 2010 18:24:55 -0800 Subject: Set the body using the accessor for AD::Response introspection mode so it gets wrapped in a [] --- actionpack/lib/action_dispatch/http/response.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/http/response.rb b/actionpack/lib/action_dispatch/http/response.rb index e6ed28742f..9cfe5a5ea9 100644 --- a/actionpack/lib/action_dispatch/http/response.rb +++ b/actionpack/lib/action_dispatch/http/response.rb @@ -43,7 +43,8 @@ module ActionDispatch # :nodoc: @block = nil @length = 0 - @status, @header, @body = status, header, body + @status, @header = status, header + self.body = body @cookie = [] @sending_file = false -- cgit v1.2.3 From 4bdc783d37b82b739c5ddcc828d3a253873f6629 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Fri, 26 Feb 2010 18:25:56 -0800 Subject: 1.9 seems to have a bug involving cloned classes and super. Fix it by not cloning (and instead creating classes on demand). The 1.9 bug should be investigated. --- actionpack/test/controller/routing_test.rb | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'actionpack') diff --git a/actionpack/test/controller/routing_test.rb b/actionpack/test/controller/routing_test.rb index 31f86d2dde..fc85b01394 100644 --- a/actionpack/test/controller/routing_test.rb +++ b/actionpack/test/controller/routing_test.rb @@ -52,11 +52,17 @@ class UriReservedCharactersRoutingTest < Test::Unit::TestCase end class MockController - def url_for(options) - options[:protocol] ||= "http" - options[:host] ||= "test.host" + def self.build(helpers) + Class.new do + def url_for(options) + options[:protocol] ||= "http" + options[:host] ||= "test.host" - super(options) + super(options) + end + + include helpers + end end end @@ -250,9 +256,7 @@ class LegacyRouteSetTests < Test::Unit::TestCase end def setup_for_named_route - inst = MockController.clone.new - inst.class.send(:include, rs.url_helpers) - inst + MockController.build(rs.url_helpers).new end def test_named_route_without_hash @@ -741,7 +745,7 @@ class RouteSetTest < ActiveSupport::TestCase map.users '/admin/users', :controller => 'admin/users', :action => 'index' end - MockController.clone.new.tap { |inst| inst.class.send(:include, set.url_helpers)} + MockController.build(set.url_helpers).new end def test_named_route_hash_access_method -- cgit v1.2.3 From 3f0ed205e721008759297909f1f224ebd58c6673 Mon Sep 17 00:00:00 2001 From: Yehuda Katz Date: Fri, 26 Feb 2010 22:47:36 -0800 Subject: Remind us that RoutingAssertions should work in an integration context --- actionpack/lib/action_dispatch/testing/assertions/routing.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/testing/assertions/routing.rb b/actionpack/lib/action_dispatch/testing/assertions/routing.rb index 726da2ee07..1d7e8090e4 100644 --- a/actionpack/lib/action_dispatch/testing/assertions/routing.rb +++ b/actionpack/lib/action_dispatch/testing/assertions/routing.rb @@ -152,6 +152,7 @@ module ActionDispatch @controller = old_controller if @controller end + # ROUTES TODO: These assertions should really work in an integration context def method_missing(selector, *args, &block) if @controller && @router.named_routes.helpers.include?(selector) @controller.send(selector, *args, &block) -- cgit v1.2.3 From 8247bd9d3e1c2772f2f1e0e7ee30ff7f19ddd0de Mon Sep 17 00:00:00 2001 From: Yehuda Katz Date: Sat, 27 Feb 2010 00:18:16 -0800 Subject: The instance_reader of default_url_options needs to not exist. --- actionpack/lib/action_dispatch/routing/url_for.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb index d467929561..7f2c9a5c12 100644 --- a/actionpack/lib/action_dispatch/routing/url_for.rb +++ b/actionpack/lib/action_dispatch/routing/url_for.rb @@ -90,6 +90,7 @@ module ActionDispatch class_attribute :default_url_options else mattr_accessor :default_url_options + remove_method :default_url_options end self.default_url_options = {} -- cgit v1.2.3 From 7317d9ef4c1361219671dc4405a02ed3896f1742 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Sun, 28 Feb 2010 16:39:01 -0600 Subject: Remove implicit controller namespacing from new dsl --- .../action_dispatch/routing/deprecated_mapper.rb | 25 ++++++++++++++++++++++ actionpack/lib/action_dispatch/routing/mapper.rb | 1 - .../lib/action_dispatch/routing/route_set.rb | 24 ++------------------- actionpack/test/abstract_unit.rb | 8 ++++--- .../test/controller/action_pack_assertions_test.rb | 9 +++++--- actionpack/test/controller/render_xml_test.rb | 3 ++- 6 files changed, 40 insertions(+), 30 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/routing/deprecated_mapper.rb b/actionpack/lib/action_dispatch/routing/deprecated_mapper.rb index 1417a9d8c0..dd650e83d9 100644 --- a/actionpack/lib/action_dispatch/routing/deprecated_mapper.rb +++ b/actionpack/lib/action_dispatch/routing/deprecated_mapper.rb @@ -1,5 +1,30 @@ module ActionDispatch module Routing + class RouteSet + attr_accessor :controller_namespaces + + CONTROLLER_REGEXP = /[_a-zA-Z0-9]+/ + + def controller_constraints + @controller_constraints ||= begin + namespaces = controller_namespaces + in_memory_controller_namespaces + source = namespaces.map { |ns| "#{Regexp.escape(ns)}/#{CONTROLLER_REGEXP.source}" } + source << CONTROLLER_REGEXP.source + Regexp.compile(source.sort.reverse.join('|')) + end + end + + def in_memory_controller_namespaces + namespaces = Set.new + ActionController::Base.subclasses.each do |klass| + controller_name = klass.underscore + namespaces << controller_name.split('/')[0...-1].join('/') + end + namespaces.delete('') + namespaces + end + end + # Mapper instances are used to build routes. The object passed to the draw # block in config/routes.rb is a Mapper instance. # diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index bead321c9c..52e7b0e77d 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -88,7 +88,6 @@ module ActionDispatch @requirements ||= returning(@options[:constraints] || {}) do |requirements| requirements.reverse_merge!(@scope[:constraints]) if @scope[:constraints] @options.each { |k, v| requirements[k] = v if v.is_a?(Regexp) } - requirements[:controller] ||= @set.controller_constraints end end diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 6bc4303be3..99436e3cb0 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -1,5 +1,6 @@ require 'rack/mount' require 'forwardable' +require 'action_dispatch/routing/deprecated_mapper' module ActionDispatch module Routing @@ -208,7 +209,7 @@ module ActionDispatch end end - attr_accessor :routes, :named_routes, :controller_namespaces + attr_accessor :routes, :named_routes attr_accessor :disable_clear_and_finalize, :resources_path_names def self.default_resources_path_names @@ -291,27 +292,6 @@ module ActionDispatch routes.empty? end - CONTROLLER_REGEXP = /[_a-zA-Z0-9]+/ - - def controller_constraints - @controller_constraints ||= begin - namespaces = controller_namespaces + in_memory_controller_namespaces - source = namespaces.map { |ns| "#{Regexp.escape(ns)}/#{CONTROLLER_REGEXP.source}" } - source << CONTROLLER_REGEXP.source - Regexp.compile(source.sort.reverse.join('|')) - end - end - - def in_memory_controller_namespaces - namespaces = Set.new - ActionController::Base.subclasses.each do |klass| - controller_name = klass.underscore - namespaces << controller_name.split('/')[0...-1].join('/') - end - namespaces.delete('') - namespaces - end - def add_route(app, conditions = {}, requirements = {}, defaults = {}, name = nil) route = Route.new(app, conditions, requirements, defaults, name) @set.add_route(*route) diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb index c178dc481c..7bcaf0a5eb 100644 --- a/actionpack/test/abstract_unit.rb +++ b/actionpack/test/abstract_unit.rb @@ -73,11 +73,13 @@ module ActiveSupport # have been loaded. setup_once do SharedTestRoutes.draw do |map| - match ':controller(/:action(/:id))' + # FIXME: match ':controller(/:action(/:id))' + map.connect ':controller/:action/:id' end - ActionController::IntegrationTest.app.router.draw do - match ':controller(/:action(/:id))' + ActionController::IntegrationTest.app.router.draw do |map| + # FIXME: match ':controller(/:action(/:id))' + map.connect ':controller/:action/:id' end end end diff --git a/actionpack/test/controller/action_pack_assertions_test.rb b/actionpack/test/controller/action_pack_assertions_test.rb index 7c83a91f4d..6906dc97e8 100644 --- a/actionpack/test/controller/action_pack_assertions_test.rb +++ b/actionpack/test/controller/action_pack_assertions_test.rb @@ -258,7 +258,8 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase with_routing do |set| set.draw do |map| match 'admin/inner_module', :to => 'admin/inner_module#index', :as => :admin_inner_module - match ':controller/:action' + # match ':controller/:action' + map.connect ':controller/:action/:id' end process :redirect_to_index # redirection is <{"action"=>"index", "controller"=>"admin/admin/inner_module"}> @@ -272,7 +273,8 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase with_routing do |set| set.draw do |map| match '/action_pack_assertions/:id', :to => 'action_pack_assertions#index', :as => :top_level - match ':controller/:action' + # match ':controller/:action' + map.connect ':controller/:action/:id' end process :redirect_to_top_level_named_route # assert_redirected_to "http://test.host/action_pack_assertions/foo" would pass because of exact match early return @@ -287,7 +289,8 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase set.draw do |map| # this controller exists in the admin namespace as well which is the only difference from previous test match '/user/:id', :to => 'user#index', :as => :top_level - match ':controller/:action' + # match ':controller/:action' + map.connect ':controller/:action/:id' end process :redirect_to_top_level_named_route # assert_redirected_to top_level_url('foo') would pass because of exact match early return diff --git a/actionpack/test/controller/render_xml_test.rb b/actionpack/test/controller/render_xml_test.rb index b5b0d0b9d5..4da6c954cf 100644 --- a/actionpack/test/controller/render_xml_test.rb +++ b/actionpack/test/controller/render_xml_test.rb @@ -62,7 +62,8 @@ class RenderXmlTest < ActionController::TestCase with_routing do |set| set.draw do |map| resources :customers - match ':controller/:action' + # match ':controller/:action' + map.connect ':controller/:action/:id' end get :render_with_object_location -- cgit v1.2.3 From fef7a77386b0e738f3b5c25fd9ab0350a6e56d6c Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Sun, 28 Feb 2010 17:16:34 -0600 Subject: Request#subdomain returns a string version of Request#subdomains --- actionpack/lib/action_dispatch/http/url.rb | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/http/url.rb b/actionpack/lib/action_dispatch/http/url.rb index 40ceb5a9b6..42ad19044d 100644 --- a/actionpack/lib/action_dispatch/http/url.rb +++ b/actionpack/lib/action_dispatch/http/url.rb @@ -81,6 +81,10 @@ module ActionDispatch parts[0..-(tld_length+2)] end + def subdomain(tld_length = 1) + subdomains(tld_length).join('.') + end + # Returns the query string, accounting for server idiosyncrasies. def query_string @env['QUERY_STRING'].present? ? @env['QUERY_STRING'] : (@env['REQUEST_URI'].to_s.split('?', 2)[1] || '') -- cgit v1.2.3 From cbefcc88b38f0ec3c885b450962623017f4cc64c Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Sun, 28 Feb 2010 18:25:02 -0600 Subject: add activesupport and activemodel load paths to actionpack tests --- actionpack/test/abstract_unit.rb | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'actionpack') diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb index 7bcaf0a5eb..660cabc554 100644 --- a/actionpack/test/abstract_unit.rb +++ b/actionpack/test/abstract_unit.rb @@ -1,5 +1,11 @@ require File.expand_path('../../../load_paths', __FILE__) +lib = File.expand_path("#{File.dirname(__FILE__)}/../lib") +$:.unshift(lib) unless $:.include?('lib') || $:.include?(lib) + +activemodel_path = File.expand_path('../../../activemodel/lib', __FILE__) +$:.unshift(activemodel_path) if File.directory?(activemodel_path) && !$:.include?(activemodel_path) + $:.unshift(File.dirname(__FILE__) + '/lib') $:.unshift(File.dirname(__FILE__) + '/fixtures/helpers') $:.unshift(File.dirname(__FILE__) + '/fixtures/alternate_helpers') -- cgit v1.2.3 From 8fbbdda52634991b047b7567fe3a8ec7c9a6c558 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Mon, 1 Mar 2010 14:10:53 -0800 Subject: Delegate formats to the controller --- actionpack/lib/action_view/base.rb | 25 ++++++++++++++++++++-- .../lib/action_view/helpers/prototype_helper.rb | 4 ++++ 2 files changed, 27 insertions(+), 2 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index a61017ae11..2d2b53a6ce 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -186,12 +186,21 @@ module ActionView #:nodoc: extend ActiveSupport::Memoizable - attr_accessor :base_path, :assigns, :template_extension, :formats + attr_accessor :base_path, :assigns, :template_extension attr_internal :captures def reset_formats(formats) - @formats = formats + old_formats, self.formats = self.formats, formats + reset_hash_key + yield if block_given? + ensure + if block_given? + self.formats = old_formats + reset_hash_key + end + end + def reset_hash_key if defined?(AbstractController::HashKey) # This is expensive, but we need to reset this when the format is updated, # which currently only happens @@ -200,6 +209,18 @@ module ActionView #:nodoc: end end + def formats + controller ? controller.formats : @formats + end + + def formats=(val) + if controller + controller.formats = val + else + @formats = val + end + end + class << self delegate :erb_trim_mode=, :to => 'ActionView::Template::Handlers::ERB' delegate :logger, :to => 'ActionController::Base', :allow_nil => true diff --git a/actionpack/lib/action_view/helpers/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb index 7eb6bceca0..3c4511d931 100644 --- a/actionpack/lib/action_view/helpers/prototype_helper.rb +++ b/actionpack/lib/action_view/helpers/prototype_helper.rb @@ -182,10 +182,14 @@ module ActionView def initialize(context, &block) #:nodoc: context._evaluate_assigns_and_ivars @context, @lines = context, [] + old_formats = @context.formats + @context.reset_formats([:js, :html]) if @context include_helpers_from_context @context.with_output_buffer(@lines) do @context.instance_exec(self, &block) end + ensure + @context.reset_formats(old_formats) if @context end private -- cgit v1.2.3 From b85ea58eb561d0a0fd2b0a3dbae1dc7846961c2d Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Mon, 1 Mar 2010 14:37:05 -0800 Subject: Change AV formats so they can delegate to the controller. Now users (or plugins) can override details_for_render in their controllers and add appropriate additional details. Now if only they could *do* something with those details... --- actionpack/lib/action_controller/base.rb | 2 +- .../lib/action_controller/metal/rendering.rb | 6 +++- .../lib/action_view/helpers/prototype_helper.rb | 32 ++++++++++++---------- actionpack/lib/action_view/render/rendering.rb | 8 ++++-- actionpack/test/template/javascript_helper_test.rb | 1 + actionpack/test/template/prototype_helper_test.rb | 1 + 6 files changed, 31 insertions(+), 19 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index f8ddc8da09..13139358c7 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -52,7 +52,7 @@ module ActionController def method_for_action(action_name) super || begin - if view_paths.exists?(action_name.to_s, {:formats => formats}, controller_path) + if view_paths.exists?(action_name.to_s, details_for_render, controller_path) "default_render" end end diff --git a/actionpack/lib/action_controller/metal/rendering.rb b/actionpack/lib/action_controller/metal/rendering.rb index a026289ee5..6e5379745b 100644 --- a/actionpack/lib/action_controller/metal/rendering.rb +++ b/actionpack/lib/action_controller/metal/rendering.rb @@ -23,10 +23,14 @@ module ActionController def _render_partial(options) options[:partial] = action_name if options[:partial] == true - options[:_details] = {:formats => formats} + options[:_details] = details_for_render super end + def details_for_render + {:formats => formats} + end + def format_for_text formats.first end diff --git a/actionpack/lib/action_view/helpers/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb index 3c4511d931..67a7586699 100644 --- a/actionpack/lib/action_view/helpers/prototype_helper.rb +++ b/actionpack/lib/action_view/helpers/prototype_helper.rb @@ -182,14 +182,12 @@ module ActionView def initialize(context, &block) #:nodoc: context._evaluate_assigns_and_ivars @context, @lines = context, [] - old_formats = @context.formats - @context.reset_formats([:js, :html]) if @context - include_helpers_from_context - @context.with_output_buffer(@lines) do - @context.instance_exec(self, &block) + @context.reset_formats([:js, :html]) do + include_helpers_from_context + @context.with_output_buffer(@lines) do + @context.instance_exec(self, &block) + end end - ensure - @context.reset_formats(old_formats) if @context end private @@ -573,15 +571,19 @@ module ActionView end end - def render(*options_for_render) - old_formats = @context && @context.formats + def render(*options) + with_formats(:html) do + case option = options.first + when Hash + @context.render(*options) + else + option.to_s + end + end + end - @context.reset_formats([:html]) if @context - Hash === options_for_render.first ? - @context.render(*options_for_render) : - options_for_render.first.to_s - ensure - @context.reset_formats(old_formats) if @context + def with_formats(*args) + @context ? @context.reset_formats(args) { yield } : yield end def javascript_object_for(object) diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb index abc7c09991..64cc0caf11 100644 --- a/actionpack/lib/action_view/render/rendering.rb +++ b/actionpack/lib/action_view/render/rendering.rb @@ -25,7 +25,7 @@ module ActionView end template = if options[:file] - find(options[:file], {:formats => formats}) + find(options[:file], details_for_render) elsif options[:inline] handler = Template.handler_class_for_extension(options[:type] || "erb") Template.new(options[:inline], "inline template", handler, {}) @@ -34,7 +34,7 @@ module ActionView end if template - layout = find(layout, {:formats => formats}) if layout + layout = find(layout, details_for_render) if layout _render_template(template, layout, :locals => options[:locals]) end when :update @@ -44,6 +44,10 @@ module ActionView end end + def details_for_render + controller.try(:details_for_render) || {:formats => formats} + end + # You can think of a layout as a method that is called with a block. _layout_for # returns the contents that are yielded to the layout. If the user calls yield # :some_name, the block, by default, returns content_for(:some_name). If the user diff --git a/actionpack/test/template/javascript_helper_test.rb b/actionpack/test/template/javascript_helper_test.rb index b3e7abc387..368a9c2514 100644 --- a/actionpack/test/template/javascript_helper_test.rb +++ b/actionpack/test/template/javascript_helper_test.rb @@ -9,6 +9,7 @@ class JavaScriptHelperTest < ActionView::TestCase def reset_formats(format) @format = format + yield if block_given? end def setup diff --git a/actionpack/test/template/prototype_helper_test.rb b/actionpack/test/template/prototype_helper_test.rb index 45f9d85e32..6811d3aaf3 100644 --- a/actionpack/test/template/prototype_helper_test.rb +++ b/actionpack/test/template/prototype_helper_test.rb @@ -41,6 +41,7 @@ class PrototypeHelperBaseTest < ActionView::TestCase def reset_formats(format) @format = format + yield if block_given? end def setup -- cgit v1.2.3 From 300d6b549d020cbfaa10657f07a22ec892d8078f Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Mon, 1 Mar 2010 15:03:51 -0800 Subject: Merge _details_defaults and details_for_render --- actionpack/lib/abstract_controller/details_cache.rb | 2 +- actionpack/lib/abstract_controller/rendering.rb | 4 ++-- actionpack/lib/action_controller/metal/rendering.rb | 4 ---- 3 files changed, 3 insertions(+), 7 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller/details_cache.rb b/actionpack/lib/abstract_controller/details_cache.rb index 5b87b41e7d..be1a1c0f34 100644 --- a/actionpack/lib/abstract_controller/details_cache.rb +++ b/actionpack/lib/abstract_controller/details_cache.rb @@ -34,7 +34,7 @@ module AbstractController end def render_to_body(*args) - Thread.current[:format_locale_key] = HashKey.get(self.class, _details_defaults) + Thread.current[:format_locale_key] = HashKey.get(self.class, details_for_render) super end diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb index 32fdf821a7..2ea4f02871 100644 --- a/actionpack/lib/abstract_controller/rendering.rb +++ b/actionpack/lib/abstract_controller/rendering.rb @@ -168,12 +168,12 @@ module AbstractController end end - def _details_defaults + def details_for_render { :formats => formats, :locale => [I18n.locale] } end def _normalize_details(options) - details = _details_defaults + details = details_for_render details[:formats] = Array(options[:format]) if options[:format] details[:locale] = Array(options[:locale]) if options[:locale] details diff --git a/actionpack/lib/action_controller/metal/rendering.rb b/actionpack/lib/action_controller/metal/rendering.rb index 6e5379745b..00a09309bf 100644 --- a/actionpack/lib/action_controller/metal/rendering.rb +++ b/actionpack/lib/action_controller/metal/rendering.rb @@ -27,10 +27,6 @@ module ActionController super end - def details_for_render - {:formats => formats} - end - def format_for_text formats.first end -- cgit v1.2.3 From 11db694e0b825e3077e7545b08c1bf975997021f Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Mon, 1 Mar 2010 21:55:43 -0500 Subject: Remove cruft in the gem packaging and release code --- actionpack/Rakefile | 31 +------------------------------ 1 file changed, 1 insertion(+), 30 deletions(-) (limited to 'actionpack') diff --git a/actionpack/Rakefile b/actionpack/Rakefile index c45f88ed04..f099a4613e 100644 --- a/actionpack/Rakefile +++ b/actionpack/Rakefile @@ -6,16 +6,6 @@ require 'rake/packagetask' require 'rake/gempackagetask' require File.join(File.dirname(__FILE__), 'lib', 'action_pack', 'version') -PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : '' -PKG_NAME = 'actionpack' -PKG_VERSION = ActionPack::VERSION::STRING + PKG_BUILD -PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}" - -RELEASE_NAME = "REL #{PKG_VERSION}" - -RUBY_FORGE_PROJECT = "actionpack" -RUBY_FORGE_USER = "webster132" - desc "Default Task" task :default => :test @@ -114,27 +104,8 @@ task :update_js => [ :update_scriptaculous ] # Publishing ------------------------------------------------------ -desc "Publish the API documentation" -task :pgem => [:package] do - require 'rake/contrib/sshpublisher' - Rake::SshFilePublisher.new("gems.rubyonrails.org", "/u/sites/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload - `ssh gems.rubyonrails.org '/u/sites/gems/gemupdate.sh'` -end - desc "Publish the API documentation" task :pdoc => [:rdoc] do require 'rake/contrib/sshpublisher' Rake::SshDirPublisher.new("wrath.rubyonrails.org", "public_html/ap", "doc").upload -end - -desc "Publish the release files to RubyForge." -task :release => [ :package ] do - require 'rubyforge' - require 'rake/contrib/rubyforgepublisher' - - packages = %w( gem tgz zip ).collect{ |ext| "pkg/#{PKG_NAME}-#{PKG_VERSION}.#{ext}" } - - rubyforge = RubyForge.new - rubyforge.login - rubyforge.add_release(PKG_NAME, PKG_NAME, "REL #{PKG_VERSION}", *packages) -end +end \ No newline at end of file -- cgit v1.2.3 From a4111bbca0884e4a748ab32ba7d7b550ec8d9186 Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Mon, 1 Mar 2010 23:03:07 -0500 Subject: Update versions of all components to normalize them to new format --- actionpack/lib/action_pack/version.rb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_pack/version.rb b/actionpack/lib/action_pack/version.rb index 67f89e1627..72a1cd30ad 100644 --- a/actionpack/lib/action_pack/version.rb +++ b/actionpack/lib/action_pack/version.rb @@ -1,9 +1,10 @@ -module ActionPack #:nodoc: +module ActionPack module VERSION #:nodoc: MAJOR = 3 MINOR = 0 - TINY = "0.beta1" + TINY = 0 + BUILD = "beta1" - STRING = [MAJOR, MINOR, TINY].join('.') + STRING = [MAJOR, MINOR, TINY, BUILD].join('.') end end -- cgit v1.2.3 From f221a6f19f4cee31e2d103ea9a1930f59223fc25 Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Mon, 1 Mar 2010 23:36:54 -0500 Subject: Leverage VERSION constants from gemspecs to avoid tedious updates when releasing --- actionpack/Rakefile | 1 - actionpack/actionpack.gemspec | 9 ++++++--- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'actionpack') diff --git a/actionpack/Rakefile b/actionpack/Rakefile index f099a4613e..b9ace8658a 100644 --- a/actionpack/Rakefile +++ b/actionpack/Rakefile @@ -4,7 +4,6 @@ require 'rake/testtask' require 'rake/rdoctask' require 'rake/packagetask' require 'rake/gempackagetask' -require File.join(File.dirname(__FILE__), 'lib', 'action_pack', 'version') desc "Default Task" task :default => :test diff --git a/actionpack/actionpack.gemspec b/actionpack/actionpack.gemspec index 00c4d7de1c..d19649a386 100644 --- a/actionpack/actionpack.gemspec +++ b/actionpack/actionpack.gemspec @@ -1,7 +1,10 @@ +$:.unshift "lib" +require "action_pack/version" + Gem::Specification.new do |s| s.platform = Gem::Platform::RUBY s.name = 'actionpack' - s.version = '3.0.0.beta1' + s.version = ActionPack::VERSION::STRING s.summary = 'Web-flow and rendering framework putting the VC in MVC (part of Rails).' s.description = 'Web-flow and rendering framework putting the VC in MVC (part of Rails).' s.required_ruby_version = '>= 1.8.7' @@ -17,8 +20,8 @@ Gem::Specification.new do |s| s.has_rdoc = true - s.add_dependency('activesupport', '= 3.0.0.beta1') - s.add_dependency('activemodel', '= 3.0.0.beta1') + s.add_dependency('activesupport', "= #{ActionPack::VERSION::STRING}") + s.add_dependency('activemodel', "= #{ActionPack::VERSION::STRING}") s.add_dependency('rack', '~> 1.1.0') s.add_dependency('rack-test', '~> 0.5.0') s.add_dependency('rack-mount', '~> 0.5.1') -- cgit v1.2.3 From ea4fd64133998ce5d6791e0cd98e42f1463ae301 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Mon, 1 Mar 2010 23:22:11 -0800 Subject: Revert orphaned SharedTestRoutes --- actionpack/lib/action_view/test_case.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/test_case.rb b/actionpack/lib/action_view/test_case.rb index f6f4e18a4a..af2ed33f3f 100644 --- a/actionpack/lib/action_view/test_case.rb +++ b/actionpack/lib/action_view/test_case.rb @@ -53,7 +53,6 @@ module ActionView setup :setup_with_controller def setup_with_controller @controller = TestController.new - @router = SharedTestRoutes @output_buffer = ActiveSupport::SafeBuffer.new @rendered = '' @@ -153,7 +152,7 @@ module ActionView end def method_missing(selector, *args) - if @router.named_routes.helpers.include?(selector) + if ActionDispatch::Routing::Routes.named_routes.helpers.include?(selector) @controller.__send__(selector, *args) else super -- cgit v1.2.3 From 56ea20605a54386158e90e290caa6d15e7623ade Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Tue, 2 Mar 2010 10:32:09 -0800 Subject: Wordsmith gem descriptions --- actionpack/actionpack.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/actionpack.gemspec b/actionpack/actionpack.gemspec index d19649a386..a281df8642 100644 --- a/actionpack/actionpack.gemspec +++ b/actionpack/actionpack.gemspec @@ -6,7 +6,7 @@ Gem::Specification.new do |s| s.name = 'actionpack' s.version = ActionPack::VERSION::STRING s.summary = 'Web-flow and rendering framework putting the VC in MVC (part of Rails).' - s.description = 'Web-flow and rendering framework putting the VC in MVC (part of Rails).' + s.description = 'Web apps on Rails. Simple, battle-tested conventions for building and testing MVC web applications. Works with any Rack-compatible server.' s.required_ruby_version = '>= 1.8.7' s.author = 'David Heinemeier Hansson' -- cgit v1.2.3 From b01db07a9f009016186da34c4936a9efb2c224c6 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Tue, 2 Mar 2010 12:32:31 -0800 Subject: Moved initializers for ActionMailer and ActionController into their own railties --- actionpack/lib/action_controller/railtie.rb | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb index 07c6b8f2b6..a18b63fb13 100644 --- a/actionpack/lib/action_controller/railtie.rb +++ b/actionpack/lib/action_controller/railtie.rb @@ -27,6 +27,11 @@ module ActionController ActionController::Base.cache_store ||= RAILS_CACHE end + initializer "action_controller.add_view_paths" do |app| + views = app.config.paths.app.views.to_a + ActionController::Base.prepend_view_path(views) + end + initializer "action_controller.set_helpers_path" do |app| ActionController::Base.helpers_path = app.config.paths.app.helpers.to_a end -- cgit v1.2.3 From ecfd6d90eeeeeffb7415b4d9316da4e0bc35743b Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Tue, 2 Mar 2010 13:41:02 -0800 Subject: Action Mailer setup obviated by test bundle --- actionpack/test/controller/assert_select_test.rb | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'actionpack') diff --git a/actionpack/test/controller/assert_select_test.rb b/actionpack/test/controller/assert_select_test.rb index 612827dd41..cb3e848dfa 100644 --- a/actionpack/test/controller/assert_select_test.rb +++ b/actionpack/test/controller/assert_select_test.rb @@ -6,18 +6,7 @@ require 'abstract_unit' require 'controller/fake_controllers' - -unless defined?(ActionMailer) - begin - $:.unshift("#{File.dirname(__FILE__)}/../../../actionmailer/lib") - require 'action_mailer' - rescue LoadError => e - raise unless e.message =~ /action_mailer/ - require 'rubygems' - gem 'actionmailer' - end -end - +require 'action_mailer' ActionMailer::Base.view_paths = FIXTURE_LOAD_PATH class AssertSelectTest < ActionController::TestCase -- cgit v1.2.3 From aa749a74f63547a503772f4489fb60b5e4fbea1a Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Tue, 2 Mar 2010 14:00:17 -0800 Subject: Get the railties tests to pass again. --- actionpack/lib/action_controller/railtie.rb | 5 ----- 1 file changed, 5 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb index a18b63fb13..07c6b8f2b6 100644 --- a/actionpack/lib/action_controller/railtie.rb +++ b/actionpack/lib/action_controller/railtie.rb @@ -27,11 +27,6 @@ module ActionController ActionController::Base.cache_store ||= RAILS_CACHE end - initializer "action_controller.add_view_paths" do |app| - views = app.config.paths.app.views.to_a - ActionController::Base.prepend_view_path(views) - end - initializer "action_controller.set_helpers_path" do |app| ActionController::Base.helpers_path = app.config.paths.app.helpers.to_a end -- cgit v1.2.3 From 6d7d03b77c281014ab01177ed47b7e887866e3f9 Mon Sep 17 00:00:00 2001 From: Yehuda Katz Date: Tue, 2 Mar 2010 14:04:57 -0800 Subject: Fix some tests that relied on hardcoded Exception information (ht: evan) --- actionpack/test/template/render_test.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'actionpack') diff --git a/actionpack/test/template/render_test.rb b/actionpack/test/template/render_test.rb index fdf3db1cdb..338ada8b0e 100644 --- a/actionpack/test/template/render_test.rb +++ b/actionpack/test/template/render_test.rb @@ -108,7 +108,7 @@ module RenderTestCases @view.render(:partial => "test/raise") flunk "Render did not raise Template::Error" rescue ActionView::Template::Error => e - assert_match "undefined local variable or method `doesnt_exist'", e.message + assert_match %r!method.*doesnt_exist!, e.message assert_equal "", e.sub_template_message assert_equal "1", e.line_number assert_equal File.expand_path("#{FIXTURE_LOAD_PATH}/test/_raise.html.erb"), e.file_name @@ -118,7 +118,7 @@ module RenderTestCases @view.render(:file => "test/sub_template_raise") flunk "Render did not raise Template::Error" rescue ActionView::Template::Error => e - assert_match "undefined local variable or method `doesnt_exist'", e.message + assert_match %r!method.*doesnt_exist!, e.message assert_equal "Trace of template inclusion: #{File.expand_path("#{FIXTURE_LOAD_PATH}/test/sub_template_raise.html.erb")}", e.sub_template_message assert_equal "1", e.line_number assert_equal File.expand_path("#{FIXTURE_LOAD_PATH}/test/_raise.html.erb"), e.file_name -- cgit v1.2.3 From 9f83cdc38e03dc3e65a702b00dc4a3cc0bb44e60 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Tue, 2 Mar 2010 14:07:42 -0800 Subject: No longer add missing leading / on path args to assert_redirected_to. Deprecated in 2.3.6. --- .../action_dispatch/testing/assertions/response.rb | 23 +++++++++++++--------- .../test/controller/action_pack_assertions_test.rb | 6 ++++-- 2 files changed, 18 insertions(+), 11 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/testing/assertions/response.rb b/actionpack/lib/action_dispatch/testing/assertions/response.rb index c2486d3730..937c9f48d2 100644 --- a/actionpack/lib/action_dispatch/testing/assertions/response.rb +++ b/actionpack/lib/action_dispatch/testing/assertions/response.rb @@ -132,16 +132,21 @@ module ActionDispatch end def normalize_argument_to_redirection(fragment) - after_routing = @controller.url_for(fragment) - if after_routing =~ %r{^\w+://.*} - after_routing - else - # FIXME - this should probably get removed. - if after_routing.first != '/' - after_routing = '/' + after_routing + case fragment + when %r{^\w[\w\d+.-]*:.*} + fragment + when String + if fragment =~ %r{^\w[\w\d+.-]*:.*} + fragment + else + @request.protocol + @request.host_with_port + fragment end - @request.protocol + @request.host_with_port + after_routing - end + when :back + raise RedirectBackError unless refer = @request.headers["Referer"] + refer + else + @controller.url_for(fragment) + end.gsub(/[\r\n]/, '') end def validate_request! diff --git a/actionpack/test/controller/action_pack_assertions_test.rb b/actionpack/test/controller/action_pack_assertions_test.rb index 6906dc97e8..26e0d6d844 100644 --- a/actionpack/test/controller/action_pack_assertions_test.rb +++ b/actionpack/test/controller/action_pack_assertions_test.rb @@ -469,9 +469,11 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase assert_redirected_to '/some/path' end - def test_redirected_to_url_no_leadling_slash + def test_redirected_to_url_no_leading_slash_fails process :redirect_to_path - assert_redirected_to 'some/path' + assert_raise ActiveSupport::TestCase::Assertion do + assert_redirected_to 'some/path' + end end def test_redirected_to_url_full_url -- cgit v1.2.3 From d78e3fe73fccb90ddb25dc04f9643b83cae2b9e3 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Tue, 2 Mar 2010 14:40:59 -0800 Subject: Fix failing Action Pack tests --- actionpack/lib/action_view/test_case.rb | 2 +- actionpack/test/abstract_unit.rb | 10 ++++++++++ actionpack/test/activerecord/controller_runtime_test.rb | 2 +- actionpack/test/controller/log_subscriber_test.rb | 3 ++- actionpack/test/template/log_subscriber_test.rb | 2 +- 5 files changed, 15 insertions(+), 4 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/test_case.rb b/actionpack/lib/action_view/test_case.rb index af2ed33f3f..f639700eaf 100644 --- a/actionpack/lib/action_view/test_case.rb +++ b/actionpack/lib/action_view/test_case.rb @@ -152,7 +152,7 @@ module ActionView end def method_missing(selector, *args) - if ActionDispatch::Routing::Routes.named_routes.helpers.include?(selector) + if @controller._router.named_routes.helpers.include?(selector) @controller.__send__(selector, *args) else super diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb index 660cabc554..f1e8779cfa 100644 --- a/actionpack/test/abstract_unit.rb +++ b/actionpack/test/abstract_unit.rb @@ -203,6 +203,16 @@ end class ::ApplicationController < ActionController::Base end +module ActionView + class TestCase + # Must repeat the setup because AV::TestCase is a duplication + # of AC::TestCase + setup do + @router = SharedTestRoutes + end + end +end + module ActionController class Base include ActionController::Testing diff --git a/actionpack/test/activerecord/controller_runtime_test.rb b/actionpack/test/activerecord/controller_runtime_test.rb index d089830857..331f861d8f 100644 --- a/actionpack/test/activerecord/controller_runtime_test.rb +++ b/actionpack/test/activerecord/controller_runtime_test.rb @@ -17,9 +17,9 @@ class ControllerRuntimeLogSubscriberTest < ActionController::TestCase tests LogSubscriberController def setup + super @old_logger = ActionController::Base.logger Rails::LogSubscriber.add(:action_controller, ActionController::Railties::LogSubscriber.new) - super end def teardown diff --git a/actionpack/test/controller/log_subscriber_test.rb b/actionpack/test/controller/log_subscriber_test.rb index 668d6ae5ea..1f8134822c 100644 --- a/actionpack/test/controller/log_subscriber_test.rb +++ b/actionpack/test/controller/log_subscriber_test.rb @@ -40,6 +40,8 @@ class ACLogSubscriberTest < ActionController::TestCase include Rails::LogSubscriber::TestHelper def setup + super + @old_logger = ActionController::Base.logger @cache_path = File.expand_path('../temp/test_cache', File.dirname(__FILE__)) @@ -47,7 +49,6 @@ class ACLogSubscriberTest < ActionController::TestCase ActionController::Base.cache_store = :file_store, @cache_path Rails::LogSubscriber.add(:action_controller, ActionController::Railties::LogSubscriber.new) - super end def teardown diff --git a/actionpack/test/template/log_subscriber_test.rb b/actionpack/test/template/log_subscriber_test.rb index 2eb2484cf5..5076dfa70f 100644 --- a/actionpack/test/template/log_subscriber_test.rb +++ b/actionpack/test/template/log_subscriber_test.rb @@ -7,11 +7,11 @@ class AVLogSubscriberTest < ActiveSupport::TestCase include Rails::LogSubscriber::TestHelper def setup + super @old_logger = ActionController::Base.logger @view = ActionView::Base.new(ActionController::Base.view_paths, {}) Rails.stubs(:root).returns(File.expand_path(FIXTURE_LOAD_PATH)) Rails::LogSubscriber.add(:action_view, ActionView::Railties::LogSubscriber.new) - super end def teardown -- cgit v1.2.3 From b4b0c4cb4154984c89a3bbbcd9970a00d8bd3cb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 3 Mar 2010 09:25:41 +0100 Subject: Add missing super call in AC::Metal. [#4085 status:resolved] --- actionpack/lib/action_controller/metal.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal.rb b/actionpack/lib/action_controller/metal.rb index 4fd37e7f31..5e0ed201cb 100644 --- a/actionpack/lib/action_controller/metal.rb +++ b/actionpack/lib/action_controller/metal.rb @@ -103,6 +103,7 @@ module ActionController def self.inherited(base) self.middleware_stack = base.middleware_stack.dup + super end def self.use(*args) -- cgit v1.2.3 From 9dae645c5f8a2aaa70b19e05daf9a7d270facb72 Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Wed, 3 Mar 2010 00:42:51 -0800 Subject: Actually move ImplicitRender into it's own file --- actionpack/lib/action_controller.rb | 1 + actionpack/lib/action_controller/base.rb | 23 ---------------------- .../lib/action_controller/metal/implicit_render.rb | 21 ++++++++++++++++++++ 3 files changed, 22 insertions(+), 23 deletions(-) create mode 100644 actionpack/lib/action_controller/metal/implicit_render.rb (limited to 'actionpack') diff --git a/actionpack/lib/action_controller.rb b/actionpack/lib/action_controller.rb index 759e52b135..a449a3364c 100644 --- a/actionpack/lib/action_controller.rb +++ b/actionpack/lib/action_controller.rb @@ -20,6 +20,7 @@ module ActionController autoload :Helpers autoload :HideActions autoload :HttpAuthentication + autoload :ImplicitRender autoload :Instrumentation autoload :MimeResponds autoload :RackDelegation diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index 13139358c7..aec14165b6 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -36,29 +36,6 @@ module ActionController # Add instrumentations hooks at the bottom, to ensure they instrument # all the methods properly. include ActionController::Instrumentation - - # TODO: Extract into its own module - # This should be moved together with other normalizing behavior - module ImplicitRender - def send_action(*) - ret = super - default_render unless response_body - ret - end - - def default_render - render - end - - def method_for_action(action_name) - super || begin - if view_paths.exists?(action_name.to_s, details_for_render, controller_path) - "default_render" - end - end - end - end - include ImplicitRender include ActionController::Rescue diff --git a/actionpack/lib/action_controller/metal/implicit_render.rb b/actionpack/lib/action_controller/metal/implicit_render.rb new file mode 100644 index 0000000000..ba2d9b686e --- /dev/null +++ b/actionpack/lib/action_controller/metal/implicit_render.rb @@ -0,0 +1,21 @@ +module ActionController + module ImplicitRender + def send_action(*) + ret = super + default_render unless response_body + ret + end + + def default_render + render + end + + def method_for_action(action_name) + super || begin + if view_paths.exists?(action_name.to_s, details_for_render, controller_path) + "default_render" + end + end + end + end +end \ No newline at end of file -- cgit v1.2.3 From 29158d4158e9ae800c5be31a796940888bd03cc5 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Tue, 2 Mar 2010 15:09:15 -0800 Subject: Remove a failed attempt at refactoring AC configuration --- actionpack/lib/action_controller.rb | 1 - actionpack/lib/action_controller/base.rb | 1 - .../lib/action_controller/metal/configuration.rb | 28 ---------------------- .../action_controller/metal/session_management.rb | 2 -- 4 files changed, 32 deletions(-) delete mode 100644 actionpack/lib/action_controller/metal/configuration.rb (limited to 'actionpack') diff --git a/actionpack/lib/action_controller.rb b/actionpack/lib/action_controller.rb index a449a3364c..3b97f38498 100644 --- a/actionpack/lib/action_controller.rb +++ b/actionpack/lib/action_controller.rb @@ -13,7 +13,6 @@ module ActionController autoload_under "metal" do autoload :Compatibility autoload :ConditionalGet - autoload :Configuration autoload :Cookies autoload :Flash autoload :Head diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index aec14165b6..ace0276a31 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -15,7 +15,6 @@ module ActionController include ActionController::Renderers::All include ActionController::ConditionalGet include ActionController::RackDelegation - include ActionController::Configuration # Legacy modules include SessionManagement diff --git a/actionpack/lib/action_controller/metal/configuration.rb b/actionpack/lib/action_controller/metal/configuration.rb deleted file mode 100644 index 5c829853b7..0000000000 --- a/actionpack/lib/action_controller/metal/configuration.rb +++ /dev/null @@ -1,28 +0,0 @@ -module ActionController - module Configuration - extend ActiveSupport::Concern - - def config - @config ||= self.class.config - end - - def config=(config) - @config = config - end - - module ClassMethods - def default_config - @default_config ||= {} - end - - def config - self.config ||= default_config - end - - def config=(config) - @config = ActiveSupport::OrderedHash.new - @config.merge!(config) - end - end - end -end \ No newline at end of file diff --git a/actionpack/lib/action_controller/metal/session_management.rb b/actionpack/lib/action_controller/metal/session_management.rb index d70f40ce7a..6997257844 100644 --- a/actionpack/lib/action_controller/metal/session_management.rb +++ b/actionpack/lib/action_controller/metal/session_management.rb @@ -2,8 +2,6 @@ module ActionController #:nodoc: module SessionManagement #:nodoc: extend ActiveSupport::Concern - include ActionController::Configuration - module ClassMethods # Set the session store to be used for keeping the session data between requests. # By default, sessions are stored in browser cookies (:cookie_store), -- cgit v1.2.3 From bf9913f8f43a2436c644ad893d3d7034f7d7e256 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Tue, 2 Mar 2010 16:22:53 -0800 Subject: Move session_store and session_options to the AC configuration object --- actionpack/lib/action_controller/metal.rb | 17 +++++++++++ .../lib/action_controller/metal/compatibility.rb | 3 -- .../action_controller/metal/http_authentication.rb | 28 ++++++++--------- .../action_controller/metal/session_management.rb | 35 +++++++++++++++------- .../controller/http_digest_authentication_test.rb | 5 ++-- 5 files changed, 57 insertions(+), 31 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal.rb b/actionpack/lib/action_controller/metal.rb index 5e0ed201cb..fbc8a9a15e 100644 --- a/actionpack/lib/action_controller/metal.rb +++ b/actionpack/lib/action_controller/metal.rb @@ -1,4 +1,13 @@ require 'active_support/core_ext/class/attribute' +require 'active_support/ordered_options' + +module ActiveSupport + class InheritableOptions < OrderedOptions + def initialize(parent) + super() { |h,k| parent[k] } + end + end +end module ActionController # ActionController::Metal provides a way to get a valid Rack application from a controller. @@ -10,6 +19,14 @@ module ActionController class Metal < AbstractController::Base abstract! + def self.config + @config ||= ActiveSupport::InheritableOptions.new(superclass < Metal ? superclass.config : {}) + end + + def config + self.class.config + end + # :api: public attr_internal :params, :env diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb index 2b1ada1426..d1c86b296d 100644 --- a/actionpack/lib/action_controller/metal/compatibility.rb +++ b/actionpack/lib/action_controller/metal/compatibility.rb @@ -12,9 +12,6 @@ module ActionController ::ActionController::UnknownAction = ::AbstractController::ActionNotFound ::ActionController::DoubleRenderError = ::AbstractController::DoubleRenderError - cattr_accessor :session_options - self.session_options = {} - cattr_accessor :relative_url_root self.relative_url_root = ENV['RAILS_RELATIVE_URL_ROOT'] diff --git a/actionpack/lib/action_controller/metal/http_authentication.rb b/actionpack/lib/action_controller/metal/http_authentication.rb index 0f35a7c040..5c6641c948 100644 --- a/actionpack/lib/action_controller/metal/http_authentication.rb +++ b/actionpack/lib/action_controller/metal/http_authentication.rb @@ -165,7 +165,7 @@ module ActionController # Authenticate with HTTP Digest, returns true or false def authenticate_with_http_digest(realm = "Application", &password_procedure) - HttpAuthentication::Digest.authenticate(request, realm, &password_procedure) + HttpAuthentication::Digest.authenticate(config.session_options[:secret], request, realm, &password_procedure) end # Render output including the HTTP Digest authentication header @@ -175,8 +175,8 @@ module ActionController end # Returns false on a valid response, true otherwise - def authenticate(request, realm, &password_procedure) - authorization(request) && validate_digest_response(request, realm, &password_procedure) + def authenticate(secret_key, request, realm, &password_procedure) + authorization(request) && validate_digest_response(secret_key, request, realm, &password_procedure) end def authorization(request) @@ -189,11 +189,11 @@ module ActionController # Returns false unless the request credentials response value matches the expected value. # First try the password as a ha1 digest password. If this fails, then try it as a plain # text password. - def validate_digest_response(request, realm, &password_procedure) + def validate_digest_response(secret_key, request, realm, &password_procedure) credentials = decode_credentials_header(request) - valid_nonce = validate_nonce(request, credentials[:nonce]) + valid_nonce = validate_nonce(secret_key, request, credentials[:nonce]) - if valid_nonce && realm == credentials[:realm] && opaque == credentials[:opaque] + if valid_nonce && realm == credentials[:realm] && opaque(secret_key) == credentials[:opaque] password = password_procedure.call(credentials[:username]) return false unless password @@ -238,6 +238,9 @@ module ActionController end def authentication_header(controller, realm) + secret_key = controller.config.session_options[:secret] + nonce = self.nonce(secret_key) + opaque = opaque(secret_key) controller.headers["WWW-Authenticate"] = %(Digest realm="#{realm}", qop="auth", algorithm=MD5, nonce="#{nonce}", opaque="#{opaque}") end @@ -280,7 +283,7 @@ module ActionController # The nonce is opaque to the client. Composed of Time, and hash of Time with secret # key from the Rails session secret generated upon creation of project. Ensures # the time cannot be modified by client. - def nonce(time = Time.now) + def nonce(secret_key, time = Time.now) t = time.to_i hashed = [t, secret_key] digest = ::Digest::MD5.hexdigest(hashed.join(":")) @@ -292,21 +295,16 @@ module ActionController # Can be much shorter if the Stale directive is implemented. This would # allow a user to use new nonce without prompting user again for their # username and password. - def validate_nonce(request, value, seconds_to_timeout=5*60) + def validate_nonce(secret_key, request, value, seconds_to_timeout=5*60) t = ActiveSupport::Base64.decode64(value).split(":").first.to_i - nonce(t) == value && (t - Time.now.to_i).abs <= seconds_to_timeout + nonce(secret_key, t) == value && (t - Time.now.to_i).abs <= seconds_to_timeout end # Opaque based on random generation - but changing each request? - def opaque() + def opaque(secret_key) ::Digest::MD5.hexdigest(secret_key) end - # Set in /initializers/session_store.rb, and loaded even if sessions are not in use. - def secret_key - ActionController::Base.session_options[:secret] - end - end end end diff --git a/actionpack/lib/action_controller/metal/session_management.rb b/actionpack/lib/action_controller/metal/session_management.rb index 6997257844..264250db1a 100644 --- a/actionpack/lib/action_controller/metal/session_management.rb +++ b/actionpack/lib/action_controller/metal/session_management.rb @@ -2,27 +2,40 @@ module ActionController #:nodoc: module SessionManagement #:nodoc: extend ActiveSupport::Concern + included do + self.config.session_store ||= :cookie_store + self.config.session_options ||= {} + end + module ClassMethods # Set the session store to be used for keeping the session data between requests. # By default, sessions are stored in browser cookies (:cookie_store), # but you can also specify one of the other included stores (:active_record_store, # :mem_cache_store, or your own custom class. def session_store=(store) - if store == :active_record_store - self.session_store = ActiveRecord::SessionStore - else - @@session_store = store.is_a?(Symbol) ? - ActionDispatch::Session.const_get(store.to_s.camelize) : - store - end + ActiveSupport::Deprecation.warn "Setting session_store directly on ActionController::Base is deprecated. " \ + "Please set it on config.action_controller.session_store" + config.session_store = store + end + + def session_options=(opts) + ActiveSupport::Deprecation.warn "Setting seession_options directly on ActionController::Base is deprecated. " \ + "Please set it on config.action_controller.session_options" + config.session_store = opts + end + + def session_options + config.session_options end - # Returns the session store class currently used. def session_store - if defined? @@session_store - @@session_store + case store = config.session_store + when :active_record_store + ActiveRecord::SessionStore + when Symbol + ActionDispatch::Session.const_get(store.to_s.camelize) else - ActionDispatch::Session::CookieStore + store end end diff --git a/actionpack/test/controller/http_digest_authentication_test.rb b/actionpack/test/controller/http_digest_authentication_test.rb index 7e9a2625f1..22d2e23de1 100644 --- a/actionpack/test/controller/http_digest_authentication_test.rb +++ b/actionpack/test/controller/http_digest_authentication_test.rb @@ -40,7 +40,8 @@ class HttpDigestAuthenticationTest < ActionController::TestCase setup do # Used as secret in generating nonce to prevent tampering of timestamp - @old_secret, ActionController::Base.session_options[:secret] = ActionController::Base.session_options[:secret], "session_options_secret" + @secret = "session_options_secret" + @old_secret, ActionController::Base.session_options[:secret] = ActionController::Base.session_options[:secret], @secret end teardown do @@ -202,7 +203,7 @@ class HttpDigestAuthenticationTest < ActionController::TestCase test "validate_digest_response should fail with nil returning password_procedure" do @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => nil, :password => nil) - assert !ActionController::HttpAuthentication::Digest.validate_digest_response(@request, "SuperSecret"){nil} + assert !ActionController::HttpAuthentication::Digest.validate_digest_response(@secret, @request, "SuperSecret"){nil} end private -- cgit v1.2.3 From 664090348154ccbf1274a13bbc3d3c37ba35bc7d Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Tue, 2 Mar 2010 17:18:01 -0800 Subject: Move InheritableOptions into ActiveSupport --- actionpack/lib/action_controller/metal.rb | 8 -------- 1 file changed, 8 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal.rb b/actionpack/lib/action_controller/metal.rb index fbc8a9a15e..1f6bbeb7c5 100644 --- a/actionpack/lib/action_controller/metal.rb +++ b/actionpack/lib/action_controller/metal.rb @@ -1,14 +1,6 @@ require 'active_support/core_ext/class/attribute' require 'active_support/ordered_options' -module ActiveSupport - class InheritableOptions < OrderedOptions - def initialize(parent) - super() { |h,k| parent[k] } - end - end -end - module ActionController # ActionController::Metal provides a way to get a valid Rack application from a controller. # -- cgit v1.2.3 From bcfb77782b9d7f28f0c19005da909162e5e27690 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Tue, 2 Mar 2010 17:20:13 -0800 Subject: Work on deprecating ActionController::Base.relative_url_root --- .../lib/action_controller/metal/compatibility.rb | 41 ++++++++++++++++++++-- .../action_controller/metal/session_management.rb | 16 --------- actionpack/lib/action_controller/metal/url_for.rb | 4 +++ actionpack/lib/action_controller/url_rewriter.rb | 4 ++- .../lib/action_view/helpers/asset_tag_helper.rb | 4 +-- actionpack/test/controller/url_for_test.rb | 15 +++----- actionpack/test/dispatch/request_test.rb | 8 ----- actionpack/test/template/asset_tag_helper_test.rb | 38 ++++++++++---------- 8 files changed, 70 insertions(+), 60 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb index d1c86b296d..93f7b8ca49 100644 --- a/actionpack/lib/action_controller/metal/compatibility.rb +++ b/actionpack/lib/action_controller/metal/compatibility.rb @@ -7,13 +7,17 @@ module ActionController class ::ActionController::ActionControllerError < StandardError #:nodoc: end + module ClassMethods + end + # Temporary hax included do ::ActionController::UnknownAction = ::AbstractController::ActionNotFound ::ActionController::DoubleRenderError = ::AbstractController::DoubleRenderError - cattr_accessor :relative_url_root - self.relative_url_root = ENV['RAILS_RELATIVE_URL_ROOT'] + # ROUTES TODO: This should be handled by a middleware and route generation + # should be able to handle SCRIPT_NAME + self.config.relative_url_root = ENV['RAILS_RELATIVE_URL_ROOT'] class << self delegate :default_charset=, :to => "ActionDispatch::Response" @@ -47,6 +51,39 @@ module ActionController cattr_accessor :trusted_proxies end + def self.deprecated_config_accessor(option, message = nil) + deprecated_config_reader(option, message) + deprecated_config_writer(option, message) + end + + def self.deprecated_config_reader(option, message = nil) + message ||= "Reading #{option} directly from ActionController::Base is deprecated. " \ + "Please read it from config.#{option}" + + ClassMethods.class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{option} + ActiveSupport::Deprecation.warn #{message.inspect} + config.#{option} + end + RUBY + end + + def self.deprecated_config_writer(option, message = nil) + message ||= "Setting #{option} directly on ActionController::Base is deprecated. " \ + "Please set it on config.action_controller.#{option}" + + ClassMethods.class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{option}=(val) + ActiveSupport::Deprecation.warn #{message.inspect} + config.#{option} = val + end + RUBY + end + + deprecated_config_writer :session_store + deprecated_config_writer :session_options + deprecated_config_accessor :relative_url_root, "relative_url_root is ineffective. Please stop using it" + # For old tests def initialize_template_class(*) end def assign_shortcuts(*) end diff --git a/actionpack/lib/action_controller/metal/session_management.rb b/actionpack/lib/action_controller/metal/session_management.rb index 264250db1a..09ef9261a4 100644 --- a/actionpack/lib/action_controller/metal/session_management.rb +++ b/actionpack/lib/action_controller/metal/session_management.rb @@ -8,22 +8,6 @@ module ActionController #:nodoc: end module ClassMethods - # Set the session store to be used for keeping the session data between requests. - # By default, sessions are stored in browser cookies (:cookie_store), - # but you can also specify one of the other included stores (:active_record_store, - # :mem_cache_store, or your own custom class. - def session_store=(store) - ActiveSupport::Deprecation.warn "Setting session_store directly on ActionController::Base is deprecated. " \ - "Please set it on config.action_controller.session_store" - config.session_store = store - end - - def session_options=(opts) - ActiveSupport::Deprecation.warn "Setting seession_options directly on ActionController::Base is deprecated. " \ - "Please set it on config.action_controller.session_options" - config.session_store = opts - end - def session_options config.session_options end diff --git a/actionpack/lib/action_controller/metal/url_for.rb b/actionpack/lib/action_controller/metal/url_for.rb index 8a06f34d23..c890dc51d4 100644 --- a/actionpack/lib/action_controller/metal/url_for.rb +++ b/actionpack/lib/action_controller/metal/url_for.rb @@ -9,6 +9,10 @@ module ActionController super.reverse_merge( :host => request.host_with_port, :protocol => request.protocol, + # ROUTES TODO: relative_url_root should be middleware + # and the generator should take SCRIPT_NAME into + # consideration + :relative_url_root => config.relative_url_root, :_path_segments => request.symbolized_path_parameters ) end diff --git a/actionpack/lib/action_controller/url_rewriter.rb b/actionpack/lib/action_controller/url_rewriter.rb index 807b21cd0e..973a6facd7 100644 --- a/actionpack/lib/action_controller/url_rewriter.rb +++ b/actionpack/lib/action_controller/url_rewriter.rb @@ -32,6 +32,7 @@ module ActionController # ROUTES TODO: Fix the tests segments = options.delete(:_path_segments) + relative_url_root = options.delete(:relative_url_root).to_s path_segments = path_segments ? path_segments.merge(segments || {}) : segments unless options[:only_path] @@ -49,7 +50,8 @@ module ActionController path_options = yield(path_options) if block_given? path = router.generate(path_options, path_segments || {}) - rewritten_url << ActionController::Base.relative_url_root.to_s unless options[:skip_relative_url_root] + # ROUTES TODO: This can be called directly, so relative_url_root should probably be set in the router + rewritten_url << relative_url_root rewritten_url << (options[:trailing_slash] ? path.sub(/\?|\z/) { "/" + $& } : path) rewritten_url << "##{Rack::Utils.escape(options[:anchor].to_param.to_s)}" if options[:anchor] diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb index 96976ce45f..5f76ff456e 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb @@ -648,8 +648,8 @@ module ActionView source = rewrite_asset_path(source) if has_request && include_host - unless source =~ %r{^#{ActionController::Base.relative_url_root}/} - source = "#{ActionController::Base.relative_url_root}#{source}" + unless source =~ %r{^#{controller.config.relative_url_root}/} + source = "#{controller.config.relative_url_root}#{source}" end end end diff --git a/actionpack/test/controller/url_for_test.rb b/actionpack/test/controller/url_for_test.rb index a7b77edc6e..07809aa480 100644 --- a/actionpack/test/controller/url_for_test.rb +++ b/actionpack/test/controller/url_for_test.rb @@ -113,15 +113,13 @@ module AbstractController end def test_relative_url_root_is_respected - orig_relative_url_root = ActionController::Base.relative_url_root - ActionController::Base.relative_url_root = '/subdir' + # ROUTES TODO: Tests should not have to pass :relative_url_root directly. This + # should probably come from the router. add_host! assert_equal('https://www.basecamphq.com/subdir/c/a/i', - W.new.url_for(:controller => 'c', :action => 'a', :id => 'i', :protocol => 'https') + W.new.url_for(:controller => 'c', :action => 'a', :id => 'i', :protocol => 'https', :relative_url_root => '/subdir') ) - ensure - ActionController::Base.relative_url_root = orig_relative_url_root end def test_named_routes @@ -146,9 +144,6 @@ module AbstractController end def test_relative_url_root_is_respected_for_named_routes - orig_relative_url_root = ActionController::Base.relative_url_root - ActionController::Base.relative_url_root = '/subdir' - with_routing do |set| set.draw do |map| match '/home/sweet/home/:user', :to => 'home#index', :as => :home @@ -158,10 +153,8 @@ module AbstractController controller = kls.new assert_equal 'http://www.basecamphq.com/subdir/home/sweet/home/again', - controller.send(:home_url, :host => 'www.basecamphq.com', :user => 'again') + controller.send(:home_url, :host => 'www.basecamphq.com', :user => 'again', :relative_url_root => "/subdir") end - ensure - ActionController::Base.relative_url_root = orig_relative_url_root end def test_only_path diff --git a/actionpack/test/dispatch/request_test.rb b/actionpack/test/dispatch/request_test.rb index cc6acead6e..703f03fa96 100644 --- a/actionpack/test/dispatch/request_test.rb +++ b/actionpack/test/dispatch/request_test.rb @@ -1,14 +1,6 @@ require 'abstract_unit' class RequestTest < ActiveSupport::TestCase - def setup - ActionController::Base.relative_url_root = nil - end - - def teardown - ActionController::Base.relative_url_root = nil - end - test "remote ip" do request = stub_request 'REMOTE_ADDR' => '1.2.3.4' assert_equal '1.2.3.4', request.remote_ip diff --git a/actionpack/test/template/asset_tag_helper_test.rb b/actionpack/test/template/asset_tag_helper_test.rb index 586de66714..ccc39e9af6 100644 --- a/actionpack/test/template/asset_tag_helper_test.rb +++ b/actionpack/test/template/asset_tag_helper_test.rb @@ -1,4 +1,13 @@ require 'abstract_unit' +require 'active_support/ordered_options' + +class FakeController + attr_accessor :request + + def config + @config ||= ActiveSupport::InheritableOptions.new(ActionController::Metal.config) + end +end class AssetTagHelperTest < ActionView::TestCase tests ActionView::Helpers::AssetTagHelper @@ -32,8 +41,7 @@ class AssetTagHelperTest < ActionView::TestCase ) end - @controller = Class.new do - attr_accessor :request + @controller = Class.new(FakeController) do def url_for(*args) "http://www.example.com" end end.new @@ -372,11 +380,9 @@ class AssetTagHelperTest < ActionView::TestCase end def test_timebased_asset_id_with_relative_url_root - ActionController::Base.relative_url_root = "/collaboration/hieraki" - expected_time = File.stat(File.expand_path(File.dirname(__FILE__) + "/../fixtures/public/images/rails.png")).mtime.to_i.to_s - assert_equal %(Rails), image_tag("rails.png") - ensure - ActionController::Base.relative_url_root = "" + @controller.config.relative_url_root = "/collaboration/hieraki" + expected_time = File.stat(File.expand_path(File.dirname(__FILE__) + "/../fixtures/public/images/rails.png")).mtime.to_i.to_s + assert_equal %(Rails), image_tag("rails.png") end def test_should_skip_asset_id_on_complete_url @@ -606,7 +612,7 @@ class AssetTagHelperTest < ActionView::TestCase def test_caching_javascript_include_tag_with_relative_url_root ENV["RAILS_ASSET_ID"] = "" - ActionController::Base.relative_url_root = "/collaboration/hieraki" + @controller.config.relative_url_root = "/collaboration/hieraki" ActionController::Base.perform_caching = true assert_dom_equal( @@ -624,7 +630,6 @@ class AssetTagHelperTest < ActionView::TestCase assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'money.js')) ensure - ActionController::Base.relative_url_root = nil FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'all.js')) FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'money.js')) end @@ -821,7 +826,7 @@ class AssetTagHelperTest < ActionView::TestCase def test_caching_stylesheet_link_tag_with_relative_url_root ENV["RAILS_ASSET_ID"] = "" - ActionController::Base.relative_url_root = "/collaboration/hieraki" + @controller.config.relative_url_root = "/collaboration/hieraki" ActionController::Base.perform_caching = true assert_dom_equal( @@ -841,7 +846,6 @@ class AssetTagHelperTest < ActionView::TestCase assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'money.css')) ensure - ActionController::Base.relative_url_root = nil FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'all.css')) FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'money.css')) end @@ -884,16 +888,14 @@ class AssetTagHelperNonVhostTest < ActionView::TestCase def setup super - ActionController::Base.relative_url_root = "/collaboration/hieraki" - - @controller = Class.new do - attr_accessor :request - + @controller = Class.new(FakeController) do def url_for(options) "http://www.example.com/collaboration/hieraki" end end.new + @controller.config.relative_url_root = "/collaboration/hieraki" + @request = Class.new do def protocol 'gopher://' @@ -905,10 +907,6 @@ class AssetTagHelperNonVhostTest < ActionView::TestCase ActionView::Helpers::AssetTagHelper::reset_javascript_include_default end - def teardown - ActionController::Base.relative_url_root = nil - end - def test_should_compute_proper_path assert_dom_equal(%(), auto_discovery_link_tag) assert_dom_equal(%(/collaboration/hieraki/javascripts/xmlhr.js), javascript_path("xmlhr")) -- cgit v1.2.3 From 2a60cc682224f8a0923de1e0bf769d5333084480 Mon Sep 17 00:00:00 2001 From: Yehuda Katz Date: Wed, 3 Mar 2010 16:06:15 -0800 Subject: don't depend on the order of cookies (Hash ordering bug) --- actionpack/test/controller/cookie_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/test/controller/cookie_test.rb b/actionpack/test/controller/cookie_test.rb index f5ccef8aaf..908967a110 100644 --- a/actionpack/test/controller/cookie_test.rb +++ b/actionpack/test/controller/cookie_test.rb @@ -157,7 +157,7 @@ class CookieTest < ActionController::TestCase def assert_cookie_header(expected) header = @response.headers["Set-Cookie"] if header.respond_to?(:to_str) - assert_equal expected, header + assert_equal expected.split("\n").sort, header.split("\n").sort else assert_equal expected.split("\n"), header end -- cgit v1.2.3 From 5e0a05b8cb236d285ebb45de006dd3600c69357d Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Tue, 2 Mar 2010 18:57:02 -0800 Subject: Tweak the semantic of various URL related methods of ActionDispatch::Request --- actionpack/lib/action_controller/test_case.rb | 22 ++++-- actionpack/lib/action_dispatch/http/url.rb | 31 ++------ actionpack/lib/action_view/helpers/url_helper.rb | 5 +- actionpack/lib/action_view/test_case.rb | 2 + .../controller/http_digest_authentication_test.rb | 10 ++- actionpack/test/controller/integration_test.rb | 4 +- actionpack/test/dispatch/request_test.rb | 86 ++-------------------- actionpack/test/template/url_helper_test.rb | 3 - 8 files changed, 41 insertions(+), 122 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb index 64d9bdab2a..7e0a833dfa 100644 --- a/actionpack/lib/action_controller/test_case.rb +++ b/actionpack/lib/action_controller/test_case.rb @@ -322,6 +322,8 @@ module ActionController @controller ||= klass.new rescue nil end + @request.env.delete('PATH_INFO') + if @controller @controller.request = @request @controller.params = {} @@ -333,15 +335,19 @@ module ActionController @request.remote_addr = '208.77.188.166' # example.com end - private - def build_request_uri(action, parameters) - unless @request.env['REQUEST_URI'] - options = @controller.__send__(:url_options).merge(parameters) - options.update(:only_path => true, :action => action) + private + def build_request_uri(action, parameters) + unless @request.env["PATH_INFO"] + options = @controller.__send__(:url_options).merge(parameters) + options.update(:only_path => true, :action => action, :relative_url_root => nil) + rewriter = ActionController::UrlRewriter.new(@request, parameters) - url = ActionController::UrlRewriter.new(@request, parameters) - @request.request_uri = url.rewrite(@router, options) - end + url, query_string = rewriter.rewrite(@router, options).split("?", 2) + + @request.env["SCRIPT_NAME"] = @controller.config.relative_url_root + @request.env["PATH_INFO"] = url + @request.env["QUERY_STRING"] = query_string || "" end + end end end diff --git a/actionpack/lib/action_dispatch/http/url.rb b/actionpack/lib/action_dispatch/http/url.rb index 42ad19044d..e67d970a23 100644 --- a/actionpack/lib/action_dispatch/http/url.rb +++ b/actionpack/lib/action_dispatch/http/url.rb @@ -85,42 +85,23 @@ module ActionDispatch subdomains(tld_length).join('.') end - # Returns the query string, accounting for server idiosyncrasies. + # The query string must always be present def query_string - @env['QUERY_STRING'].present? ? @env['QUERY_STRING'] : (@env['REQUEST_URI'].to_s.split('?', 2)[1] || '') + @env['QUERY_STRING'] end # Returns the request URI, accounting for server idiosyncrasies. # WEBrick includes the full URL. IIS leaves REQUEST_URI blank. def request_uri - if uri = @env['REQUEST_URI'] - # Remove domain, which webrick puts into the request_uri. - (%r{^\w+\://[^/]+(/.*|$)$} =~ uri) ? $1 : uri - else - # Construct IIS missing REQUEST_URI from SCRIPT_NAME and PATH_INFO. - uri = @env['PATH_INFO'].to_s - - if script_filename = @env['SCRIPT_NAME'].to_s.match(%r{[^/]+$}) - uri = uri.sub(/#{script_filename}\//, '') - end - - env_qs = @env['QUERY_STRING'].to_s - uri += "?#{env_qs}" unless env_qs.empty? - - if uri.blank? - @env.delete('REQUEST_URI') - else - @env['REQUEST_URI'] = uri - end - end + uri = "#{@env["SCRIPT_NAME"]}#{@env["PATH_INFO"]}" + uri << "?#{@env["QUERY_STRING"]}" if @env["QUERY_STRING"].present? + uri end # Returns the interpreted \path to requested resource after all the installation # directory of this application was taken into account. def path - path = request_uri.to_s[/\A[^\?]*/] - path.sub!(/\A#{ActionController::Base.relative_url_root}/, '') - path + @env['PATH_INFO'] end private diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb index d9607c0095..148f2868e9 100644 --- a/actionpack/lib/action_view/helpers/url_helper.rb +++ b/actionpack/lib/action_view/helpers/url_helper.rb @@ -544,10 +544,11 @@ module ActionView # submitted url doesn't have any either. This lets the function # work with things like ?order=asc if url_string.index("?") - request_uri = request.request_uri + request_uri = request.fullpath else - request_uri = request.request_uri.split('?').first + request_uri = request.path end + if url_string =~ /^\w+:\/\// url_string == "#{request.protocol}#{request.host_with_port}#{request_uri}" else diff --git a/actionpack/lib/action_view/test_case.rb b/actionpack/lib/action_view/test_case.rb index f639700eaf..12142a3728 100644 --- a/actionpack/lib/action_view/test_case.rb +++ b/actionpack/lib/action_view/test_case.rb @@ -34,6 +34,8 @@ module ActionView @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new + @request.env.delete('PATH_INFO') + @params = {} end end diff --git a/actionpack/test/controller/http_digest_authentication_test.rb b/actionpack/test/controller/http_digest_authentication_test.rb index 22d2e23de1..6f167fe627 100644 --- a/actionpack/test/controller/http_digest_authentication_test.rb +++ b/actionpack/test/controller/http_digest_authentication_test.rb @@ -139,7 +139,7 @@ class HttpDigestAuthenticationTest < ActionController::TestCase test "authentication request with request-uri that doesn't match credentials digest-uri" do @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'please') - @request.env['REQUEST_URI'] = "/http_digest_authentication_test/dummy_digest/altered/uri" + @request.env['PATH_INFO'] = "/http_digest_authentication_test/dummy_digest/altered/uri" get :display assert_response :unauthorized @@ -148,7 +148,8 @@ class HttpDigestAuthenticationTest < ActionController::TestCase test "authentication request with absolute request uri (as in webrick)" do @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'please') - @request.env['REQUEST_URI'] = "http://test.host/http_digest_authentication_test/dummy_digest" + @request.env["SERVER_NAME"] = "test.host" + @request.env['PATH_INFO'] = "/http_digest_authentication_test/dummy_digest" get :display @@ -171,7 +172,8 @@ class HttpDigestAuthenticationTest < ActionController::TestCase test "authentication request with absolute uri in both request and credentials (as in Webrick with IE)" do @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:url => "http://test.host/http_digest_authentication_test/dummy_digest", :username => 'pretty', :password => 'please') - @request.env['REQUEST_URI'] = "http://test.host/http_digest_authentication_test/dummy_digest" + @request.env['SERVER_NAME'] = "test.host" + @request.env['PATH_INFO'] = "/http_digest_authentication_test/dummy_digest" get :display @@ -226,7 +228,7 @@ class HttpDigestAuthenticationTest < ActionController::TestCase credentials = decode_credentials(@response.headers['WWW-Authenticate']) credentials.merge!(options) - credentials.merge!(:uri => @request.env['REQUEST_URI'].to_s) + credentials.merge!(:uri => @request.env['PATH_INFO'].to_s) ActionController::HttpAuthentication::Digest.encode_credentials(method, credentials, password, options[:password_is_ha1]) end diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb index c38348fa68..814699978d 100644 --- a/actionpack/test/controller/integration_test.rb +++ b/actionpack/test/controller/integration_test.rb @@ -346,8 +346,8 @@ class IntegrationProcessTest < ActionController::IntegrationTest def test_get_with_parameters with_test_route_set do get '/get_with_params', :foo => "bar" - assert_equal '/get_with_params', request.env["REQUEST_URI"] - assert_equal '/get_with_params', request.request_uri + assert_equal '/get_with_params', request.env["PATH_INFO"] + assert_equal '/get_with_params', request.path_info assert_equal 'foo=bar', request.env["QUERY_STRING"] assert_equal 'foo=bar', request.query_string assert_equal 'bar', request.parameters['foo'] diff --git a/actionpack/test/dispatch/request_test.rb b/actionpack/test/dispatch/request_test.rb index 703f03fa96..1dfcdaebfd 100644 --- a/actionpack/test/dispatch/request_test.rb +++ b/actionpack/test/dispatch/request_test.rb @@ -144,103 +144,33 @@ class RequestTest < ActiveSupport::TestCase end test "request uri" do - request = stub_request 'REQUEST_URI' => "http://www.rubyonrails.org/path/of/some/uri?mapped=1" + request = stub_request 'SCRIPT_NAME' => '', 'PATH_INFO' => '/path/of/some/uri', 'QUERY_STRING' => 'mapped=1' assert_equal "/path/of/some/uri?mapped=1", request.request_uri assert_equal "/path/of/some/uri", request.path - request = stub_request 'REQUEST_URI' => "http://www.rubyonrails.org/path/of/some/uri" + request = stub_request 'SCRIPT_NAME' => '', 'PATH_INFO' => '/path/of/some/uri' assert_equal "/path/of/some/uri", request.request_uri assert_equal "/path/of/some/uri", request.path - request = stub_request 'REQUEST_URI' => "/path/of/some/uri" - assert_equal "/path/of/some/uri", request.request_uri - assert_equal "/path/of/some/uri", request.path - - request = stub_request 'REQUEST_URI' => "/" + request = stub_request 'SCRIPT_NAME' => '', 'PATH_INFO' => '/' assert_equal "/", request.request_uri assert_equal "/", request.path - request = stub_request 'REQUEST_URI' => "/?m=b" + request = stub_request 'SCRIPT_NAME' => '', 'PATH_INFO' => '/', 'QUERY_STRING' => 'm=b' assert_equal "/?m=b", request.request_uri assert_equal "/", request.path - request = stub_request 'REQUEST_URI' => "/", 'SCRIPT_NAME' => '/dispatch.cgi' - assert_equal "/", request.request_uri - assert_equal "/", request.path - - ActionController::Base.relative_url_root = "/hieraki" - request = stub_request 'REQUEST_URI' => "/hieraki/", 'SCRIPT_NAME' => "/hieraki/dispatch.cgi" + request = stub_request 'SCRIPT_NAME' => '/hieraki', 'PATH_INFO' => '/' assert_equal "/hieraki/", request.request_uri assert_equal "/", request.path - ActionController::Base.relative_url_root = nil - ActionController::Base.relative_url_root = "/collaboration/hieraki" - request = stub_request 'REQUEST_URI' => "/collaboration/hieraki/books/edit/2", - 'SCRIPT_NAME' => "/collaboration/hieraki/dispatch.cgi" + request = stub_request 'SCRIPT_NAME' => '/collaboration/hieraki', 'PATH_INFO' => '/books/edit/2' assert_equal "/collaboration/hieraki/books/edit/2", request.request_uri assert_equal "/books/edit/2", request.path - ActionController::Base.relative_url_root = nil - - # The following tests are for when REQUEST_URI is not supplied (as in IIS) - request = stub_request 'PATH_INFO' => "/path/of/some/uri?mapped=1", - 'SCRIPT_NAME' => nil, - 'REQUEST_URI' => nil - assert_equal "/path/of/some/uri?mapped=1", request.request_uri - assert_equal "/path/of/some/uri", request.path - ActionController::Base.relative_url_root = '/path' - request = stub_request 'PATH_INFO' => "/path/of/some/uri?mapped=1", - 'SCRIPT_NAME' => "/path/dispatch.rb", - 'REQUEST_URI' => nil + request = stub_request 'SCRIPT_NAME' => '/path', 'PATH_INFO' => '/of/some/uri', 'QUERY_STRING' => 'mapped=1' assert_equal "/path/of/some/uri?mapped=1", request.request_uri assert_equal "/of/some/uri", request.path - ActionController::Base.relative_url_root = nil - - request = stub_request 'PATH_INFO' => "/path/of/some/uri", - 'SCRIPT_NAME' => nil, - 'REQUEST_URI' => nil - assert_equal "/path/of/some/uri", request.request_uri - assert_equal "/path/of/some/uri", request.path - - request = stub_request 'PATH_INFO' => '/', 'REQUEST_URI' => nil - assert_equal "/", request.request_uri - assert_equal "/", request.path - - request = stub_request 'PATH_INFO' => '/?m=b', 'REQUEST_URI' => nil - assert_equal "/?m=b", request.request_uri - assert_equal "/", request.path - - request = stub_request 'PATH_INFO' => "/", - 'SCRIPT_NAME' => "/dispatch.cgi", - 'REQUEST_URI' => nil - assert_equal "/", request.request_uri - assert_equal "/", request.path - - ActionController::Base.relative_url_root = '/hieraki' - request = stub_request 'PATH_INFO' => "/hieraki/", - 'SCRIPT_NAME' => "/hieraki/dispatch.cgi", - 'REQUEST_URI' => nil - assert_equal "/hieraki/", request.request_uri - assert_equal "/", request.path - ActionController::Base.relative_url_root = nil - - request = stub_request 'REQUEST_URI' => '/hieraki/dispatch.cgi' - ActionController::Base.relative_url_root = '/hieraki' - assert_equal "/dispatch.cgi", request.path - ActionController::Base.relative_url_root = nil - - request = stub_request 'REQUEST_URI' => '/hieraki/dispatch.cgi' - ActionController::Base.relative_url_root = '/foo' - assert_equal "/hieraki/dispatch.cgi", request.path - ActionController::Base.relative_url_root = nil - - # This test ensures that Rails uses REQUEST_URI over PATH_INFO - ActionController::Base.relative_url_root = nil - request = stub_request 'REQUEST_URI' => "/some/path", - 'PATH_INFO' => "/another/path", - 'SCRIPT_NAME' => "/dispatch.cgi" - assert_equal "/some/path", request.request_uri - assert_equal "/some/path", request.path end @@ -498,7 +428,7 @@ class RequestTest < ActiveSupport::TestCase protected - def stub_request(env={}) + def stub_request(env = {}) ActionDispatch::Request.new(env) end diff --git a/actionpack/test/template/url_helper_test.rb b/actionpack/test/template/url_helper_test.rb index b047466aaf..afec78ddce 100644 --- a/actionpack/test/template/url_helper_test.rb +++ b/actionpack/test/template/url_helper_test.rb @@ -464,8 +464,6 @@ end class LinkToUnlessCurrentWithControllerTest < ActionController::TestCase def setup super - @request = ActionController::TestRequest.new - @response = ActionController::TestResponse.new @controller = TasksController.new end @@ -565,7 +563,6 @@ end class PolymorphicControllerTest < ActionController::TestCase def setup super - @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new end -- cgit v1.2.3 From c92d598abff54270337ad1eddf7bc41a71c4cbda Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Wed, 3 Mar 2010 00:03:29 -0800 Subject: Rack::Request actually defines #query_string --- actionpack/lib/action_dispatch/http/url.rb | 5 ----- 1 file changed, 5 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/http/url.rb b/actionpack/lib/action_dispatch/http/url.rb index e67d970a23..049e1758fe 100644 --- a/actionpack/lib/action_dispatch/http/url.rb +++ b/actionpack/lib/action_dispatch/http/url.rb @@ -85,11 +85,6 @@ module ActionDispatch subdomains(tld_length).join('.') end - # The query string must always be present - def query_string - @env['QUERY_STRING'] - end - # Returns the request URI, accounting for server idiosyncrasies. # WEBrick includes the full URL. IIS leaves REQUEST_URI blank. def request_uri -- cgit v1.2.3 From eb49bd694997954783632eada901553f041c9507 Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Wed, 3 Mar 2010 00:03:56 -0800 Subject: Fix tests for the request refactor --- actionpack/test/controller/caching_test.rb | 3 +- actionpack/test/controller/test_test.rb | 6 ++-- actionpack/test/template/url_helper_test.rb | 52 +++++++++++++++++++---------- 3 files changed, 40 insertions(+), 21 deletions(-) (limited to 'actionpack') diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index 80c968cc04..37f7483427 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -51,6 +51,7 @@ class PageCachingTest < ActionController::TestCase @request = ActionController::TestRequest.new @request.host = 'hostname.com' + @request.env.delete('PATH_INFO') @response = ActionController::TestResponse.new @controller = PageCachingTestController.new @@ -110,7 +111,7 @@ class PageCachingTest < ActionController::TestCase end def test_should_cache_ok_at_custom_path - @request.request_uri = "/index.html" + @request.env['PATH_INFO'] = '/index.html' get :ok assert_response :ok assert File.exist?("#{FILE_STORE_PATH}/index.html") diff --git a/actionpack/test/controller/test_test.rb b/actionpack/test/controller/test_test.rb index d716dc2661..7312c5dfcc 100644 --- a/actionpack/test/controller/test_test.rb +++ b/actionpack/test/controller/test_test.rb @@ -128,6 +128,7 @@ XML @controller = TestController.new @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new + @request.env['PATH_INFO'] = nil end def test_raw_post_handling @@ -199,7 +200,7 @@ XML end def test_process_with_request_uri_with_params_with_explicit_uri - @request.request_uri = "/explicit/uri" + @request.env['PATH_INFO'] = "/explicit/uri" process :test_uri, :id => 7 assert_equal "/explicit/uri", @response.body end @@ -210,7 +211,8 @@ XML end def test_process_with_query_string_with_explicit_uri - @request.request_uri = "/explicit/uri?q=test?extra=question" + @request.env['PATH_INFO'] = '/explicit/uri' + @request.env['QUERY_STRING'] = 'q=test?extra=question' process :test_query_string assert_equal "q=test?extra=question", @response.body end diff --git a/actionpack/test/template/url_helper_test.rb b/actionpack/test/template/url_helper_test.rb index afec78ddce..d8ccb380a6 100644 --- a/actionpack/test/template/url_helper_test.rb +++ b/actionpack/test/template/url_helper_test.rb @@ -1,9 +1,8 @@ # encoding: utf-8 require 'abstract_unit' +require 'active_support/ordered_options' require 'controller/fake_controllers' -RequestMock = Struct.new("Request", :request_uri, :protocol, :host_with_port, :env) - class UrlHelperTest < ActionView::TestCase include ActiveSupport::Configurable DEFAULT_CONFIG = ActionView::DEFAULT_CONFIG @@ -15,8 +14,13 @@ class UrlHelperTest < ActionView::TestCase def url_for(options) url end + def config + ActiveSupport::InheritableOptions.new({}) + end end + @controller = @controller.new + @request = @controller.request = ActionDispatch::TestRequest.new @controller.url = "http://www.example.com" end @@ -38,12 +42,13 @@ class UrlHelperTest < ActionView::TestCase end def test_url_for_with_back - @controller.request = RequestMock.new("http://www.example.com/weblog/show", nil, nil, {'HTTP_REFERER' => 'http://www.example.com/referer'}) + @request.env['HTTP_REFERER'] = 'http://www.example.com/referer' assert_equal 'http://www.example.com/referer', url_for(:back) end def test_url_for_with_back_and_no_referer - @controller.request = RequestMock.new("http://www.example.com/weblog/show", nil, nil, {}) + @request.env['HOST_NAME'] = 'www.example.com' + @request.env['PATH_INFO'] = '/weblog/show' assert_equal 'javascript:history.back()', url_for(:back) end @@ -144,22 +149,28 @@ class UrlHelperTest < ActionView::TestCase end def test_link_tag_with_back - @controller.request = RequestMock.new("http://www.example.com/weblog/show", nil, nil, {'HTTP_REFERER' => 'http://www.example.com/referer'}) + @request.env['HOST_NAME'] = 'www.example.com' + @request.env['PATH_INFO'] = '/weblog/show' + @request.env['HTTP_REFERER'] = 'http://www.example.com/referer' assert_dom_equal "go back", link_to('go back', :back) end def test_link_tag_with_back_and_no_referer - @controller.request = RequestMock.new("http://www.example.com/weblog/show", nil, nil, {}) + @request.env['HOST_NAME'] = 'www.example.com' + @request.env['PATH_INFO'] = '/weblog/show' assert_dom_equal "go back", link_to('go back', :back) end def test_link_tag_with_back - @controller.request = RequestMock.new("http://www.example.com/weblog/show", nil, nil, {'HTTP_REFERER' => 'http://www.example.com/referer'}) + @request.env['HOST_NAME'] = 'www.example.com' + @request.env['PATH_INFO'] = '/weblog/show' + @request.env['HTTP_REFERER'] = 'http://www.example.com/referer' assert_dom_equal "go back", link_to('go back', :back) end def test_link_tag_with_back_and_no_referer - @controller.request = RequestMock.new("http://www.example.com/weblog/show", nil, nil, {}) + @request.env['HOST_NAME'] = 'www.example.com' + @request.env['PATH_INFO'] = '/weblog/show' assert_dom_equal "go back", link_to('go back', :back) end @@ -263,55 +274,60 @@ class UrlHelperTest < ActionView::TestCase end def test_current_page_with_simple_url - @controller.request = RequestMock.new("http://www.example.com/weblog/show") + @request.env['HTTP_HOST'] = 'www.example.com' + @request.env['PATH_INFO'] = '/weblog/show' @controller.url = "http://www.example.com/weblog/show" assert current_page?({ :action => "show", :controller => "weblog" }) assert current_page?("http://www.example.com/weblog/show") end def test_current_page_ignoring_params - @controller.request = RequestMock.new("http://www.example.com/weblog/show?order=desc&page=1") + @request.env['HTTP_HOST'] = 'www.example.com' + @request.env['PATH_INFO'] = '/weblog/show' + @request.env['QUERY_STRING'] = 'order=desc&page=1' @controller.url = "http://www.example.com/weblog/show?order=desc&page=1" assert current_page?({ :action => "show", :controller => "weblog" }) assert current_page?("http://www.example.com/weblog/show") end def test_current_page_with_params_that_match - @controller.request = RequestMock.new("http://www.example.com/weblog/show?order=desc&page=1") + @request.env['HTTP_HOST'] = 'www.example.com' + @request.env['PATH_INFO'] = '/weblog/show' + @request.env['QUERY_STRING'] = 'order=desc&page=1' @controller.url = "http://www.example.com/weblog/show?order=desc&page=1" assert current_page?({ :action => "show", :controller => "weblog", :order => "desc", :page => "1" }) assert current_page?("http://www.example.com/weblog/show?order=desc&page=1") end def test_link_unless_current - @controller.request = RequestMock.new("http://www.example.com/weblog/show") + @request.env['HTTP_HOST'] = 'www.example.com' + @request.env['PATH_INFO'] = '/weblog/show' @controller.url = "http://www.example.com/weblog/show" assert_equal "Showing", link_to_unless_current("Showing", { :action => "show", :controller => "weblog" }) assert_equal "Showing", link_to_unless_current("Showing", "http://www.example.com/weblog/show") - @controller.request = RequestMock.new("http://www.example.com/weblog/show?order=desc") + @request.env['QUERY_STRING'] = 'order=desc' @controller.url = "http://www.example.com/weblog/show" assert_equal "Showing", link_to_unless_current("Showing", { :action => "show", :controller => "weblog" }) assert_equal "Showing", link_to_unless_current("Showing", "http://www.example.com/weblog/show") - @controller.request = RequestMock.new("http://www.example.com/weblog/show?order=desc&page=1") + @request.env['QUERY_STRING'] = 'order=desc&page=1' @controller.url = "http://www.example.com/weblog/show?order=desc&page=1" assert_equal "Showing", link_to_unless_current("Showing", { :action => "show", :controller => "weblog", :order=>'desc', :page=>'1' }) assert_equal "Showing", link_to_unless_current("Showing", "http://www.example.com/weblog/show?order=desc&page=1") assert_equal "Showing", link_to_unless_current("Showing", "http://www.example.com/weblog/show?order=desc&page=1") - @controller.request = RequestMock.new("http://www.example.com/weblog/show?order=desc") + @request.env['QUERY_STRING'] = 'order=desc' @controller.url = "http://www.example.com/weblog/show?order=asc" assert_equal "Showing", link_to_unless_current("Showing", { :action => "show", :controller => "weblog" }) assert_equal "Showing", link_to_unless_current("Showing", "http://www.example.com/weblog/show?order=asc") - @controller.request = RequestMock.new("http://www.example.com/weblog/show?order=desc&page=1") + @request.env['QUERY_STRING'] = 'order=desc&page=1' @controller.url = "http://www.example.com/weblog/show?order=desc&page=2" assert_equal "Showing", link_to_unless_current("Showing", { :action => "show", :controller => "weblog" }) assert_equal "Showing", link_to_unless_current("Showing", "http://www.example.com/weblog/show?order=desc&page=2") - - @controller.request = RequestMock.new("http://www.example.com/weblog/show") + @request.env['QUERY_STRING'] = '' @controller.url = "http://www.example.com/weblog/list" assert_equal "Listing", link_to_unless_current("Listing", :action => "list", :controller => "weblog") -- cgit v1.2.3 From fb14b8c6fddae818b2688ac1e584534390c37f72 Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Wed, 3 Mar 2010 00:31:55 -0800 Subject: ActionDispatch::Request deprecates #request_uri * Refactored ActionPatch to use fullpath instead --- .../action_controller/metal/http_authentication.rb | 2 +- .../lib/action_controller/metal/instrumentation.rb | 2 +- actionpack/lib/action_dispatch/http/url.rb | 13 +++------- .../lib/action_view/helpers/atom_feed_helper.rb | 2 +- actionpack/test/controller/integration_test.rb | 2 +- actionpack/test/controller/test_test.rb | 2 +- actionpack/test/dispatch/request_test.rb | 30 +++++++++++----------- 7 files changed, 23 insertions(+), 30 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/http_authentication.rb b/actionpack/lib/action_controller/metal/http_authentication.rb index 5c6641c948..afa7674e40 100644 --- a/actionpack/lib/action_controller/metal/http_authentication.rb +++ b/actionpack/lib/action_controller/metal/http_authentication.rb @@ -198,7 +198,7 @@ module ActionController return false unless password method = request.env['rack.methodoverride.original_method'] || request.env['REQUEST_METHOD'] - uri = credentials[:uri][0,1] == '/' ? request.request_uri : request.url + uri = credentials[:uri][0,1] == '/' ? request.fullpath : request.url [true, false].any? do |password_is_ha1| expected = expected_response(method, uri, credentials, password, password_is_ha1) diff --git a/actionpack/lib/action_controller/metal/instrumentation.rb b/actionpack/lib/action_controller/metal/instrumentation.rb index 85035dc09c..d69de65f28 100644 --- a/actionpack/lib/action_controller/metal/instrumentation.rb +++ b/actionpack/lib/action_controller/metal/instrumentation.rb @@ -20,7 +20,7 @@ module ActionController :params => request.filtered_parameters, :formats => request.formats.map(&:to_sym), :method => request.method, - :path => (request.request_uri rescue "unknown") + :path => (request.fullpath rescue "unknown") } ActiveSupport::Notifications.instrument("action_controller.start_processing", raw_payload.dup) diff --git a/actionpack/lib/action_dispatch/http/url.rb b/actionpack/lib/action_dispatch/http/url.rb index 049e1758fe..f7afbe7fed 100644 --- a/actionpack/lib/action_dispatch/http/url.rb +++ b/actionpack/lib/action_dispatch/http/url.rb @@ -3,7 +3,7 @@ module ActionDispatch module URL # Returns the complete URL used for this request. def url - protocol + host_with_port + request_uri + protocol + host_with_port + fullpath end # Returns 'https://' if this is an SSL request and 'http://' otherwise. @@ -88,15 +88,8 @@ module ActionDispatch # Returns the request URI, accounting for server idiosyncrasies. # WEBrick includes the full URL. IIS leaves REQUEST_URI blank. def request_uri - uri = "#{@env["SCRIPT_NAME"]}#{@env["PATH_INFO"]}" - uri << "?#{@env["QUERY_STRING"]}" if @env["QUERY_STRING"].present? - uri - end - - # Returns the interpreted \path to requested resource after all the installation - # directory of this application was taken into account. - def path - @env['PATH_INFO'] + ActiveSupport::Deprecation.warn "Using #request_uri is deprecated. Use fullpath instead." + fullpath end private diff --git a/actionpack/lib/action_view/helpers/atom_feed_helper.rb b/actionpack/lib/action_view/helpers/atom_feed_helper.rb index a26a8c9b4b..58c3a8752e 100644 --- a/actionpack/lib/action_view/helpers/atom_feed_helper.rb +++ b/actionpack/lib/action_view/helpers/atom_feed_helper.rb @@ -114,7 +114,7 @@ module ActionView feed_opts.merge!(options).reject!{|k,v| !k.to_s.match(/^xml/)} xml.feed(feed_opts) do - xml.id(options[:id] || "tag:#{request.host},#{options[:schema_date]}:#{request.request_uri.split(".")[0]}") + xml.id(options[:id] || "tag:#{request.host},#{options[:schema_date]}:#{request.fullpath.split(".")[0]}") xml.link(:rel => 'alternate', :type => 'text/html', :href => options[:root_url] || (request.protocol + request.host_with_port)) xml.link(:rel => 'self', :type => 'application/atom+xml', :href => options[:url] || request.url) diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb index 814699978d..5cb6aa6997 100644 --- a/actionpack/test/controller/integration_test.rb +++ b/actionpack/test/controller/integration_test.rb @@ -333,7 +333,7 @@ class IntegrationProcessTest < ActionController::IntegrationTest with_test_route_set do get '/get_with_params?foo=bar' assert_equal '/get_with_params?foo=bar', request.env["REQUEST_URI"] - assert_equal '/get_with_params?foo=bar', request.request_uri + assert_equal '/get_with_params?foo=bar', request.fullpath assert_equal "foo=bar", request.env["QUERY_STRING"] assert_equal 'foo=bar', request.query_string assert_equal 'bar', request.parameters['foo'] diff --git a/actionpack/test/controller/test_test.rb b/actionpack/test/controller/test_test.rb index 7312c5dfcc..f6ba275849 100644 --- a/actionpack/test/controller/test_test.rb +++ b/actionpack/test/controller/test_test.rb @@ -42,7 +42,7 @@ class TestTest < ActionController::TestCase end def test_uri - render :text => request.request_uri + render :text => request.fullpath end def test_query_string diff --git a/actionpack/test/dispatch/request_test.rb b/actionpack/test/dispatch/request_test.rb index 1dfcdaebfd..84c06ca113 100644 --- a/actionpack/test/dispatch/request_test.rb +++ b/actionpack/test/dispatch/request_test.rb @@ -143,34 +143,34 @@ class RequestTest < ActiveSupport::TestCase assert_equal ":8080", request.port_string end - test "request uri" do + test "full path" do request = stub_request 'SCRIPT_NAME' => '', 'PATH_INFO' => '/path/of/some/uri', 'QUERY_STRING' => 'mapped=1' - assert_equal "/path/of/some/uri?mapped=1", request.request_uri - assert_equal "/path/of/some/uri", request.path + assert_equal "/path/of/some/uri?mapped=1", request.fullpath + assert_equal "/path/of/some/uri", request.path_info request = stub_request 'SCRIPT_NAME' => '', 'PATH_INFO' => '/path/of/some/uri' - assert_equal "/path/of/some/uri", request.request_uri - assert_equal "/path/of/some/uri", request.path + assert_equal "/path/of/some/uri", request.fullpath + assert_equal "/path/of/some/uri", request.path_info request = stub_request 'SCRIPT_NAME' => '', 'PATH_INFO' => '/' - assert_equal "/", request.request_uri - assert_equal "/", request.path + assert_equal "/", request.fullpath + assert_equal "/", request.path_info request = stub_request 'SCRIPT_NAME' => '', 'PATH_INFO' => '/', 'QUERY_STRING' => 'm=b' - assert_equal "/?m=b", request.request_uri - assert_equal "/", request.path + assert_equal "/?m=b", request.fullpath + assert_equal "/", request.path_info request = stub_request 'SCRIPT_NAME' => '/hieraki', 'PATH_INFO' => '/' - assert_equal "/hieraki/", request.request_uri - assert_equal "/", request.path + assert_equal "/hieraki/", request.fullpath + assert_equal "/", request.path_info request = stub_request 'SCRIPT_NAME' => '/collaboration/hieraki', 'PATH_INFO' => '/books/edit/2' - assert_equal "/collaboration/hieraki/books/edit/2", request.request_uri - assert_equal "/books/edit/2", request.path + assert_equal "/collaboration/hieraki/books/edit/2", request.fullpath + assert_equal "/books/edit/2", request.path_info request = stub_request 'SCRIPT_NAME' => '/path', 'PATH_INFO' => '/of/some/uri', 'QUERY_STRING' => 'mapped=1' - assert_equal "/path/of/some/uri?mapped=1", request.request_uri - assert_equal "/of/some/uri", request.path + assert_equal "/path/of/some/uri?mapped=1", request.fullpath + assert_equal "/of/some/uri", request.path_info end -- cgit v1.2.3 From 18bcce596efaa4e77a202431ab5e736001a394c6 Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Wed, 3 Mar 2010 09:32:27 -0800 Subject: ActionController::Base.use_accept_header is not actually used anymore, so let's deprecate it. --- actionpack/lib/action_controller/metal/compatibility.rb | 10 ++++++++-- actionpack/test/controller/caching_test.rb | 3 --- actionpack/test/controller/content_type_test.rb | 12 ------------ actionpack/test/controller/mime_responds_test.rb | 4 ---- actionpack/test/dispatch/request_test.rb | 7 ------- 5 files changed, 8 insertions(+), 28 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb index 93f7b8ca49..d6d8d612a3 100644 --- a/actionpack/lib/action_controller/metal/compatibility.rb +++ b/actionpack/lib/action_controller/metal/compatibility.rb @@ -35,8 +35,14 @@ module ActionController cattr_accessor :resource_action_separator self.resource_action_separator = "/" - cattr_accessor :use_accept_header - self.use_accept_header = true + def self.use_accept_header + ActiveSupport::Deprecation.warn "ActionController::Base.use_accept_header doesn't do anything anymore. " \ + "The accept header is always taken into account." + end + + def self.use_accept_header=(val) + use_accept_header + end self.page_cache_directory = defined?(Rails.public_path) ? Rails.public_path : "" diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index 37f7483427..e42ef85b98 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -306,12 +306,9 @@ class ActionCacheTest < ActionController::TestCase end def test_action_cache_conditional_options - old_use_accept_header = ActionController::Base.use_accept_header - ActionController::Base.use_accept_header = true @request.env['HTTP_ACCEPT'] = 'application/json' get :index assert !fragment_exist?('hostname.com/action_caching_test') - ActionController::Base.use_accept_header = old_use_accept_header end def test_action_cache_with_store_options diff --git a/actionpack/test/controller/content_type_test.rb b/actionpack/test/controller/content_type_test.rb index e5ffe20ecc..967107853b 100644 --- a/actionpack/test/controller/content_type_test.rb +++ b/actionpack/test/controller/content_type_test.rb @@ -145,18 +145,6 @@ end class AcceptBasedContentTypeTest < ActionController::TestCase tests OldContentTypeController - def setup - super - @_old_accept_header = ActionController::Base.use_accept_header - ActionController::Base.use_accept_header = true - end - - def teardown - super - ActionController::Base.use_accept_header = @_old_accept_header - end - - def test_render_default_content_types_for_respond_to @request.accept = Mime::HTML.to_s get :render_default_content_types_for_respond_to diff --git a/actionpack/test/controller/mime_responds_test.rb b/actionpack/test/controller/mime_responds_test.rb index 5e34773899..5c1eaf453c 100644 --- a/actionpack/test/controller/mime_responds_test.rb +++ b/actionpack/test/controller/mime_responds_test.rb @@ -155,13 +155,11 @@ class RespondToControllerTest < ActionController::TestCase def setup super - ActionController::Base.use_accept_header = true @request.host = "www.example.com" end def teardown super - ActionController::Base.use_accept_header = false end def test_html @@ -544,13 +542,11 @@ class RespondWithControllerTest < ActionController::TestCase def setup super - ActionController::Base.use_accept_header = true @request.host = "www.example.com" end def teardown super - ActionController::Base.use_accept_header = false end def test_using_resource diff --git a/actionpack/test/dispatch/request_test.rb b/actionpack/test/dispatch/request_test.rb index 84c06ca113..78200ca17e 100644 --- a/actionpack/test/dispatch/request_test.rb +++ b/actionpack/test/dispatch/request_test.rb @@ -435,11 +435,4 @@ protected def with_set(*args) args end - - def with_accept_header(value) - ActionController::Base.use_accept_header, old = value, ActionController::Base.use_accept_header - yield - ensure - ActionController::Base.use_accept_header = old - end end -- cgit v1.2.3 From 902d5a4f05c879674a3d010ac8ca76902308e18e Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Wed, 3 Mar 2010 09:41:23 -0800 Subject: Indicate that ActionController::Base.resource_action_separator is deprecated and only has an effect with the deprecated router DSL. --- actionpack/lib/action_controller/metal/compatibility.rb | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb index d6d8d612a3..1a4d0349fe 100644 --- a/actionpack/lib/action_controller/metal/compatibility.rb +++ b/actionpack/lib/action_controller/metal/compatibility.rb @@ -32,8 +32,15 @@ module ActionController @_response) # Controls the resource action separator - cattr_accessor :resource_action_separator - self.resource_action_separator = "/" + def self.resource_action_separator + @resource_action_separator ||= "/" + end + + def self.resource_action_separator=(val) + ActiveSupport::Deprecation.warn "ActionController::Base.resource_action_separator is deprecated and only " \ + "works with the deprecated router DSL." + @resource_action_separator = val + end def self.use_accept_header ActiveSupport::Deprecation.warn "ActionController::Base.use_accept_header doesn't do anything anymore. " \ -- cgit v1.2.3 From 9a9caf646d020e33ccdeac0f9b114acec019b599 Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Wed, 3 Mar 2010 11:01:49 -0800 Subject: Add a BlockUntrustedIps middleware --- actionpack/lib/action_dispatch.rb | 1 + .../middleware/block_untrusted_ips.rb | 25 ++++++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 actionpack/lib/action_dispatch/middleware/block_untrusted_ips.rb (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch.rb b/actionpack/lib/action_dispatch.rb index 479ea959e6..1abb283b11 100644 --- a/actionpack/lib/action_dispatch.rb +++ b/actionpack/lib/action_dispatch.rb @@ -42,6 +42,7 @@ module ActionDispatch end autoload_under 'middleware' do + autoload :BlockUntrustedIps autoload :Callbacks autoload :Cascade autoload :Cookies diff --git a/actionpack/lib/action_dispatch/middleware/block_untrusted_ips.rb b/actionpack/lib/action_dispatch/middleware/block_untrusted_ips.rb new file mode 100644 index 0000000000..8aed0c45a6 --- /dev/null +++ b/actionpack/lib/action_dispatch/middleware/block_untrusted_ips.rb @@ -0,0 +1,25 @@ +module ActionDispatch + class BlockUntrustedIps + class SpoofAttackError < StandardError ; end + + def initialize(app) + @app = app + end + + def call(env) + if @env['HTTP_X_FORWARDED_FOR'] && @env['HTTP_CLIENT_IP'] + remote_ips = @env['HTTP_X_FORWARDED_FOR'].split(',') + + unless remote_ips.include?(@env['HTTP_CLIENT_IP']) + http_client_ip = @env['HTTP_CLIENT_IP'].inspect + http_forwarded_for = @env['HTTP_X_FORWARDED_FOR'].inspect + + raise SpoofAttackError, "IP spoofing attack?!\n " \ + "HTTP_CLIENT_IP=#{http_client_ip}\n HTTP_X_FORWARDED_FOR=http_forwarded_for" + end + end + + @app.call(env) + end + end +end \ No newline at end of file -- cgit v1.2.3 From 93422af5d5bc0285bd72cfb2fd9b59f6d64ba141 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Wed, 3 Mar 2010 16:22:30 -0800 Subject: Move remote_ip to a middleware: * ActionController::Base.ip_spoofing_check deprecated => config.action_dispatch.ip_spoofing_check * ActionController::Base.trusted_proxies deprecated => config.action_dispatch.trusted_proxies --- actionpack/lib/action_dispatch.rb | 2 +- actionpack/lib/action_dispatch/http/request.rb | 31 +------------ .../middleware/block_untrusted_ips.rb | 25 ----------- .../lib/action_dispatch/middleware/remote_ip.rb | 51 ++++++++++++++++++++++ actionpack/lib/action_dispatch/railtie.rb | 1 + actionpack/test/dispatch/request_test.rb | 12 ++--- 6 files changed, 61 insertions(+), 61 deletions(-) delete mode 100644 actionpack/lib/action_dispatch/middleware/block_untrusted_ips.rb create mode 100644 actionpack/lib/action_dispatch/middleware/remote_ip.rb (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch.rb b/actionpack/lib/action_dispatch.rb index 1abb283b11..dfb8919561 100644 --- a/actionpack/lib/action_dispatch.rb +++ b/actionpack/lib/action_dispatch.rb @@ -42,13 +42,13 @@ module ActionDispatch end autoload_under 'middleware' do - autoload :BlockUntrustedIps autoload :Callbacks autoload :Cascade autoload :Cookies autoload :Flash autoload :Head autoload :ParamsParser + autoload :RemoteIp autoload :Rescue autoload :ShowExceptions autoload :Static diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb index 7a17023ed2..56a2b9bf6a 100755 --- a/actionpack/lib/action_dispatch/http/request.rb +++ b/actionpack/lib/action_dispatch/http/request.rb @@ -119,36 +119,7 @@ module ActionDispatch # delimited list in the case of multiple chained proxies; the last # address which is not trusted is the originating IP. def remote_ip - remote_addr_list = @env['REMOTE_ADDR'] && @env['REMOTE_ADDR'].scan(/[^,\s]+/) - - unless remote_addr_list.blank? - not_trusted_addrs = remote_addr_list.reject {|addr| addr =~ TRUSTED_PROXIES || addr =~ ActionController::Base.trusted_proxies} - return not_trusted_addrs.first unless not_trusted_addrs.empty? - end - remote_ips = @env['HTTP_X_FORWARDED_FOR'] && @env['HTTP_X_FORWARDED_FOR'].split(',') - - if @env.include? 'HTTP_CLIENT_IP' - if ActionController::Base.ip_spoofing_check && remote_ips && !remote_ips.include?(@env['HTTP_CLIENT_IP']) - # We don't know which came from the proxy, and which from the user - raise ActionController::ActionControllerError.new < 1 && (TRUSTED_PROXIES =~ remote_ips.last.strip || ActionController::Base.trusted_proxies =~ remote_ips.last.strip) - remote_ips.pop - end - - return remote_ips.last.strip - end - - @env['REMOTE_ADDR'] + (@env["action_dispatch.remote_ip"] || ip).to_s end # Returns the lowercase name of the HTTP server software. diff --git a/actionpack/lib/action_dispatch/middleware/block_untrusted_ips.rb b/actionpack/lib/action_dispatch/middleware/block_untrusted_ips.rb deleted file mode 100644 index 8aed0c45a6..0000000000 --- a/actionpack/lib/action_dispatch/middleware/block_untrusted_ips.rb +++ /dev/null @@ -1,25 +0,0 @@ -module ActionDispatch - class BlockUntrustedIps - class SpoofAttackError < StandardError ; end - - def initialize(app) - @app = app - end - - def call(env) - if @env['HTTP_X_FORWARDED_FOR'] && @env['HTTP_CLIENT_IP'] - remote_ips = @env['HTTP_X_FORWARDED_FOR'].split(',') - - unless remote_ips.include?(@env['HTTP_CLIENT_IP']) - http_client_ip = @env['HTTP_CLIENT_IP'].inspect - http_forwarded_for = @env['HTTP_X_FORWARDED_FOR'].inspect - - raise SpoofAttackError, "IP spoofing attack?!\n " \ - "HTTP_CLIENT_IP=#{http_client_ip}\n HTTP_X_FORWARDED_FOR=http_forwarded_for" - end - end - - @app.call(env) - end - end -end \ No newline at end of file diff --git a/actionpack/lib/action_dispatch/middleware/remote_ip.rb b/actionpack/lib/action_dispatch/middleware/remote_ip.rb new file mode 100644 index 0000000000..c7d710b98e --- /dev/null +++ b/actionpack/lib/action_dispatch/middleware/remote_ip.rb @@ -0,0 +1,51 @@ +module ActionDispatch + class RemoteIp + class IpSpoofAttackError < StandardError ; end + + class RemoteIpGetter + def initialize(env, check_ip_spoofing, trusted_proxies) + @env = env + @check_ip_spoofing = check_ip_spoofing + @trusted_proxies = trusted_proxies + end + + def remote_addrs + @remote_addrs ||= begin + list = @env['REMOTE_ADDR'] ? @env['REMOTE_ADDR'].split(/[,\s]+/) : [] + list.reject { |addr| addr =~ @trusted_proxies } + end + end + + def to_s + return remote_addrs.first if remote_addrs.any? + + forwarded_ips = @env['HTTP_X_FORWARDED_FOR'] ? @env['HTTP_X_FORWARDED_FOR'].strip.split(/[,\s]+/) : [] + + if client_ip = @env['HTTP_CLIENT_IP'] + if @check_ip_spoofing && !forwarded_ips.include?(client_ip) + # We don't know which came from the proxy, and which from the user + raise IpSpoofAttackError, "IP spoofing attack?!" \ + "HTTP_CLIENT_IP=#{@env['HTTP_CLIENT_IP'].inspect}" \ + "HTTP_X_FORWARDED_FOR=#{@env['HTTP_X_FORWARDED_FOR'].inspect}" + end + return client_ip + end + + return forwarded_ips.reject { |ip| ip =~ @trusted_proxies }.last || @env["REMOTE_ADDR"] + end + end + + def initialize(app, check_ip_spoofing = true, trusted_proxies = nil) + @app = app + @check_ip_spoofing = check_ip_spoofing + regex = '(^127\.0\.0\.1$|^(10|172\.(1[6-9]|2[0-9]|30|31)|192\.168)\.)' + regex << "|(#{trusted_proxies})" if trusted_proxies + @trusted_proxies = Regexp.new(regex, "i") + end + + def call(env) + env["action_dispatch.remote_ip"] = RemoteIpGetter.new(env, @check_ip_spoofing, @trusted_proxies) + @app.call(env) + end + end +end \ No newline at end of file diff --git a/actionpack/lib/action_dispatch/railtie.rb b/actionpack/lib/action_dispatch/railtie.rb index 79e9464337..e486bd4079 100644 --- a/actionpack/lib/action_dispatch/railtie.rb +++ b/actionpack/lib/action_dispatch/railtie.rb @@ -6,6 +6,7 @@ module ActionDispatch railtie_name :action_dispatch config.action_dispatch.x_sendfile_header = "X-Sendfile" + config.action_dispatch.ip_spoofing_check = true # Prepare dispatcher callbacks and run 'prepare' callbacks initializer "action_dispatch.prepare_dispatcher" do |app| diff --git a/actionpack/test/dispatch/request_test.rb b/actionpack/test/dispatch/request_test.rb index 78200ca17e..3a07185586 100644 --- a/actionpack/test/dispatch/request_test.rb +++ b/actionpack/test/dispatch/request_test.rb @@ -42,7 +42,7 @@ class RequestTest < ActiveSupport::TestCase request = stub_request 'HTTP_X_FORWARDED_FOR' => '1.1.1.1', 'HTTP_CLIENT_IP' => '2.2.2.2' - e = assert_raise(ActionController::ActionControllerError) { + e = assert_raise(ActionDispatch::RemoteIp::IpSpoofAttackError) { request.remote_ip } assert_match /IP spoofing attack/, e.message @@ -54,18 +54,17 @@ class RequestTest < ActiveSupport::TestCase # example is WAP. Since the cellular network is not IP based, it's a # leap of faith to assume that their proxies are ever going to set the # HTTP_CLIENT_IP/HTTP_X_FORWARDED_FOR headers properly. - ActionController::Base.ip_spoofing_check = false request = stub_request 'HTTP_X_FORWARDED_FOR' => '1.1.1.1', - 'HTTP_CLIENT_IP' => '2.2.2.2' + 'HTTP_CLIENT_IP' => '2.2.2.2', + :ip_spoofing_check => false assert_equal '2.2.2.2', request.remote_ip - ActionController::Base.ip_spoofing_check = true request = stub_request 'HTTP_X_FORWARDED_FOR' => '8.8.8.8, 9.9.9.9' assert_equal '9.9.9.9', request.remote_ip end test "remote ip with user specified trusted proxies" do - ActionController::Base.trusted_proxies = /^67\.205\.106\.73$/i + @trusted_proxies = /^67\.205\.106\.73$/i request = stub_request 'REMOTE_ADDR' => '67.205.106.73', 'HTTP_X_FORWARDED_FOR' => '3.4.5.6' @@ -429,6 +428,9 @@ class RequestTest < ActiveSupport::TestCase protected def stub_request(env = {}) + ip_spoofing_check = env.key?(:ip_spoofing_check) ? env.delete(:ip_spoofing_check) : true + ip_app = ActionDispatch::RemoteIp.new(Proc.new { }, ip_spoofing_check, @trusted_proxies) + ip_app.call(env) ActionDispatch::Request.new(env) end -- cgit v1.2.3 From 52efbdcdefa678ae2ee9530bcfefd0e2529b188f Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Wed, 3 Mar 2010 16:23:00 -0800 Subject: Add caller to request_uri deprecation notice --- actionpack/lib/action_dispatch/http/url.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/http/url.rb b/actionpack/lib/action_dispatch/http/url.rb index f7afbe7fed..b64a83c62e 100644 --- a/actionpack/lib/action_dispatch/http/url.rb +++ b/actionpack/lib/action_dispatch/http/url.rb @@ -88,7 +88,7 @@ module ActionDispatch # Returns the request URI, accounting for server idiosyncrasies. # WEBrick includes the full URL. IIS leaves REQUEST_URI blank. def request_uri - ActiveSupport::Deprecation.warn "Using #request_uri is deprecated. Use fullpath instead." + ActiveSupport::Deprecation.warn "Using #request_uri is deprecated. Use fullpath instead.", caller fullpath end -- cgit v1.2.3 From 786724107c3dedaeccaae9e187458b48df472f90 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Wed, 3 Mar 2010 16:32:27 -0800 Subject: Deprecate IP spoofing settings that are directly on the controller in favor of configuring a middleware --- .../lib/action_controller/metal/compatibility.rb | 33 +++++++++++++++++----- actionpack/test/dispatch/request_test.rb | 2 -- 2 files changed, 26 insertions(+), 9 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb index 1a4d0349fe..ab59ffc0b4 100644 --- a/actionpack/lib/action_controller/metal/compatibility.rb +++ b/actionpack/lib/action_controller/metal/compatibility.rb @@ -57,11 +57,6 @@ module ActionController # and images to a dedicated asset server away from the main web server. Example: # ActionController::Base.asset_host = "http://assets.example.com" cattr_accessor :asset_host - - cattr_accessor :ip_spoofing_check - self.ip_spoofing_check = true - - cattr_accessor :trusted_proxies end def self.deprecated_config_accessor(option, message = nil) @@ -119,7 +114,7 @@ module ActionController end def consider_all_requests_local=(value) - ActiveSupport::Deprecation.warn "ActionController::Base.consider_all_requests_local= is no longer effective. " << + ActiveSupport::Deprecation.warn "ActionController::Base.consider_all_requests_local= is deprecated. " << "Please configure it on your application with config.consider_all_requests_local=" Rails.application.config.consider_all_requests_local = value end @@ -131,11 +126,35 @@ module ActionController end def allow_concurrency=(value) - ActiveSupport::Deprecation.warn "ActionController::Base.allow_concurrency= is no longer effective. " << + ActiveSupport::Deprecation.warn "ActionController::Base.allow_concurrency= is deprecated. " << "Please configure it on your application with config.allow_concurrency=" Rails.application.config.allow_concurrency = value end + def ip_spoofing_check=(value) + ActiveSupport::Deprecation.warn "ActionController::Base.ip_spoofing_check= is deprecated. " << + "Please configure it on your application with config.action_dispatch.ip_spoofing_check=" + Rails.application.config.action_disaptch.ip_spoofing_check = value + end + + def ip_spoofing_check + ActiveSupport::Deprecation.warn "ActionController::Base.ip_spoofing_check is deprecated. " + "Configuring ip_spoofing_check on the application configures a middleware." + Rails.application.config.action_disaptch.ip_spoofing_check + end + + def trusted_proxies=(value) + ActiveSupport::Deprecation.warn "ActionController::Base.trusted_proxies= is deprecated. " << + "Please configure it on your application with config.action_dispatch.trusted_proxies=" + Rails.application.config.action_dispatch.ip_spoofing_check = value + end + + def trusted_proxies + ActiveSupport::Deprecation.warn "ActionController::Base.trusted_proxies is deprecated. " << + "Configuring trusted_proxies on the application configures a middleware." + Rails.application.config.action_dispatch.ip_spoofing_check = value + end + def rescue_action(env) raise env["action_dispatch.rescue.exception"] end diff --git a/actionpack/test/dispatch/request_test.rb b/actionpack/test/dispatch/request_test.rb index 3a07185586..badef4e92e 100644 --- a/actionpack/test/dispatch/request_test.rb +++ b/actionpack/test/dispatch/request_test.rb @@ -87,8 +87,6 @@ class RequestTest < ActiveSupport::TestCase request = stub_request 'HTTP_X_FORWARDED_FOR' => '9.9.9.9, 3.4.5.6, 10.0.0.1, 67.205.106.73' assert_equal '3.4.5.6', request.remote_ip - - ActionController::Base.trusted_proxies = nil end test "domains" do -- cgit v1.2.3 From 54302ef55bffd1a93f20f5d1ae81217b2e4149c4 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Wed, 3 Mar 2010 17:08:54 -0800 Subject: Add caller to deprecation notices --- .../lib/action_controller/metal/compatibility.rb | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb index ab59ffc0b4..9471f36de3 100644 --- a/actionpack/lib/action_controller/metal/compatibility.rb +++ b/actionpack/lib/action_controller/metal/compatibility.rb @@ -70,7 +70,7 @@ module ActionController ClassMethods.class_eval <<-RUBY, __FILE__, __LINE__ + 1 def #{option} - ActiveSupport::Deprecation.warn #{message.inspect} + ActiveSupport::Deprecation.warn #{message.inspect}, caller config.#{option} end RUBY @@ -82,7 +82,7 @@ module ActionController ClassMethods.class_eval <<-RUBY, __FILE__, __LINE__ + 1 def #{option}=(val) - ActiveSupport::Deprecation.warn #{message.inspect} + ActiveSupport::Deprecation.warn #{message.inspect}, caller config.#{option} = val end RUBY @@ -109,49 +109,49 @@ module ActionController module ClassMethods def consider_all_requests_local ActiveSupport::Deprecation.warn "ActionController::Base.consider_all_requests_local is deprecated, " << - "use Rails.application.config.consider_all_requests_local instead" + "use Rails.application.config.consider_all_requests_local instead", caller Rails.application.config.consider_all_requests_local end def consider_all_requests_local=(value) ActiveSupport::Deprecation.warn "ActionController::Base.consider_all_requests_local= is deprecated. " << - "Please configure it on your application with config.consider_all_requests_local=" + "Please configure it on your application with config.consider_all_requests_local=", caller Rails.application.config.consider_all_requests_local = value end def allow_concurrency ActiveSupport::Deprecation.warn "ActionController::Base.allow_concurrency is deprecated, " << - "use Rails.application.config.allow_concurrency instead" + "use Rails.application.config.allow_concurrency instead", caller Rails.application.config.allow_concurrency end def allow_concurrency=(value) ActiveSupport::Deprecation.warn "ActionController::Base.allow_concurrency= is deprecated. " << - "Please configure it on your application with config.allow_concurrency=" + "Please configure it on your application with config.allow_concurrency=", caller Rails.application.config.allow_concurrency = value end def ip_spoofing_check=(value) ActiveSupport::Deprecation.warn "ActionController::Base.ip_spoofing_check= is deprecated. " << - "Please configure it on your application with config.action_dispatch.ip_spoofing_check=" + "Please configure it on your application with config.action_dispatch.ip_spoofing_check=", caller Rails.application.config.action_disaptch.ip_spoofing_check = value end def ip_spoofing_check - ActiveSupport::Deprecation.warn "ActionController::Base.ip_spoofing_check is deprecated. " - "Configuring ip_spoofing_check on the application configures a middleware." + ActiveSupport::Deprecation.warn "ActionController::Base.ip_spoofing_check is deprecated. " << + "Configuring ip_spoofing_check on the application configures a middleware.", caller Rails.application.config.action_disaptch.ip_spoofing_check end def trusted_proxies=(value) ActiveSupport::Deprecation.warn "ActionController::Base.trusted_proxies= is deprecated. " << - "Please configure it on your application with config.action_dispatch.trusted_proxies=" + "Please configure it on your application with config.action_dispatch.trusted_proxies=", caller Rails.application.config.action_dispatch.ip_spoofing_check = value end def trusted_proxies ActiveSupport::Deprecation.warn "ActionController::Base.trusted_proxies is deprecated. " << - "Configuring trusted_proxies on the application configures a middleware." + "Configuring trusted_proxies on the application configures a middleware.", caller Rails.application.config.action_dispatch.ip_spoofing_check = value end -- cgit v1.2.3 From b160663bd13d08bf845bc8cdf87a2c5e7e46f901 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Wed, 3 Mar 2010 17:36:08 -0800 Subject: Start refactoring the method of configuring ActionView --- actionpack/lib/action_controller/railtie.rb | 14 ++++++++++++++ actionpack/lib/action_view/base.rb | 12 ++---------- actionpack/lib/action_view/helpers/asset_tag_helper.rb | 7 ------- actionpack/lib/action_view/test_case.rb | 4 ++++ actionpack/test/abstract_unit.rb | 15 +++++++++++++++ actionpack/test/template/asset_tag_helper_test.rb | 14 ++------------ actionpack/test/template/form_tag_helper_test.rb | 9 ++++----- actionpack/test/template/url_helper_test.rb | 9 ++------- 8 files changed, 43 insertions(+), 41 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb index 07c6b8f2b6..f4c51ba760 100644 --- a/actionpack/lib/action_controller/railtie.rb +++ b/actionpack/lib/action_controller/railtie.rb @@ -17,7 +17,21 @@ module ActionController ActionController::Base.logger ||= Rails.logger end + # assets_dir = defined?(Rails.public_path) ? Rails.public_path : "public" + # ActionView::DEFAULT_CONFIG = { + # :assets_dir => assets_dir, + # :javascripts_dir => "#{assets_dir}/javascripts", + # :stylesheets_dir => "#{assets_dir}/stylesheets", + # } + + initializer "action_controller.set_configs" do |app| + paths = app.config.paths + ac = app.config.action_controller + ac.assets_dir = paths.public + ac.javascripts_dir = paths.public.javascripts + ac.stylesheets_dir = paths.public.stylesheets + app.config.action_controller.each do |k,v| ActionController::Base.send "#{k}=", v end diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 2d2b53a6ce..87a1972fb4 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -175,15 +175,6 @@ module ActionView #:nodoc: include Helpers, Rendering, Partials, ::ERB::Util - def config - self.config = DEFAULT_CONFIG unless @config - @config - end - - def config=(config) - @config = ActiveSupport::OrderedOptions.new.merge(config) - end - extend ActiveSupport::Memoizable attr_accessor :base_path, :assigns, :template_extension @@ -306,12 +297,13 @@ module ActionView #:nodoc: @helpers = self.class.helpers || Module.new @_controller = controller + @_config = controller.config if controller @_content_for = Hash.new {|h,k| h[k] = ActiveSupport::SafeBuffer.new } @_virtual_path = nil self.view_paths = view_paths end - attr_internal :controller, :template + attr_internal :controller, :template, :config attr_reader :view_paths def view_paths=(paths) diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb index 5f76ff456e..b52d255d1f 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb @@ -133,13 +133,6 @@ module ActionView # change. You can use something like Live HTTP Headers for Firefox to verify # that the cache is indeed working. module AssetTagHelper - assets_dir = defined?(Rails.public_path) ? Rails.public_path : "public" - ActionView::DEFAULT_CONFIG = { - :assets_dir => assets_dir, - :javascripts_dir => "#{assets_dir}/javascripts", - :stylesheets_dir => "#{assets_dir}/stylesheets", - } - JAVASCRIPT_DEFAULT_SOURCES = ['prototype', 'effects', 'dragdrop', 'controls', 'rails'].freeze unless const_defined?(:JAVASCRIPT_DEFAULT_SOURCES) # Returns a link tag that browsers and news readers can use to auto-detect diff --git a/actionpack/lib/action_view/test_case.rb b/actionpack/lib/action_view/test_case.rb index 12142a3728..72dbead14b 100644 --- a/actionpack/lib/action_view/test_case.rb +++ b/actionpack/lib/action_view/test_case.rb @@ -62,6 +62,10 @@ module ActionView make_test_case_available_to_view! end + def config + @controller.config + end + def render(options = {}, local_assigns = {}, &block) @rendered << output = _view.render(options, local_assigns, &block) output diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb index f1e8779cfa..7223a7824e 100644 --- a/actionpack/test/abstract_unit.rb +++ b/actionpack/test/abstract_unit.rb @@ -105,6 +105,21 @@ class RoutedRackApp end end +class BasicController + attr_accessor :request + + def config + @config ||= ActiveSupport::InheritableOptions.new(ActionController::Metal.config).tap do |config| + # VIEW TODO: View tests should not require a controller + public_dir = File.expand_path("../fixtures/public", __FILE__) + config.assets_dir = public_dir + config.javascripts_dir = "#{public_dir}/javascripts" + config.stylesheets_dir = "#{public_dir}/stylesheets" + config + end + end +end + class ActionController::IntegrationTest < ActiveSupport::TestCase def self.build_app(routes = nil) RoutedRackApp.new(routes || ActionDispatch::Routing::RouteSet.new) do |middleware| diff --git a/actionpack/test/template/asset_tag_helper_test.rb b/actionpack/test/template/asset_tag_helper_test.rb index ccc39e9af6..8b24f66a6e 100644 --- a/actionpack/test/template/asset_tag_helper_test.rb +++ b/actionpack/test/template/asset_tag_helper_test.rb @@ -12,13 +12,6 @@ end class AssetTagHelperTest < ActionView::TestCase tests ActionView::Helpers::AssetTagHelper - DEFAULT_CONFIG = ActionView::DEFAULT_CONFIG.merge( - :assets_dir => File.dirname(__FILE__) + "/../fixtures/public", - :javascripts_dir => File.dirname(__FILE__) + "/../fixtures/public/javascripts", - :stylesheets_dir => File.dirname(__FILE__) + "/../fixtures/public/stylesheets") - - include ActiveSupport::Configurable - def setup super silence_warnings do @@ -41,7 +34,7 @@ class AssetTagHelperTest < ActionView::TestCase ) end - @controller = Class.new(FakeController) do + @controller = Class.new(BasicController) do def url_for(*args) "http://www.example.com" end end.new @@ -883,12 +876,9 @@ end class AssetTagHelperNonVhostTest < ActionView::TestCase tests ActionView::Helpers::AssetTagHelper - DEFAULT_CONFIG = ActionView::DEFAULT_CONFIG - include ActiveSupport::Configurable - def setup super - @controller = Class.new(FakeController) do + @controller = Class.new(BasicController) do def url_for(options) "http://www.example.com/collaboration/hieraki" end diff --git a/actionpack/test/template/form_tag_helper_test.rb b/actionpack/test/template/form_tag_helper_test.rb index 0ceec1afbf..c7d4bc986c 100644 --- a/actionpack/test/template/form_tag_helper_test.rb +++ b/actionpack/test/template/form_tag_helper_test.rb @@ -3,17 +3,16 @@ require 'abstract_unit' class FormTagHelperTest < ActionView::TestCase tests ActionView::Helpers::FormTagHelper - include ActiveSupport::Configurable - DEFAULT_CONFIG = ActionView::DEFAULT_CONFIG + # include ActiveSupport::Configurable + # DEFAULT_CONFIG = ActionView::DEFAULT_CONFIG def setup super - @controller = Class.new do + @controller = Class.new(BasicController) do def url_for(options) "http://www.example.com" end - end - @controller = @controller.new + end.new end VALID_HTML_ID = /^[A-Za-z][-_:.A-Za-z0-9]*$/ # see http://www.w3.org/TR/html4/types.html#type-name diff --git a/actionpack/test/template/url_helper_test.rb b/actionpack/test/template/url_helper_test.rb index d8ccb380a6..533a07b6f4 100644 --- a/actionpack/test/template/url_helper_test.rb +++ b/actionpack/test/template/url_helper_test.rb @@ -4,19 +4,14 @@ require 'active_support/ordered_options' require 'controller/fake_controllers' class UrlHelperTest < ActionView::TestCase - include ActiveSupport::Configurable - DEFAULT_CONFIG = ActionView::DEFAULT_CONFIG def setup super - @controller = Class.new do - attr_accessor :url, :request + @controller = Class.new(BasicController) do + attr_accessor :url def url_for(options) url end - def config - ActiveSupport::InheritableOptions.new({}) - end end @controller = @controller.new -- cgit v1.2.3 From 1f0f05b10c924d2f0d0ff4c74cbd979e77deea1d Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Wed, 3 Mar 2010 19:45:08 -0800 Subject: Move the original config method onto AbstractController --- actionpack/lib/abstract_controller/base.rb | 8 ++++++++ actionpack/lib/action_controller/metal.rb | 8 -------- actionpack/test/abstract_unit.rb | 2 +- actionpack/test/template/asset_tag_helper_test.rb | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller/base.rb b/actionpack/lib/abstract_controller/base.rb index e14818e464..cbd021e246 100644 --- a/actionpack/lib/abstract_controller/base.rb +++ b/actionpack/lib/abstract_controller/base.rb @@ -28,6 +28,10 @@ module AbstractController @descendants ||= [] end + def config + @config ||= ActiveSupport::InheritableOptions.new(superclass < Base ? superclass.config : {}) + end + # A list of all internal methods for a controller. This finds the first # abstract superclass of a controller, and gets a list of all public # instance methods on that abstract class. Public instance methods of @@ -95,6 +99,10 @@ module AbstractController @_formats = nil end + def config + self.class.config + end + # Calls the action going through the entire action dispatch stack. # # The actual method that is called is determined by calling diff --git a/actionpack/lib/action_controller/metal.rb b/actionpack/lib/action_controller/metal.rb index 1f6bbeb7c5..4374ab0a6b 100644 --- a/actionpack/lib/action_controller/metal.rb +++ b/actionpack/lib/action_controller/metal.rb @@ -11,14 +11,6 @@ module ActionController class Metal < AbstractController::Base abstract! - def self.config - @config ||= ActiveSupport::InheritableOptions.new(superclass < Metal ? superclass.config : {}) - end - - def config - self.class.config - end - # :api: public attr_internal :params, :env diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb index 7223a7824e..29270ed228 100644 --- a/actionpack/test/abstract_unit.rb +++ b/actionpack/test/abstract_unit.rb @@ -109,7 +109,7 @@ class BasicController attr_accessor :request def config - @config ||= ActiveSupport::InheritableOptions.new(ActionController::Metal.config).tap do |config| + @config ||= ActiveSupport::InheritableOptions.new(ActionController::Base.config).tap do |config| # VIEW TODO: View tests should not require a controller public_dir = File.expand_path("../fixtures/public", __FILE__) config.assets_dir = public_dir diff --git a/actionpack/test/template/asset_tag_helper_test.rb b/actionpack/test/template/asset_tag_helper_test.rb index 8b24f66a6e..bbfab05a0f 100644 --- a/actionpack/test/template/asset_tag_helper_test.rb +++ b/actionpack/test/template/asset_tag_helper_test.rb @@ -5,7 +5,7 @@ class FakeController attr_accessor :request def config - @config ||= ActiveSupport::InheritableOptions.new(ActionController::Metal.config) + @config ||= ActiveSupport::InheritableOptions.new(ActionController::Base.config) end end -- cgit v1.2.3 From 15b3b74624eb4c5ae383956950cab12ca9899131 Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Wed, 3 Mar 2010 21:16:35 -0800 Subject: Fix all the broken tests due to the AC configuration refactor --- .../lib/action_controller/metal/compatibility.rb | 3 +++ .../action_controller/metal/session_management.rb | 22 +++++++++++++--------- actionpack/lib/action_controller/railtie.rb | 3 +++ 3 files changed, 19 insertions(+), 9 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb index 9471f36de3..4c2136de8a 100644 --- a/actionpack/lib/action_controller/metal/compatibility.rb +++ b/actionpack/lib/action_controller/metal/compatibility.rb @@ -91,6 +91,9 @@ module ActionController deprecated_config_writer :session_store deprecated_config_writer :session_options deprecated_config_accessor :relative_url_root, "relative_url_root is ineffective. Please stop using it" + deprecated_config_accessor :assets_dir + deprecated_config_accessor :javascripts_dir + deprecated_config_accessor :stylesheets_dir # For old tests def initialize_template_class(*) end diff --git a/actionpack/lib/action_controller/metal/session_management.rb b/actionpack/lib/action_controller/metal/session_management.rb index 09ef9261a4..ce8b20964b 100644 --- a/actionpack/lib/action_controller/metal/session_management.rb +++ b/actionpack/lib/action_controller/metal/session_management.rb @@ -3,24 +3,28 @@ module ActionController #:nodoc: extend ActiveSupport::Concern included do - self.config.session_store ||= :cookie_store + # This is still needed for the session secret for some reason. self.config.session_options ||= {} end + def self.session_store_for(store) + case store + when :active_record_store + ActiveRecord::SessionStore + when Symbol + ActionDispatch::Session.const_get(store.to_s.camelize) + else + store + end + end + module ClassMethods def session_options config.session_options end def session_store - case store = config.session_store - when :active_record_store - ActiveRecord::SessionStore - when Symbol - ActionDispatch::Session.const_get(store.to_s.camelize) - else - store - end + SessionManagement.session_store_for(config.session_store) end def session=(options = {}) diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb index f4c51ba760..3a084cdf67 100644 --- a/actionpack/lib/action_controller/railtie.rb +++ b/actionpack/lib/action_controller/railtie.rb @@ -13,6 +13,9 @@ module ActionController log_subscriber ActionController::Railties::LogSubscriber.new + config.action_controller.session_store = :cookie_store + config.action_controller.session_options = {} + initializer "action_controller.logger" do ActionController::Base.logger ||= Rails.logger end -- cgit v1.2.3 From 7dbf5c820b3454da8194e2c823cdfd3982657f03 Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Wed, 3 Mar 2010 21:29:26 -0800 Subject: Tweak how ActionPack handles InheritableOptions --- actionpack/lib/abstract_controller/base.rb | 2 ++ actionpack/lib/action_controller/metal.rb | 1 - actionpack/lib/action_view/base.rb | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller/base.rb b/actionpack/lib/abstract_controller/base.rb index cbd021e246..8e24d55ad0 100644 --- a/actionpack/lib/abstract_controller/base.rb +++ b/actionpack/lib/abstract_controller/base.rb @@ -1,3 +1,5 @@ +require 'active_support/ordered_options' + module AbstractController class Error < StandardError; end class ActionNotFound < StandardError; end diff --git a/actionpack/lib/action_controller/metal.rb b/actionpack/lib/action_controller/metal.rb index 4374ab0a6b..5e0ed201cb 100644 --- a/actionpack/lib/action_controller/metal.rb +++ b/actionpack/lib/action_controller/metal.rb @@ -1,5 +1,4 @@ require 'active_support/core_ext/class/attribute' -require 'active_support/ordered_options' module ActionController # ActionController::Metal provides a way to get a valid Rack application from a controller. diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 87a1972fb4..76f9eb2b0d 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -297,7 +297,7 @@ module ActionView #:nodoc: @helpers = self.class.helpers || Module.new @_controller = controller - @_config = controller.config if controller + @_config = ActiveSupport::InheritableOptions.new(controller.config) if controller @_content_for = Hash.new {|h,k| h[k] = ActiveSupport::SafeBuffer.new } @_virtual_path = nil self.view_paths = view_paths -- cgit v1.2.3 From 13a932cddcd3165792d3454009b6d07471031a2c Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Wed, 3 Mar 2010 21:32:05 -0800 Subject: Modifying configurations on the instance of a controller should not affect the class --- actionpack/lib/abstract_controller/base.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller/base.rb b/actionpack/lib/abstract_controller/base.rb index 8e24d55ad0..24f3b552ba 100644 --- a/actionpack/lib/abstract_controller/base.rb +++ b/actionpack/lib/abstract_controller/base.rb @@ -102,7 +102,7 @@ module AbstractController end def config - self.class.config + @config ||= ActiveSupport::InheritableOptions.new(self.class.config) end # Calls the action going through the entire action dispatch stack. -- cgit v1.2.3 From 9eddc8544417323dcd8460026027c3359b2ad717 Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Thu, 4 Mar 2010 00:52:10 -0800 Subject: Add a method for configuring abstract controllers --- actionpack/lib/abstract_controller/base.rb | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller/base.rb b/actionpack/lib/abstract_controller/base.rb index 24f3b552ba..ea88a2d24d 100644 --- a/actionpack/lib/abstract_controller/base.rb +++ b/actionpack/lib/abstract_controller/base.rb @@ -34,6 +34,10 @@ module AbstractController @config ||= ActiveSupport::InheritableOptions.new(superclass < Base ? superclass.config : {}) end + def configure + yield config + end + # A list of all internal methods for a controller. This finds the first # abstract superclass of a controller, and gets a list of all public # instance methods on that abstract class. Public instance methods of -- cgit v1.2.3 From ad2e6ee4ec5cc6c6bc5f11bfb875e582dbe55468 Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Thu, 4 Mar 2010 01:01:21 -0800 Subject: Fix a bunch of failing AP / AM specs created from the previous AbstractController configuration refactor. --- .../lib/action_view/helpers/asset_tag_helper.rb | 2 +- actionpack/test/template/asset_tag_helper_test.rb | 42 ++++++++-------------- 2 files changed, 16 insertions(+), 28 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb index b52d255d1f..de3d61ebbe 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb @@ -670,7 +670,7 @@ module ActionView # or the value returned from invoking the proc if it's a proc or the value from # invoking call if it's an object responding to call. def compute_asset_host(source) - if host = ActionController::Base.asset_host + if host = config.asset_host if host.is_a?(Proc) || host.respond_to?(:call) case host.is_a?(Proc) ? host.arity : host.method(:call).arity when 2 diff --git a/actionpack/test/template/asset_tag_helper_test.rb b/actionpack/test/template/asset_tag_helper_test.rb index bbfab05a0f..6089048088 100644 --- a/actionpack/test/template/asset_tag_helper_test.rb +++ b/actionpack/test/template/asset_tag_helper_test.rb @@ -401,7 +401,7 @@ class AssetTagHelperTest < ActionView::TestCase def test_caching_image_path_with_caching_and_proc_asset_host_using_request ENV['RAILS_ASSET_ID'] = '' - ActionController::Base.asset_host = Proc.new do |source, request| + @controller.config.asset_host = Proc.new do |source, request| if request.ssl? "#{request.protocol}#{request.host_with_port}" else @@ -409,8 +409,6 @@ class AssetTagHelperTest < ActionView::TestCase end end - ActionController::Base.perform_caching = true - @controller.request.stubs(:ssl?).returns(false) assert_equal "http://assets15.example.com/images/xml.png", image_path("xml.png") @@ -421,7 +419,7 @@ class AssetTagHelperTest < ActionView::TestCase def test_caching_javascript_include_tag_when_caching_on ENV["RAILS_ASSET_ID"] = "" - ActionController::Base.asset_host = 'http://a0.example.com' + @controller.config.asset_host = 'http://a0.example.com' ActionController::Base.perform_caching = true assert_dom_equal( @@ -453,7 +451,7 @@ class AssetTagHelperTest < ActionView::TestCase def test_caching_javascript_include_tag_when_caching_on_with_proc_asset_host ENV['RAILS_ASSET_ID'] = '' - ActionController::Base.asset_host = Proc.new { |source| "http://a#{source.length}.example.com" } + @controller.config.asset_host = Proc.new { |source| "http://a#{source.length}.example.com" } ActionController::Base.perform_caching = true assert_equal '/javascripts/scripts.js'.length, 23 @@ -470,7 +468,7 @@ class AssetTagHelperTest < ActionView::TestCase def test_caching_javascript_include_tag_when_caching_on_with_2_argument_proc_asset_host ENV['RAILS_ASSET_ID'] = '' - ActionController::Base.asset_host = Proc.new { |source, request| + @controller.config.asset_host = Proc.new { |source, request| if request.ssl? "#{request.protocol}#{request.host_with_port}" else @@ -507,7 +505,7 @@ class AssetTagHelperTest < ActionView::TestCase def test_caching_javascript_include_tag_when_caching_on_with_2_argument_object_asset_host ENV['RAILS_ASSET_ID'] = '' - ActionController::Base.asset_host = Class.new do + @controller.config.asset_host = Class.new do def call(source, request) if request.ssl? "#{request.protocol}#{request.host_with_port}" @@ -547,7 +545,7 @@ class AssetTagHelperTest < ActionView::TestCase def test_caching_javascript_include_tag_when_caching_on_and_using_subdirectory ENV["RAILS_ASSET_ID"] = "" - ActionController::Base.asset_host = 'http://a%d.example.com' + @controller.config.asset_host = 'http://a%d.example.com' ActionController::Base.perform_caching = true hash = '/javascripts/cache/money.js'.hash % 4 @@ -563,7 +561,7 @@ class AssetTagHelperTest < ActionView::TestCase def test_caching_javascript_include_tag_with_all_and_recursive_puts_defaults_at_the_start_of_the_file ENV["RAILS_ASSET_ID"] = "" - ActionController::Base.asset_host = 'http://a0.example.com' + @controller.config.asset_host = 'http://a0.example.com' ActionController::Base.perform_caching = true assert_dom_equal( @@ -584,7 +582,7 @@ class AssetTagHelperTest < ActionView::TestCase def test_caching_javascript_include_tag_with_all_puts_defaults_at_the_start_of_the_file ENV["RAILS_ASSET_ID"] = "" - ActionController::Base.asset_host = 'http://a0.example.com' + @controller.config.asset_host = 'http://a0.example.com' ActionController::Base.perform_caching = true assert_dom_equal( @@ -692,7 +690,7 @@ class AssetTagHelperTest < ActionView::TestCase def test_caching_stylesheet_link_tag_when_caching_on ENV["RAILS_ASSET_ID"] = "" - ActionController::Base.asset_host = 'http://a0.example.com' + @controller.config.asset_host = 'http://a0.example.com' ActionController::Base.perform_caching = true assert_dom_equal( @@ -802,7 +800,7 @@ class AssetTagHelperTest < ActionView::TestCase def test_caching_stylesheet_link_tag_when_caching_on_with_proc_asset_host ENV["RAILS_ASSET_ID"] = "" - ActionController::Base.asset_host = Proc.new { |source| "http://a#{source.length}.example.com" } + @controller.config.asset_host = Proc.new { |source| "http://a#{source.length}.example.com" } ActionController::Base.perform_caching = true assert_equal '/stylesheets/styles.css'.length, 23 @@ -911,43 +909,33 @@ class AssetTagHelperNonVhostTest < ActionView::TestCase end def test_should_compute_proper_path_with_asset_host - ActionController::Base.asset_host = "http://assets.example.com" + @controller.config.asset_host = "http://assets.example.com" assert_dom_equal(%(), auto_discovery_link_tag) assert_dom_equal(%(http://assets.example.com/collaboration/hieraki/javascripts/xmlhr.js), javascript_path("xmlhr")) assert_dom_equal(%(http://assets.example.com/collaboration/hieraki/stylesheets/style.css), stylesheet_path("style")) assert_dom_equal(%(http://assets.example.com/collaboration/hieraki/images/xml.png), image_path("xml.png")) assert_dom_equal(%(Mouse), image_tag("mouse.png", :mouseover => "/images/mouse_over.png")) assert_dom_equal(%(Mouse2), image_tag("mouse2.png", :mouseover => image_path("mouse_over2.png"))) - ensure - ActionController::Base.asset_host = "" end def test_should_ignore_asset_host_on_complete_url - ActionController::Base.asset_host = "http://assets.example.com" + @controller.config.asset_host = "http://assets.example.com" assert_dom_equal(%(), stylesheet_link_tag("http://bar.example.com/stylesheets/style.css")) - ensure - ActionController::Base.asset_host = "" end def test_should_wildcard_asset_host_between_zero_and_four - ActionController::Base.asset_host = 'http://a%d.example.com' + @controller.config.asset_host = 'http://a%d.example.com' assert_match %r(http://a[0123].example.com/collaboration/hieraki/images/xml.png), image_path('xml.png') - ensure - ActionController::Base.asset_host = nil end def test_asset_host_without_protocol_should_use_request_protocol - ActionController::Base.asset_host = 'a.example.com' + @controller.config.asset_host = 'a.example.com' assert_equal 'gopher://a.example.com/collaboration/hieraki/images/xml.png', image_path('xml.png') - ensure - ActionController::Base.asset_host = nil end def test_asset_host_without_protocol_should_use_request_protocol_even_if_path_present - ActionController::Base.asset_host = 'a.example.com/files/go/here' + @controller.config.asset_host = 'a.example.com/files/go/here' assert_equal 'gopher://a.example.com/files/go/here/collaboration/hieraki/images/xml.png', image_path('xml.png') - ensure - ActionController::Base.asset_host = nil end def test_assert_css_and_js_of_the_same_name_return_correct_extension -- cgit v1.2.3 From 17769696279810c6c24a10b0d47f9b712205f0ce Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Thu, 4 Mar 2010 11:58:30 -0800 Subject: Move session and session_store onto ActionDispatch and add deprecation warnings --- .../lib/action_controller/metal/compatibility.rb | 6 +++ .../action_controller/metal/session_management.rb | 5 --- actionpack/lib/action_controller/railtie.rb | 50 ++++++++++++++-------- actionpack/lib/action_dispatch/railtie.rb | 2 + 4 files changed, 41 insertions(+), 22 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb index 4c2136de8a..024c58ffc4 100644 --- a/actionpack/lib/action_controller/metal/compatibility.rb +++ b/actionpack/lib/action_controller/metal/compatibility.rb @@ -158,6 +158,12 @@ module ActionController Rails.application.config.action_dispatch.ip_spoofing_check = value end + def session=(value) + ActiveSupport::Deprecation.warn "ActionController::Base.session= is deprecated. " << + "Please configure it on your application with config.action_dispatch.session=", caller + Rails.application.config.action_dispatch.session = value.delete(:disabled) ? nil : value + end + def rescue_action(env) raise env["action_dispatch.rescue.exception"] end diff --git a/actionpack/lib/action_controller/metal/session_management.rb b/actionpack/lib/action_controller/metal/session_management.rb index ce8b20964b..1ea22b7b28 100644 --- a/actionpack/lib/action_controller/metal/session_management.rb +++ b/actionpack/lib/action_controller/metal/session_management.rb @@ -27,11 +27,6 @@ module ActionController #:nodoc: SessionManagement.session_store_for(config.session_store) end - def session=(options = {}) - self.session_store = nil if options.delete(:disabled) - session_options.merge!(options) - end - def session(*args) ActiveSupport::Deprecation.warn( "Disabling sessions for a single controller has been deprecated. " + diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb index 3a084cdf67..031df9423f 100644 --- a/actionpack/lib/action_controller/railtie.rb +++ b/actionpack/lib/action_controller/railtie.rb @@ -3,6 +3,7 @@ require "action_controller" require "action_view/railtie" require "active_support/core_ext/class/subclasses" require "active_support/deprecation/proxy_wrappers" +require "active_support/deprecation" module ActionController class Railtie < Rails::Railtie @@ -11,33 +12,48 @@ module ActionController require "action_controller/railties/log_subscriber" require "action_controller/railties/url_helpers" - log_subscriber ActionController::Railties::LogSubscriber.new + ad = config.action_dispatch + config.action_controller.singleton_class.send(:define_method, :session) do + ActiveSupport::Deprecation.warn "config.action_controller.session has been " \ + "renamed to config.action_dispatch.session.", caller + ad.session + end - config.action_controller.session_store = :cookie_store - config.action_controller.session_options = {} + config.action_controller.singleton_class.send(:define_method, :session=) do |val| + ActiveSupport::Deprecation.warn "config.action_controller.session has been " \ + "renamed to config.action_dispatch.session.", caller + ad.session = val + end - initializer "action_controller.logger" do - ActionController::Base.logger ||= Rails.logger + config.action_controller.singleton_class.send(:define_method, :session_store) do + ActiveSupport::Deprecation.warn "config.action_controller.session_store has been " \ + "renamed to config.action_dispatch.session_store.", caller + ad.session_store end - # assets_dir = defined?(Rails.public_path) ? Rails.public_path : "public" - # ActionView::DEFAULT_CONFIG = { - # :assets_dir => assets_dir, - # :javascripts_dir => "#{assets_dir}/javascripts", - # :stylesheets_dir => "#{assets_dir}/stylesheets", - # } + config.action_controller.singleton_class.send(:define_method, :session_store=) do |val| + ActiveSupport::Deprecation.warn "config.action_controller.session_store has been " \ + "renamed to config.action_dispatch.session_store.", caller + ad.session_store = val + end + log_subscriber ActionController::Railties::LogSubscriber.new + + initializer "action_controller.logger" do + ActionController::Base.logger ||= Rails.logger + end initializer "action_controller.set_configs" do |app| paths = app.config.paths ac = app.config.action_controller - ac.assets_dir = paths.public - ac.javascripts_dir = paths.public.javascripts - ac.stylesheets_dir = paths.public.stylesheets + ac.assets_dir = paths.public.to_a.first + ac.javascripts_dir = paths.public.javascripts.to_a.first + ac.stylesheets_dir = paths.public.stylesheets.to_a.first - app.config.action_controller.each do |k,v| - ActionController::Base.send "#{k}=", v - end + ActionController::Base.config.replace(ac) + # app.config.action_controller.each do |k,v| + # ActionController::Base.send "#{k}=", v + # end end initializer "action_controller.initialize_framework_caches" do diff --git a/actionpack/lib/action_dispatch/railtie.rb b/actionpack/lib/action_dispatch/railtie.rb index e486bd4079..30b3535e17 100644 --- a/actionpack/lib/action_dispatch/railtie.rb +++ b/actionpack/lib/action_dispatch/railtie.rb @@ -7,6 +7,8 @@ module ActionDispatch config.action_dispatch.x_sendfile_header = "X-Sendfile" config.action_dispatch.ip_spoofing_check = true + config.action_dispatch.session = {} + config.action_dispatch.session_store = :cookie_store # Prepare dispatcher callbacks and run 'prepare' callbacks initializer "action_dispatch.prepare_dispatcher" do |app| -- cgit v1.2.3 From 70916f6a9ce190cae5c545da552bb96f05ee4914 Mon Sep 17 00:00:00 2001 From: wycats Date: Thu, 4 Mar 2010 12:21:12 -0800 Subject: Fixes test ordering bug (ht: evan) --- actionpack/test/controller/view_paths_test.rb | 3 +++ 1 file changed, 3 insertions(+) (limited to 'actionpack') diff --git a/actionpack/test/controller/view_paths_test.rb b/actionpack/test/controller/view_paths_test.rb index 56821332c5..b8972b04b6 100644 --- a/actionpack/test/controller/view_paths_test.rb +++ b/actionpack/test/controller/view_paths_test.rb @@ -36,9 +36,12 @@ class ViewLoadPathsTest < ActionController::TestCase @old_behavior = ActiveSupport::Deprecation.behavior @last_message = nil ActiveSupport::Deprecation.behavior = Proc.new { |message, callback| @last_message = message } + + @paths = TestController.view_paths end def teardown + TestController.view_paths = @paths ActiveSupport::Deprecation.behavior = @old_behavior end -- cgit v1.2.3 From 7c785592ec9a9d7a73978d133dfa03b5b9b78fdc Mon Sep 17 00:00:00 2001 From: wycats Date: Thu, 4 Mar 2010 15:07:26 -0800 Subject: Safely cleans up a test to avoid relying on a particular test order --- actionpack/test/template/test_case_test.rb | 33 +++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 10 deletions(-) (limited to 'actionpack') diff --git a/actionpack/test/template/test_case_test.rb b/actionpack/test/template/test_case_test.rb index 12807baaa7..87408d8475 100644 --- a/actionpack/test/template/test_case_test.rb +++ b/actionpack/test/template/test_case_test.rb @@ -89,16 +89,23 @@ module ActionView end test "helper class that is being tested is always included in view instance" do - self.class.helper_class.module_eval do - def render_from_helper - render :partial => 'customer', :collection => @customers + # This ensure is a hidious hack to deal with these tests bleeding + # methods between eachother + begin + self.class.helper_class.module_eval do + def render_from_helper + render :partial => 'customer', :collection => @customers + end end - end - TestController.stubs(:controller_path).returns('test') + TestController.stubs(:controller_path).returns('test') - @customers = [stub(:name => 'Eloy'), stub(:name => 'Manfred')] - assert_match /Hello: EloyHello: Manfred/, render(:partial => 'test/from_helper') + @customers = [stub(:name => 'Eloy'), stub(:name => 'Manfred')] + assert_match /Hello: EloyHello: Manfred/, render(:partial => 'test/from_helper') + + ensure + self.class.helper_class.remove_method :render_from_helper + end end test "no additional helpers should shared across test cases" do @@ -147,10 +154,16 @@ module ActionView end test "is able to make methods available to the view" do - _helpers.module_eval do - def render_from_helper; from_test_case end + # This ensure is a hidious hack to deal with these tests bleeding + # methods between eachother + begin + _helpers.module_eval do + def render_from_helper; from_test_case end + end + assert_equal 'Word!', render(:partial => 'test/from_helper') + ensure + _helpers.remove_method :render_from_helper end - assert_equal 'Word!', render(:partial => 'test/from_helper') end def from_test_case; 'Word!'; end -- cgit v1.2.3 From 5e3e5ac12baf8432b4c2a324a81fc81901479ef5 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Thu, 4 Mar 2010 15:31:22 -0800 Subject: Clarify cookie jar test --- actionpack/test/controller/integration_test.rb | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'actionpack') diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb index 5cb6aa6997..2180466ca7 100644 --- a/actionpack/test/controller/integration_test.rb +++ b/actionpack/test/controller/integration_test.rb @@ -284,18 +284,13 @@ class IntegrationProcessTest < ActionController::IntegrationTest end end - def test_cookie_monster + test 'response cookies are added to the cookie jar for the next request' do with_test_route_set do self.cookies['cookie_1'] = "sugar" self.cookies['cookie_2'] = "oatmeal" get '/cookie_monster' - assert_equal 410, status - assert_equal "Gone", status_message - assert_response 410 - assert_response :gone assert_equal "cookie_1=; path=/\ncookie_3=chocolate; path=/", headers["Set-Cookie"] assert_equal({"cookie_1"=>"", "cookie_2"=>"oatmeal", "cookie_3"=>"chocolate"}, cookies.to_hash) - assert_equal "Gone", response.body end end -- cgit v1.2.3 From 48bb3b3904806abaea7c62961559c03e689dd12f Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Thu, 4 Mar 2010 12:21:49 -0800 Subject: Move stuff from compatibility.rb to deprecated.rb --- actionpack/lib/action_controller/base.rb | 2 + .../lib/action_controller/deprecated/base.rb | 118 +++++++++++++++++++ .../lib/action_controller/metal/compatibility.rb | 131 +-------------------- actionpack/test/template/asset_tag_helper_test.rb | 1 - 4 files changed, 125 insertions(+), 127 deletions(-) create mode 100644 actionpack/lib/action_controller/deprecated/base.rb (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index ace0276a31..78871154c3 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -60,3 +60,5 @@ module ActionController end end + +require "action_controller/deprecated/base" diff --git a/actionpack/lib/action_controller/deprecated/base.rb b/actionpack/lib/action_controller/deprecated/base.rb new file mode 100644 index 0000000000..7aa2a34d37 --- /dev/null +++ b/actionpack/lib/action_controller/deprecated/base.rb @@ -0,0 +1,118 @@ +module ActionController + class Base + class << self + def deprecated_config_accessor(option, message = nil) + deprecated_config_reader(option, message) + deprecated_config_writer(option, message) + end + + def deprecated_config_reader(option, message = nil) + message ||= "Reading #{option} directly from ActionController::Base is deprecated. " \ + "Please read it from config.#{option}" + + self.class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{option} + ActiveSupport::Deprecation.warn #{message.inspect}, caller + config.#{option} + end + RUBY + end + + def deprecated_config_writer(option, message = nil) + message ||= "Setting #{option} directly on ActionController::Base is deprecated. " \ + "Please set it on config.action_controller.#{option}" + + self.class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{option}=(val) + ActiveSupport::Deprecation.warn #{message.inspect}, caller + config.#{option} = val + end + RUBY + end + + def consider_all_requests_local + ActiveSupport::Deprecation.warn "ActionController::Base.consider_all_requests_local is deprecated, " << + "use Rails.application.config.consider_all_requests_local instead", caller + Rails.application.config.consider_all_requests_local + end + + def consider_all_requests_local=(value) + ActiveSupport::Deprecation.warn "ActionController::Base.consider_all_requests_local= is deprecated. " << + "Please configure it on your application with config.consider_all_requests_local=", caller + Rails.application.config.consider_all_requests_local = value + end + + def allow_concurrency + ActiveSupport::Deprecation.warn "ActionController::Base.allow_concurrency is deprecated, " << + "use Rails.application.config.allow_concurrency instead", caller + Rails.application.config.allow_concurrency + end + + def allow_concurrency=(value) + ActiveSupport::Deprecation.warn "ActionController::Base.allow_concurrency= is deprecated. " << + "Please configure it on your application with config.allow_concurrency=", caller + Rails.application.config.allow_concurrency = value + end + + def ip_spoofing_check=(value) + ActiveSupport::Deprecation.warn "ActionController::Base.ip_spoofing_check= is deprecated. " << + "Please configure it on your application with config.action_dispatch.ip_spoofing_check=", caller + Rails.application.config.action_disaptch.ip_spoofing_check = value + end + + def ip_spoofing_check + ActiveSupport::Deprecation.warn "ActionController::Base.ip_spoofing_check is deprecated. " << + "Configuring ip_spoofing_check on the application configures a middleware.", caller + Rails.application.config.action_disaptch.ip_spoofing_check + end + + def trusted_proxies=(value) + ActiveSupport::Deprecation.warn "ActionController::Base.trusted_proxies= is deprecated. " << + "Please configure it on your application with config.action_dispatch.trusted_proxies=", caller + Rails.application.config.action_dispatch.ip_spoofing_check = value + end + + def trusted_proxies + ActiveSupport::Deprecation.warn "ActionController::Base.trusted_proxies is deprecated. " << + "Configuring trusted_proxies on the application configures a middleware.", caller + Rails.application.config.action_dispatch.ip_spoofing_check = value + end + + def session=(value) + ActiveSupport::Deprecation.warn "ActionController::Base.session= is deprecated. " << + "Please configure it on your application with config.action_dispatch.session=", caller + Rails.application.config.action_dispatch.session = value.delete(:disabled) ? nil : value + end + + # Controls the resource action separator + def resource_action_separator + @resource_action_separator ||= "/" + end + + def resource_action_separator=(val) + ActiveSupport::Deprecation.warn "ActionController::Base.resource_action_separator is deprecated and only " \ + "works with the deprecated router DSL." + @resource_action_separator = val + end + + def use_accept_header + ActiveSupport::Deprecation.warn "ActionController::Base.use_accept_header doesn't do anything anymore. " \ + "The accept header is always taken into account." + end + + def use_accept_header=(val) + use_accept_header + end + end + + deprecated_config_writer :session_store + deprecated_config_writer :session_options + deprecated_config_accessor :relative_url_root, "relative_url_root is ineffective. Please stop using it" + deprecated_config_accessor :assets_dir + deprecated_config_accessor :javascripts_dir + deprecated_config_accessor :stylesheets_dir + + delegate :consider_all_requests_local, :consider_all_requests_local=, + :allow_concurrency, :allow_concurrency=, :to => :"self.class" + end +end \ No newline at end of file diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb index 024c58ffc4..44ace925e9 100644 --- a/actionpack/lib/action_controller/metal/compatibility.rb +++ b/actionpack/lib/action_controller/metal/compatibility.rb @@ -31,75 +31,22 @@ module ActionController @before_filter_chain_aborted @_headers @_params @_response) - # Controls the resource action separator - def self.resource_action_separator - @resource_action_separator ||= "/" - end - - def self.resource_action_separator=(val) - ActiveSupport::Deprecation.warn "ActionController::Base.resource_action_separator is deprecated and only " \ - "works with the deprecated router DSL." - @resource_action_separator = val - end - - def self.use_accept_header - ActiveSupport::Deprecation.warn "ActionController::Base.use_accept_header doesn't do anything anymore. " \ - "The accept header is always taken into account." + def rescue_action(env) + raise env["action_dispatch.rescue.exception"] end - def self.use_accept_header=(val) - use_accept_header + # Defines the storage option for cached fragments + def cache_store=(store_option) + @@cache_store = ActiveSupport::Cache.lookup_store(store_option) end self.page_cache_directory = defined?(Rails.public_path) ? Rails.public_path : "" - - # Prepends all the URL-generating helpers from AssetHelper. This makes it possible to easily move javascripts, stylesheets, - # and images to a dedicated asset server away from the main web server. Example: - # ActionController::Base.asset_host = "http://assets.example.com" - cattr_accessor :asset_host end - def self.deprecated_config_accessor(option, message = nil) - deprecated_config_reader(option, message) - deprecated_config_writer(option, message) - end - - def self.deprecated_config_reader(option, message = nil) - message ||= "Reading #{option} directly from ActionController::Base is deprecated. " \ - "Please read it from config.#{option}" - - ClassMethods.class_eval <<-RUBY, __FILE__, __LINE__ + 1 - def #{option} - ActiveSupport::Deprecation.warn #{message.inspect}, caller - config.#{option} - end - RUBY - end - - def self.deprecated_config_writer(option, message = nil) - message ||= "Setting #{option} directly on ActionController::Base is deprecated. " \ - "Please set it on config.action_controller.#{option}" - - ClassMethods.class_eval <<-RUBY, __FILE__, __LINE__ + 1 - def #{option}=(val) - ActiveSupport::Deprecation.warn #{message.inspect}, caller - config.#{option} = val - end - RUBY - end - - deprecated_config_writer :session_store - deprecated_config_writer :session_options - deprecated_config_accessor :relative_url_root, "relative_url_root is ineffective. Please stop using it" - deprecated_config_accessor :assets_dir - deprecated_config_accessor :javascripts_dir - deprecated_config_accessor :stylesheets_dir - # For old tests def initialize_template_class(*) end def assign_shortcuts(*) end - # TODO: Remove this after we flip def template @template ||= view_context end @@ -109,74 +56,6 @@ module ActionController super end - module ClassMethods - def consider_all_requests_local - ActiveSupport::Deprecation.warn "ActionController::Base.consider_all_requests_local is deprecated, " << - "use Rails.application.config.consider_all_requests_local instead", caller - Rails.application.config.consider_all_requests_local - end - - def consider_all_requests_local=(value) - ActiveSupport::Deprecation.warn "ActionController::Base.consider_all_requests_local= is deprecated. " << - "Please configure it on your application with config.consider_all_requests_local=", caller - Rails.application.config.consider_all_requests_local = value - end - - def allow_concurrency - ActiveSupport::Deprecation.warn "ActionController::Base.allow_concurrency is deprecated, " << - "use Rails.application.config.allow_concurrency instead", caller - Rails.application.config.allow_concurrency - end - - def allow_concurrency=(value) - ActiveSupport::Deprecation.warn "ActionController::Base.allow_concurrency= is deprecated. " << - "Please configure it on your application with config.allow_concurrency=", caller - Rails.application.config.allow_concurrency = value - end - - def ip_spoofing_check=(value) - ActiveSupport::Deprecation.warn "ActionController::Base.ip_spoofing_check= is deprecated. " << - "Please configure it on your application with config.action_dispatch.ip_spoofing_check=", caller - Rails.application.config.action_disaptch.ip_spoofing_check = value - end - - def ip_spoofing_check - ActiveSupport::Deprecation.warn "ActionController::Base.ip_spoofing_check is deprecated. " << - "Configuring ip_spoofing_check on the application configures a middleware.", caller - Rails.application.config.action_disaptch.ip_spoofing_check - end - - def trusted_proxies=(value) - ActiveSupport::Deprecation.warn "ActionController::Base.trusted_proxies= is deprecated. " << - "Please configure it on your application with config.action_dispatch.trusted_proxies=", caller - Rails.application.config.action_dispatch.ip_spoofing_check = value - end - - def trusted_proxies - ActiveSupport::Deprecation.warn "ActionController::Base.trusted_proxies is deprecated. " << - "Configuring trusted_proxies on the application configures a middleware.", caller - Rails.application.config.action_dispatch.ip_spoofing_check = value - end - - def session=(value) - ActiveSupport::Deprecation.warn "ActionController::Base.session= is deprecated. " << - "Please configure it on your application with config.action_dispatch.session=", caller - Rails.application.config.action_dispatch.session = value.delete(:disabled) ? nil : value - end - - def rescue_action(env) - raise env["action_dispatch.rescue.exception"] - end - - # Defines the storage option for cached fragments - def cache_store=(store_option) - @@cache_store = ActiveSupport::Cache.lookup_store(store_option) - end - end - - delegate :consider_all_requests_local, :consider_all_requests_local=, - :allow_concurrency, :allow_concurrency=, :to => :"self.class" - def render_to_body(options) if options.is_a?(Hash) && options.key?(:template) options[:template].sub!(/^\//, '') diff --git a/actionpack/test/template/asset_tag_helper_test.rb b/actionpack/test/template/asset_tag_helper_test.rb index 6089048088..50c3ab0b60 100644 --- a/actionpack/test/template/asset_tag_helper_test.rb +++ b/actionpack/test/template/asset_tag_helper_test.rb @@ -51,7 +51,6 @@ class AssetTagHelperTest < ActionView::TestCase def teardown ActionController::Base.perform_caching = false - ActionController::Base.asset_host = nil ENV.delete('RAILS_ASSET_ID') end -- cgit v1.2.3 From e311622e7b20b3fdeab6a93418c8a45c6e7137b6 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Thu, 4 Mar 2010 15:06:25 -0800 Subject: Deprecated ActionController::Base.session_options= and ActionController::Base.session_store= in favor of a config.session_store method (which takes params) and a config.cookie_secret variable, which is used in various secret scenarios. The old AC::Base options will continue to work with deprecation warnings. --- .../lib/action_controller/deprecated/base.rb | 17 ++++++++++-- .../action_controller/metal/http_authentication.rb | 4 +-- .../action_controller/metal/session_management.rb | 30 ---------------------- actionpack/lib/action_controller/railtie.rb | 4 +-- .../middleware/session/cookie_store.rb | 12 ++++----- actionpack/lib/action_dispatch/railtie.rb | 2 -- actionpack/test/abstract_unit.rb | 3 +-- .../controller/http_digest_authentication_test.rb | 5 ++-- 8 files changed, 27 insertions(+), 50 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/deprecated/base.rb b/actionpack/lib/action_controller/deprecated/base.rb index 7aa2a34d37..34f8f4a822 100644 --- a/actionpack/lib/action_controller/deprecated/base.rb +++ b/actionpack/lib/action_controller/deprecated/base.rb @@ -78,10 +78,23 @@ module ActionController Rails.application.config.action_dispatch.ip_spoofing_check = value end + def session(*args) + ActiveSupport::Deprecation.warn( + "Disabling sessions for a single controller has been deprecated. " + + "Sessions are now lazy loaded. So if you don't access them, " + + "consider them off. You can still modify the session cookie " + + "options with request.session_options.", caller) + end + def session=(value) ActiveSupport::Deprecation.warn "ActionController::Base.session= is deprecated. " << - "Please configure it on your application with config.action_dispatch.session=", caller - Rails.application.config.action_dispatch.session = value.delete(:disabled) ? nil : value + "Please configure it on your application with config.session_store :cookie_store, :key => '....'", caller + if value.delete(:disabled) + Rails.application.config.session_store :disabled + else + store = Rails.application.config.session_store + Rails.application.config.session_store store, value + end end # Controls the resource action separator diff --git a/actionpack/lib/action_controller/metal/http_authentication.rb b/actionpack/lib/action_controller/metal/http_authentication.rb index afa7674e40..f1355a83a3 100644 --- a/actionpack/lib/action_controller/metal/http_authentication.rb +++ b/actionpack/lib/action_controller/metal/http_authentication.rb @@ -165,7 +165,7 @@ module ActionController # Authenticate with HTTP Digest, returns true or false def authenticate_with_http_digest(realm = "Application", &password_procedure) - HttpAuthentication::Digest.authenticate(config.session_options[:secret], request, realm, &password_procedure) + HttpAuthentication::Digest.authenticate(config.secret, request, realm, &password_procedure) end # Render output including the HTTP Digest authentication header @@ -238,7 +238,7 @@ module ActionController end def authentication_header(controller, realm) - secret_key = controller.config.session_options[:secret] + secret_key = controller.config.secret nonce = self.nonce(secret_key) opaque = opaque(secret_key) controller.headers["WWW-Authenticate"] = %(Digest realm="#{realm}", qop="auth", algorithm=MD5, nonce="#{nonce}", opaque="#{opaque}") diff --git a/actionpack/lib/action_controller/metal/session_management.rb b/actionpack/lib/action_controller/metal/session_management.rb index 1ea22b7b28..91d89ff9a4 100644 --- a/actionpack/lib/action_controller/metal/session_management.rb +++ b/actionpack/lib/action_controller/metal/session_management.rb @@ -2,38 +2,8 @@ module ActionController #:nodoc: module SessionManagement #:nodoc: extend ActiveSupport::Concern - included do - # This is still needed for the session secret for some reason. - self.config.session_options ||= {} - end - - def self.session_store_for(store) - case store - when :active_record_store - ActiveRecord::SessionStore - when Symbol - ActionDispatch::Session.const_get(store.to_s.camelize) - else - store - end - end - module ClassMethods - def session_options - config.session_options - end - - def session_store - SessionManagement.session_store_for(config.session_store) - end - def session(*args) - ActiveSupport::Deprecation.warn( - "Disabling sessions for a single controller has been deprecated. " + - "Sessions are now lazy loaded. So if you don't access them, " + - "consider them off. You can still modify the session cookie " + - "options with request.session_options.", caller) - end end end end diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb index 031df9423f..e9edf80451 100644 --- a/actionpack/lib/action_controller/railtie.rb +++ b/actionpack/lib/action_controller/railtie.rb @@ -49,11 +49,9 @@ module ActionController ac.assets_dir = paths.public.to_a.first ac.javascripts_dir = paths.public.javascripts.to_a.first ac.stylesheets_dir = paths.public.stylesheets.to_a.first + ac.secret = app.config.cookie_secret ActionController::Base.config.replace(ac) - # app.config.action_controller.each do |k,v| - # ActionController::Base.send "#{k}=", v - # end end initializer "action_controller.initialize_framework_caches" do diff --git a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb index 04a101dbb2..db64711052 100644 --- a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb +++ b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb @@ -177,9 +177,8 @@ module ActionDispatch if key.blank? raise ArgumentError, 'A key is required to write a ' + 'cookie containing the session data. Use ' + - 'config.action_controller.session = { :key => ' + - '"_myapp_session", :secret => "some secret phrase" } in ' + - 'config/application.rb' + 'config.action_controller.session_store :cookie_store, { :key => ' + + '"_myapp_session" } in config/application.rb' end end @@ -193,10 +192,9 @@ module ActionDispatch if secret.blank? raise ArgumentError, "A secret is required to generate an " + "integrity hash for cookie session data. Use " + - "config.action_controller.session = { :key => " + - "\"_myapp_session\", :secret => \"some secret phrase of at " + - "least #{SECRET_MIN_LENGTH} characters\" } " + - "in config/environment.rb" + "config.cookie_secret = \"some secret phrase of at " + + "least #{SECRET_MIN_LENGTH} characters\"" + + "in config/application.rb" end if secret.length < SECRET_MIN_LENGTH diff --git a/actionpack/lib/action_dispatch/railtie.rb b/actionpack/lib/action_dispatch/railtie.rb index 30b3535e17..e486bd4079 100644 --- a/actionpack/lib/action_dispatch/railtie.rb +++ b/actionpack/lib/action_dispatch/railtie.rb @@ -7,8 +7,6 @@ module ActionDispatch config.action_dispatch.x_sendfile_header = "X-Sendfile" config.action_dispatch.ip_spoofing_check = true - config.action_dispatch.session = {} - config.action_dispatch.session_store = :cookie_store # Prepare dispatcher callbacks and run 'prepare' callbacks initializer "action_dispatch.prepare_dispatcher" do |app| diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb index 29270ed228..d103c4e485 100644 --- a/actionpack/test/abstract_unit.rb +++ b/actionpack/test/abstract_unit.rb @@ -170,8 +170,7 @@ end # Temporary base class class Rack::TestCase < ActionController::IntegrationTest setup do - ActionController::Base.session_options[:key] = "abc" - ActionController::Base.session_options[:secret] = ("*" * 30) + ActionController::Base.config.secret = "abc" * 30 end def self.testing(klass = nil) diff --git a/actionpack/test/controller/http_digest_authentication_test.rb b/actionpack/test/controller/http_digest_authentication_test.rb index 6f167fe627..eb2af523a2 100644 --- a/actionpack/test/controller/http_digest_authentication_test.rb +++ b/actionpack/test/controller/http_digest_authentication_test.rb @@ -41,11 +41,12 @@ class HttpDigestAuthenticationTest < ActionController::TestCase setup do # Used as secret in generating nonce to prevent tampering of timestamp @secret = "session_options_secret" - @old_secret, ActionController::Base.session_options[:secret] = ActionController::Base.session_options[:secret], @secret + @controller.config.secret = @secret + # @old_secret, ActionController::Base.config.secret[:secret] = ActionController::Base.session_options[:secret], @secret end teardown do - ActionController::Base.session_options[:secret] = @old_secret + # ActionController::Base.session_options[:secret] = @old_secret end AUTH_HEADERS.each do |header| -- cgit v1.2.3 From c8e1cc8657c19a852f3c84cdc61df538486f5adf Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Thu, 4 Mar 2010 16:35:05 -0800 Subject: remove_method is private --- actionpack/test/template/test_case_test.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'actionpack') diff --git a/actionpack/test/template/test_case_test.rb b/actionpack/test/template/test_case_test.rb index 87408d8475..195a6ea3ae 100644 --- a/actionpack/test/template/test_case_test.rb +++ b/actionpack/test/template/test_case_test.rb @@ -104,7 +104,7 @@ module ActionView assert_match /Hello: EloyHello: Manfred/, render(:partial => 'test/from_helper') ensure - self.class.helper_class.remove_method :render_from_helper + self.class.helper_class.send(:remove_method, :render_from_helper) end end @@ -162,7 +162,7 @@ module ActionView end assert_equal 'Word!', render(:partial => 'test/from_helper') ensure - _helpers.remove_method :render_from_helper + _helpers.send(:remove_method, :render_from_helper) end end -- cgit v1.2.3 From ff29606c061099f82668ab62e50660cda8645512 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Thu, 4 Mar 2010 16:50:57 -0800 Subject: Refactor cache_store to use ActionController config --- actionpack/lib/action_controller/caching.rb | 34 ++++++++++++---------- .../lib/action_controller/metal/compatibility.rb | 5 ---- actionpack/test/controller/caching_test.rb | 21 ++++++++----- actionpack/test/controller/log_subscriber_test.rb | 3 +- 4 files changed, 33 insertions(+), 30 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/caching.rb b/actionpack/lib/action_controller/caching.rb index d784138ebe..7fae4e924d 100644 --- a/actionpack/lib/action_controller/caching.rb +++ b/actionpack/lib/action_controller/caching.rb @@ -40,15 +40,27 @@ module ActionController #:nodoc: autoload :Sweeping, 'action_controller/caching/sweeping' end - included do - @@cache_store = nil - cattr_reader :cache_store + module ConfigMethods + def cache_store + config.cache_store + end - # Defines the storage option for cached fragments - def self.cache_store=(store_option) - @@cache_store = ActiveSupport::Cache.lookup_store(store_option) + def cache_store=(store) + config.cache_store = ActiveSupport::Cache.lookup_store(store) end + private + + def cache_configured? + perform_caching && cache_store + end + end + + include ConfigMethods + + included do + extend ConfigMethods + include Pages, Actions, Fragments include Sweeping if defined?(ActiveRecord) @@ -56,11 +68,6 @@ module ActionController #:nodoc: cattr_accessor :perform_caching end - module ClassMethods - def cache_configured? - perform_caching && cache_store - end - end def caching_allowed? request.get? && response.status == 200 @@ -75,10 +82,5 @@ module ActionController #:nodoc: yield end end - - private - def cache_configured? - self.class.cache_configured? - end end end diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb index 44ace925e9..317a9fd951 100644 --- a/actionpack/lib/action_controller/metal/compatibility.rb +++ b/actionpack/lib/action_controller/metal/compatibility.rb @@ -35,11 +35,6 @@ module ActionController raise env["action_dispatch.rescue.exception"] end - # Defines the storage option for cached fragments - def cache_store=(store_option) - @@cache_store = ActiveSupport::Cache.lookup_store(store_option) - end - self.page_cache_directory = defined?(Rails.public_path) ? Rails.public_path : "" end diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index e42ef85b98..11ef3cdd92 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -6,12 +6,18 @@ CACHE_DIR = 'test_cache' # Don't change '/../temp/' cavalierly or you might hose something you don't want hosed FILE_STORE_PATH = File.join(File.dirname(__FILE__), '/../temp/', CACHE_DIR) ActionController::Base.page_cache_directory = FILE_STORE_PATH -ActionController::Base.cache_store = :file_store, FILE_STORE_PATH -class PageCachingTestController < ActionController::Base +class CachingController < ActionController::Base + abstract! + + self.cache_store = :file_store, FILE_STORE_PATH +end + +class PageCachingTestController < CachingController caches_page :ok, :no_content, :if => Proc.new { |c| !c.request.format.json? } caches_page :found, :not_found + def ok head :ok end @@ -55,6 +61,7 @@ class PageCachingTest < ActionController::TestCase @response = ActionController::TestResponse.new @controller = PageCachingTestController.new + @controller.cache_store = :file_store, FILE_STORE_PATH @params = {:controller => 'posts', :action => 'index', :only_path => true, :skip_relative_url_root => true} @rewriter = ActionController::UrlRewriter.new(@request, @params) @@ -148,7 +155,7 @@ class PageCachingTest < ActionController::TestCase end end -class ActionCachingTestController < ActionController::Base +class ActionCachingTestController < CachingController rescue_from(Exception) { head 500 } if defined? ActiveRecord rescue_from(ActiveRecord::RecordNotFound) { head :not_found } @@ -522,7 +529,7 @@ class ActionCacheTest < ActionController::TestCase end end -class FragmentCachingTestController < ActionController::Base +class FragmentCachingTestController < CachingController def some_action; end; end @@ -531,8 +538,8 @@ class FragmentCachingTest < ActionController::TestCase super ActionController::Base.perform_caching = true @store = ActiveSupport::Cache::MemoryStore.new - ActionController::Base.cache_store = @store @controller = FragmentCachingTestController.new + @controller.cache_store = @store @params = {:controller => 'posts', :action => 'index'} @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new @@ -630,7 +637,7 @@ class FragmentCachingTest < ActionController::TestCase end -class FunctionalCachingController < ActionController::Base +class FunctionalCachingController < CachingController def fragment_cached end @@ -664,8 +671,8 @@ class FunctionalFragmentCachingTest < ActionController::TestCase super ActionController::Base.perform_caching = true @store = ActiveSupport::Cache::MemoryStore.new - ActionController::Base.cache_store = @store @controller = FunctionalCachingController.new + @controller.cache_store = @store @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new end diff --git a/actionpack/test/controller/log_subscriber_test.rb b/actionpack/test/controller/log_subscriber_test.rb index 1f8134822c..20d3e77b6e 100644 --- a/actionpack/test/controller/log_subscriber_test.rb +++ b/actionpack/test/controller/log_subscriber_test.rb @@ -46,8 +46,7 @@ class ACLogSubscriberTest < ActionController::TestCase @cache_path = File.expand_path('../temp/test_cache', File.dirname(__FILE__)) ActionController::Base.page_cache_directory = @cache_path - ActionController::Base.cache_store = :file_store, @cache_path - + @controller.cache_store = :file_store, @cache_path Rails::LogSubscriber.add(:action_controller, ActionController::Railties::LogSubscriber.new) end -- cgit v1.2.3 From 3438373f038cefda664b879f49eec8aec6a15a76 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Thu, 4 Mar 2010 16:59:54 -0800 Subject: Use AS::Concern for caching modules --- actionpack/lib/action_controller/caching.rb | 5 ++- actionpack/lib/action_controller/caching/pages.rb | 42 +++++++++++----------- .../lib/action_controller/caching/sweeping.rb | 4 +-- 3 files changed, 24 insertions(+), 27 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/caching.rb b/actionpack/lib/action_controller/caching.rb index 7fae4e924d..b3fa129929 100644 --- a/actionpack/lib/action_controller/caching.rb +++ b/actionpack/lib/action_controller/caching.rb @@ -57,13 +57,12 @@ module ActionController #:nodoc: end include ConfigMethods + include Pages, Actions, Fragments + include Sweeping if defined?(ActiveRecord) included do extend ConfigMethods - include Pages, Actions, Fragments - include Sweeping if defined?(ActiveRecord) - @@perform_caching = true cattr_accessor :perform_caching end diff --git a/actionpack/lib/action_controller/caching/pages.rb b/actionpack/lib/action_controller/caching/pages.rb index 5797eeebd6..36a97d390c 100644 --- a/actionpack/lib/action_controller/caching/pages.rb +++ b/actionpack/lib/action_controller/caching/pages.rb @@ -1,5 +1,6 @@ require 'fileutils' require 'uri' +require 'active_support/core_ext/class/attribute_accessors' module ActionController #:nodoc: module Caching @@ -34,27 +35,26 @@ module ActionController #:nodoc: # Additionally, you can expire caches using Sweepers that act on changes in the model to determine when a cache is supposed to be # expired. module Pages - def self.included(base) #:nodoc: - base.extend(ClassMethods) - base.class_eval do - @@page_cache_directory = defined?(Rails.public_path) ? Rails.public_path : "" - ## - # :singleton-method: - # The cache directory should be the document root for the web server and is set using Base.page_cache_directory = "/document/root". - # For Rails, this directory has already been set to Rails.public_path (which is usually set to RAILS_ROOT + "/public"). Changing - # this setting can be useful to avoid naming conflicts with files in public/, but doing so will likely require configuring your - # web server to look in the new location for cached files. - cattr_accessor :page_cache_directory - - @@page_cache_extension = '.html' - ## - # :singleton-method: - # Most Rails requests do not have an extension, such as /weblog/new. In these cases, the page caching mechanism will add one in - # order to make it easy for the cached files to be picked up properly by the web server. By default, this cache extension is .html. - # If you want something else, like .php or .shtml, just set Base.page_cache_extension. In cases where a request already has an - # extension, such as .xml or .rss, page caching will not add an extension. This allows it to work well with RESTful apps. - cattr_accessor :page_cache_extension - end + extend ActiveSupport::Concern + + included do + @@page_cache_directory = defined?(Rails.public_path) ? Rails.public_path : "" + ## + # :singleton-method: + # The cache directory should be the document root for the web server and is set using Base.page_cache_directory = "/document/root". + # For Rails, this directory has already been set to Rails.public_path (which is usually set to RAILS_ROOT + "/public"). Changing + # this setting can be useful to avoid naming conflicts with files in public/, but doing so will likely require configuring your + # web server to look in the new location for cached files. + cattr_accessor :page_cache_directory + + @@page_cache_extension = '.html' + ## + # :singleton-method: + # Most Rails requests do not have an extension, such as /weblog/new. In these cases, the page caching mechanism will add one in + # order to make it easy for the cached files to be picked up properly by the web server. By default, this cache extension is .html. + # If you want something else, like .php or .shtml, just set Base.page_cache_extension. In cases where a request already has an + # extension, such as .xml or .rss, page caching will not add an extension. This allows it to work well with RESTful apps. + cattr_accessor :page_cache_extension end module ClassMethods diff --git a/actionpack/lib/action_controller/caching/sweeping.rb b/actionpack/lib/action_controller/caching/sweeping.rb index 871f41bfdd..cf16417e84 100644 --- a/actionpack/lib/action_controller/caching/sweeping.rb +++ b/actionpack/lib/action_controller/caching/sweeping.rb @@ -30,9 +30,7 @@ module ActionController #:nodoc: # cache_sweeper OpenBar::Sweeper, :only => [ :edit, :destroy, :share ] # end module Sweeping - def self.included(base) #:nodoc: - base.extend(ClassMethods) - end + extend ActiveSupport::Concern module ClassMethods #:nodoc: def cache_sweeper(*sweepers) -- cgit v1.2.3 From 900a2d304a83bad7a3958464b8dfa6fb49670686 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Thu, 4 Mar 2010 17:43:46 -0800 Subject: Get rid of relative_url_path in favor of respecting SCRIPT_NAME. Also added a way to specify a default SCRIPT_NAME when generating URLs out of the context of a request. --- actionpack/lib/action_controller/metal/url_for.rb | 2 +- actionpack/lib/action_controller/railtie.rb | 6 ++++++ actionpack/lib/action_controller/url_rewriter.rb | 2 +- actionpack/lib/action_dispatch/routing/route_set.rb | 5 ++++- actionpack/lib/action_dispatch/routing/url_for.rb | 6 +++++- actionpack/test/controller/url_for_test.rb | 4 ++-- 6 files changed, 19 insertions(+), 6 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/url_for.rb b/actionpack/lib/action_controller/metal/url_for.rb index c890dc51d4..89ab0b4753 100644 --- a/actionpack/lib/action_controller/metal/url_for.rb +++ b/actionpack/lib/action_controller/metal/url_for.rb @@ -12,7 +12,7 @@ module ActionController # ROUTES TODO: relative_url_root should be middleware # and the generator should take SCRIPT_NAME into # consideration - :relative_url_root => config.relative_url_root, + :script_name => request.env["SCRIPT_NAME"], :_path_segments => request.symbolized_path_parameters ) end diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb index e9edf80451..e638be5251 100644 --- a/actionpack/lib/action_controller/railtie.rb +++ b/actionpack/lib/action_controller/railtie.rb @@ -51,6 +51,12 @@ module ActionController ac.stylesheets_dir = paths.public.stylesheets.to_a.first ac.secret = app.config.cookie_secret + if ac.relative_url_root + ActiveSupport::Deprecation.warn "config.action_controller.relative_url_root " \ + "is no longer effective. Please set it in the router as " \ + "routes.draw(:script_name => #{ac.relative_url_root.inspect})" + end + ActionController::Base.config.replace(ac) end diff --git a/actionpack/lib/action_controller/url_rewriter.rb b/actionpack/lib/action_controller/url_rewriter.rb index 973a6facd7..8821892b3a 100644 --- a/actionpack/lib/action_controller/url_rewriter.rb +++ b/actionpack/lib/action_controller/url_rewriter.rb @@ -32,7 +32,7 @@ module ActionController # ROUTES TODO: Fix the tests segments = options.delete(:_path_segments) - relative_url_root = options.delete(:relative_url_root).to_s + relative_url_root = options.delete(:script_name).to_s path_segments = path_segments ? path_segments.merge(segments || {}) : segments unless options[:only_path] diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 99436e3cb0..9ca1857966 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -211,6 +211,7 @@ module ActionDispatch attr_accessor :routes, :named_routes attr_accessor :disable_clear_and_finalize, :resources_path_names + attr_accessor :script_name def self.default_resources_path_names { :new => 'new', :edit => 'edit' } @@ -225,9 +226,11 @@ module ActionDispatch @disable_clear_and_finalize = false end - def draw(&block) + def draw(options = {}, &block) clear! unless @disable_clear_and_finalize + @script_name = options[:script_name] + mapper = Mapper.new(self) if block.arity == 1 mapper.instance_exec(DeprecatedMapper.new(self), &block) diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb index 7f2c9a5c12..afbb2ecf16 100644 --- a/actionpack/lib/action_dispatch/routing/url_for.rb +++ b/actionpack/lib/action_dispatch/routing/url_for.rb @@ -101,7 +101,11 @@ module ActionDispatch # end def url_options - self.class.default_url_options.merge(@url_options || {}) + @url_options ||= begin + opts = self.class.default_url_options + opts.merge(:script_name => _router.script_name) if respond_to?(:_router) + opts + end end def url_options=(options) diff --git a/actionpack/test/controller/url_for_test.rb b/actionpack/test/controller/url_for_test.rb index 07809aa480..fc7773dffe 100644 --- a/actionpack/test/controller/url_for_test.rb +++ b/actionpack/test/controller/url_for_test.rb @@ -118,7 +118,7 @@ module AbstractController add_host! assert_equal('https://www.basecamphq.com/subdir/c/a/i', - W.new.url_for(:controller => 'c', :action => 'a', :id => 'i', :protocol => 'https', :relative_url_root => '/subdir') + W.new.url_for(:controller => 'c', :action => 'a', :id => 'i', :protocol => 'https', :script_name => '/subdir') ) end @@ -153,7 +153,7 @@ module AbstractController controller = kls.new assert_equal 'http://www.basecamphq.com/subdir/home/sweet/home/again', - controller.send(:home_url, :host => 'www.basecamphq.com', :user => 'again', :relative_url_root => "/subdir") + controller.send(:home_url, :host => 'www.basecamphq.com', :user => 'again', :script_name => "/subdir") end end -- cgit v1.2.3 From deb00bcb8cf88eb6420282c9af0af64fb69aeed4 Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Thu, 4 Mar 2010 22:41:39 -0500 Subject: Read Rails version from a file instead of modifying the load path and doing requires Signed-off-by: Jeremy Kemper --- actionpack/actionpack.gemspec | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'actionpack') diff --git a/actionpack/actionpack.gemspec b/actionpack/actionpack.gemspec index a281df8642..a50c55ed9a 100644 --- a/actionpack/actionpack.gemspec +++ b/actionpack/actionpack.gemspec @@ -1,10 +1,9 @@ -$:.unshift "lib" -require "action_pack/version" +version = File.read("../RAILS_VERSION").strip Gem::Specification.new do |s| s.platform = Gem::Platform::RUBY s.name = 'actionpack' - s.version = ActionPack::VERSION::STRING + s.version = version s.summary = 'Web-flow and rendering framework putting the VC in MVC (part of Rails).' s.description = 'Web apps on Rails. Simple, battle-tested conventions for building and testing MVC web applications. Works with any Rack-compatible server.' s.required_ruby_version = '>= 1.8.7' @@ -20,8 +19,8 @@ Gem::Specification.new do |s| s.has_rdoc = true - s.add_dependency('activesupport', "= #{ActionPack::VERSION::STRING}") - s.add_dependency('activemodel', "= #{ActionPack::VERSION::STRING}") + s.add_dependency('activesupport', version) + s.add_dependency('activemodel', version) s.add_dependency('rack', '~> 1.1.0') s.add_dependency('rack-test', '~> 0.5.0') s.add_dependency('rack-mount', '~> 0.5.1') -- cgit v1.2.3 From 48672cd1997618f21f50e1204e60dc681e647ddb Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Thu, 4 Mar 2010 19:01:48 -0800 Subject: Have ActionDispatch::Routing::RouteSet.new ready to receive routes as is. --- actionpack/lib/action_dispatch/routing/route_set.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 9ca1857966..26189329c2 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -224,6 +224,7 @@ module ActionDispatch self.controller_namespaces = Set.new @disable_clear_and_finalize = false + clear! end def draw(options = {}, &block) -- cgit v1.2.3 From 9a17416d8bda0df0a6961e547c3cf1d677e66b5e Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Thu, 4 Mar 2010 21:59:42 -0800 Subject: Tweak out url_for uses :script_name and add some tests --- actionpack/lib/action_controller/metal/url_for.rb | 6 +-- actionpack/lib/action_controller/railtie.rb | 6 --- actionpack/lib/action_controller/url_rewriter.rb | 4 +- .../lib/action_dispatch/routing/route_set.rb | 12 ++--- actionpack/lib/action_dispatch/routing/url_for.rb | 9 ++-- actionpack/test/dispatch/url_generation_test.rb | 58 ++++++++++++++++++++++ 6 files changed, 71 insertions(+), 24 deletions(-) create mode 100644 actionpack/test/dispatch/url_generation_test.rb (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/url_for.rb b/actionpack/lib/action_controller/metal/url_for.rb index 89ab0b4753..f6b6cb2ff4 100644 --- a/actionpack/lib/action_controller/metal/url_for.rb +++ b/actionpack/lib/action_controller/metal/url_for.rb @@ -9,12 +9,8 @@ module ActionController super.reverse_merge( :host => request.host_with_port, :protocol => request.protocol, - # ROUTES TODO: relative_url_root should be middleware - # and the generator should take SCRIPT_NAME into - # consideration - :script_name => request.env["SCRIPT_NAME"], :_path_segments => request.symbolized_path_parameters - ) + ).merge(:script_name => request.script_name) end def _router diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb index e638be5251..e9edf80451 100644 --- a/actionpack/lib/action_controller/railtie.rb +++ b/actionpack/lib/action_controller/railtie.rb @@ -51,12 +51,6 @@ module ActionController ac.stylesheets_dir = paths.public.stylesheets.to_a.first ac.secret = app.config.cookie_secret - if ac.relative_url_root - ActiveSupport::Deprecation.warn "config.action_controller.relative_url_root " \ - "is no longer effective. Please set it in the router as " \ - "routes.draw(:script_name => #{ac.relative_url_root.inspect})" - end - ActionController::Base.config.replace(ac) end diff --git a/actionpack/lib/action_controller/url_rewriter.rb b/actionpack/lib/action_controller/url_rewriter.rb index 8821892b3a..981865517f 100644 --- a/actionpack/lib/action_controller/url_rewriter.rb +++ b/actionpack/lib/action_controller/url_rewriter.rb @@ -32,7 +32,6 @@ module ActionController # ROUTES TODO: Fix the tests segments = options.delete(:_path_segments) - relative_url_root = options.delete(:script_name).to_s path_segments = path_segments ? path_segments.merge(segments || {}) : segments unless options[:only_path] @@ -50,8 +49,7 @@ module ActionController path_options = yield(path_options) if block_given? path = router.generate(path_options, path_segments || {}) - # ROUTES TODO: This can be called directly, so relative_url_root should probably be set in the router - rewritten_url << relative_url_root + # ROUTES TODO: This can be called directly, so script_name should probably be set in the router rewritten_url << (options[:trailing_slash] ? path.sub(/\?|\z/) { "/" + $& } : path) rewritten_url << "##{Rack::Utils.escape(options[:anchor].to_param.to_s)}" if options[:anchor] diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 26189329c2..a53d8067dd 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -209,29 +209,27 @@ module ActionDispatch end end - attr_accessor :routes, :named_routes + attr_accessor :routes, :named_routes, :mount_point attr_accessor :disable_clear_and_finalize, :resources_path_names - attr_accessor :script_name def self.default_resources_path_names { :new => 'new', :edit => 'edit' } end - def initialize + def initialize(options = {}) self.routes = [] self.named_routes = NamedRouteCollection.new self.resources_path_names = self.class.default_resources_path_names.dup self.controller_namespaces = Set.new + self.mount_point = options[:mount_point] @disable_clear_and_finalize = false clear! end - def draw(options = {}, &block) + def draw(&block) clear! unless @disable_clear_and_finalize - @script_name = options[:script_name] - mapper = Mapper.new(self) if block.arity == 1 mapper.instance_exec(DeprecatedMapper.new(self), &block) @@ -341,6 +339,7 @@ module ActionDispatch def generate(options, recall = {}, method = :generate) options, recall = options.dup, recall.dup + script_name = options.delete(:script_name) || mount_point named_route = options.delete(:use_route) options = options_as_params(options) @@ -406,6 +405,7 @@ module ActionDispatch [path, params.keys] elsif path path << "?#{params.to_query}" if params.any? + path = "#{script_name}#{path}" path else raise ActionController::RoutingError, "No route matches #{options.inspect}" diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb index afbb2ecf16..be5edcc120 100644 --- a/actionpack/lib/action_dispatch/routing/url_for.rb +++ b/actionpack/lib/action_dispatch/routing/url_for.rb @@ -102,14 +102,15 @@ module ActionDispatch def url_options @url_options ||= begin - opts = self.class.default_url_options - opts.merge(:script_name => _router.script_name) if respond_to?(:_router) - opts + # self.class does not respond to default_url_options when the helpers are extended + # onto a singleton + self.class.respond_to?(:default_url_options) ? self.class.default_url_options : {} end end def url_options=(options) - @url_options = options + defaults = self.class.respond_to?(:default_url_options) ? self.class.default_url_options : {} + @url_options = defaults.merge(options) end # def merge_options(options) #:nodoc: diff --git a/actionpack/test/dispatch/url_generation_test.rb b/actionpack/test/dispatch/url_generation_test.rb new file mode 100644 index 0000000000..b55e001fa7 --- /dev/null +++ b/actionpack/test/dispatch/url_generation_test.rb @@ -0,0 +1,58 @@ +require 'abstract_unit' + +module TestUrlGeneration + class WithoutMountpoint < ActiveSupport::TestCase + setup do + app = lambda { |env| [200, {}, "Hello"] } + @router = ActionDispatch::Routing::RouteSet.new + @router.draw do + match "/foo", :to => app, :as => :foo + end + + singleton_class.send(:include, @router.url_helpers) + end + + test "generating URLS normally" do + assert_equal "/foo", foo_path + end + + test "accepting a :script_name option" do + assert_equal "/bar/foo", foo_path(:script_name => "/bar") + end + end + + class WithMountPoint < ActionDispatch::IntegrationTest + Router = ActionDispatch::Routing::RouteSet.new(:mount_point => "/baz") + Router.draw { match "/foo", :to => "my_route_generating#index", :as => :foo } + + class ::MyRouteGeneratingController < ActionController::Base + include Router.url_helpers + def index + render :text => foo_path + end + end + + include Router.url_helpers + + def _router + Router + end + + def app + Router + end + + test "using the default :script_name option" do + assert_equal "/baz/foo", foo_path + end + + test "overriding the default :script_name option" do + assert_equal "/bar/foo", foo_path(:script_name => "/bar") + end + + test "the request's SCRIPT_NAME takes precedence over the router's" do + get "/foo", {}, 'SCRIPT_NAME' => "/new" + assert_equal "/new/foo", response.body + end + end +end \ No newline at end of file -- cgit v1.2.3 From 57cf1c578a5a3823ae280cf786c1d2ec71001ba8 Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Thu, 4 Mar 2010 22:17:25 -0800 Subject: Remove the ability to set the mountpoint when initializing a route set. --- .../lib/action_dispatch/routing/route_set.rb | 7 +++--- actionpack/test/dispatch/url_generation_test.rb | 28 ++++------------------ 2 files changed, 7 insertions(+), 28 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index a53d8067dd..5c246d8781 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -209,19 +209,18 @@ module ActionDispatch end end - attr_accessor :routes, :named_routes, :mount_point + attr_accessor :routes, :named_routes attr_accessor :disable_clear_and_finalize, :resources_path_names def self.default_resources_path_names { :new => 'new', :edit => 'edit' } end - def initialize(options = {}) + def initialize self.routes = [] self.named_routes = NamedRouteCollection.new self.resources_path_names = self.class.default_resources_path_names.dup self.controller_namespaces = Set.new - self.mount_point = options[:mount_point] @disable_clear_and_finalize = false clear! @@ -339,7 +338,7 @@ module ActionDispatch def generate(options, recall = {}, method = :generate) options, recall = options.dup, recall.dup - script_name = options.delete(:script_name) || mount_point + script_name = options.delete(:script_name) named_route = options.delete(:use_route) options = options_as_params(options) diff --git a/actionpack/test/dispatch/url_generation_test.rb b/actionpack/test/dispatch/url_generation_test.rb index b55e001fa7..18b5b7ee00 100644 --- a/actionpack/test/dispatch/url_generation_test.rb +++ b/actionpack/test/dispatch/url_generation_test.rb @@ -1,28 +1,8 @@ require 'abstract_unit' module TestUrlGeneration - class WithoutMountpoint < ActiveSupport::TestCase - setup do - app = lambda { |env| [200, {}, "Hello"] } - @router = ActionDispatch::Routing::RouteSet.new - @router.draw do - match "/foo", :to => app, :as => :foo - end - - singleton_class.send(:include, @router.url_helpers) - end - - test "generating URLS normally" do - assert_equal "/foo", foo_path - end - - test "accepting a :script_name option" do - assert_equal "/bar/foo", foo_path(:script_name => "/bar") - end - end - class WithMountPoint < ActionDispatch::IntegrationTest - Router = ActionDispatch::Routing::RouteSet.new(:mount_point => "/baz") + Router = ActionDispatch::Routing::RouteSet.new Router.draw { match "/foo", :to => "my_route_generating#index", :as => :foo } class ::MyRouteGeneratingController < ActionController::Base @@ -42,11 +22,11 @@ module TestUrlGeneration Router end - test "using the default :script_name option" do - assert_equal "/baz/foo", foo_path + test "generating URLS normally" do + assert_equal "/foo", foo_path end - test "overriding the default :script_name option" do + test "accepting a :script_name option" do assert_equal "/bar/foo", foo_path(:script_name => "/bar") end -- cgit v1.2.3 From 80715cee73856d0ccade7b912b1e6a0aa5ca135b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Fri, 5 Mar 2010 15:40:06 +0100 Subject: Define to_s method in ActionView::Resolver, so I'm not required to write it in inherited classes. --- actionpack/lib/action_view/template/resolver.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb index 20402f9d6d..962fa0e260 100644 --- a/actionpack/lib/action_view/template/resolver.rb +++ b/actionpack/lib/action_view/template/resolver.rb @@ -29,11 +29,11 @@ module ActionView @cached = {} end - # Normalizes the arguments and passes it on to find_template def find(*args) find_all(*args).first end + # Normalizes the arguments and passes it on to find_template def find_all(name, details = {}, prefix = nil, partial = nil) details = normalize_details(details) name, prefix = normalize_name(name, prefix) @@ -43,6 +43,10 @@ module ActionView end end + def to_s + self.class.name + end + private # This is what child classes implement. No defaults are needed -- cgit v1.2.3 From 7d4d97e22ad3cb1ff280265cbbc880feff47e694 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Fri, 5 Mar 2010 15:49:36 +0100 Subject: Actually, revert previous commit. Having a lot of information is better than having no information at all. --- actionpack/lib/action_view/template/resolver.rb | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb index 962fa0e260..8c81914aac 100644 --- a/actionpack/lib/action_view/template/resolver.rb +++ b/actionpack/lib/action_view/template/resolver.rb @@ -18,11 +18,9 @@ module ActionView end end - register_detail(:locale) { [I18n.locale] } - register_detail(:formats) { Mime::SET.symbols } - register_detail(:handlers) do - Template::Handlers.extensions - end + register_detail(:locale) { [I18n.locale] } + register_detail(:formats) { Mime::SET.symbols } + register_detail(:handlers) { Template::Handlers.extensions } def initialize(options = {}) @cache = options[:cache] @@ -43,10 +41,6 @@ module ActionView end end - def to_s - self.class.name - end - private # This is what child classes implement. No defaults are needed -- cgit v1.2.3 From 8da026cb797519deac807721096fab5182ca61af Mon Sep 17 00:00:00 2001 From: Xavier Shay Date: Wed, 17 Feb 2010 15:07:01 +1100 Subject: Remove some of the blank rescues from number helper. This makes the code easier to understand, as you're not left wondering what the rescue is actually doing. This does not change documented/tested behaviour. Signed-off-by: wycats --- .../lib/action_view/helpers/number_helper.rb | 86 +++++++++++----------- 1 file changed, 42 insertions(+), 44 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/number_helper.rb b/actionpack/lib/action_view/helpers/number_helper.rb index 3d3502a08b..46e41bc406 100644 --- a/actionpack/lib/action_view/helpers/number_helper.rb +++ b/actionpack/lib/action_view/helpers/number_helper.rb @@ -28,27 +28,25 @@ module ActionView # number_to_phone(1235551234, :country_code => 1, :extension => 1343, :delimiter => ".") # => +1.123.555.1234 x 1343 def number_to_phone(number, options = {}) - number = number.to_s.strip unless number.nil? + return nil if number.nil? + + number = number.to_s.strip options = options.symbolize_keys area_code = options[:area_code] || nil delimiter = options[:delimiter] || "-" extension = options[:extension].to_s.strip || nil country_code = options[:country_code] || nil - begin - str = "" - str << "+#{country_code}#{delimiter}" unless country_code.blank? - str << if area_code - number.gsub!(/([0-9]{1,3})([0-9]{3})([0-9]{4}$)/,"(\\1) \\2#{delimiter}\\3") - else - number.gsub!(/([0-9]{0,3})([0-9]{3})([0-9]{4})$/,"\\1#{delimiter}\\2#{delimiter}\\3") - number.starts_with?('-') ? number.slice!(1..-1) : number - end - str << " x #{extension}" unless extension.blank? - str - rescue - number + str = "" + str << "+#{country_code}#{delimiter}" unless country_code.blank? + str << if area_code + number.gsub!(/([0-9]{1,3})([0-9]{3})([0-9]{4}$)/,"(\\1) \\2#{delimiter}\\3") + else + number.gsub!(/([0-9]{0,3})([0-9]{3})([0-9]{4})$/,"\\1#{delimiter}\\2#{delimiter}\\3") + number.starts_with?('-') ? number.slice!(1..-1) : number end + str << " x #{extension}" unless extension.blank? + str end # Formats a +number+ into a currency string (e.g., $13.65). You can customize the format @@ -87,13 +85,14 @@ module ActionView format = options[:format] || defaults[:format] separator = '' if precision == 0 - begin - format.gsub(/%n/, number_with_precision(number, - :precision => precision, - :delimiter => delimiter, - :separator => separator) - ).gsub(/%u/, unit).html_safe - rescue + value = number_with_precision(number, + :precision => precision, + :delimiter => delimiter, + :separator => separator) + + if value + format.gsub(/%n/, value).gsub(/%u/, unit).html_safe + else number end end @@ -122,14 +121,11 @@ module ActionView separator = options[:separator] || defaults[:separator] delimiter = options[:delimiter] || defaults[:delimiter] - begin - number_with_precision(number, - :precision => precision, - :separator => separator, - :delimiter => delimiter) + "%" - rescue - number - end + value = number_with_precision(number, + :precision => precision, + :separator => separator, + :delimiter => delimiter) + value ? value + "%" : number end # Formats a +number+ with grouped thousands using +delimiter+ (e.g., 12,324). You can @@ -168,11 +164,11 @@ module ActionView delimiter ||= (options[:delimiter] || defaults[:delimiter]) separator ||= (options[:separator] || defaults[:separator]) - begin - parts = number.to_s.split('.') + parts = number.to_s.split('.') + if parts[0] parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{delimiter}") parts.join(separator) - rescue + else number end end @@ -216,11 +212,17 @@ module ActionView delimiter ||= (options[:delimiter] || defaults[:delimiter]) begin + value = Float(number) + rescue ArgumentError, TypeError + value = nil + end + + if value rounded_number = BigDecimal.new((Float(number) * (10 ** precision)).to_s).round.to_f / 10 ** precision number_with_delimiter("%01.#{precision}f" % rounded_number, :separator => separator, :delimiter => delimiter) - rescue + else number end end @@ -293,17 +295,13 @@ module ActionView unit_key = STORAGE_UNITS[exponent] unit = I18n.translate(:"number.human.storage_units.units.#{unit_key}", :locale => options[:locale], :count => number, :raise => true) - begin - escaped_separator = Regexp.escape(separator) - formatted_number = number_with_precision(number, - :precision => precision, - :separator => separator, - :delimiter => delimiter - ).sub(/(#{escaped_separator})(\d*[1-9])?0+\z/, '\1\2').sub(/#{escaped_separator}\z/, '') - storage_units_format.gsub(/%n/, formatted_number).gsub(/%u/, unit) - rescue - number - end + escaped_separator = Regexp.escape(separator) + formatted_number = number_with_precision(number, + :precision => precision, + :separator => separator, + :delimiter => delimiter + ).sub(/(#{escaped_separator})(\d*[1-9])?0+\z/, '\1\2').sub(/#{escaped_separator}\z/, '') + storage_units_format.gsub(/%n/, formatted_number).gsub(/%u/, unit) end end end -- cgit v1.2.3 From a04b44910e57387bd1bcfbd95c3a6754a08e77af Mon Sep 17 00:00:00 2001 From: Jose Fernandez Date: Tue, 23 Feb 2010 18:50:05 +0100 Subject: Solved a problem that prevented render :file => work in layouts Signed-off-by: wycats --- actionpack/lib/action_view/render/rendering.rb | 2 +- actionpack/test/fixtures/test/layout_render_file.erb | 2 ++ actionpack/test/template/render_test.rb | 5 +++++ 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 actionpack/test/fixtures/test/layout_render_file.erb (limited to 'actionpack') diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb index 64cc0caf11..28b79bfcb7 100644 --- a/actionpack/lib/action_view/render/rendering.rb +++ b/actionpack/lib/action_view/render/rendering.rb @@ -102,7 +102,7 @@ module ActionView ActiveSupport::Notifications.instrument("action_view.render_template", :identifier => template.identifier, :layout => layout.try(:identifier)) do - content = template.render(self, locals) + content = template.render(self, locals) {|*name| _layout_for(*name) } @_content_for[:layout] = content if layout diff --git a/actionpack/test/fixtures/test/layout_render_file.erb b/actionpack/test/fixtures/test/layout_render_file.erb new file mode 100644 index 0000000000..2f8e921c5f --- /dev/null +++ b/actionpack/test/fixtures/test/layout_render_file.erb @@ -0,0 +1,2 @@ +<% content_for :title do %>title<% end -%> +<%= render :file => 'layouts/yield' -%> \ No newline at end of file diff --git a/actionpack/test/template/render_test.rb b/actionpack/test/template/render_test.rb index 338ada8b0e..6dbadc9304 100644 --- a/actionpack/test/template/render_test.rb +++ b/actionpack/test/template/render_test.rb @@ -233,6 +233,11 @@ module RenderTestCases @view.render(:file => "test/nested_layout.erb", :layout => "layouts/yield") end + def test_render_with_file_in_layout + assert_equal %(\ntitle\n\n), + @view.render(:file => "test/layout_render_file.erb") + end + if '1.9'.respond_to?(:force_encoding) def test_render_utf8_template_with_magic_comment with_external_encoding Encoding::ASCII_8BIT do -- cgit v1.2.3 From a82cf0a9327d85f5787427e1d06d0ae374b11103 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Fri, 5 Mar 2010 12:15:45 -0800 Subject: Tweak default_url_options deprecation warning --- actionpack/lib/action_dispatch/routing/url_for.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb index be5edcc120..0ab20dcb39 100644 --- a/actionpack/lib/action_dispatch/routing/url_for.rb +++ b/actionpack/lib/action_dispatch/routing/url_for.rb @@ -152,7 +152,7 @@ module ActionDispatch when Hash # Handle the deprecated instance level default_url_options if respond_to?(:default_url_options, true) - ActiveSupport::Deprecation.warn "Overwriting #default_url_options is deprecated. Please set url options with self.url_options = { ... }" + ActiveSupport::Deprecation.warn "Overriding the #default_url_options method is deprecated. Instead, set self.url_options = { ... } in a before_filter." if defaults = default_url_options(options) options = defaults.merge(options) end @@ -165,4 +165,4 @@ module ActionDispatch end end end -end \ No newline at end of file +end -- cgit v1.2.3 From e472f76e4c86cfc1350f3b769d9ac3d96f062e3f Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 5 Mar 2010 19:40:41 -0200 Subject: =?UTF-8?q?Adds=20disable=20option=20to=20date=5Fhelpers=20generat?= =?UTF-8?q?ed=20hidden=20fields=20when=20html=5Foptions=20specifies=20it.?= =?UTF-8?q?=20ht=20by=20Marc=20Sch=C3=BCtz?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [#3807 state:committed] Signed-off-by: Jeremy Kemper --- actionpack/lib/action_view/helpers/date_helper.rb | 3 +- actionpack/test/template/date_helper_test.rb | 55 +++++++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb index 89ac682c18..42018ee261 100644 --- a/actionpack/lib/action_view/helpers/date_helper.rb +++ b/actionpack/lib/action_view/helpers/date_helper.rb @@ -1,5 +1,6 @@ require "date" require 'action_view/helpers/tag_helper' +require 'active_support/core_ext/hash/slice' module ActionView module Helpers @@ -865,7 +866,7 @@ module ActionView :id => input_id_from_type(type), :name => input_name_from_type(type), :value => value - }) + "\n").html_safe + }.merge(@html_options.slice(:disabled))) + "\n").html_safe end # Returns the name attribute for the input tag diff --git a/actionpack/test/template/date_helper_test.rb b/actionpack/test/template/date_helper_test.rb index 7d3075d232..9a2d490854 100644 --- a/actionpack/test/template/date_helper_test.rb +++ b/actionpack/test/template/date_helper_test.rb @@ -1229,6 +1229,23 @@ class DateHelperTest < ActionView::TestCase assert_dom_equal expected, date_select("post", "written_on", :order => [ :month, :year ]) end + def test_date_select_without_day_and_with_disabled_html_option + @post = Post.new + @post.written_on = Date.new(2004, 6, 15) + + expected = "\n" + + expected << %{\n" + + expected << %{\n" + + assert_dom_equal expected, date_select("post", "written_on", { :order => [ :month, :year ] }, :disabled => true) + end + def test_date_select_within_fields_for @post = Post.new @post.written_on = Date.new(2004, 6, 15) @@ -1713,6 +1730,25 @@ class DateHelperTest < ActionView::TestCase assert_dom_equal expected, time_select("post", "written_on", :prompt => {:hour => 'Choose hour', :minute => 'Choose minute'}) end + def test_time_select_with_disabled_html_option + @post = Post.new + @post.written_on = Time.local(2004, 6, 15, 15, 16, 35) + + expected = %{\n} + expected << %{\n} + expected << %{\n} + + expected << %(\n" + expected << " : " + expected << %(\n" + + assert_dom_equal expected, time_select("post", "written_on", {}, :disabled => true) + end + def test_datetime_select @post = Post.new @post.updated_at = Time.local(2004, 6, 15, 16, 35) @@ -2173,6 +2209,25 @@ class DateHelperTest < ActionView::TestCase assert_dom_equal expected, datetime_select("post", "updated_at", :discard_year => true, :discard_month => true) end + def test_datetime_select_discard_year_and_month_with_disabled_html_option + @post = Post.new + @post.updated_at = Time.local(2004, 6, 15, 15, 16, 35) + + expected = %{\n} + expected << %{\n} + expected << %{\n} + + expected << %{\n" + expected << " : " + expected << %{\n" + + assert_dom_equal expected, datetime_select("post", "updated_at", { :discard_year => true, :discard_month => true }, :disabled => true) + end + def test_datetime_select_discard_hour @post = Post.new @post.updated_at = Time.local(2004, 6, 15, 15, 16, 35) -- cgit v1.2.3 From 4bc2cbc3cfa231b3dea0dce38a6fa2723c7ed94d Mon Sep 17 00:00:00 2001 From: Stefan Penner Date: Sat, 6 Mar 2010 13:30:25 -0600 Subject: Load RAILS_VERSION relative to the gemspec file. --- actionpack/actionpack.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/actionpack.gemspec b/actionpack/actionpack.gemspec index a50c55ed9a..790efc4ec5 100644 --- a/actionpack/actionpack.gemspec +++ b/actionpack/actionpack.gemspec @@ -1,4 +1,4 @@ -version = File.read("../RAILS_VERSION").strip +version = File.read(File.expand_path("../../RAILS_VERSION", __FILE__)).strip Gem::Specification.new do |s| s.platform = Gem::Platform::RUBY -- cgit v1.2.3 From 6e0443fd433393dc1967fab4f4fa06dc2b3c02fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sun, 7 Mar 2010 12:49:27 +0100 Subject: First take on ViewPaths clean up. --- actionpack/lib/action_view/paths.rb | 78 ++++++------------------- actionpack/lib/action_view/template/resolver.rb | 19 +++--- actionpack/test/lib/fixture_template.rb | 4 +- 3 files changed, 32 insertions(+), 69 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/paths.rb b/actionpack/lib/action_view/paths.rb index 6e55d69d00..459b6bba54 100644 --- a/actionpack/lib/action_view/paths.rb +++ b/actionpack/lib/action_view/paths.rb @@ -1,46 +1,17 @@ module ActionView #:nodoc: class PathSet < Array #:nodoc: - def self.type_cast(obj, cache = nil) - # TODO: Clean this up - if obj.is_a?(String) - if cache.nil? - cache = !defined?(Rails.application) || Rails.application.config.cache_classes + %w(initialize << concat insert push unshift).each do |method| + class_eval <<-METHOD, __FILE__, __LINE__ + 1 + def #{method}(*args) + super + typecast! end - FileSystemResolverWithFallback.new(obj, :cache => cache) - else - obj - end - end - - def initialize(*args) - super(*args).map! { |obj| self.class.type_cast(obj) } - end - - def <<(obj) - super(self.class.type_cast(obj)) - end - - def concat(array) - super(array.map! { |obj| self.class.type_cast(obj) }) - end - - def insert(index, obj) - super(index, self.class.type_cast(obj)) - end - - def push(*objs) - super(*objs.map { |obj| self.class.type_cast(obj) }) - end - - def unshift(*objs) - super(*objs.map { |obj| self.class.type_cast(obj) }) + METHOD end def find(path, details = {}, prefix = nil, partial = false) - template_path = path - - each do |load_path| - if template = load_path.find(template_path, details, prefix, partial) + each do |resolver| + if template = resolver.find(path, details, prefix, partial) return template end end @@ -48,33 +19,22 @@ module ActionView #:nodoc: raise ActionView::MissingTemplate.new(self, "#{prefix}/#{path}", details, partial) end - def exists?(path, extension = nil, prefix = nil, partial = false) - template_path = path.sub(/^\//, '') - - each do |load_path| - return true if template = load_path.find(template_path, extension, prefix, partial) - end + def exists?(path, details = {}, prefix = nil, partial = false) + each do |resolver| + if resolver.find(path, details, prefix, partial) + return true + end + end false end - def find_template(original_template_path, format = nil, html_fallback = true) - return original_template_path if original_template_path.respond_to?(:render) - template_path = original_template_path.sub(/^\//, '') + protected - each do |load_path| - if template = load_path.find(template_path, format) - return template - # Try to find html version if the format is javascript - elsif format == :js && html_fallback && template = load_path["#{template_path}.#{I18n.locale}.html"] - return template - elsif format == :js && html_fallback && template = load_path["#{template_path}.html"] - return template - end + def typecast! + each_with_index do |path, i| + next unless path.is_a?(String) + self[i] = FileSystemResolverWithFallback.new(path) end - - return Template.new(original_template_path, original_template_path.to_s =~ /\A\// ? "" : ".") if File.file?(original_template_path) - - raise MissingTemplate.new(self, original_template_path, format) end end end diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb index 8c81914aac..40326f9193 100644 --- a/actionpack/lib/action_view/template/resolver.rb +++ b/actionpack/lib/action_view/template/resolver.rb @@ -22,8 +22,7 @@ module ActionView register_detail(:formats) { Mime::SET.symbols } register_detail(:handlers) { Template::Handlers.extensions } - def initialize(options = {}) - @cache = options[:cache] + def initialize @cached = {} end @@ -43,6 +42,10 @@ module ActionView private + def caching? + @caching ||= !defined?(Rails.application) || Rails.application.config.cache_classes + end + # This is what child classes implement. No defaults are needed # because Resolver guarantees that the arguments are present and # normalized. @@ -72,7 +75,7 @@ module ActionView end def cached(key) - return yield unless @cache + return yield unless caching? return @cached[key] if @cached.key?(key) @cached[key] = yield end @@ -133,18 +136,18 @@ module ActionView end class FileSystemResolver < PathResolver - def initialize(path, options = {}) + def initialize(path) raise ArgumentError, "path already is a Resolver class" if path.is_a?(Resolver) - super(options) + super() @path = Pathname.new(path).expand_path end end # TODO: remove hack class FileSystemResolverWithFallback < Resolver - def initialize(path, options = {}) - super(options) - @paths = [FileSystemResolver.new(path, options), FileSystemResolver.new("", options), FileSystemResolver.new("/", options)] + def initialize(path) + super() + @paths = [FileSystemResolver.new(path), FileSystemResolver.new(""), FileSystemResolver.new("/")] end def find_templates(*args) diff --git a/actionpack/test/lib/fixture_template.rb b/actionpack/test/lib/fixture_template.rb index 6b9e7c5270..a7f0490984 100644 --- a/actionpack/test/lib/fixture_template.rb +++ b/actionpack/test/lib/fixture_template.rb @@ -1,7 +1,7 @@ module ActionView #:nodoc: class FixtureResolver < PathResolver - def initialize(hash = {}, options = {}) - super(options) + def initialize(hash = {}) + super() @hash = hash end -- cgit v1.2.3 From 39d6f9e112f2320d8c2006ee3bcc160cfa761d0a Mon Sep 17 00:00:00 2001 From: wycats Date: Sun, 7 Mar 2010 06:24:30 -0800 Subject: Make many parts of Rails lazy. In order to facilitate this, add lazy_load_hooks.rb, which allows us to declare code that should be run at some later time. For instance, this allows us to defer requiring ActiveRecord::Base at boot time purely to apply configuration. Instead, we register a hook that should apply configuration once ActiveRecord::Base is loaded. With these changes, brings down total boot time of a new app to 300ms in production and 400ms in dev. TODO: rename base_hook --- actionpack/lib/action_controller/base.rb | 2 ++ actionpack/lib/action_controller/railtie.rb | 14 +++++++++----- actionpack/lib/action_dispatch/middleware/params_parser.rb | 1 - .../lib/action_dispatch/middleware/session/cookie_store.rb | 1 - actionpack/lib/action_dispatch/middleware/stack.rb | 2 +- actionpack/lib/action_dispatch/routing/mapper.rb | 4 +++- actionpack/lib/action_view.rb | 2 +- actionpack/lib/action_view/base.rb | 2 ++ actionpack/lib/action_view/helpers/active_model_helper.rb | 8 +++++--- actionpack/lib/action_view/helpers/form_helper.rb | 8 +++++--- actionpack/lib/action_view/railtie.rb | 4 +++- actionpack/lib/action_view/test_case.rb | 1 + actionpack/test/abstract_unit.rb | 1 - 13 files changed, 32 insertions(+), 18 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index 78871154c3..d00afa6d4e 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -58,6 +58,8 @@ module ActionController filter end + ActionController.run_base_hooks(self) + end end diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb index e9edf80451..ca03fc62da 100644 --- a/actionpack/lib/action_controller/railtie.rb +++ b/actionpack/lib/action_controller/railtie.rb @@ -40,7 +40,7 @@ module ActionController log_subscriber ActionController::Railties::LogSubscriber.new initializer "action_controller.logger" do - ActionController::Base.logger ||= Rails.logger + ActionController.base_hook { self.logger ||= Rails.logger } end initializer "action_controller.set_configs" do |app| @@ -51,19 +51,23 @@ module ActionController ac.stylesheets_dir = paths.public.stylesheets.to_a.first ac.secret = app.config.cookie_secret - ActionController::Base.config.replace(ac) + ActionController.base_hook { self.config.replace(ac) } end initializer "action_controller.initialize_framework_caches" do - ActionController::Base.cache_store ||= RAILS_CACHE + ActionController.base_hook { self.cache_store ||= RAILS_CACHE } end initializer "action_controller.set_helpers_path" do |app| - ActionController::Base.helpers_path = app.config.paths.app.helpers.to_a + ActionController.base_hook do + self.helpers_path = app.config.paths.app.helpers.to_a + end end initializer "action_controller.url_helpers" do |app| - ActionController::Base.extend ::ActionController::Railtie::UrlHelpers.with(app.routes) + ActionController.base_hook do + extend ::ActionController::Railtie::UrlHelpers.with(app.routes) + end message = "ActionController::Routing::Routes is deprecated. " \ "Instead, use Rails.application.routes" diff --git a/actionpack/lib/action_dispatch/middleware/params_parser.rb b/actionpack/lib/action_dispatch/middleware/params_parser.rb index 522982e202..f4c4324fb0 100644 --- a/actionpack/lib/action_dispatch/middleware/params_parser.rb +++ b/actionpack/lib/action_dispatch/middleware/params_parser.rb @@ -1,4 +1,3 @@ -require 'active_support/json' require 'action_dispatch/http/request' module ActionDispatch diff --git a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb index db64711052..22da82479e 100644 --- a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb +++ b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb @@ -1,5 +1,4 @@ require 'active_support/core_ext/hash/keys' -require 'rack/request' module ActionDispatch module Session diff --git a/actionpack/lib/action_dispatch/middleware/stack.rb b/actionpack/lib/action_dispatch/middleware/stack.rb index 18a2922fa7..c52c8c0e6a 100644 --- a/actionpack/lib/action_dispatch/middleware/stack.rb +++ b/actionpack/lib/action_dispatch/middleware/stack.rb @@ -58,7 +58,7 @@ module ActionDispatch if lazy_compare?(@klass) && lazy_compare?(middleware) normalize(@klass) == normalize(middleware) else - klass == ActiveSupport::Inflector.constantize(middleware.to_s) + klass.name == middleware.to_s end end end diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 52e7b0e77d..52a8df4273 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -1,3 +1,5 @@ +require "active_support/core_ext/hash/except" + module ActionDispatch module Routing class Mapper @@ -85,7 +87,7 @@ module ActionDispatch end def requirements - @requirements ||= returning(@options[:constraints] || {}) do |requirements| + @requirements ||= (@options[:constraints] || {}).tap do |requirements| requirements.reverse_merge!(@scope[:constraints]) if @scope[:constraints] @options.each { |k, v| requirements[k] = v if v.is_a?(Regexp) } end diff --git a/actionpack/lib/action_view.rb b/actionpack/lib/action_view.rb index f5035fe45a..33bf0b8deb 100644 --- a/actionpack/lib/action_view.rb +++ b/actionpack/lib/action_view.rb @@ -41,6 +41,7 @@ module ActionView autoload :Rendering end + autoload :Base autoload :MissingTemplate, 'action_view/base' autoload :Resolver, 'action_view/template/resolver' autoload :PathResolver, 'action_view/template/resolver' @@ -56,6 +57,5 @@ module ActionView end require 'active_support/core_ext/string/output_safety' -require 'action_view/base' I18n.load_path << "#{File.dirname(__FILE__)}/action_view/locale/en.yml" diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 76f9eb2b0d..e88ccc645e 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -177,6 +177,8 @@ module ActionView #:nodoc: extend ActiveSupport::Memoizable + ActionView.run_base_hooks(self) + attr_accessor :base_path, :assigns, :template_extension attr_internal :captures diff --git a/actionpack/lib/action_view/helpers/active_model_helper.rb b/actionpack/lib/action_view/helpers/active_model_helper.rb index ed83b8a8b2..4e12cdab54 100644 --- a/actionpack/lib/action_view/helpers/active_model_helper.rb +++ b/actionpack/lib/action_view/helpers/active_model_helper.rb @@ -5,9 +5,11 @@ require 'active_support/core_ext/enumerable' require 'active_support/core_ext/kernel/reporting' module ActionView - class Base - @@field_error_proc = Proc.new{ |html_tag, instance| "
#{html_tag}
".html_safe } - cattr_accessor :field_error_proc + ActionView.base_hook do + class ActionView::Base + @@field_error_proc = Proc.new{ |html_tag, instance| "
#{html_tag}
".html_safe } + cattr_accessor :field_error_proc + end end module Helpers diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index ace3bcfde3..742e873a49 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -1211,8 +1211,10 @@ module ActionView end end - class Base - cattr_accessor :default_form_builder - @@default_form_builder = ::ActionView::Helpers::FormBuilder + ActionView.base_hook do + class ActionView::Base + cattr_accessor :default_form_builder + @@default_form_builder = ::ActionView::Helpers::FormBuilder + end end end diff --git a/actionpack/lib/action_view/railtie.rb b/actionpack/lib/action_view/railtie.rb index 03f18ac172..2e5d115630 100644 --- a/actionpack/lib/action_view/railtie.rb +++ b/actionpack/lib/action_view/railtie.rb @@ -10,7 +10,9 @@ module ActionView initializer "action_view.cache_asset_timestamps" do |app| unless app.config.cache_classes - ActionView::Helpers::AssetTagHelper.cache_asset_timestamps = false + ActionView.base_hook do + ActionView::Helpers::AssetTagHelper.cache_asset_timestamps = false + end end end end diff --git a/actionpack/lib/action_view/test_case.rb b/actionpack/lib/action_view/test_case.rb index 72dbead14b..1578ac9479 100644 --- a/actionpack/lib/action_view/test_case.rb +++ b/actionpack/lib/action_view/test_case.rb @@ -1,4 +1,5 @@ require 'action_controller/test_case' +require 'action_view' module ActionView class Base diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb index d103c4e485..67aa412d3d 100644 --- a/actionpack/test/abstract_unit.rb +++ b/actionpack/test/abstract_unit.rb @@ -16,7 +16,6 @@ require 'test/unit' require 'abstract_controller' require 'action_controller' require 'action_view' -require 'action_view/base' require 'action_dispatch' require 'fixture_template' require 'active_support/dependencies' -- cgit v1.2.3 From e00bc711d8780d9c7018dec8a794cb0772cd3ad5 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Sun, 7 Mar 2010 11:09:50 -0600 Subject: Bump rack-mount requirement to 0.6 --- actionpack/actionpack.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/actionpack.gemspec b/actionpack/actionpack.gemspec index 790efc4ec5..ed5b7e1e93 100644 --- a/actionpack/actionpack.gemspec +++ b/actionpack/actionpack.gemspec @@ -23,6 +23,6 @@ Gem::Specification.new do |s| s.add_dependency('activemodel', version) s.add_dependency('rack', '~> 1.1.0') s.add_dependency('rack-test', '~> 0.5.0') - s.add_dependency('rack-mount', '~> 0.5.1') + s.add_dependency('rack-mount', '~> 0.6.0') s.add_dependency('erubis', '~> 2.6.5') end -- cgit v1.2.3 From c7564d74e8a9b451f9fc78566ab0c734671f9612 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sun, 7 Mar 2010 19:41:58 +0100 Subject: Added template lookup responsible to hold all information used in template lookup. --- .../lib/abstract_controller/compatibility.rb | 2 +- .../lib/abstract_controller/details_cache.rb | 48 ------------- actionpack/lib/abstract_controller/layouts.rb | 37 +++------- actionpack/lib/abstract_controller/rendering.rb | 42 ++++++------ .../lib/action_controller/metal/compatibility.rb | 13 ---- .../lib/action_controller/metal/implicit_render.rb | 1 + .../lib/action_controller/metal/rendering.rb | 1 - actionpack/lib/action_view/base.rb | 78 +++++++--------------- .../lib/action_view/helpers/prototype_helper.rb | 4 +- actionpack/lib/action_view/paths.rb | 4 +- actionpack/lib/action_view/render/partials.rb | 4 +- actionpack/lib/action_view/render/rendering.rb | 8 +-- actionpack/lib/action_view/template.rb | 1 + actionpack/lib/action_view/template/lookup.rb | 48 +++++++++++++ actionpack/test/abstract/details_cache_test.rb | 57 ---------------- actionpack/test/template/javascript_helper_test.rb | 4 +- actionpack/test/template/prototype_helper_test.rb | 4 +- 17 files changed, 118 insertions(+), 238 deletions(-) delete mode 100644 actionpack/lib/abstract_controller/details_cache.rb create mode 100644 actionpack/lib/action_view/template/lookup.rb delete mode 100644 actionpack/test/abstract/details_cache_test.rb (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller/compatibility.rb b/actionpack/lib/abstract_controller/compatibility.rb index 7fb93a0eb5..85fb1364b7 100644 --- a/actionpack/lib/abstract_controller/compatibility.rb +++ b/actionpack/lib/abstract_controller/compatibility.rb @@ -11,7 +11,7 @@ module AbstractController def _default_layout(details, require_layout = false) super rescue ActionView::MissingTemplate - _find_layout(_layout({}), {}) + _layout_for_name(_layout({}), {}) nil end end diff --git a/actionpack/lib/abstract_controller/details_cache.rb b/actionpack/lib/abstract_controller/details_cache.rb deleted file mode 100644 index be1a1c0f34..0000000000 --- a/actionpack/lib/abstract_controller/details_cache.rb +++ /dev/null @@ -1,48 +0,0 @@ -module AbstractController - class HashKey - @hash_keys = Hash.new {|h,k| h[k] = {} } - - def self.get(klass, details) - @hash_keys[klass][details] ||= new(klass, details) - end - - attr_reader :hash - alias_method :eql?, :equal? - - def initialize(klass, details) - @details, @hash = details, details.hash - end - - def inspect - "#" - end - end - - module DetailsCache - extend ActiveSupport::Concern - - module ClassMethods - def clear_template_caches! - ActionView::Partials::PartialRenderer::TEMPLATES.clear - template_cache.clear - super - end - - def template_cache - @template_cache ||= Hash.new {|h,k| h[k] = {} } - end - end - - def render_to_body(*args) - Thread.current[:format_locale_key] = HashKey.get(self.class, details_for_render) - super - end - - private - - def with_template_cache(name, details) - self.class.template_cache[HashKey.get(self.class, details)][name] ||= super - end - - end -end diff --git a/actionpack/lib/abstract_controller/layouts.rb b/actionpack/lib/abstract_controller/layouts.rb index beda4e633e..c26593dd19 100644 --- a/actionpack/lib/abstract_controller/layouts.rb +++ b/actionpack/lib/abstract_controller/layouts.rb @@ -170,27 +170,7 @@ module AbstractController module ClassMethods def inherited(klass) super - klass.class_eval do - _write_layout_method - @found_layouts = {} - end - end - - def clear_template_caches! - @found_layouts.clear if defined? @found_layouts - super - end - - def cache_layout(details) - layout = @found_layouts - key = Thread.current[:format_locale_key] - - # Cache nil - if layout.key?(key) - return layout[key] - else - layout[key] = yield - end + klass._write_layout_method end # This module is mixed in if layout conditions are provided. This means @@ -282,12 +262,10 @@ module AbstractController if name self.class_eval <<-RUBY, __FILE__, __LINE__ + 1 def _layout(details) - self.class.cache_layout(details) do - if template_exists?("#{_implied_layout_name}", details, :_prefix => "layouts") - "#{_implied_layout_name}" - else - super - end + if template_exists?("#{_implied_layout_name}", :_prefix => "layouts") + "#{_implied_layout_name}" + else + super end end RUBY @@ -372,9 +350,10 @@ module AbstractController # ==== Returns # Template:: A template object matching the name and details def _find_layout(name, details) - # TODO: Make prefix actually part of details in ViewPath#find_by_parts prefix = details.key?(:prefix) ? details.delete(:prefix) : "layouts" - find_template(name, details, :_prefix => prefix) + # TODO This should happen automatically + template_lookup.details = template_lookup.details.merge(:formats => details[:formats]) + find_template(name, :_prefix => prefix) end # Returns the default layout for this controller and a given set of details. diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb index 2ea4f02871..df33e8b480 100644 --- a/actionpack/lib/abstract_controller/rendering.rb +++ b/actionpack/lib/abstract_controller/rendering.rb @@ -90,10 +90,22 @@ module AbstractController view_context.render_partial(options) end + def template_lookup + @template_lookup ||= ActionView::Template::Lookup.new(_view_paths, details_for_render) + end + # The list of view paths for this controller. See ActionView::ViewPathSet for # more details about writing custom view paths. def view_paths - _view_paths + template_lookup.view_paths + end + + def append_view_path(path) + template_lookup.view_paths.push(*path) + end + + def prepend_view_path(path) + template_lookup.view_paths.unshift(*path) end # The prefix used in render "foo" shortcuts. @@ -162,10 +174,9 @@ module AbstractController options[:_prefix] ||= _prefix if (options.keys & [:partial, :file, :template]).empty? details = _normalize_details(options) + template_lookup.details = details - options[:_template] ||= with_template_cache(name, details) do - find_template(name, details, options) - end + options[:_template] ||= find_template(name, options) end def details_for_render @@ -179,16 +190,12 @@ module AbstractController details end - def find_template(name, details, options) - view_paths.find(name, details, options[:_prefix], options[:_partial]) - end - - def template_exists?(name, details, options) - view_paths.exists?(name, details, options[:_prefix], options[:_partial]) + def find_template(name, options) + template_lookup.find(name, options[:_prefix], options[:_partial]) end - def with_template_cache(name, details) - yield + def template_exists?(name, options) + template_lookup.exists?(name, options[:_prefix], options[:_partial]) end def format_for_text @@ -196,9 +203,6 @@ module AbstractController end module ClassMethods - def clear_template_caches! - end - # Append a path to the list of view paths for this controller. # # ==== Parameters @@ -206,7 +210,7 @@ module AbstractController # the default view path. You may also provide a custom view path # (see ActionView::ViewPathSet for more information) def append_view_path(path) - self.view_paths = view_paths.dup + Array.wrap(path) + self.view_paths = view_paths.dup + Array(path) end # Prepend a path to the list of view paths for this controller. @@ -216,8 +220,7 @@ module AbstractController # the default view path. You may also provide a custom view path # (see ActionView::ViewPathSet for more information) def prepend_view_path(path) - clear_template_caches! - self.view_paths = Array.wrap(path) + view_paths.dup + self.view_paths = Array(path) + view_paths.dup end # A list of all of the default view paths for this controller. @@ -231,9 +234,8 @@ module AbstractController # paths:: If a ViewPathSet is provided, use that; # otherwise, process the parameter into a ViewPathSet. def view_paths=(paths) - clear_template_caches! self._view_paths = paths.is_a?(ActionView::PathSet) ? paths : ActionView::Base.process_view_paths(paths) - _view_paths.freeze + self._view_paths.freeze end end end diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb index 317a9fd951..518272b4cf 100644 --- a/actionpack/lib/action_controller/metal/compatibility.rb +++ b/actionpack/lib/action_controller/metal/compatibility.rb @@ -73,18 +73,5 @@ module ActionController def performed? response_body end - - # ==== Request only view path switching ==== - def append_view_path(path) - view_paths.push(*path) - end - - def prepend_view_path(path) - view_paths.unshift(*path) - end - - def view_paths - view_context.view_paths - end end end diff --git a/actionpack/lib/action_controller/metal/implicit_render.rb b/actionpack/lib/action_controller/metal/implicit_render.rb index ba2d9b686e..da717fcce2 100644 --- a/actionpack/lib/action_controller/metal/implicit_render.rb +++ b/actionpack/lib/action_controller/metal/implicit_render.rb @@ -12,6 +12,7 @@ module ActionController def method_for_action(action_name) super || begin + # TODO This should use template lookup if view_paths.exists?(action_name.to_s, details_for_render, controller_path) "default_render" end diff --git a/actionpack/lib/action_controller/metal/rendering.rb b/actionpack/lib/action_controller/metal/rendering.rb index 00a09309bf..0a4215028b 100644 --- a/actionpack/lib/action_controller/metal/rendering.rb +++ b/actionpack/lib/action_controller/metal/rendering.rb @@ -4,7 +4,6 @@ module ActionController include ActionController::RackDelegation include AbstractController::Rendering - include AbstractController::DetailsCache def process_action(*) self.formats = request.formats.map {|x| x.to_sym } diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 76f9eb2b0d..22bc390dc5 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -180,64 +180,21 @@ module ActionView #:nodoc: attr_accessor :base_path, :assigns, :template_extension attr_internal :captures - def reset_formats(formats) - old_formats, self.formats = self.formats, formats - reset_hash_key - yield if block_given? - ensure - if block_given? - self.formats = old_formats - reset_hash_key - end - end - - def reset_hash_key - if defined?(AbstractController::HashKey) - # This is expensive, but we need to reset this when the format is updated, - # which currently only happens - Thread.current[:format_locale_key] = - AbstractController::HashKey.get(self.class, :formats => formats, :locale => [I18n.locale]) - end - end - - def formats - controller ? controller.formats : @formats - end - - def formats=(val) - if controller - controller.formats = val - else - @formats = val - end - end - class << self delegate :erb_trim_mode=, :to => 'ActionView::Template::Handlers::ERB' delegate :logger, :to => 'ActionController::Base', :allow_nil => true end - @@debug_rjs = false - ## - # :singleton-method: # Specify whether RJS responses should be wrapped in a try/catch block # that alert()s the caught exception (and then re-raises it). cattr_accessor :debug_rjs - - # Specify whether templates should be cached. Otherwise the file we be read everytime it is accessed. - # Automatically reloading templates are not thread safe and should only be used in development mode. - @@cache_template_loading = nil - cattr_accessor :cache_template_loading + @@debug_rjs = false # :nodoc: def self.xss_safe? true end - def self.cache_template_loading? - ActionController::Base.allow_concurrency || (cache_template_loading.nil? ? !ActiveSupport::Dependencies.load? : cache_template_loading) - end - attr_internal :request, :layout def controller_path @@ -249,8 +206,6 @@ module ActionView #:nodoc: delegate :logger, :to => :controller, :allow_nil => true - delegate :find, :to => :view_paths - include Context def self.process_view_paths(value) @@ -287,10 +242,10 @@ module ActionView #:nodoc: klass = self end - klass.new(controller.class.view_paths, {}, controller) + klass.new(controller.template_lookup, {}, controller) end - def initialize(view_paths = [], assigns_for_first_render = {}, controller = nil, formats = nil)#:nodoc: + def initialize(template_lookup = nil, assigns_for_first_render = {}, controller = nil, formats = nil) #:nodoc: @config = nil @formats = formats @assigns = assigns_for_first_render.each { |key, value| instance_variable_set("@#{key}", value) } @@ -298,16 +253,33 @@ module ActionView #:nodoc: @_controller = controller @_config = ActiveSupport::InheritableOptions.new(controller.config) if controller - @_content_for = Hash.new {|h,k| h[k] = ActiveSupport::SafeBuffer.new } + @_content_for = Hash.new { |h,k| h[k] = ActiveSupport::SafeBuffer.new } @_virtual_path = nil - self.view_paths = view_paths + + @template_lookup = template_lookup.is_a?(ActionView::Template::Lookup) ? + template_lookup : ActionView::Template::Lookup.new(template_lookup) end attr_internal :controller, :template, :config - attr_reader :view_paths - def view_paths=(paths) - @view_paths = self.class.process_view_paths(paths) + attr_reader :template_lookup + delegate :find, :view_paths, :view_paths=, :to => :template_lookup + + def formats=(formats) + update_details(:formats => Array(formats)) + end + + def update_details(details) + old_details = template_lookup.details + template_lookup.details = old_details.merge(details) + + if block_given? + begin + yield + ensure + template_lookup.details = old_details + end + end end def punctuate_body!(part) diff --git a/actionpack/lib/action_view/helpers/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb index 67a7586699..be49b5cc28 100644 --- a/actionpack/lib/action_view/helpers/prototype_helper.rb +++ b/actionpack/lib/action_view/helpers/prototype_helper.rb @@ -182,7 +182,7 @@ module ActionView def initialize(context, &block) #:nodoc: context._evaluate_assigns_and_ivars @context, @lines = context, [] - @context.reset_formats([:js, :html]) do + @context.update_details(:formats => [:js, :html]) do include_helpers_from_context @context.with_output_buffer(@lines) do @context.instance_exec(self, &block) @@ -583,7 +583,7 @@ module ActionView end def with_formats(*args) - @context ? @context.reset_formats(args) { yield } : yield + @context ? @context.update_details(:formats => args) { yield } : yield end def javascript_object_for(object) diff --git a/actionpack/lib/action_view/paths.rb b/actionpack/lib/action_view/paths.rb index 459b6bba54..154a79a8f1 100644 --- a/actionpack/lib/action_view/paths.rb +++ b/actionpack/lib/action_view/paths.rb @@ -9,7 +9,7 @@ module ActionView #:nodoc: METHOD end - def find(path, details = {}, prefix = nil, partial = false) + def find(path, details = {}, prefix = nil, partial = false, key=nil) each do |resolver| if template = resolver.find(path, details, prefix, partial) return template @@ -19,7 +19,7 @@ module ActionView #:nodoc: raise ActionView::MissingTemplate.new(self, "#{prefix}/#{path}", details, partial) end - def exists?(path, details = {}, prefix = nil, partial = false) + def exists?(path, details = {}, prefix = nil, partial = false, key=nil) each do |resolver| if resolver.find(path, details, prefix, partial) return true diff --git a/actionpack/lib/action_view/render/partials.rb b/actionpack/lib/action_view/render/partials.rb index 8b6dce0c1c..74513935a7 100644 --- a/actionpack/lib/action_view/render/partials.rb +++ b/actionpack/lib/action_view/render/partials.rb @@ -309,7 +309,7 @@ module ActionView prefix = controller.controller_path unless path.include?(?/) end - @view.find(path, {:formats => @view.formats}, prefix, true) + @view.find(path, prefix, true) end def partial_path(object = @object) @@ -329,7 +329,7 @@ module ActionView details = options[:_details] - # Is this needed + # TODO This should happen automatically as well self.formats = details[:formats] if details renderer = PartialRenderer.new(self, options, nil) text = renderer.render diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb index 28b79bfcb7..1be5675e37 100644 --- a/actionpack/lib/action_view/render/rendering.rb +++ b/actionpack/lib/action_view/render/rendering.rb @@ -25,7 +25,7 @@ module ActionView end template = if options[:file] - find(options[:file], details_for_render) + find(options[:file]) elsif options[:inline] handler = Template.handler_class_for_extension(options[:type] || "erb") Template.new(options[:inline], "inline template", handler, {}) @@ -34,7 +34,7 @@ module ActionView end if template - layout = find(layout, details_for_render) if layout + layout = find(layout) if layout _render_template(template, layout, :locals => options[:locals]) end when :update @@ -44,10 +44,6 @@ module ActionView end end - def details_for_render - controller.try(:details_for_render) || {:formats => formats} - end - # You can think of a layout as a method that is called with a block. _layout_for # returns the contents that are yielded to the layout. If the user calls yield # :some_name, the block, by default, returns content_for(:some_name). If the user diff --git a/actionpack/lib/action_view/template.rb b/actionpack/lib/action_view/template.rb index cd6b1930a1..c176359253 100644 --- a/actionpack/lib/action_view/template.rb +++ b/actionpack/lib/action_view/template.rb @@ -13,6 +13,7 @@ module ActionView autoload :Handler autoload :Handlers autoload :Text + autoload :Lookup end extend Template::Handlers diff --git a/actionpack/lib/action_view/template/lookup.rb b/actionpack/lib/action_view/template/lookup.rb new file mode 100644 index 0000000000..ea3a12615b --- /dev/null +++ b/actionpack/lib/action_view/template/lookup.rb @@ -0,0 +1,48 @@ +module ActionView + class Template + class Lookup + attr_reader :details, :view_paths + + class DetailsKey + attr_reader :details + alias :eql? :equal? + + @details_keys = Hash.new + + def self.get(details) + @details_keys[details] ||= new(details) + end + + def initialize(details) + @details, @hash = details, details.hash + end + end + + def initialize(view_paths, details = {}) + @details = details + self.view_paths = view_paths + end + + def view_paths=(paths) + @view_paths = ActionView::Base.process_view_paths(paths) + end + + def details=(details) + @details = details + @details_key = nil if @details_key && @details_key.details != details + end + + def details_key + @details_key ||= DetailsKey.get(details) unless details.empty? + end + + def find(name, prefix = nil, partial = false) + @view_paths.find(name, details, prefix, partial || false, details_key) + end + + def exists?(name, prefix = nil, partial = false) + @view_paths.exists?(name, details, prefix, partial || false, details_key) + end + end + end +end \ No newline at end of file diff --git a/actionpack/test/abstract/details_cache_test.rb b/actionpack/test/abstract/details_cache_test.rb deleted file mode 100644 index ee746c1bb0..0000000000 --- a/actionpack/test/abstract/details_cache_test.rb +++ /dev/null @@ -1,57 +0,0 @@ -require 'abstract_unit' - -module AbstractController - module Testing - - class CachedController < AbstractController::Base - include AbstractController::Rendering - include AbstractController::DetailsCache - - self.view_paths = [ActionView::FixtureResolver.new( - "default.erb" => "With Default", - "template.erb" => "With Template", - "some/file.erb" => "With File", - "template_name.erb" => "With Template Name" - )] - end - - class TestLocalizedCache < ActiveSupport::TestCase - - def setup - @controller = CachedController.new - CachedController.clear_template_caches! - end - - def test_templates_are_cached - @controller.render :template => "default.erb" - assert_equal "With Default", @controller.response_body - - cached = @controller.class.template_cache - assert_equal 1, cached.size - assert_kind_of ActionView::Template, cached.values.first["default.erb"] - end - - def test_cache_is_used - CachedController.new.render :template => "default.erb" - - @controller.expects(:find_template).never - @controller.render :template => "default.erb" - - assert_equal 1, @controller.class.template_cache.size - end - - def test_cache_changes_with_locale - CachedController.new.render :template => "default.erb" - - I18n.locale = :es - @controller.render :template => "default.erb" - - assert_equal 2, @controller.class.template_cache.size - ensure - I18n.locale = :en - end - - end - - end -end diff --git a/actionpack/test/template/javascript_helper_test.rb b/actionpack/test/template/javascript_helper_test.rb index 368a9c2514..6604f1c095 100644 --- a/actionpack/test/template/javascript_helper_test.rb +++ b/actionpack/test/template/javascript_helper_test.rb @@ -7,8 +7,8 @@ class JavaScriptHelperTest < ActionView::TestCase attr_accessor :formats, :output_buffer - def reset_formats(format) - @format = format + def update_details(details) + @details = details yield if block_given? end diff --git a/actionpack/test/template/prototype_helper_test.rb b/actionpack/test/template/prototype_helper_test.rb index 6811d3aaf3..619293dc43 100644 --- a/actionpack/test/template/prototype_helper_test.rb +++ b/actionpack/test/template/prototype_helper_test.rb @@ -39,8 +39,8 @@ class Author::Nested < Author; end class PrototypeHelperBaseTest < ActionView::TestCase attr_accessor :formats, :output_buffer - def reset_formats(format) - @format = format + def update_details(details) + @details = details yield if block_given? end -- cgit v1.2.3 From dfc7ff64298e1a0656639a630cc0ddbf93c1eeb9 Mon Sep 17 00:00:00 2001 From: Jan De Poorter Date: Fri, 12 Feb 2010 11:39:19 +0100 Subject: Make sure nested singular resources get the correct name [#3911 state:committed] Signed-off-by: Jeremy Kemper --- actionpack/lib/action_dispatch/routing/mapper.rb | 5 ++++- actionpack/test/dispatch/routing_test.rb | 10 ++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 52a8df4273..7a33259054 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -452,7 +452,10 @@ module ActionDispatch scope(:path => resource.name.to_s, :controller => resource.controller) do with_scope_level(:resource, resource) do - yield if block_given? + + scope(:name_prefix => resource.name.to_s) do + yield if block_given? + end get :show if resource.actions.include?(:show) post :create if resource.actions.include?(:create) diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb index 37c2f1421b..b46276c453 100644 --- a/actionpack/test/dispatch/routing_test.rb +++ b/actionpack/test/dispatch/routing_test.rb @@ -24,6 +24,8 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest resource :session do get :create + + resource :info end match 'account/logout' => redirect("/logout"), :as => :logout_redirect @@ -234,6 +236,14 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest end end + def test_session_info_nested_singleton_resource + with_test_routes do + get '/session/info' + assert_equal 'infos#show', @response.body + assert_equal '/session/info', session_info_path + end + end + def test_redirect_modulo with_test_routes do get '/account/modulo/name' -- cgit v1.2.3 From ffd8d753f171a33cb0f8dadaff7fc5ba12b8f6b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Mon, 8 Mar 2010 02:04:18 +0100 Subject: Move layout lookup to views. --- actionpack/lib/abstract_controller/base.rb | 6 ------ .../lib/abstract_controller/compatibility.rb | 18 ---------------- actionpack/lib/abstract_controller/layouts.rb | 25 ++++++---------------- actionpack/lib/abstract_controller/rendering.rb | 8 ++++--- .../lib/action_controller/metal/implicit_render.rb | 3 +-- .../lib/action_controller/metal/rendering.rb | 2 +- actionpack/lib/action_view/base.rb | 6 +----- actionpack/lib/action_view/render/partials.rb | 2 +- actionpack/lib/action_view/render/rendering.rb | 16 +++++++++++++- actionpack/lib/action_view/template/lookup.rb | 8 +++++++ actionpack/test/abstract/layouts_test.rb | 2 +- 11 files changed, 39 insertions(+), 57 deletions(-) delete mode 100644 actionpack/lib/abstract_controller/compatibility.rb (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller/base.rb b/actionpack/lib/abstract_controller/base.rb index ea88a2d24d..c12b584144 100644 --- a/actionpack/lib/abstract_controller/base.rb +++ b/actionpack/lib/abstract_controller/base.rb @@ -7,7 +7,6 @@ module AbstractController class Base attr_internal :response_body attr_internal :action_name - attr_internal :formats class << self attr_reader :abstract @@ -100,11 +99,6 @@ module AbstractController abstract! - # Initialize controller with nil formats. - def initialize #:nodoc: - @_formats = nil - end - def config @config ||= ActiveSupport::InheritableOptions.new(self.class.config) end diff --git a/actionpack/lib/abstract_controller/compatibility.rb b/actionpack/lib/abstract_controller/compatibility.rb deleted file mode 100644 index 85fb1364b7..0000000000 --- a/actionpack/lib/abstract_controller/compatibility.rb +++ /dev/null @@ -1,18 +0,0 @@ -module AbstractController - module Compatibility - extend ActiveSupport::Concern - - def _find_layout(name, details) - details[:prefix] = nil if name =~ /\blayouts/ - super - end - - # Move this into a "don't run in production" module - def _default_layout(details, require_layout = false) - super - rescue ActionView::MissingTemplate - _layout_for_name(_layout({}), {}) - nil - end - end -end diff --git a/actionpack/lib/abstract_controller/layouts.rb b/actionpack/lib/abstract_controller/layouts.rb index c26593dd19..ac0f646e19 100644 --- a/actionpack/lib/abstract_controller/layouts.rb +++ b/actionpack/lib/abstract_controller/layouts.rb @@ -260,9 +260,11 @@ module AbstractController raise ArgumentError, "Layouts must be specified as a String, Symbol, false, or nil" when nil if name + _prefix = "layouts" unless _implied_layout_name =~ /\blayouts/ + self.class_eval <<-RUBY, __FILE__, __LINE__ + 1 def _layout(details) - if template_exists?("#{_implied_layout_name}", :_prefix => "layouts") + if template_exists?("#{_implied_layout_name}", :_prefix => #{_prefix.inspect}) "#{_implied_layout_name}" else super @@ -290,6 +292,7 @@ module AbstractController # render_template if layout layout = _layout_for_option(layout, options[:_template].details) + layout = find_template(layout, {}) response = layout.render(view_context, options[:locals] || {}) { response } end @@ -309,7 +312,7 @@ module AbstractController # the lookup to. By default, layout lookup is limited to the # formats specified for the current request. def _layout_for_name(name, details) - name && _find_layout(name, details) + name end # Determine the layout for a given name and details, taking into account @@ -337,23 +340,7 @@ module AbstractController return unless (options.keys & [:text, :inline, :partial]).empty? || options.key?(:layout) layout = options.key?(:layout) ? options[:layout] : :default - options[:_layout] = _layout_for_option(layout, options[:_template].details) - end - - # Take in the name and details and find a Template. - # - # ==== Parameters - # name:: The name of the template to retrieve - # details:: A list of details to restrict the search by. This - # might include details like the format or locale of the template. - # - # ==== Returns - # Template:: A template object matching the name and details - def _find_layout(name, details) - prefix = details.key?(:prefix) ? details.delete(:prefix) : "layouts" - # TODO This should happen automatically - template_lookup.details = template_lookup.details.merge(:formats => details[:formats]) - find_template(name, :_prefix => prefix) + options[:layout] = _layout_for_option(layout, options[:_template].details) end # Returns the default layout for this controller and a given set of details. diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb index df33e8b480..8125badc75 100644 --- a/actionpack/lib/abstract_controller/rendering.rb +++ b/actionpack/lib/abstract_controller/rendering.rb @@ -15,10 +15,12 @@ module AbstractController included do class_attribute :_view_paths - delegate :_view_paths, :to => :'self.class' self._view_paths = ActionView::PathSet.new end + delegate :formats, :formats=, :to => :template_lookup + delegate :_view_paths, :to => :'self.class' + # An instance of a view class. The default view class is ActionView::Base # # The view class must have the following methods: @@ -180,11 +182,11 @@ module AbstractController end def details_for_render - { :formats => formats, :locale => [I18n.locale] } + { } end def _normalize_details(options) - details = details_for_render + details = template_lookup.details details[:formats] = Array(options[:format]) if options[:format] details[:locale] = Array(options[:locale]) if options[:locale] details diff --git a/actionpack/lib/action_controller/metal/implicit_render.rb b/actionpack/lib/action_controller/metal/implicit_render.rb index da717fcce2..c3e3b8fdf5 100644 --- a/actionpack/lib/action_controller/metal/implicit_render.rb +++ b/actionpack/lib/action_controller/metal/implicit_render.rb @@ -12,8 +12,7 @@ module ActionController def method_for_action(action_name) super || begin - # TODO This should use template lookup - if view_paths.exists?(action_name.to_s, details_for_render, controller_path) + if template_exists?(action_name.to_s, :_prefix => controller_path) "default_render" end end diff --git a/actionpack/lib/action_controller/metal/rendering.rb b/actionpack/lib/action_controller/metal/rendering.rb index 0a4215028b..e2d2e2312b 100644 --- a/actionpack/lib/action_controller/metal/rendering.rb +++ b/actionpack/lib/action_controller/metal/rendering.rb @@ -5,7 +5,7 @@ module ActionController include ActionController::RackDelegation include AbstractController::Rendering - def process_action(*) + def process(*) self.formats = request.formats.map {|x| x.to_sym } super end diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 22bc390dc5..5acd2a8b82 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -263,11 +263,7 @@ module ActionView #:nodoc: attr_internal :controller, :template, :config attr_reader :template_lookup - delegate :find, :view_paths, :view_paths=, :to => :template_lookup - - def formats=(formats) - update_details(:formats => Array(formats)) - end + delegate :find, :formats, :formats=, :view_paths, :view_paths=, :to => :template_lookup def update_details(details) old_details = template_lookup.details diff --git a/actionpack/lib/action_view/render/partials.rb b/actionpack/lib/action_view/render/partials.rb index 74513935a7..52cb188508 100644 --- a/actionpack/lib/action_view/render/partials.rb +++ b/actionpack/lib/action_view/render/partials.rb @@ -330,7 +330,7 @@ module ActionView details = options[:_details] # TODO This should happen automatically as well - self.formats = details[:formats] if details + self.formats = details[:formats] if details[:formats] renderer = PartialRenderer.new(self, options, nil) text = renderer.render options[:_template] = renderer.template diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb index 1be5675e37..b92a03ddbd 100644 --- a/actionpack/lib/action_view/render/rendering.rb +++ b/actionpack/lib/action_view/render/rendering.rb @@ -88,12 +88,26 @@ module ActionView # _layout:: The layout, if any, to wrap the Template in def render_template(options) _evaluate_assigns_and_ivars - template, layout = options.values_at(:_template, :_layout) + template, layout = options.values_at(:_template, :layout) _render_template(template, layout, options) end + def _find_layout(template, layout) + begin + prefix = "layouts" unless layout =~ /\blayouts/ + layout = find(layout, prefix) + rescue ActionView::MissingTemplate => e + update_details(:formats => nil) do + raise unless template_lookup.exists?(layout, prefix) + end + end + end + def _render_template(template, layout = nil, options = {}) + self.formats = template.details[:formats] + locals = options[:locals] || {} + layout = _find_layout(template, layout) if layout.is_a?(String) ActiveSupport::Notifications.instrument("action_view.render_template", :identifier => template.identifier, :layout => layout.try(:identifier)) do diff --git a/actionpack/lib/action_view/template/lookup.rb b/actionpack/lib/action_view/template/lookup.rb index ea3a12615b..30de093934 100644 --- a/actionpack/lib/action_view/template/lookup.rb +++ b/actionpack/lib/action_view/template/lookup.rb @@ -23,6 +23,14 @@ module ActionView self.view_paths = view_paths end + def formats + @details[:formats] + end + + def formats=(value) + self.details = @details.merge(:formats => Array(value)) + end + def view_paths=(paths) @view_paths = ActionView::Base.process_view_paths(paths) end diff --git a/actionpack/test/abstract/layouts_test.rb b/actionpack/test/abstract/layouts_test.rb index b6d89ea489..fcc91d03f1 100644 --- a/actionpack/test/abstract/layouts_test.rb +++ b/actionpack/test/abstract/layouts_test.rb @@ -11,7 +11,7 @@ module AbstractControllerTests self.view_paths = [ActionView::FixtureResolver.new( "layouts/hello.erb" => "With String <%= yield %>", "layouts/hello_override.erb" => "With Override <%= yield %>", - "layouts/abstract_controller_tests/layouts/with_string_implied_child.erb" => + "abstract_controller_tests/layouts/with_string_implied_child.erb" => "With Implied <%= yield %>", "layouts/overwrite.erb" => "Overwrite <%= yield %>", "layouts/with_false_layout.erb" => "False Layout <%= yield %>" -- cgit v1.2.3 From 4bae77a89baf0fee15c6b2cfd3987f7344b56a1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Mon, 8 Mar 2010 02:58:16 +0100 Subject: More cleanup on the layouts side. --- actionpack/lib/abstract_controller.rb | 2 - actionpack/lib/abstract_controller/layouts.rb | 81 ++++++++-------------- .../lib/action_controller/metal/compatibility.rb | 2 - actionpack/lib/action_view/render/partials.rb | 13 +--- actionpack/lib/action_view/render/rendering.rb | 10 ++- 5 files changed, 34 insertions(+), 74 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller.rb b/actionpack/lib/abstract_controller.rb index c1b035306b..05348d8ba0 100644 --- a/actionpack/lib/abstract_controller.rb +++ b/actionpack/lib/abstract_controller.rb @@ -14,8 +14,6 @@ module AbstractController autoload :Base autoload :Callbacks autoload :Collector - autoload :Compatibility - autoload :DetailsCache autoload :Helpers autoload :Layouts autoload :Logger diff --git a/actionpack/lib/abstract_controller/layouts.rb b/actionpack/lib/abstract_controller/layouts.rb index ac0f646e19..c6a94c5220 100644 --- a/actionpack/lib/abstract_controller/layouts.rb +++ b/actionpack/lib/abstract_controller/layouts.rb @@ -239,10 +239,10 @@ module AbstractController def _write_layout_method case defined?(@_layout) ? @_layout : nil when String - self.class_eval %{def _layout(details) #{@_layout.inspect} end} + self.class_eval %{def _layout; #{@_layout.inspect} end} when Symbol self.class_eval <<-ruby_eval, __FILE__, __LINE__ + 1 - def _layout(details) + def _layout #{@_layout}.tap do |layout| unless layout.is_a?(String) || !layout raise ArgumentError, "Your layout method :#{@_layout} returned \#{layout}. It " \ @@ -253,9 +253,9 @@ module AbstractController ruby_eval when Proc define_method :_layout_from_proc, &@_layout - self.class_eval %{def _layout(details) _layout_from_proc(self) end} + self.class_eval %{def _layout; _layout_from_proc(self) end} when false - self.class_eval %{def _layout(details) end} + self.class_eval %{def _layout; end} when true raise ArgumentError, "Layouts must be specified as a String, Symbol, false, or nil" when nil @@ -263,7 +263,7 @@ module AbstractController _prefix = "layouts" unless _implied_layout_name =~ /\blayouts/ self.class_eval <<-RUBY, __FILE__, __LINE__ + 1 - def _layout(details) + def _layout if template_exists?("#{_implied_layout_name}", :_prefix => #{_prefix.inspect}) "#{_implied_layout_name}" else @@ -277,43 +277,24 @@ module AbstractController end end - def render_to_body(options = {}) - # In the case of a partial with a layout, handle the layout - # here, and make sure the view does not try to handle it - layout = options.delete(:layout) if options.key?(:partial) + def render_to_body(options={}) + if (options.keys & [:text, :inline, :partial]).empty? || options.key?(:layout) + layout = options.key?(:layout) ? options[:layout] : :default + value = _layout_for_option(layout) - response = super + # TODO Revisit this. Maybe we should pass a :layout_prefix? + options[:layout] = ((!value || value =~ /\blayouts/) ? value : "layouts/#{value}") - # This is a little bit messy. We need to explicitly handle partial - # layouts here since the core lookup logic is in the view, but - # we need to determine the layout based on the controller - # - # TODO: An easier way to handle this would probably be to override - # render_template - if layout - layout = _layout_for_option(layout, options[:_template].details) - layout = find_template(layout, {}) - response = layout.render(view_context, options[:locals] || {}) { response } + # TODO Revisit this. :layout with :partial from controllers are not the same as in views + options[:layout] = view_context._find_layout(options[:layout]) if options.key?(:partial) end - - response + super end private # This will be overwritten by _write_layout_method - def _layout(details) end - - # Determine the layout for a given name and details. - # - # ==== Parameters - # name:: The name of the template - # details Object}>:: A list of details to restrict - # the lookup to. By default, layout lookup is limited to the - # formats specified for the current request. - def _layout_for_name(name, details) - name - end + def _layout; end # Determine the layout for a given name and details, taking into account # the name type. @@ -323,11 +304,11 @@ module AbstractController # details Object}>:: A list of details to restrict # the lookup to. By default, layout lookup is limited to the # formats specified for the current request. - def _layout_for_option(name, details) + def _layout_for_option(name) case name - when String then _layout_for_name(name, details) - when true then _default_layout(details, true) - when :default then _default_layout(details, false) + when String then name + when true then _default_layout(true) + when :default then _default_layout(false) when false, nil then nil else raise ArgumentError, @@ -335,14 +316,6 @@ module AbstractController end end - def _determine_template(options) - super - - return unless (options.keys & [:text, :inline, :partial]).empty? || options.key?(:layout) - layout = options.key?(:layout) ? options[:layout] : :default - options[:layout] = _layout_for_option(layout, options[:_template].details) - end - # Returns the default layout for this controller and a given set of details. # Optionally raises an exception if the layout could not be found. # @@ -355,18 +328,20 @@ module AbstractController # # ==== Returns # Template:: The template object for the default layout (or nil) - def _default_layout(details, require_layout = false) - if require_layout && _action_has_layout? && !_layout(details) - raise ArgumentError, - "There was no default layout for #{self.class} in #{view_paths.inspect}" - end - + def _default_layout(require_layout = false) begin - _layout_for_name(_layout(details), details) if _action_has_layout? + layout_name = _layout if _action_has_layout? rescue NameError => e raise NoMethodError, "You specified #{@_layout.inspect} as the layout, but no such method was found" end + + if require_layout && _action_has_layout? && !layout_name + raise ArgumentError, + "There was no default layout for #{self.class} in #{view_paths.inspect}" + end + + layout_name end def _action_has_layout? diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb index 518272b4cf..0cb20b2f0f 100644 --- a/actionpack/lib/action_controller/metal/compatibility.rb +++ b/actionpack/lib/action_controller/metal/compatibility.rb @@ -2,8 +2,6 @@ module ActionController module Compatibility extend ActiveSupport::Concern - include AbstractController::Compatibility - class ::ActionController::ActionControllerError < StandardError #:nodoc: end diff --git a/actionpack/lib/action_view/render/partials.rb b/actionpack/lib/action_view/render/partials.rb index 52cb188508..eecc88a1e0 100644 --- a/actionpack/lib/action_view/render/partials.rb +++ b/actionpack/lib/action_view/render/partials.rb @@ -182,9 +182,6 @@ module ActionView @view = view_context @partial_names = PARTIAL_NAMES[@view.controller.class] - key = Thread.current[:format_locale_key] - @templates = TEMPLATES[key] if key - setup(options, block) end @@ -296,15 +293,9 @@ module ActionView end end - def find_template(path = @path) - unless @templates - path && _find_template(path) - else - path && @templates[path] ||= _find_template(path) - end - end + def find_template(path=@path) + return path unless path.is_a?(String) - def _find_template(path) if controller = @view.controller prefix = controller.controller_path unless path.include?(?/) end diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb index b92a03ddbd..17fb110eb4 100644 --- a/actionpack/lib/action_view/render/rendering.rb +++ b/actionpack/lib/action_view/render/rendering.rb @@ -34,7 +34,6 @@ module ActionView end if template - layout = find(layout) if layout _render_template(template, layout, :locals => options[:locals]) end when :update @@ -92,13 +91,12 @@ module ActionView _render_template(template, layout, options) end - def _find_layout(template, layout) + def _find_layout(layout) begin - prefix = "layouts" unless layout =~ /\blayouts/ - layout = find(layout, prefix) + find(layout) rescue ActionView::MissingTemplate => e update_details(:formats => nil) do - raise unless template_lookup.exists?(layout, prefix) + raise unless template_lookup.exists?(layout) end end end @@ -107,7 +105,7 @@ module ActionView self.formats = template.details[:formats] locals = options[:locals] || {} - layout = _find_layout(template, layout) if layout.is_a?(String) + layout = _find_layout(layout) if layout ActiveSupport::Notifications.instrument("action_view.render_template", :identifier => template.identifier, :layout => layout.try(:identifier)) do -- cgit v1.2.3 From 34b2180451f842b180dd925bab10e8f4afa34490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Mon, 8 Mar 2010 03:23:16 +0100 Subject: More refactoring. Split _normalize_args and _normalize_options concerns. --- actionpack/lib/abstract_controller/layouts.rb | 8 ++++++-- actionpack/lib/abstract_controller/rendering.rb | 12 ++++++++---- actionpack/lib/action_controller/metal/rendering.rb | 19 +++++++++++++------ 3 files changed, 27 insertions(+), 12 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller/layouts.rb b/actionpack/lib/abstract_controller/layouts.rb index c6a94c5220..648a2da795 100644 --- a/actionpack/lib/abstract_controller/layouts.rb +++ b/actionpack/lib/abstract_controller/layouts.rb @@ -277,8 +277,8 @@ module AbstractController end end - def render_to_body(options={}) - if (options.keys & [:text, :inline, :partial]).empty? || options.key?(:layout) + def render_to_body(options) + if _include_layout?(options) layout = options.key?(:layout) ? options[:layout] : :default value = _layout_for_option(layout) @@ -344,6 +344,10 @@ module AbstractController layout_name end + def _include_layout?(options) + (options.keys & [:text, :inline, :partial]).empty? || options.key?(:layout) + end + def _action_has_layout? true end diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb index 8125badc75..9093e90c97 100644 --- a/actionpack/lib/abstract_controller/rendering.rb +++ b/actionpack/lib/abstract_controller/rendering.rb @@ -45,7 +45,8 @@ module AbstractController # Mostly abstracts the fact that calling render twice is a DoubleRenderError. # Delegates render_to_body and sticks the result in self.response_body. def render(*args, &block) - options = _normalize_options(*args, &block) + options = _normalize_args(*args, &block) + _normalize_options(options) self.response_body = render_to_body(options) end @@ -70,8 +71,8 @@ module AbstractController # render_to_body into a String. # # :api: plugin - def render_to_string(*args) - options = _normalize_options(*args) + def render_to_string(options={}) + _normalize_options(options) AbstractController::Rendering.body_to_s(render_to_body(options)) end @@ -131,7 +132,7 @@ module AbstractController # Normalize options, by converting render "foo" to render :template => "prefix/foo" # and render "/foo" to render :file => "/foo". - def _normalize_options(action=nil, options={}) + def _normalize_args(action=nil, options={}) case action when Hash options, action = action, nil @@ -151,6 +152,9 @@ module AbstractController options end + def _normalize_options(options) + end + # Take in a set of options and determine the template to render # # ==== Options diff --git a/actionpack/lib/action_controller/metal/rendering.rb b/actionpack/lib/action_controller/metal/rendering.rb index e2d2e2312b..60d61999de 100644 --- a/actionpack/lib/action_controller/metal/rendering.rb +++ b/actionpack/lib/action_controller/metal/rendering.rb @@ -18,6 +18,11 @@ module ActionController response_body end + def render_to_body(options) + _process_options(options) + super + end + private def _render_partial(options) @@ -30,7 +35,7 @@ module ActionController formats.first end - def _normalize_options(action=nil, options={}, &blk) + def _normalize_args(action=nil, options={}, &blk) case action when NilClass when Hash @@ -38,9 +43,14 @@ module ActionController when String, Symbol options = super else - options.merge! :partial => action + options.merge!(:partial => action) end + options[:update] = blk if block_given? + options + end + + def _normalize_options(options) if options.key?(:text) && options[:text].respond_to?(:to_text) options[:text] = options[:text].to_text end @@ -49,10 +59,7 @@ module ActionController options[:status] = Rack::Utils.status_code(options[:status]) end - options[:update] = blk if block_given? - - _process_options(options) - options + super end def _process_options(options) -- cgit v1.2.3 From 54a69c31edd240c8ed06d12be7b065153f44529f Mon Sep 17 00:00:00 2001 From: wycats Date: Sun, 7 Mar 2010 21:27:25 -0800 Subject: Typo in config.action_dispatch --- actionpack/lib/action_controller/deprecated/base.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/deprecated/base.rb b/actionpack/lib/action_controller/deprecated/base.rb index 34f8f4a822..1d05b3fbd6 100644 --- a/actionpack/lib/action_controller/deprecated/base.rb +++ b/actionpack/lib/action_controller/deprecated/base.rb @@ -57,7 +57,7 @@ module ActionController def ip_spoofing_check=(value) ActiveSupport::Deprecation.warn "ActionController::Base.ip_spoofing_check= is deprecated. " << "Please configure it on your application with config.action_dispatch.ip_spoofing_check=", caller - Rails.application.config.action_disaptch.ip_spoofing_check = value + Rails.application.config.action_dispatch.ip_spoofing_check = value end def ip_spoofing_check -- cgit v1.2.3 From 0a85380966e47a38292242e6c3b259d77c738ab5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Mon, 8 Mar 2010 11:32:01 +0100 Subject: Finally moved the find template logic to the views. --- actionpack/lib/abstract_controller/layouts.rb | 7 +- actionpack/lib/abstract_controller/rendering.rb | 232 +++++++++------------ .../lib/action_controller/metal/compatibility.rb | 11 +- .../lib/action_controller/metal/implicit_render.rb | 2 +- .../lib/action_controller/metal/rendering.rb | 41 ++-- actionpack/lib/action_view/render/rendering.rb | 40 ++-- actionpack/lib/action_view/template/text.rb | 7 +- .../test/abstract/abstract_controller_test.rb | 4 +- 8 files changed, 152 insertions(+), 192 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller/layouts.rb b/actionpack/lib/abstract_controller/layouts.rb index 648a2da795..6ac3806149 100644 --- a/actionpack/lib/abstract_controller/layouts.rb +++ b/actionpack/lib/abstract_controller/layouts.rb @@ -264,7 +264,7 @@ module AbstractController self.class_eval <<-RUBY, __FILE__, __LINE__ + 1 def _layout - if template_exists?("#{_implied_layout_name}", :_prefix => #{_prefix.inspect}) + if template_exists?("#{_implied_layout_name}", #{_prefix.inspect}) "#{_implied_layout_name}" else super @@ -277,7 +277,9 @@ module AbstractController end end - def render_to_body(options) + def _normalize_options(options) + super + if _include_layout?(options) layout = options.key?(:layout) ? options[:layout] : :default value = _layout_for_option(layout) @@ -288,7 +290,6 @@ module AbstractController # TODO Revisit this. :layout with :partial from controllers are not the same as in views options[:layout] = view_context._find_layout(options[:layout]) if options.key?(:partial) end - super end private diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb index 9093e90c97..d9087ce294 100644 --- a/actionpack/lib/abstract_controller/rendering.rb +++ b/actionpack/lib/abstract_controller/rendering.rb @@ -10,7 +10,7 @@ module AbstractController end end - module Rendering + module ViewPaths extend ActiveSupport::Concern included do @@ -21,21 +21,87 @@ module AbstractController delegate :formats, :formats=, :to => :template_lookup delegate :_view_paths, :to => :'self.class' + def template_lookup + @template_lookup ||= ActionView::Template::Lookup.new(_view_paths, details_for_lookup) + end + + def details_for_lookup + { } + end + + # The list of view paths for this controller. See ActionView::ViewPathSet for + # more details about writing custom view paths. + def view_paths + template_lookup.view_paths + end + + def append_view_path(path) + template_lookup.view_paths.push(*path) + end + + def prepend_view_path(path) + template_lookup.view_paths.unshift(*path) + end + + protected + + def template_exists?(*args) + template_lookup.exists?(*args) + end + + def find_template(*args) + template_lookup.find(*args) + end + + module ClassMethods + # Append a path to the list of view paths for this controller. + # + # ==== Parameters + # path:: If a String is provided, it gets converted into + # the default view path. You may also provide a custom view path + # (see ActionView::ViewPathSet for more information) + def append_view_path(path) + self.view_paths = view_paths.dup + Array(path) + end + + # Prepend a path to the list of view paths for this controller. + # + # ==== Parameters + # path:: If a String is provided, it gets converted into + # the default view path. You may also provide a custom view path + # (see ActionView::ViewPathSet for more information) + def prepend_view_path(path) + self.view_paths = Array(path) + view_paths.dup + end + + # A list of all of the default view paths for this controller. + def view_paths + _view_paths + end + + # Set the view paths. + # + # ==== Parameters + # paths:: If a ViewPathSet is provided, use that; + # otherwise, process the parameter into a ViewPathSet. + def view_paths=(paths) + self._view_paths = paths.is_a?(ActionView::PathSet) ? paths : ActionView::Base.process_view_paths(paths) + self._view_paths.freeze + end + end + end + + module Rendering + extend ActiveSupport::Concern + include AbstractController::ViewPaths + # An instance of a view class. The default view class is ActionView::Base # # The view class must have the following methods: - # View.for_controller[controller] Create a new ActionView instance for a - # controller - # View#render_partial[options] - # - responsible for setting options[:_template] - # - Returns String with the rendered partial - # options:: see _render_partial in ActionView::Base - # View#render_template[template, layout, options, partial] - # - Returns String with the rendered template - # template:: The template to render - # layout:: The layout to render around the template - # options:: See _render_template_with_layout in ActionView::Base - # partial:: Whether or not the template to render is a partial + # View.for_controller[controller] + # Create a new ActionView instance for a controller + # View#render_template[options] + # Returns String with the rendered template # # Override this method in a module to change the default behavior. def view_context @@ -51,64 +117,23 @@ module AbstractController end # Raw rendering of a template to a Rack-compatible body. - # - # ==== Options - # _partial_object:: The object that is being rendered. If this - # exists, we are in the special case of rendering an object as a partial. - # # :api: plugin def render_to_body(options = {}) - # TODO: Refactor so we can just use the normal template logic for this - if options.key?(:partial) - _render_partial(options) - else - _determine_template(options) - _render_template(options) - end + _process_options(options) + _render_template(options) end # Raw rendering of a template to a string. Just convert the results of # render_to_body into a String. - # # :api: plugin def render_to_string(options={}) _normalize_options(options) AbstractController::Rendering.body_to_s(render_to_body(options)) end - # Renders the template from an object. - # - # ==== Options - # _template:: The template to render - # _layout:: The layout to wrap the template in (optional) + # Find and renders a template based on the options given. def _render_template(options) - view_context.render_template(options) - end - - # Renders the given partial. - # - # ==== Options - # partial:: The partial name or the object to be rendered - def _render_partial(options) - view_context.render_partial(options) - end - - def template_lookup - @template_lookup ||= ActionView::Template::Lookup.new(_view_paths, details_for_render) - end - - # The list of view paths for this controller. See ActionView::ViewPathSet for - # more details about writing custom view paths. - def view_paths - template_lookup.view_paths - end - - def append_view_path(path) - template_lookup.view_paths.push(*path) - end - - def prepend_view_path(path) - template_lookup.view_paths.unshift(*path) + view_context.render_template(options) { |template| _with_template_hook(template) } end # The prefix used in render "foo" shortcuts. @@ -134,59 +159,40 @@ module AbstractController # and render "/foo" to render :file => "/foo". def _normalize_args(action=nil, options={}) case action + when NilClass when Hash options, action = action, nil when String, Symbol action = action.to_s case action.index("/") when NilClass - options[:_prefix] = _prefix - options[:_template_name] = action + options[:action] = action when 0 options[:file] = action else options[:template] = action end + else + options.merge!(:partial => action) end options end def _normalize_options(options) - end + if options[:partial] == true + options[:partial] = action_name + end - # Take in a set of options and determine the template to render - # - # ==== Options - # _template:: If this is provided, the search is over - # _template_name<#to_s>:: The name of the template to look up. Otherwise, - # use the current action name. - # _prefix:: The prefix to look inside of. In a file system, this corresponds - # to a directory. - # _partial:: Whether or not the file to look up is a partial - def _determine_template(options) - if options.key?(:text) - options[:_template] = ActionView::Template::Text.new(options[:text], format_for_text) - elsif options.key?(:inline) - handler = ActionView::Template.handler_class_for_extension(options[:type] || "erb") - template = ActionView::Template.new(options[:inline], "inline template", handler, {}) - options[:_template] = template - elsif options.key?(:template) - options[:_template_name] = options[:template] - elsif options.key?(:file) - options[:_template_name] = options[:file] + if (options.keys & [:partial, :file, :template]).empty? + options[:_prefix] ||= _prefix end - name = (options[:_template_name] || options[:action] || action_name).to_s - options[:_prefix] ||= _prefix if (options.keys & [:partial, :file, :template]).empty? + + options[:template] ||= (options[:action] || action_name).to_s details = _normalize_details(options) template_lookup.details = details - - options[:_template] ||= find_template(name, options) - end - - def details_for_render - { } + options end def _normalize_details(options) @@ -196,53 +202,11 @@ module AbstractController details end - def find_template(name, options) - template_lookup.find(name, options[:_prefix], options[:_partial]) - end - - def template_exists?(name, options) - template_lookup.exists?(name, options[:_prefix], options[:_partial]) - end - - def format_for_text - Mime[:text] + def _process_options(options) end - module ClassMethods - # Append a path to the list of view paths for this controller. - # - # ==== Parameters - # path:: If a String is provided, it gets converted into - # the default view path. You may also provide a custom view path - # (see ActionView::ViewPathSet for more information) - def append_view_path(path) - self.view_paths = view_paths.dup + Array(path) - end - - # Prepend a path to the list of view paths for this controller. - # - # ==== Parameters - # path:: If a String is provided, it gets converted into - # the default view path. You may also provide a custom view path - # (see ActionView::ViewPathSet for more information) - def prepend_view_path(path) - self.view_paths = Array(path) + view_paths.dup - end - - # A list of all of the default view paths for this controller. - def view_paths - _view_paths - end - - # Set the view paths. - # - # ==== Parameters - # paths:: If a ViewPathSet is provided, use that; - # otherwise, process the parameter into a ViewPathSet. - def view_paths=(paths) - self._view_paths = paths.is_a?(ActionView::PathSet) ? paths : ActionView::Base.process_view_paths(paths) - self._view_paths.freeze - end + def _with_template_hook(template) + self.formats = template.details[:formats] end end end diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb index 0cb20b2f0f..5cad0814ca 100644 --- a/actionpack/lib/action_controller/metal/compatibility.rb +++ b/actionpack/lib/action_controller/metal/compatibility.rb @@ -49,14 +49,19 @@ module ActionController super end - def render_to_body(options) - if options.is_a?(Hash) && options.key?(:template) - options[:template].sub!(/^\//, '') + def _normalize_options(options) + # TODO Deprecate this. Rails 2.x allowed to give a template as action. + if options[:action] && options[:action].to_s.include?(?/) + options[:template] = options.delete(:action) end options[:text] = nil if options.delete(:nothing) == true options[:text] = " " if options.key?(:text) && options[:text].nil? + super + end + def render_to_body(options) + options[:template].sub!(/^\//, '') if options.key?(:template) super || " " end diff --git a/actionpack/lib/action_controller/metal/implicit_render.rb b/actionpack/lib/action_controller/metal/implicit_render.rb index c3e3b8fdf5..282dcf66b3 100644 --- a/actionpack/lib/action_controller/metal/implicit_render.rb +++ b/actionpack/lib/action_controller/metal/implicit_render.rb @@ -12,7 +12,7 @@ module ActionController def method_for_action(action_name) super || begin - if template_exists?(action_name.to_s, :_prefix => controller_path) + if template_exists?(action_name.to_s, _prefix) "default_render" end end diff --git a/actionpack/lib/action_controller/metal/rendering.rb b/actionpack/lib/action_controller/metal/rendering.rb index 60d61999de..f892bd9b91 100644 --- a/actionpack/lib/action_controller/metal/rendering.rb +++ b/actionpack/lib/action_controller/metal/rendering.rb @@ -6,46 +6,20 @@ module ActionController include AbstractController::Rendering def process(*) - self.formats = request.formats.map {|x| x.to_sym } + self.formats = request.formats.map { |x| x.to_sym } super end def render(*args) raise ::AbstractController::DoubleRenderError if response_body - args << {} unless args.last.is_a?(Hash) - super(*args) - self.content_type ||= args.last[:_template].mime_type.to_s - response_body - end - - def render_to_body(options) - _process_options(options) super + response_body end private - def _render_partial(options) - options[:partial] = action_name if options[:partial] == true - options[:_details] = details_for_render - super - end - - def format_for_text - formats.first - end - def _normalize_args(action=nil, options={}, &blk) - case action - when NilClass - when Hash - options = super(action.delete(:action), action) - when String, Symbol - options = super - else - options.merge!(:partial => action) - end - + options = super options[:update] = blk if block_given? options end @@ -64,9 +38,18 @@ module ActionController def _process_options(options) status, content_type, location = options.values_at(:status, :content_type, :location) + self.status = status if status self.content_type = content_type if content_type self.headers["Location"] = url_for(location) if location + + super end + + def _with_template_hook(template) + super + self.content_type ||= template.mime_type.to_s + end + end end diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb index 17fb110eb4..c6d95e88e2 100644 --- a/actionpack/lib/action_view/render/rendering.rb +++ b/actionpack/lib/action_view/render/rendering.rb @@ -24,18 +24,8 @@ module ActionView return _render_partial(options) end - template = if options[:file] - find(options[:file]) - elsif options[:inline] - handler = Template.handler_class_for_extension(options[:type] || "erb") - Template.new(options[:inline], "inline template", handler, {}) - elsif options[:text] - Template::Text.new(options[:text]) - end - - if template - _render_template(template, layout, :locals => options[:locals]) - end + template = _determine_template(options) + _render_template(template, layout, :locals => options[:locals]) if template when :update update_page(&block) else @@ -87,8 +77,28 @@ module ActionView # _layout:: The layout, if any, to wrap the Template in def render_template(options) _evaluate_assigns_and_ivars - template, layout = options.values_at(:_template, :layout) - _render_template(template, layout, options) + if options.key?(:partial) + _render_partial(options) + else + template = _determine_template(options) + yield template if block_given? + _render_template(template, options[:layout], options) + end + end + + def _determine_template(options) + if options.key?(:inline) + handler = Template.handler_class_for_extension(options[:type] || "erb") + Template.new(options[:inline], "inline template", handler, {}) + elsif options.key?(:text) + Template::Text.new(options[:text], self.formats.try(:first)) + elsif options.key?(:_template) + options[:_template] + elsif options.key?(:file) + find(options[:file], options[:_prefix]) + elsif options.key?(:template) + find(options[:template], options[:_prefix]) + end end def _find_layout(layout) @@ -102,8 +112,6 @@ module ActionView end def _render_template(template, layout = nil, options = {}) - self.formats = template.details[:formats] - locals = options[:locals] || {} layout = _find_layout(layout) if layout diff --git a/actionpack/lib/action_view/template/text.rb b/actionpack/lib/action_view/template/text.rb index 2abb352d4e..5978a8a3ac 100644 --- a/actionpack/lib/action_view/template/text.rb +++ b/actionpack/lib/action_view/template/text.rb @@ -1,11 +1,10 @@ module ActionView #:nodoc: class Template class Text < String #:nodoc: - HTML = Mime[:html] - - def initialize(string, content_type = HTML) + def initialize(string, content_type = nil) super(string.to_s) - @content_type = Mime[content_type] || content_type + @content_type = Mime[content_type] || content_type if content_type + @content_type ||= Mime::TEXT end def details diff --git a/actionpack/test/abstract/abstract_controller_test.rb b/actionpack/test/abstract/abstract_controller_test.rb index 4ad87d9762..f70d497481 100644 --- a/actionpack/test/abstract/abstract_controller_test.rb +++ b/actionpack/test/abstract/abstract_controller_test.rb @@ -59,11 +59,11 @@ module AbstractController end def rendering_to_body - self.response_body = render_to_body :_template_name => "naked_render.erb" + self.response_body = render_to_body :template => "naked_render.erb" end def rendering_to_string - self.response_body = render_to_string :_template_name => "naked_render.erb" + self.response_body = render_to_string :template => "naked_render.erb" end end -- cgit v1.2.3 From ea68fe59c670dd5580f3aa34fdfa0eb89eb717d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Mon, 8 Mar 2010 14:46:57 +0100 Subject: More refactoring on the views side of rendering. --- actionpack/lib/abstract_controller/layouts.rb | 9 +- actionpack/lib/action_view.rb | 1 + actionpack/lib/action_view/base.rb | 2 +- actionpack/lib/action_view/render/layouts.rb | 64 ++++++++++++++ actionpack/lib/action_view/render/partials.rb | 33 ++----- actionpack/lib/action_view/render/rendering.rb | 95 ++++++-------------- actionpack/test/abstract/layouts_test.rb | 116 ++++++++++++++++++------- actionpack/test/abstract/render_test.rb | 19 ---- 8 files changed, 185 insertions(+), 154 deletions(-) create mode 100644 actionpack/lib/action_view/render/layouts.rb (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller/layouts.rb b/actionpack/lib/abstract_controller/layouts.rb index 6ac3806149..2f9616124a 100644 --- a/actionpack/lib/abstract_controller/layouts.rb +++ b/actionpack/lib/abstract_controller/layouts.rb @@ -281,14 +281,9 @@ module AbstractController super if _include_layout?(options) - layout = options.key?(:layout) ? options[:layout] : :default + layout = options.key?(:layout) ? options.delete(:layout) : :default value = _layout_for_option(layout) - - # TODO Revisit this. Maybe we should pass a :layout_prefix? - options[:layout] = ((!value || value =~ /\blayouts/) ? value : "layouts/#{value}") - - # TODO Revisit this. :layout with :partial from controllers are not the same as in views - options[:layout] = view_context._find_layout(options[:layout]) if options.key?(:partial) + options[:layout] = (value =~ /\blayouts/ ? value : "layouts/#{value}") if value end end diff --git a/actionpack/lib/action_view.rb b/actionpack/lib/action_view.rb index f5035fe45a..f111950540 100644 --- a/actionpack/lib/action_view.rb +++ b/actionpack/lib/action_view.rb @@ -37,6 +37,7 @@ module ActionView autoload :Helpers autoload_under "render" do + autoload :Layouts autoload :Partials autoload :Rendering end diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 5acd2a8b82..656d73e32d 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -173,7 +173,7 @@ module ActionView #:nodoc: module Subclasses end - include Helpers, Rendering, Partials, ::ERB::Util + include Helpers, Rendering, Partials, Layouts, ::ERB::Util extend ActiveSupport::Memoizable diff --git a/actionpack/lib/action_view/render/layouts.rb b/actionpack/lib/action_view/render/layouts.rb new file mode 100644 index 0000000000..e1dbd3c120 --- /dev/null +++ b/actionpack/lib/action_view/render/layouts.rb @@ -0,0 +1,64 @@ +require 'active_support/core_ext/object/try' + +module ActionView + module Layouts + + # You can think of a layout as a method that is called with a block. _layout_for + # returns the contents that are yielded to the layout. If the user calls yield + # :some_name, the block, by default, returns content_for(:some_name). If the user + # calls yield, the default block returns content_for(:layout). + # + # The user can override this default by passing a block to the layout. + # + # ==== Example + # + # # The template + # <% render :layout => "my_layout" do %>Content<% end %> + # + # # The layout + # <% yield %> + # + # In this case, instead of the default block, which would return content_for(:layout), + # this method returns the block that was passed in to render layout, and the response + # would be Content. + # + # Finally, the block can take block arguments, which can be passed in by yield. + # + # ==== Example + # + # # The template + # <% render :layout => "my_layout" do |customer| %>Hello <%= customer.name %><% end %> + # + # # The layout + # <% yield Struct.new(:name).new("David") %> + # + # In this case, the layout would receive the block passed into render :layout, + # and the Struct specified in the layout would be passed into the block. The result + # would be Hello David. + def _layout_for(name = nil, &block) #:nodoc: + if !block || name + @_content_for[name || :layout] + else + capture(&block) + end + end + + # This is the method which actually finds the layout using details in the lookup + # context object. If no layout is found, it checkes if at least a layout with + # the given name exists across all details before raising the error. + def _find_layout(layout) #:nodoc: + begin + find(layout) + rescue ActionView::MissingTemplate => e + update_details(:formats => nil) do + raise unless template_lookup.exists?(layout) + end + end + end + + # Contains the logic that actually renders the layout. + def _render_layout(layout, locals, &block) #:nodoc: + layout.render(self, locals){ |*name| _layout_for(*name, &block) } + end + end +end diff --git a/actionpack/lib/action_view/render/partials.rb b/actionpack/lib/action_view/render/partials.rb index eecc88a1e0..950c9d2cd8 100644 --- a/actionpack/lib/action_view/render/partials.rb +++ b/actionpack/lib/action_view/render/partials.rb @@ -174,9 +174,6 @@ module ActionView class PartialRenderer PARTIAL_NAMES = Hash.new {|h,k| h[k] = {} } - TEMPLATES = Hash.new {|h,k| h[k] = {} } - - attr_reader :template def initialize(view_context, options, block) @view = view_context @@ -225,6 +222,7 @@ module ActionView if !@block && (layout = @options[:layout]) content = @view._render_layout(find_template(layout), @locals){ content } end + content end end @@ -241,9 +239,9 @@ module ActionView end def collection_with_template(template = @template) - segments, locals, as = [], @locals, @options[:as] || template.variable_name + segments, locals, as, template = [], @locals, @options[:as] || @template.variable_name, @template - counter_name = template.counter_name + counter_name = template.counter_name locals[counter_name] = -1 @collection.each do |object| @@ -253,7 +251,6 @@ module ActionView segments << template.render(@view, locals) end - @template = template segments end @@ -274,7 +271,7 @@ module ActionView end def render_partial(object = @object) - locals, view = @locals, @view + locals, view, template = @locals, @view, @template object ||= locals[template.variable_name] locals[@options[:as] || template.variable_name] = object @@ -285,6 +282,7 @@ module ActionView end private + def collection if @object.respond_to?(:to_ary) @object @@ -295,11 +293,7 @@ module ActionView def find_template(path=@path) return path unless path.is_a?(String) - - if controller = @view.controller - prefix = controller.controller_path unless path.include?(?/) - end - + prefix = @view.controller_path unless path.include?(?/) @view.find(path, prefix, true) end @@ -315,21 +309,8 @@ module ActionView end end - def render_partial(options) - _evaluate_assigns_and_ivars - - details = options[:_details] - - # TODO This should happen automatically as well - self.formats = details[:formats] if details[:formats] - renderer = PartialRenderer.new(self, options, nil) - text = renderer.render - options[:_template] = renderer.template - text - end - def _render_partial(options, &block) #:nodoc: - if defined? @renderer + if defined?(@renderer) @renderer.setup(options, block) else @renderer = PartialRenderer.new(self, options, block) diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb index c6d95e88e2..61fea6f49e 100644 --- a/actionpack/lib/action_view/render/rendering.rb +++ b/actionpack/lib/action_view/render/rendering.rb @@ -15,17 +15,12 @@ module ActionView def render(options = {}, locals = {}, &block) #:nodoc: case options when Hash - layout = options[:layout] - options[:locals] ||= {} - if block_given? - return safe_concat(_render_partial(options.merge(:partial => layout), &block)) - elsif options.key?(:partial) - return _render_partial(options) + content = _render_partial(options.merge(:partial => options[:layout]), &block) + safe_concat(content) + else + _render(options) end - - template = _determine_template(options) - _render_template(template, layout, :locals => options[:locals]) if template when :update update_page(&block) else @@ -33,50 +28,24 @@ module ActionView end end - # You can think of a layout as a method that is called with a block. _layout_for - # returns the contents that are yielded to the layout. If the user calls yield - # :some_name, the block, by default, returns content_for(:some_name). If the user - # calls yield, the default block returns content_for(:layout). - # - # The user can override this default by passing a block to the layout. - # - # ==== Example - # - # # The template - # <% render :layout => "my_layout" do %>Content<% end %> - # - # # The layout - # <% yield %> - # - # In this case, instead of the default block, which would return content_for(:layout), - # this method returns the block that was passed in to render layout, and the response - # would be Content. - # - # Finally, the block can take block arguments, which can be passed in by yield. - # - # ==== Example - # - # # The template - # <% render :layout => "my_layout" do |customer| %>Hello <%= customer.name %><% end %> - # - # # The layout - # <% yield Struct.new(:name).new("David") %> - # - # In this case, the layout would receive the block passed into render :layout, - # and the Struct specified in the layout would be passed into the block. The result - # would be Hello David. - def _layout_for(name = nil, &block) - return @_content_for[name || :layout] if !block_given? || name - capture(&block) - end - # This is the API to render a ViewContext's template from a controller. - # - # Internal Options: - # _template:: The Template object to render - # _layout:: The layout, if any, to wrap the Template in - def render_template(options) + # TODO Review this name since it does not render only templates, but also + # partials, files and so forth. + def render_template(options, &block) _evaluate_assigns_and_ivars + + # TODO Layout for partials should be handled here, because inside the + # partial renderer it looks for the layout as a partial. + if options.key?(:partial) && options[:layout] + options[:layout] = _find_layout(options[:layout]) + end + + _render(options, &block) + end + + # This method holds the common render logic for both controllers and + # views rendering stacks. + def _render(options) #:nodoc: if options.key?(:partial) _render_partial(options) else @@ -86,14 +55,13 @@ module ActionView end end - def _determine_template(options) + # Determine the template to be rendered using the given options. + def _determine_template(options) #:nodoc: if options.key?(:inline) handler = Template.handler_class_for_extension(options[:type] || "erb") Template.new(options[:inline], "inline template", handler, {}) elsif options.key?(:text) Template::Text.new(options[:text], self.formats.try(:first)) - elsif options.key?(:_template) - options[:_template] elsif options.key?(:file) find(options[:file], options[:_prefix]) elsif options.key?(:template) @@ -101,24 +69,16 @@ module ActionView end end - def _find_layout(layout) - begin - find(layout) - rescue ActionView::MissingTemplate => e - update_details(:formats => nil) do - raise unless template_lookup.exists?(layout) - end - end - end - - def _render_template(template, layout = nil, options = {}) + # Renders the given template. An string representing the layout can be + # supplied as well. + def _render_template(template, layout = nil, options = {}) #:nodoc: locals = options[:locals] || {} layout = _find_layout(layout) if layout ActiveSupport::Notifications.instrument("action_view.render_template", :identifier => template.identifier, :layout => layout.try(:identifier)) do - content = template.render(self, locals) {|*name| _layout_for(*name) } + content = template.render(self, locals) { |*name| _layout_for(*name) } @_content_for[:layout] = content if layout @@ -130,8 +90,5 @@ module ActionView end end - def _render_layout(layout, locals, &block) - layout.render(self, locals){ |*name| _layout_for(*name, &block) } - end end end diff --git a/actionpack/test/abstract/layouts_test.rb b/actionpack/test/abstract/layouts_test.rb index fcc91d03f1..65a50807fd 100644 --- a/actionpack/test/abstract/layouts_test.rb +++ b/actionpack/test/abstract/layouts_test.rb @@ -8,41 +8,52 @@ module AbstractControllerTests include AbstractController::Rendering include AbstractController::Layouts + def _prefix + "template" + end + self.view_paths = [ActionView::FixtureResolver.new( - "layouts/hello.erb" => "With String <%= yield %>", - "layouts/hello_override.erb" => "With Override <%= yield %>", "abstract_controller_tests/layouts/with_string_implied_child.erb" => - "With Implied <%= yield %>", - "layouts/overwrite.erb" => "Overwrite <%= yield %>", - "layouts/with_false_layout.erb" => "False Layout <%= yield %>" + "With Implied <%= yield %>", + "layouts/hello.erb" => "With String <%= yield %>", + "layouts/hello_override.erb" => "With Override <%= yield %>", + "layouts/overwrite.erb" => "Overwrite <%= yield %>", + "layouts/with_false_layout.erb" => "False Layout <%= yield %>" )] end class Blank < Base - self.view_paths = [] - + self.view_paths = ActionView::FixtureResolver.new("template/index.erb" => "Hello blank!") + def index - render :_template => ActionView::Template::Text.new("Hello blank!") + render end end class WithString < Base layout "hello" - + + append_view_path ActionView::FixtureResolver.new( + "template/index.erb" => "Hello string!", + "template/overwrite_default.erb" => "Hello string!", + "template/overwrite_false.erb" => "Hello string!", + "template/overwrite_string.erb" => "Hello string!" + ) + def index - render :_template => ActionView::Template::Text.new("Hello string!") + render end def overwrite_default - render :_template => ActionView::Template::Text.new("Hello string!"), :layout => :default + render :layout => :default end def overwrite_false - render :_template => ActionView::Template::Text.new("Hello string!"), :layout => false + render :layout => false end def overwrite_string - render :_template => ActionView::Template::Text.new("Hello string!"), :layout => "overwrite" + render :layout => "overwrite" end def overwrite_skip @@ -70,18 +81,28 @@ module AbstractControllerTests class WithProc < Base layout proc { |c| "overwrite" } + append_view_path ActionView::FixtureResolver.new( + "template/index.erb" => "Hello proc!" + ) + def index - render :_template => ActionView::Template::Text.new("Hello proc!") + render end end class WithSymbol < Base layout :hello - + + append_view_path ActionView::FixtureResolver.new( + "template/index.erb" => "Hello symbol!" + ) + def index - render :_template => ActionView::Template::Text.new("Hello symbol!") + render end - private + + private + def hello "overwrite" end @@ -89,11 +110,17 @@ module AbstractControllerTests class WithSymbolReturningString < Base layout :no_hello - + + append_view_path ActionView::FixtureResolver.new( + "template/index.erb" => "Hello missing symbol!" + ) + def index - render :_template => ActionView::Template::Text.new("Hello missing symbol!") + render end - private + + private + def no_hello nil end @@ -101,19 +128,28 @@ module AbstractControllerTests class WithSymbolReturningNil < Base layout :nilz - + + append_view_path ActionView::FixtureResolver.new( + "template/index.erb" => "Hello nilz!" + ) + def index - render :_template => ActionView::Template::Text.new("Hello nilz!") + render end - def nilz() end + def nilz + end end class WithSymbolReturningObj < Base layout :objekt - + + append_view_path ActionView::FixtureResolver.new( + "template/index.erb" => "Hello object!" + ) + def index - render :_template => ActionView::Template::Text.new("Hello nilz!") + render end def objekt @@ -123,33 +159,49 @@ module AbstractControllerTests class WithSymbolAndNoMethod < Base layout :no_method - + + append_view_path ActionView::FixtureResolver.new( + "template/index.erb" => "Hello boom!" + ) + def index - render :_template => ActionView::Template::Text.new("Hello boom!") + render end end class WithMissingLayout < Base layout "missing" - + + append_view_path ActionView::FixtureResolver.new( + "template/index.erb" => "Hello missing!" + ) + def index - render :_template => ActionView::Template::Text.new("Hello missing!") + render end end class WithFalseLayout < Base layout false - + + append_view_path ActionView::FixtureResolver.new( + "template/index.erb" => "Hello false!" + ) + def index - render :_template => ActionView::Template::Text.new("Hello false!") + render end end class WithNilLayout < Base layout nil + + append_view_path ActionView::FixtureResolver.new( + "template/index.erb" => "Hello nil!" + ) def index - render :_template => ActionView::Template::Text.new("Hello nil!") + render end end diff --git a/actionpack/test/abstract/render_test.rb b/actionpack/test/abstract/render_test.rb index db924633ca..e54d056666 100644 --- a/actionpack/test/abstract/render_test.rb +++ b/actionpack/test/abstract/render_test.rb @@ -15,7 +15,6 @@ module AbstractController "renderer/default.erb" => "With Default", "renderer/string.erb" => "With String", "renderer/symbol.erb" => "With Symbol", - "renderer/template_name.erb" => "With Template Name", "string/with_path.erb" => "With String With Path", "some/file.erb" => "With File", "with_format.html.erb" => "With html format", @@ -56,14 +55,6 @@ module AbstractController render :symbol end - def template_name - render :_template_name => :template_name - end - - def object - render :_template => ActionView::Template::Text.new("With Object") - end - def with_html_format render :template => "with_format", :format => :html end @@ -127,16 +118,6 @@ module AbstractController assert_equal "With String With Path", @controller.response_body end - def test_render_template_name - @controller.process(:template_name) - assert_equal "With Template Name", @controller.response_body - end - - def test_render_object - @controller.process(:object) - assert_equal "With Object", @controller.response_body - end - def test_render_with_html_format @controller.process(:with_html_format) assert_equal "With html format", @controller.response_body -- cgit v1.2.3 From 44ebab96da0ab47cc45c64a6efdd2cbb80f9d042 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Mon, 8 Mar 2010 15:19:03 +0100 Subject: Rename Template::Lookup to LookupContext. --- actionpack/lib/abstract_controller/rendering.rb | 35 ++++------- actionpack/lib/action_view.rb | 1 + actionpack/lib/action_view/base.rb | 27 +++------ actionpack/lib/action_view/lookup_context.rb | 80 +++++++++++++++++++++++++ actionpack/lib/action_view/render/layouts.rb | 4 +- actionpack/lib/action_view/render/partials.rb | 2 +- actionpack/lib/action_view/render/rendering.rb | 4 +- actionpack/lib/action_view/template.rb | 1 - actionpack/lib/action_view/template/lookup.rb | 56 ----------------- 9 files changed, 105 insertions(+), 105 deletions(-) create mode 100644 actionpack/lib/action_view/lookup_context.rb delete mode 100644 actionpack/lib/action_view/template/lookup.rb (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb index d9087ce294..356f1ec7f6 100644 --- a/actionpack/lib/abstract_controller/rendering.rb +++ b/actionpack/lib/abstract_controller/rendering.rb @@ -18,39 +18,26 @@ module AbstractController self._view_paths = ActionView::PathSet.new end - delegate :formats, :formats=, :to => :template_lookup - delegate :_view_paths, :to => :'self.class' + delegate :find_template, :template_exists?, + :view_paths, :formats, :formats=, :to => :lookup_context - def template_lookup - @template_lookup ||= ActionView::Template::Lookup.new(_view_paths, details_for_lookup) + # LookupContext is the object responsible to hold all information required to lookup + # templates, i.e. view paths and details. Check ActionView::LookupContext for more + # information. + def lookup_context + @lookup_context ||= ActionView::LookupContext.new(self.class._view_paths, details_for_lookup) end def details_for_lookup { } end - # The list of view paths for this controller. See ActionView::ViewPathSet for - # more details about writing custom view paths. - def view_paths - template_lookup.view_paths - end - def append_view_path(path) - template_lookup.view_paths.push(*path) + lookup_context.view_paths.push(*path) end def prepend_view_path(path) - template_lookup.view_paths.unshift(*path) - end - - protected - - def template_exists?(*args) - template_lookup.exists?(*args) - end - - def find_template(*args) - template_lookup.find(*args) + lookup_context.view_paths.unshift(*path) end module ClassMethods @@ -191,12 +178,12 @@ module AbstractController options[:template] ||= (options[:action] || action_name).to_s details = _normalize_details(options) - template_lookup.details = details + lookup_context.update_details(details) options end def _normalize_details(options) - details = template_lookup.details + details = {} details[:formats] = Array(options[:format]) if options[:format] details[:locale] = Array(options[:locale]) if options[:locale] details diff --git a/actionpack/lib/action_view.rb b/actionpack/lib/action_view.rb index f111950540..c37cea824a 100644 --- a/actionpack/lib/action_view.rb +++ b/actionpack/lib/action_view.rb @@ -42,6 +42,7 @@ module ActionView autoload :Rendering end + autoload :LookupContext, 'action_view/lookup_context' autoload :MissingTemplate, 'action_view/base' autoload :Resolver, 'action_view/template/resolver' autoload :PathResolver, 'action_view/template/resolver' diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 656d73e32d..d18f524060 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -242,12 +242,11 @@ module ActionView #:nodoc: klass = self end - klass.new(controller.template_lookup, {}, controller) + klass.new(controller.lookup_context, {}, controller) end - def initialize(template_lookup = nil, assigns_for_first_render = {}, controller = nil, formats = nil) #:nodoc: + def initialize(lookup_context = nil, assigns_for_first_render = {}, controller = nil, formats = nil) #:nodoc: @config = nil - @formats = formats @assigns = assigns_for_first_render.each { |key, value| instance_variable_set("@#{key}", value) } @helpers = self.class.helpers || Module.new @@ -256,27 +255,17 @@ module ActionView #:nodoc: @_content_for = Hash.new { |h,k| h[k] = ActiveSupport::SafeBuffer.new } @_virtual_path = nil - @template_lookup = template_lookup.is_a?(ActionView::Template::Lookup) ? - template_lookup : ActionView::Template::Lookup.new(template_lookup) + @lookup_context = lookup_context.is_a?(ActionView::LookupContext) ? + lookup_context : ActionView::LookupContext.new(lookup_context) + @lookup_context.formats = formats if formats end attr_internal :controller, :template, :config - attr_reader :template_lookup - delegate :find, :formats, :formats=, :view_paths, :view_paths=, :to => :template_lookup + attr_reader :lookup_context - def update_details(details) - old_details = template_lookup.details - template_lookup.details = old_details.merge(details) - - if block_given? - begin - yield - ensure - template_lookup.details = old_details - end - end - end + delegate :find_template, :template_exists?, :formats, :formats=, + :view_paths, :view_paths=, :update_details, :to => :lookup_context def punctuate_body!(part) flush_output_buffer diff --git a/actionpack/lib/action_view/lookup_context.rb b/actionpack/lib/action_view/lookup_context.rb new file mode 100644 index 0000000000..82aebe1678 --- /dev/null +++ b/actionpack/lib/action_view/lookup_context.rb @@ -0,0 +1,80 @@ +module ActionView + # LookupContext is the object responsible to hold all information required to lookup + # templates, i.e. view paths and details. The LookupContext is also responsible to + # generate a key, given to view paths, used in the resolver cache lookup. Since + # this key is generated just once during the request, it speeds up all cache accesses. + class LookupContext #:nodoc: + attr_reader :details, :view_paths + + class DetailsKey #:nodoc: + attr_reader :details + alias :eql? :equal? + + @details_keys = Hash.new + + def self.get(details) + @details_keys[details] ||= new(details) + end + + def initialize(details) + @details, @hash = details, details.hash + end + end + + def initialize(view_paths, details = {}) + @details, @details_key = details, nil + self.view_paths = view_paths + end + + # Shortcut to read formats from details. + def formats + @details[:formats] + end + + # Shortcut to set formats in details. + def formats=(value) + self.details = @details.merge(:formats => Array(value)) + end + + # Whenever setting view paths, makes a copy so we can manipulate then in + # instance objects as we wish. + def view_paths=(paths) + @view_paths = ActionView::Base.process_view_paths(paths) + end + + # Setter for details. Everything this method is invoked, we need to nullify + # the details key if it changed. + def details=(details) + @details = details + @details_key = nil if @details_key && @details_key.details != details + end + + def details_key + @details_key ||= DetailsKey.get(details) unless details.empty? + end + + # Update the details keys by merging the given hash into the current + # details hash. If a block is given, the details are modified just during + # the execution of the block and reverted to the previous value after. + def update_details(new_details) + old_details = self.details + self.details = old_details.merge(new_details) + + if block_given? + begin + yield + ensure + self.details = old_details + end + end + end + + def find_template(name, prefix = nil, partial = false) + @view_paths.find(name, details, prefix, partial || false, details_key) + end + + def template_exists?(name, prefix = nil, partial = false) + @view_paths.exists?(name, details, prefix, partial || false, details_key) + end + end +end \ No newline at end of file diff --git a/actionpack/lib/action_view/render/layouts.rb b/actionpack/lib/action_view/render/layouts.rb index e1dbd3c120..b9c63e0090 100644 --- a/actionpack/lib/action_view/render/layouts.rb +++ b/actionpack/lib/action_view/render/layouts.rb @@ -48,10 +48,10 @@ module ActionView # the given name exists across all details before raising the error. def _find_layout(layout) #:nodoc: begin - find(layout) + find_template(layout) rescue ActionView::MissingTemplate => e update_details(:formats => nil) do - raise unless template_lookup.exists?(layout) + raise unless template_exists?(layout) end end end diff --git a/actionpack/lib/action_view/render/partials.rb b/actionpack/lib/action_view/render/partials.rb index 950c9d2cd8..0fe2d560f7 100644 --- a/actionpack/lib/action_view/render/partials.rb +++ b/actionpack/lib/action_view/render/partials.rb @@ -294,7 +294,7 @@ module ActionView def find_template(path=@path) return path unless path.is_a?(String) prefix = @view.controller_path unless path.include?(?/) - @view.find(path, prefix, true) + @view.find_template(path, prefix, true) end def partial_path(object = @object) diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb index 61fea6f49e..96c0b4fe6a 100644 --- a/actionpack/lib/action_view/render/rendering.rb +++ b/actionpack/lib/action_view/render/rendering.rb @@ -63,9 +63,9 @@ module ActionView elsif options.key?(:text) Template::Text.new(options[:text], self.formats.try(:first)) elsif options.key?(:file) - find(options[:file], options[:_prefix]) + find_template(options[:file], options[:_prefix]) elsif options.key?(:template) - find(options[:template], options[:_prefix]) + find_template(options[:template], options[:_prefix]) end end diff --git a/actionpack/lib/action_view/template.rb b/actionpack/lib/action_view/template.rb index c176359253..cd6b1930a1 100644 --- a/actionpack/lib/action_view/template.rb +++ b/actionpack/lib/action_view/template.rb @@ -13,7 +13,6 @@ module ActionView autoload :Handler autoload :Handlers autoload :Text - autoload :Lookup end extend Template::Handlers diff --git a/actionpack/lib/action_view/template/lookup.rb b/actionpack/lib/action_view/template/lookup.rb deleted file mode 100644 index 30de093934..0000000000 --- a/actionpack/lib/action_view/template/lookup.rb +++ /dev/null @@ -1,56 +0,0 @@ -module ActionView - class Template - class Lookup - attr_reader :details, :view_paths - - class DetailsKey - attr_reader :details - alias :eql? :equal? - - @details_keys = Hash.new - - def self.get(details) - @details_keys[details] ||= new(details) - end - - def initialize(details) - @details, @hash = details, details.hash - end - end - - def initialize(view_paths, details = {}) - @details = details - self.view_paths = view_paths - end - - def formats - @details[:formats] - end - - def formats=(value) - self.details = @details.merge(:formats => Array(value)) - end - - def view_paths=(paths) - @view_paths = ActionView::Base.process_view_paths(paths) - end - - def details=(details) - @details = details - @details_key = nil if @details_key && @details_key.details != details - end - - def details_key - @details_key ||= DetailsKey.get(details) unless details.empty? - end - - def find(name, prefix = nil, partial = false) - @view_paths.find(name, details, prefix, partial || false, details_key) - end - - def exists?(name, prefix = nil, partial = false) - @view_paths.exists?(name, details, prefix, partial || false, details_key) - end - end - end -end \ No newline at end of file -- cgit v1.2.3 From 68cda695da27f57cae682d160a13dab4dacb1ef8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Mon, 8 Mar 2010 16:32:40 +0100 Subject: Speed up performance in resolvers by adding fallbacks just when required. --- actionpack/lib/abstract_controller/rendering.rb | 14 ++----- actionpack/lib/action_view/base.rb | 46 +++++++++------------- actionpack/lib/action_view/lookup_context.rb | 16 ++++++++ actionpack/lib/action_view/paths.rb | 2 +- actionpack/lib/action_view/render/layouts.rb | 3 +- actionpack/lib/action_view/render/rendering.rb | 2 +- actionpack/lib/action_view/template/resolver.rb | 31 ++++----------- .../test/template/compiled_templates_test.rb | 2 +- actionpack/test/template/render_test.rb | 6 +-- 9 files changed, 53 insertions(+), 69 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb index 356f1ec7f6..840f0b6c78 100644 --- a/actionpack/lib/abstract_controller/rendering.rb +++ b/actionpack/lib/abstract_controller/rendering.rb @@ -142,8 +142,8 @@ module AbstractController private - # Normalize options, by converting render "foo" to render :template => "prefix/foo" - # and render "/foo" to render :file => "/foo". + # Normalize options by converting render "foo" to render :action => "foo" and + # render "foo/bar" to render :file => "foo/bar". def _normalize_args(action=nil, options={}) case action when NilClass @@ -151,14 +151,8 @@ module AbstractController options, action = action, nil when String, Symbol action = action.to_s - case action.index("/") - when NilClass - options[:action] = action - when 0 - options[:file] = action - else - options[:template] = action - end + key = action.include?(?/) ? :file : :action + options[key] = action else options.merge!(:partial => action) end diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index d18f524060..d2b77b2560 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -173,48 +173,41 @@ module ActionView #:nodoc: module Subclasses end - include Helpers, Rendering, Partials, Layouts, ::ERB::Util - - extend ActiveSupport::Memoizable - - attr_accessor :base_path, :assigns, :template_extension - attr_internal :captures - - class << self - delegate :erb_trim_mode=, :to => 'ActionView::Template::Handlers::ERB' - delegate :logger, :to => 'ActionController::Base', :allow_nil => true - end + include Helpers, Rendering, Partials, Layouts, ::ERB::Util, Context + extend ActiveSupport::Memoizable # Specify whether RJS responses should be wrapped in a try/catch block # that alert()s the caught exception (and then re-raises it). cattr_accessor :debug_rjs @@debug_rjs = false - # :nodoc: - def self.xss_safe? - true + class_attribute :helpers + attr_reader :helpers + + class << self + delegate :erb_trim_mode=, :to => 'ActionView::Template::Handlers::ERB' + delegate :logger, :to => 'ActionController::Base', :allow_nil => true end - attr_internal :request, :layout + attr_accessor :base_path, :assigns, :template_extension, :lookup_context + attr_internal :captures, :request, :layout, :controller, :template, :config - def controller_path - @controller_path ||= controller && controller.controller_path - end + delegate :find_template, :template_exists?, :formats, :formats=, + :view_paths, :view_paths=, :with_fallbacks, :update_details, :to => :lookup_context delegate :request_forgery_protection_token, :template, :params, :session, :cookies, :response, :headers, :flash, :action_name, :controller_name, :to => :controller delegate :logger, :to => :controller, :allow_nil => true - include Context + def self.xss_safe? #:nodoc: + true + end def self.process_view_paths(value) ActionView::PathSet.new(Array(value)) end - class_attribute :helpers - attr_reader :helpers - def self.for_controller(controller) @views ||= {} @@ -260,12 +253,9 @@ module ActionView #:nodoc: @lookup_context.formats = formats if formats end - attr_internal :controller, :template, :config - - attr_reader :lookup_context - - delegate :find_template, :template_exists?, :formats, :formats=, - :view_paths, :view_paths=, :update_details, :to => :lookup_context + def controller_path + @controller_path ||= controller && controller.controller_path + end def punctuate_body!(part) flush_output_buffer diff --git a/actionpack/lib/action_view/lookup_context.rb b/actionpack/lib/action_view/lookup_context.rb index 82aebe1678..e259a78c5c 100644 --- a/actionpack/lib/action_view/lookup_context.rb +++ b/actionpack/lib/action_view/lookup_context.rb @@ -6,6 +6,9 @@ module ActionView class LookupContext #:nodoc: attr_reader :details, :view_paths + mattr_accessor :fallbacks + @@fallbacks = [FileSystemResolver.new(""), FileSystemResolver.new("/")] + class DetailsKey #:nodoc: attr_reader :details alias :eql? :equal? @@ -69,6 +72,19 @@ module ActionView end end + # Added fallbacks to the view paths. Useful in cases you are rendering a file. + def with_fallbacks + added_resolvers = 0 + self.class.fallbacks.each do |resolver| + next if view_paths.include?(resolver) + view_paths.push(resolver) + added_resolvers += 1 + end + yield + ensure + added_resolvers.times { view_paths.pop } + end + def find_template(name, prefix = nil, partial = false) @view_paths.find(name, details, prefix, partial || false, details_key) end diff --git a/actionpack/lib/action_view/paths.rb b/actionpack/lib/action_view/paths.rb index 154a79a8f1..628546e443 100644 --- a/actionpack/lib/action_view/paths.rb +++ b/actionpack/lib/action_view/paths.rb @@ -33,7 +33,7 @@ module ActionView #:nodoc: def typecast! each_with_index do |path, i| next unless path.is_a?(String) - self[i] = FileSystemResolverWithFallback.new(path) + self[i] = FileSystemResolver.new(path) end end end diff --git a/actionpack/lib/action_view/render/layouts.rb b/actionpack/lib/action_view/render/layouts.rb index b9c63e0090..91a92a833a 100644 --- a/actionpack/lib/action_view/render/layouts.rb +++ b/actionpack/lib/action_view/render/layouts.rb @@ -48,7 +48,8 @@ module ActionView # the given name exists across all details before raising the error. def _find_layout(layout) #:nodoc: begin - find_template(layout) + layout =~ /^\// ? + with_fallbacks { find_template(layout) } : find_template(layout) rescue ActionView::MissingTemplate => e update_details(:formats => nil) do raise unless template_exists?(layout) diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb index 96c0b4fe6a..d11f1fa2a7 100644 --- a/actionpack/lib/action_view/render/rendering.rb +++ b/actionpack/lib/action_view/render/rendering.rb @@ -63,7 +63,7 @@ module ActionView elsif options.key?(:text) Template::Text.new(options[:text], self.formats.try(:first)) elsif options.key?(:file) - find_template(options[:file], options[:_prefix]) + with_fallbacks { find_template(options[:file], options[:_prefix]) } elsif options.key?(:template) find_template(options[:template], options[:_prefix]) end diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb index 40326f9193..fde13a4bdf 100644 --- a/actionpack/lib/action_view/template/resolver.rb +++ b/actionpack/lib/action_view/template/resolver.rb @@ -4,7 +4,6 @@ require "active_support/core_ext/array/wrap" require "action_view/template" module ActionView - # Abstract superclass class Resolver class_inheritable_accessor(:registered_details) @@ -30,7 +29,7 @@ module ActionView find_all(*args).first end - # Normalizes the arguments and passes it on to find_template + # Normalizes the arguments and passes it on to find_template. def find_all(name, details = {}, prefix = nil, partial = nil) details = normalize_details(details) name, prefix = normalize_name(name, prefix) @@ -82,21 +81,20 @@ module ActionView end class PathResolver < Resolver - EXTENSION_ORDER = [:locale, :formats, :handlers] def to_s @path.to_s end - alias to_path to_s + alias :to_path :to_s + + private def find_templates(name, details, prefix, partial) path = build_path(name, details, prefix, partial) query(path, EXTENSION_ORDER.map { |ext| details[ext] }) end - private - def build_path(name, details, prefix, partial) path = "" path << "#{prefix}/" unless prefix.empty? @@ -141,25 +139,10 @@ module ActionView super() @path = Pathname.new(path).expand_path end - end - - # TODO: remove hack - class FileSystemResolverWithFallback < Resolver - def initialize(path) - super() - @paths = [FileSystemResolver.new(path), FileSystemResolver.new(""), FileSystemResolver.new("/")] - end - def find_templates(*args) - @paths.each do |p| - template = p.find_templates(*args) - return template unless template.empty? - end - [] - end - - def to_s - @paths.first.to_s + def eql?(resolver) + self.class.equal?(resolver.class) && to_path == resolver.to_path end + alias :== :eql? end end diff --git a/actionpack/test/template/compiled_templates_test.rb b/actionpack/test/template/compiled_templates_test.rb index 632988bb2e..0a3409064f 100644 --- a/actionpack/test/template/compiled_templates_test.rb +++ b/actionpack/test/template/compiled_templates_test.rb @@ -44,7 +44,7 @@ class CompiledTemplatesTest < Test::Unit::TestCase end def render_without_cache(*args) - path = ActionView::FileSystemResolverWithFallback.new(FIXTURE_LOAD_PATH) + path = ActionView::FileSystemResolver.new(FIXTURE_LOAD_PATH) view_paths = ActionView::Base.process_view_paths(path) ActionView::Base.new(view_paths, {}).render(*args) end diff --git a/actionpack/test/template/render_test.rb b/actionpack/test/template/render_test.rb index 6dbadc9304..37a3975a54 100644 --- a/actionpack/test/template/render_test.rb +++ b/actionpack/test/template/render_test.rb @@ -270,7 +270,7 @@ class CachedViewRenderTest < ActiveSupport::TestCase # Ensure view path cache is primed def setup view_paths = ActionController::Base.view_paths - assert_equal ActionView::FileSystemResolverWithFallback, view_paths.first.class + assert_equal ActionView::FileSystemResolver, view_paths.first.class setup_view(view_paths) end end @@ -281,9 +281,9 @@ class LazyViewRenderTest < ActiveSupport::TestCase # Test the same thing as above, but make sure the view path # is not eager loaded def setup - path = ActionView::FileSystemResolverWithFallback.new(FIXTURE_LOAD_PATH) + path = ActionView::FileSystemResolver.new(FIXTURE_LOAD_PATH) view_paths = ActionView::Base.process_view_paths(path) - assert_equal ActionView::FileSystemResolverWithFallback, view_paths.first.class + assert_equal ActionView::FileSystemResolver.new(FIXTURE_LOAD_PATH), view_paths.first setup_view(view_paths) end end -- cgit v1.2.3 From 67a6725bf934452219cc054c8cd0535148d4fcd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Mon, 8 Mar 2010 16:50:10 +0100 Subject: Move ViewPaths module to its own file. --- actionpack/lib/abstract_controller.rb | 1 + actionpack/lib/abstract_controller/rendering.rb | 71 +----------------------- actionpack/lib/abstract_controller/view_paths.rb | 69 +++++++++++++++++++++++ 3 files changed, 71 insertions(+), 70 deletions(-) create mode 100644 actionpack/lib/abstract_controller/view_paths.rb (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller.rb b/actionpack/lib/abstract_controller.rb index 05348d8ba0..7028cd0379 100644 --- a/actionpack/lib/abstract_controller.rb +++ b/actionpack/lib/abstract_controller.rb @@ -19,4 +19,5 @@ module AbstractController autoload :Logger autoload :Rendering autoload :Translation + autoload :ViewPaths end diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb index 840f0b6c78..46a457e3f4 100644 --- a/actionpack/lib/abstract_controller/rendering.rb +++ b/actionpack/lib/abstract_controller/rendering.rb @@ -1,5 +1,4 @@ require "abstract_controller/base" -require "active_support/core_ext/array/wrap" module AbstractController class DoubleRenderError < Error @@ -10,74 +9,6 @@ module AbstractController end end - module ViewPaths - extend ActiveSupport::Concern - - included do - class_attribute :_view_paths - self._view_paths = ActionView::PathSet.new - end - - delegate :find_template, :template_exists?, - :view_paths, :formats, :formats=, :to => :lookup_context - - # LookupContext is the object responsible to hold all information required to lookup - # templates, i.e. view paths and details. Check ActionView::LookupContext for more - # information. - def lookup_context - @lookup_context ||= ActionView::LookupContext.new(self.class._view_paths, details_for_lookup) - end - - def details_for_lookup - { } - end - - def append_view_path(path) - lookup_context.view_paths.push(*path) - end - - def prepend_view_path(path) - lookup_context.view_paths.unshift(*path) - end - - module ClassMethods - # Append a path to the list of view paths for this controller. - # - # ==== Parameters - # path:: If a String is provided, it gets converted into - # the default view path. You may also provide a custom view path - # (see ActionView::ViewPathSet for more information) - def append_view_path(path) - self.view_paths = view_paths.dup + Array(path) - end - - # Prepend a path to the list of view paths for this controller. - # - # ==== Parameters - # path:: If a String is provided, it gets converted into - # the default view path. You may also provide a custom view path - # (see ActionView::ViewPathSet for more information) - def prepend_view_path(path) - self.view_paths = Array(path) + view_paths.dup - end - - # A list of all of the default view paths for this controller. - def view_paths - _view_paths - end - - # Set the view paths. - # - # ==== Parameters - # paths:: If a ViewPathSet is provided, use that; - # otherwise, process the parameter into a ViewPathSet. - def view_paths=(paths) - self._view_paths = paths.is_a?(ActionView::PathSet) ? paths : ActionView::Base.process_view_paths(paths) - self._view_paths.freeze - end - end - end - module Rendering extend ActiveSupport::Concern include AbstractController::ViewPaths @@ -166,7 +97,7 @@ module AbstractController end if (options.keys & [:partial, :file, :template]).empty? - options[:_prefix] ||= _prefix + options[:_prefix] ||= _prefix end options[:template] ||= (options[:action] || action_name).to_s diff --git a/actionpack/lib/abstract_controller/view_paths.rb b/actionpack/lib/abstract_controller/view_paths.rb new file mode 100644 index 0000000000..ec8f31cdfe --- /dev/null +++ b/actionpack/lib/abstract_controller/view_paths.rb @@ -0,0 +1,69 @@ +module AbstractController + module ViewPaths + extend ActiveSupport::Concern + + included do + class_attribute :_view_paths + self._view_paths = ActionView::PathSet.new + end + + delegate :find_template, :template_exists?, + :view_paths, :formats, :formats=, :to => :lookup_context + + # LookupContext is the object responsible to hold all information required to lookup + # templates, i.e. view paths and details. Check ActionView::LookupContext for more + # information. + def lookup_context + @lookup_context ||= ActionView::LookupContext.new(self.class._view_paths, details_for_lookup) + end + + def details_for_lookup + { } + end + + def append_view_path(path) + lookup_context.view_paths.push(*path) + end + + def prepend_view_path(path) + lookup_context.view_paths.unshift(*path) + end + + module ClassMethods + # Append a path to the list of view paths for this controller. + # + # ==== Parameters + # path:: If a String is provided, it gets converted into + # the default view path. You may also provide a custom view path + # (see ActionView::ViewPathSet for more information) + def append_view_path(path) + self.view_paths = view_paths.dup + Array(path) + end + + # Prepend a path to the list of view paths for this controller. + # + # ==== Parameters + # path:: If a String is provided, it gets converted into + # the default view path. You may also provide a custom view path + # (see ActionView::ViewPathSet for more information) + def prepend_view_path(path) + self.view_paths = Array(path) + view_paths.dup + end + + # A list of all of the default view paths for this controller. + def view_paths + _view_paths + end + + # Set the view paths. + # + # ==== Parameters + # paths:: If a ViewPathSet is provided, use that; + # otherwise, process the parameter into a ViewPathSet. + def view_paths=(paths) + self._view_paths = paths.is_a?(ActionView::PathSet) ? paths : ActionView::Base.process_view_paths(paths) + self._view_paths.freeze + end + end + end +end \ No newline at end of file -- cgit v1.2.3 From bdf5096816d03f2bdaefd20a07a0fa562543549c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Mon, 8 Mar 2010 20:39:15 +0100 Subject: Move details to lookup_context and make resolvers use the cache key. --- actionpack/lib/abstract_controller/rendering.rb | 10 -- actionpack/lib/action_view/lookup_context.rb | 157 ++++++++++++++++-------- actionpack/lib/action_view/paths.rb | 4 +- actionpack/lib/action_view/template/resolver.rb | 46 ++----- actionpack/test/abstract/render_test.rb | 42 +------ 5 files changed, 118 insertions(+), 141 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb index 46a457e3f4..77c554fa3f 100644 --- a/actionpack/lib/abstract_controller/rendering.rb +++ b/actionpack/lib/abstract_controller/rendering.rb @@ -101,19 +101,9 @@ module AbstractController end options[:template] ||= (options[:action] || action_name).to_s - - details = _normalize_details(options) - lookup_context.update_details(details) options end - def _normalize_details(options) - details = {} - details[:formats] = Array(options[:format]) if options[:format] - details[:locale] = Array(options[:locale]) if options[:locale] - details - end - def _process_options(options) end diff --git a/actionpack/lib/action_view/lookup_context.rb b/actionpack/lib/action_view/lookup_context.rb index e259a78c5c..231882185f 100644 --- a/actionpack/lib/action_view/lookup_context.rb +++ b/actionpack/lib/action_view/lookup_context.rb @@ -1,14 +1,30 @@ +require 'active_support/core_ext/object/try' + module ActionView # LookupContext is the object responsible to hold all information required to lookup # templates, i.e. view paths and details. The LookupContext is also responsible to # generate a key, given to view paths, used in the resolver cache lookup. Since # this key is generated just once during the request, it speeds up all cache accesses. class LookupContext #:nodoc: - attr_reader :details, :view_paths - mattr_accessor :fallbacks @@fallbacks = [FileSystemResolver.new(""), FileSystemResolver.new("/")] + mattr_accessor :registered_details + self.registered_details = {} + + def self.register_detail(name, options = {}) + registered_details[name] = lambda do |value| + value = (value.blank? || options[:accessible] == false) ? + Array(yield) : Array(value) + value |= [nil] unless options[:allow_nil] == false + value + end + end + + register_detail(:formats) { Mime::SET.symbols } + register_detail(:locale, :accessible => false) { [I18n.locale] } + register_detail(:handlers, :accessible => false) { Template::Handlers.extensions } + class DetailsKey #:nodoc: attr_reader :details alias :eql? :equal? @@ -22,75 +38,108 @@ module ActionView def initialize(details) @details, @hash = details, details.hash end + + def outdated?(details) + @details != details + end end def initialize(view_paths, details = {}) - @details, @details_key = details, nil self.view_paths = view_paths + self.details = details + @details_key = nil end - # Shortcut to read formats from details. - def formats - @details[:formats] - end - - # Shortcut to set formats in details. - def formats=(value) - self.details = @details.merge(:formats => Array(value)) - end + module ViewPaths + attr_reader :view_paths - # Whenever setting view paths, makes a copy so we can manipulate then in - # instance objects as we wish. - def view_paths=(paths) - @view_paths = ActionView::Base.process_view_paths(paths) - end + # Whenever setting view paths, makes a copy so we can manipulate then in + # instance objects as we wish. + def view_paths=(paths) + @view_paths = ActionView::Base.process_view_paths(paths) + end - # Setter for details. Everything this method is invoked, we need to nullify - # the details key if it changed. - def details=(details) - @details = details - @details_key = nil if @details_key && @details_key.details != details - end + def find_template(name, prefix = nil, partial = false) + key = details_key + @view_paths.find(name, key.details, prefix, partial || false, key) + end - def details_key - @details_key ||= DetailsKey.get(details) unless details.empty? - end + def template_exists?(name, prefix = nil, partial = false) + key = details_key + @view_paths.exists?(name, key.details, prefix, partial || false, key) + end - # Update the details keys by merging the given hash into the current - # details hash. If a block is given, the details are modified just during - # the execution of the block and reverted to the previous value after. - def update_details(new_details) - old_details = self.details - self.details = old_details.merge(new_details) - - if block_given? - begin - yield - ensure - self.details = old_details + # Add fallbacks to the view paths. Useful in cases you are rendering a file. + def with_fallbacks + added_resolvers = 0 + self.class.fallbacks.each do |resolver| + next if view_paths.include?(resolver) + view_paths.push(resolver) + added_resolvers += 1 end + yield + ensure + added_resolvers.times { view_paths.pop } end end - # Added fallbacks to the view paths. Useful in cases you are rendering a file. - def with_fallbacks - added_resolvers = 0 - self.class.fallbacks.each do |resolver| - next if view_paths.include?(resolver) - view_paths.push(resolver) - added_resolvers += 1 + module Details + def details + @details = normalize_details(@details) end - yield - ensure - added_resolvers.times { view_paths.pop } - end - def find_template(name, prefix = nil, partial = false) - @view_paths.find(name, details, prefix, partial || false, details_key) - end + def details=(new_details) + @details = new_details + details + end - def template_exists?(name, prefix = nil, partial = false) - @view_paths.exists?(name, details, prefix, partial || false, details_key) + # TODO This is too expensive. Revisit this. + def details_key + latest_details = self.details + @details_key = nil if @details_key.try(:outdated?, latest_details) + @details_key ||= DetailsKey.get(latest_details) + end + + # Shortcut to read formats from details. + def formats + self.details[:formats] + end + + # Shortcut to set formats in details. + def formats=(value) + self.details = @details.merge(:formats => value) + end + + # Update the details keys by merging the given hash into the current + # details hash. If a block is given, the details are modified just during + # the execution of the block and reverted to the previous value after. + def update_details(new_details) + old_details = self.details + self.details = old_details.merge(new_details) + + if block_given? + begin + yield + ensure + self.details = old_details + end + end + end + + protected + + def normalize_details(details) + details = details.dup + # TODO: Refactor this concern out of the resolver + details.delete(:formats) if details[:formats] == [:"*/*"] + self.class.registered_details.each do |k, v| + details[k] = v.call(details[k]) + end + details + end end + + include Details + include ViewPaths end end \ No newline at end of file diff --git a/actionpack/lib/action_view/paths.rb b/actionpack/lib/action_view/paths.rb index 628546e443..1205d26e3b 100644 --- a/actionpack/lib/action_view/paths.rb +++ b/actionpack/lib/action_view/paths.rb @@ -11,7 +11,7 @@ module ActionView #:nodoc: def find(path, details = {}, prefix = nil, partial = false, key=nil) each do |resolver| - if template = resolver.find(path, details, prefix, partial) + if template = resolver.find(path, details, prefix, partial, key) return template end end @@ -21,7 +21,7 @@ module ActionView #:nodoc: def exists?(path, details = {}, prefix = nil, partial = false, key=nil) each do |resolver| - if resolver.find(path, details, prefix, partial) + if resolver.find(path, details, prefix, partial, key) return true end end diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb index fde13a4bdf..9a011f7638 100644 --- a/actionpack/lib/action_view/template/resolver.rb +++ b/actionpack/lib/action_view/template/resolver.rb @@ -5,24 +5,9 @@ require "action_view/template" module ActionView class Resolver - - class_inheritable_accessor(:registered_details) - self.registered_details = {} - - def self.register_detail(name, options = {}) - registered_details[name] = lambda do |val| - val = Array.wrap(val || yield) - val |= [nil] unless options[:allow_nil] == false - val - end - end - - register_detail(:locale) { [I18n.locale] } - register_detail(:formats) { Mime::SET.symbols } - register_detail(:handlers) { Template::Handlers.extensions } - def initialize - @cached = {} + @cached = Hash.new { |h1,k1| h1[k1] = + Hash.new { |h2,k2| h2[k2] = Hash.new { |h3, k3| h3[k3] = {} } } } end def find(*args) @@ -30,11 +15,10 @@ module ActionView end # Normalizes the arguments and passes it on to find_template. - def find_all(name, details = {}, prefix = nil, partial = nil) - details = normalize_details(details) + def find_all(name, details = {}, prefix = nil, partial = nil, key=nil) name, prefix = normalize_name(name, prefix) - cached([name, details, prefix, partial]) do + cached(key, prefix, name, partial) do find_templates(name, details, prefix, partial) end end @@ -52,16 +36,6 @@ module ActionView raise NotImplementedError end - def normalize_details(details) - details = details.dup - # TODO: Refactor this concern out of the resolver - details.delete(:formats) if details[:formats] == [:"*/*"] - registered_details.each do |k, v| - details[k] = v.call(details[k]) - end - details - end - # Support legacy foo.erb names even though we now ignore .erb # as well as incorrectly putting part of the path in the template # name instead of the prefix. @@ -73,10 +47,14 @@ module ActionView return parts.pop, [prefix, *parts].compact.join("/") end - def cached(key) - return yield unless caching? - return @cached[key] if @cached.key?(key) - @cached[key] = yield + def cached(key, prefix, name, partial) + return yield unless key && caching? + scope = @cached[key][prefix][name] + if scope.key?(partial) + scope[partial] + else + scope[partial] = yield + end end end diff --git a/actionpack/test/abstract/render_test.rb b/actionpack/test/abstract/render_test.rb index e54d056666..25dc8bd804 100644 --- a/actionpack/test/abstract/render_test.rb +++ b/actionpack/test/abstract/render_test.rb @@ -16,11 +16,7 @@ module AbstractController "renderer/string.erb" => "With String", "renderer/symbol.erb" => "With Symbol", "string/with_path.erb" => "With String With Path", - "some/file.erb" => "With File", - "with_format.html.erb" => "With html format", - "with_format.xml.erb" => "With xml format", - "with_locale.en.erb" => "With en locale", - "with_locale.pl.erb" => "With pl locale" + "some/file.erb" => "With File" )] def template @@ -54,22 +50,6 @@ module AbstractController def symbol render :symbol end - - def with_html_format - render :template => "with_format", :format => :html - end - - def with_xml_format - render :template => "with_format", :format => :xml - end - - def with_en_locale - render :template => "with_locale" - end - - def with_pl_locale - render :template => "with_locale", :locale => :pl - end end class TestRenderer < ActiveSupport::TestCase @@ -117,26 +97,6 @@ module AbstractController @controller.process(:string_with_path) assert_equal "With String With Path", @controller.response_body end - - def test_render_with_html_format - @controller.process(:with_html_format) - assert_equal "With html format", @controller.response_body - end - - def test_render_with_xml_format - @controller.process(:with_xml_format) - assert_equal "With xml format", @controller.response_body - end - - def test_render_with_en_locale - @controller.process(:with_en_locale) - assert_equal "With en locale", @controller.response_body - end - - def test_render_with_pl_locale - @controller.process(:with_pl_locale) - assert_equal "With pl locale", @controller.response_body - end end end end -- cgit v1.2.3 From 36eb1a686c831d5a14998bb9ac7cc60efa363373 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Mon, 8 Mar 2010 20:57:33 +0100 Subject: Bring AM up to date with new rendering stack. --- actionpack/lib/action_view/lookup_context.rb | 5 +++++ actionpack/lib/action_view/paths.rb | 8 ++++++++ actionpack/lib/action_view/render/rendering.rb | 2 ++ 3 files changed, 15 insertions(+) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/lookup_context.rb b/actionpack/lib/action_view/lookup_context.rb index 231882185f..608f1ef818 100644 --- a/actionpack/lib/action_view/lookup_context.rb +++ b/actionpack/lib/action_view/lookup_context.rb @@ -64,6 +64,11 @@ module ActionView @view_paths.find(name, key.details, prefix, partial || false, key) end + def find_all(name, prefix = nil, partial = false) + key = details_key + @view_paths.find_all(name, key.details, prefix, partial || false, key) + end + def template_exists?(name, prefix = nil, partial = false) key = details_key @view_paths.exists?(name, key.details, prefix, partial || false, key) diff --git a/actionpack/lib/action_view/paths.rb b/actionpack/lib/action_view/paths.rb index 1205d26e3b..82a9f9a13c 100644 --- a/actionpack/lib/action_view/paths.rb +++ b/actionpack/lib/action_view/paths.rb @@ -9,6 +9,14 @@ module ActionView #:nodoc: METHOD end + def find_all(path, details = {}, prefix = nil, partial = false, key=nil) + each do |resolver| + templates = resolver.find_all(path, details, prefix, partial, key) + return templates unless templates.empty? + end + [] + end + def find(path, details = {}, prefix = nil, partial = false, key=nil) each do |resolver| if template = resolver.find(path, details, prefix, partial, key) diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb index d11f1fa2a7..0322d4b641 100644 --- a/actionpack/lib/action_view/render/rendering.rb +++ b/actionpack/lib/action_view/render/rendering.rb @@ -64,6 +64,8 @@ module ActionView Template::Text.new(options[:text], self.formats.try(:first)) elsif options.key?(:file) with_fallbacks { find_template(options[:file], options[:_prefix]) } + elsif options.key?(:_template) + options[:_template] elsif options.key?(:template) find_template(options[:template], options[:_prefix]) end -- cgit v1.2.3 From f38e2e03351da463f84f6850fa10718ece98ff26 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Mon, 8 Mar 2010 12:24:49 -0800 Subject: Add support for mount RackApp, :at => "/sprockets" with a shorthand of mount Sprockets => "/sprockets". This is different from the match syntax in that it cannot be used for controller/action and it does not assume an anchor at the end of the match. For instance, in the above example, if the client asked for "/sprockets/foo.js", the Sprockets app would have a SCRIPT_NAME of "/sprockets" and PATH_INFO of "/foo.js". --- actionpack/lib/action_dispatch/routing/mapper.rb | 27 ++++++++++++---- actionpack/lib/action_dispatch/routing/route.rb | 4 +-- .../lib/action_dispatch/routing/route_set.rb | 4 +-- actionpack/test/dispatch/mount_test.rb | 36 ++++++++++++++++++++++ 4 files changed, 61 insertions(+), 10 deletions(-) create mode 100644 actionpack/test/dispatch/mount_test.rb (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 7a33259054..e6c563d7b7 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -1,5 +1,3 @@ -require "active_support/core_ext/hash/except" - module ActionDispatch module Routing class Mapper @@ -38,7 +36,7 @@ module ActionDispatch end def to_route - [ app, conditions, requirements, defaults, @options[:as] ] + [ app, conditions, requirements, defaults, @options[:as], @options[:anchor] ] end private @@ -66,7 +64,7 @@ module ActionDispatch # match "account/overview" def using_match_shorthand?(args, options) - args.present? && options.except(:via).empty? && !args.first.include?(':') + args.present? && options.except(:via, :anchor).empty? && !args.first.include?(':') end def normalize_path(path) @@ -87,7 +85,7 @@ module ActionDispatch end def requirements - @requirements ||= (@options[:constraints] || {}).tap do |requirements| + @requirements ||= returning(@options[:constraints] || {}) do |requirements| requirements.reverse_merge!(@scope[:constraints]) if @scope[:constraints] @options.each { |k, v| requirements[k] = v if v.is_a?(Regexp) } end @@ -176,7 +174,8 @@ module ActionDispatch end def match(*args) - @set.add_route(*Mapping.new(@set, @scope, args).to_route) + mapping = Mapping.new(@set, @scope, args).to_route + @set.add_route(*mapping) self end end @@ -295,6 +294,7 @@ module ActionDispatch options = args.extract_options! options = (@scope[:options] || {}).merge(options) + options[:anchor] = true unless options.key?(:anchor) if @scope[:name_prefix] && !options[:as].blank? options[:as] = "#{@scope[:name_prefix]}_#{options[:as]}" @@ -538,6 +538,21 @@ module ActionDispatch end end + def mount(app, options = nil) + if options + path = options.delete(:at) + else + options = app + app, path = options.find { |k, v| k.respond_to?(:call) } + options.delete(app) if app + end + + raise "A rack application must be specified" unless path + + match(path, options.merge(:to => app, :anchor => false)) + self + end + def match(*args) options = args.extract_options! diff --git a/actionpack/lib/action_dispatch/routing/route.rb b/actionpack/lib/action_dispatch/routing/route.rb index e6e44d3546..6f37eadd6b 100644 --- a/actionpack/lib/action_dispatch/routing/route.rb +++ b/actionpack/lib/action_dispatch/routing/route.rb @@ -4,7 +4,7 @@ module ActionDispatch attr_reader :app, :conditions, :defaults, :name attr_reader :path, :requirements - def initialize(app, conditions = {}, requirements = {}, defaults = {}, name = nil) + def initialize(app, conditions, requirements, defaults, name, anchor) @app = app @defaults = defaults @name = name @@ -17,7 +17,7 @@ module ActionDispatch if path = conditions[:path_info] @path = path - conditions[:path_info] = ::Rack::Mount::Strexp.compile(path, requirements, SEPARATORS) + conditions[:path_info] = ::Rack::Mount::Strexp.compile(path, requirements, SEPARATORS, anchor) end @conditions = conditions.inject({}) { |h, (k, v)| diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 5c246d8781..550e54e955 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -293,8 +293,8 @@ module ActionDispatch routes.empty? end - def add_route(app, conditions = {}, requirements = {}, defaults = {}, name = nil) - route = Route.new(app, conditions, requirements, defaults, name) + def add_route(app, conditions = {}, requirements = {}, defaults = {}, name = nil, anchor = true) + route = Route.new(app, conditions, requirements, defaults, name, anchor) @set.add_route(*route) named_routes[name] = route if name routes << route diff --git a/actionpack/test/dispatch/mount_test.rb b/actionpack/test/dispatch/mount_test.rb new file mode 100644 index 0000000000..f89e5fda07 --- /dev/null +++ b/actionpack/test/dispatch/mount_test.rb @@ -0,0 +1,36 @@ +require 'abstract_unit' + +class TestRoutingMount < ActionDispatch::IntegrationTest + SprocketsApp = lambda { |env| + [200, {"Content-Type" => "text/html"}, ["#{env["SCRIPT_NAME"]} -- #{env["PATH_INFO"]}"]] + } + + Router = ActionDispatch::Routing::RouteSet.new + Router.draw do + mount SprocketsApp, :at => "/sprockets" + mount SprocketsApp => "/shorthand" + + scope "/its_a" do + mount SprocketsApp, :at => "/sprocket" + end + end + + def app + Router + end + + def test_mounting_sets_script_name + get "/sprockets/omg" + assert_equal "/sprockets -- /omg", response.body + end + + def test_mounting_works_with_scope + get "/its_a/sprocket/omg" + assert_equal "/its_a/sprocket -- /omg", response.body + end + + def test_mounting_with_shorthand + get "/shorthand/omg" + assert_equal "/shorthand -- /omg", response.body + end +end \ No newline at end of file -- cgit v1.2.3 From 0045f37681acdb8fe844fb8118e93cfe9d73140d Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Mon, 8 Mar 2010 12:30:51 -0800 Subject: Whoops. We meant to switch from returning to tap, not vice versa --- actionpack/lib/action_dispatch/routing/mapper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index e6c563d7b7..dee4516fbe 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -85,7 +85,7 @@ module ActionDispatch end def requirements - @requirements ||= returning(@options[:constraints] || {}) do |requirements| + @requirements ||= (@options[:constraints] || {}).tap do |requirements| requirements.reverse_merge!(@scope[:constraints]) if @scope[:constraints] @options.each { |k, v| requirements[k] = v if v.is_a?(Regexp) } end -- cgit v1.2.3 From 01f0e47663bbbc593af0c36d4cf49124b200e3d8 Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Mon, 8 Mar 2010 14:02:41 -0800 Subject: Move request forgery protection configuration to the AC config object This is an interim solution pending revisiting the rails framework configuration situation. --- .../metal/request_forgery_protection.rb | 45 ++++++++++++++++++++-- actionpack/lib/action_controller/railtie.rb | 5 ++- 2 files changed, 44 insertions(+), 6 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/request_forgery_protection.rb b/actionpack/lib/action_controller/metal/request_forgery_protection.rb index 276c703307..6765314df2 100644 --- a/actionpack/lib/action_controller/metal/request_forgery_protection.rb +++ b/actionpack/lib/action_controller/metal/request_forgery_protection.rb @@ -12,11 +12,10 @@ module ActionController #:nodoc: included do # Sets the token parameter name for RequestForgery. Calling +protect_from_forgery+ # sets it to :authenticity_token by default. - cattr_accessor :request_forgery_protection_token + config.request_forgery_protection_token ||= true # Controls whether request forgergy protection is turned on or not. Turned off by default only in test mode. - class_attribute :allow_forgery_protection - self.allow_forgery_protection = true + config.allow_forgery_protection ||= true helper_method :form_authenticity_token helper_method :protect_against_forgery? @@ -80,9 +79,47 @@ module ActionController #:nodoc: self.request_forgery_protection_token ||= :authenticity_token before_filter :verify_authenticity_token, options end + + def request_forgery_protection_token + config.request_forgery_protection_token + end + + def request_forgery_protection_token=(val) + config.request_forgery_protection_token = val + end + + def allow_forgery_protection + config.allow_forgery_protection + end + + def allow_forgery_protection=(val) + config.allow_forgery_protection = val + end end protected + + def protect_from_forgery(options = {}) + self.request_forgery_protection_token ||= :authenticity_token + before_filter :verify_authenticity_token, options + end + + def request_forgery_protection_token + config.request_forgery_protection_token + end + + def request_forgery_protection_token=(val) + config.request_forgery_protection_token = val + end + + def allow_forgery_protection + config.allow_forgery_protection + end + + def allow_forgery_protection=(val) + config.allow_forgery_protection = val + end + # The actual before_filter that is used. Modify this to change how you handle unverified requests. def verify_authenticity_token verified_request? || raise(ActionController::InvalidAuthenticityToken) @@ -109,7 +146,7 @@ module ActionController #:nodoc: end def protect_against_forgery? - self.class.allow_forgery_protection + config.allow_forgery_protection end end end diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb index ca03fc62da..6a3afbb157 100644 --- a/actionpack/lib/action_controller/railtie.rb +++ b/actionpack/lib/action_controller/railtie.rb @@ -46,10 +46,11 @@ module ActionController initializer "action_controller.set_configs" do |app| paths = app.config.paths ac = app.config.action_controller - ac.assets_dir = paths.public.to_a.first + + ac.assets_dir = paths.public.to_a.first ac.javascripts_dir = paths.public.javascripts.to_a.first ac.stylesheets_dir = paths.public.stylesheets.to_a.first - ac.secret = app.config.cookie_secret + ac.secret = app.config.cookie_secret ActionController.base_hook { self.config.replace(ac) } end -- cgit v1.2.3 From 8f082ff4217175f52234f2223658619a9c923afc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Mon, 8 Mar 2010 23:13:24 +0100 Subject: Clean LookupContext API. --- actionpack/lib/abstract_controller/rendering.rb | 2 +- actionpack/lib/abstract_controller/view_paths.rb | 7 ++++-- .../lib/action_controller/metal/compatibility.rb | 3 ++- actionpack/lib/action_view/base.rb | 2 +- actionpack/lib/action_view/lookup_context.rb | 10 ++++---- actionpack/lib/action_view/paths.rb | 29 ++++++++-------------- actionpack/lib/action_view/render/layouts.rb | 4 +-- actionpack/lib/action_view/render/partials.rb | 2 +- actionpack/lib/action_view/render/rendering.rb | 8 +++--- actionpack/lib/action_view/template/resolver.rb | 16 +++++++----- actionpack/test/controller/render_test.rb | 6 ++--- 11 files changed, 43 insertions(+), 46 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb index 77c554fa3f..5048754e33 100644 --- a/actionpack/lib/abstract_controller/rendering.rb +++ b/actionpack/lib/abstract_controller/rendering.rb @@ -97,7 +97,7 @@ module AbstractController end if (options.keys & [:partial, :file, :template]).empty? - options[:_prefix] ||= _prefix + options[:prefix] ||= _prefix end options[:template] ||= (options[:action] || action_name).to_s diff --git a/actionpack/lib/abstract_controller/view_paths.rb b/actionpack/lib/abstract_controller/view_paths.rb index ec8f31cdfe..6513c0778e 100644 --- a/actionpack/lib/abstract_controller/view_paths.rb +++ b/actionpack/lib/abstract_controller/view_paths.rb @@ -7,8 +7,7 @@ module AbstractController self._view_paths = ActionView::PathSet.new end - delegate :find_template, :template_exists?, - :view_paths, :formats, :formats=, :to => :lookup_context + delegate :template_exists?, :view_paths, :formats, :formats=, :to => :lookup_context # LookupContext is the object responsible to hold all information required to lookup # templates, i.e. view paths and details. Check ActionView::LookupContext for more @@ -29,6 +28,10 @@ module AbstractController lookup_context.view_paths.unshift(*path) end + def template_exists?(*args) + lookup_context.exists?(*args) + end + module ClassMethods # Append a path to the list of view paths for this controller. # diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb index 5cad0814ca..ab8d87b2c4 100644 --- a/actionpack/lib/action_controller/metal/compatibility.rb +++ b/actionpack/lib/action_controller/metal/compatibility.rb @@ -50,8 +50,9 @@ module ActionController end def _normalize_options(options) - # TODO Deprecate this. Rails 2.x allowed to give a template as action. if options[:action] && options[:action].to_s.include?(?/) + ActiveSupport::Deprecation.warn "Giving a path to render :action is deprecated. " << + "Please use render :template instead", caller options[:template] = options.delete(:action) end diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 38413560f3..564ea6684c 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -194,7 +194,7 @@ module ActionView #:nodoc: attr_accessor :base_path, :assigns, :template_extension, :lookup_context attr_internal :captures, :request, :layout, :controller, :template, :config - delegate :find_template, :template_exists?, :formats, :formats=, + delegate :find, :exists?, :formats, :formats=, :view_paths, :view_paths=, :with_fallbacks, :update_details, :to => :lookup_context delegate :request_forgery_protection_token, :template, :params, :session, :cookies, :response, :headers, diff --git a/actionpack/lib/action_view/lookup_context.rb b/actionpack/lib/action_view/lookup_context.rb index 608f1ef818..4a4dc0d06c 100644 --- a/actionpack/lib/action_view/lookup_context.rb +++ b/actionpack/lib/action_view/lookup_context.rb @@ -59,19 +59,19 @@ module ActionView @view_paths = ActionView::Base.process_view_paths(paths) end - def find_template(name, prefix = nil, partial = false) + def find(name, prefix = nil, partial = false) key = details_key - @view_paths.find(name, key.details, prefix, partial || false, key) + @view_paths.find(name, prefix, partial || false, key.details, key) end def find_all(name, prefix = nil, partial = false) key = details_key - @view_paths.find_all(name, key.details, prefix, partial || false, key) + @view_paths.find_all(name, prefix, partial || false, key.details, key) end - def template_exists?(name, prefix = nil, partial = false) + def exists?(name, prefix = nil, partial = false) key = details_key - @view_paths.exists?(name, key.details, prefix, partial || false, key) + @view_paths.exists?(name, prefix, partial || false, key.details, key) end # Add fallbacks to the view paths. Useful in cases you are rendering a file. diff --git a/actionpack/lib/action_view/paths.rb b/actionpack/lib/action_view/paths.rb index 82a9f9a13c..35927d09d1 100644 --- a/actionpack/lib/action_view/paths.rb +++ b/actionpack/lib/action_view/paths.rb @@ -9,31 +9,22 @@ module ActionView #:nodoc: METHOD end - def find_all(path, details = {}, prefix = nil, partial = false, key=nil) + def find(path, prefix = nil, partial = false, details = {}, key = nil) + template = find_all(path, prefix, partial, details, key).first + raise MissingTemplate.new(self, "#{prefix}/#{path}", details, partial) unless template + template + end + + def find_all(*args) each do |resolver| - templates = resolver.find_all(path, details, prefix, partial, key) + templates = resolver.find_all(*args) return templates unless templates.empty? end [] end - def find(path, details = {}, prefix = nil, partial = false, key=nil) - each do |resolver| - if template = resolver.find(path, details, prefix, partial, key) - return template - end - end - - raise ActionView::MissingTemplate.new(self, "#{prefix}/#{path}", details, partial) - end - - def exists?(path, details = {}, prefix = nil, partial = false, key=nil) - each do |resolver| - if resolver.find(path, details, prefix, partial, key) - return true - end - end - false + def exists?(*args) + find_all(*args).any? end protected diff --git a/actionpack/lib/action_view/render/layouts.rb b/actionpack/lib/action_view/render/layouts.rb index 91a92a833a..8688de3d18 100644 --- a/actionpack/lib/action_view/render/layouts.rb +++ b/actionpack/lib/action_view/render/layouts.rb @@ -49,10 +49,10 @@ module ActionView def _find_layout(layout) #:nodoc: begin layout =~ /^\// ? - with_fallbacks { find_template(layout) } : find_template(layout) + with_fallbacks { find(layout) } : find(layout) rescue ActionView::MissingTemplate => e update_details(:formats => nil) do - raise unless template_exists?(layout) + raise unless exists?(layout) end end end diff --git a/actionpack/lib/action_view/render/partials.rb b/actionpack/lib/action_view/render/partials.rb index 0fe2d560f7..950c9d2cd8 100644 --- a/actionpack/lib/action_view/render/partials.rb +++ b/actionpack/lib/action_view/render/partials.rb @@ -294,7 +294,7 @@ module ActionView def find_template(path=@path) return path unless path.is_a?(String) prefix = @view.controller_path unless path.include?(?/) - @view.find_template(path, prefix, true) + @view.find(path, prefix, true) end def partial_path(object = @object) diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb index 0322d4b641..47ea70f5ad 100644 --- a/actionpack/lib/action_view/render/rendering.rb +++ b/actionpack/lib/action_view/render/rendering.rb @@ -29,8 +29,6 @@ module ActionView end # This is the API to render a ViewContext's template from a controller. - # TODO Review this name since it does not render only templates, but also - # partials, files and so forth. def render_template(options, &block) _evaluate_assigns_and_ivars @@ -62,12 +60,12 @@ module ActionView Template.new(options[:inline], "inline template", handler, {}) elsif options.key?(:text) Template::Text.new(options[:text], self.formats.try(:first)) - elsif options.key?(:file) - with_fallbacks { find_template(options[:file], options[:_prefix]) } elsif options.key?(:_template) options[:_template] + elsif options.key?(:file) + with_fallbacks { find(options[:file], options[:prefix]) } elsif options.key?(:template) - find_template(options[:template], options[:_prefix]) + find(options[:template], options[:prefix]) end end diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb index 9a011f7638..6e6c4c21ee 100644 --- a/actionpack/lib/action_view/template/resolver.rb +++ b/actionpack/lib/action_view/template/resolver.rb @@ -10,16 +10,20 @@ module ActionView Hash.new { |h2,k2| h2[k2] = Hash.new { |h3, k3| h3[k3] = {} } } } end + def clear_cache + @cached.clear + end + def find(*args) find_all(*args).first end # Normalizes the arguments and passes it on to find_template. - def find_all(name, details = {}, prefix = nil, partial = nil, key=nil) + def find_all(name, prefix=nil, partial=false, details={}, key=nil) name, prefix = normalize_name(name, prefix) cached(key, prefix, name, partial) do - find_templates(name, details, prefix, partial) + find_templates(name, prefix, partial, details) end end @@ -32,7 +36,7 @@ module ActionView # This is what child classes implement. No defaults are needed # because Resolver guarantees that the arguments are present and # normalized. - def find_templates(name, details, prefix, partial) + def find_templates(name, prefix, partial, details) raise NotImplementedError end @@ -68,12 +72,12 @@ module ActionView private - def find_templates(name, details, prefix, partial) - path = build_path(name, details, prefix, partial) + def find_templates(name, prefix, partial, details) + path = build_path(name, prefix, partial, details) query(path, EXTENSION_ORDER.map { |ext| details[ext] }) end - def build_path(name, details, prefix, partial) + def build_path(name, prefix, partial, details) path = "" path << "#{prefix}/" unless prefix.empty? path << (partial ? "_#{name}" : name) diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb index ecfe14b797..e3c4869391 100644 --- a/actionpack/test/controller/render_test.rb +++ b/actionpack/test/controller/render_test.rb @@ -355,7 +355,7 @@ class TestController < ActionController::Base @before = "i'm before the render" render_to_string :text => "foo" @after = "i'm after the render" - render :action => "test/hello_world" + render :template => "test/hello_world" end def render_to_string_with_exception @@ -369,7 +369,7 @@ class TestController < ActionController::Base rescue end @after = "i'm after the render" - render :action => "test/hello_world" + render :template => "test/hello_world" end def accessing_params_in_template_with_layout @@ -514,7 +514,7 @@ class TestController < ActionController::Base def render_to_string_with_partial @partial_only = render_to_string :partial => "partial_only" @partial_with_locals = render_to_string :partial => "customer", :locals => { :customer => Customer.new("david") } - render :action => "test/hello_world" + render :template => "test/hello_world" end def partial_with_counter -- cgit v1.2.3 From 8e9d9232b0c3d96c662762e13848c275a86c0c61 Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Mon, 8 Mar 2010 14:22:25 -0800 Subject: Require 'active_support/core_ext/hash/except' in the router. --- actionpack/lib/action_dispatch/routing/mapper.rb | 2 ++ 1 file changed, 2 insertions(+) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index dee4516fbe..ae4470d033 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -1,3 +1,5 @@ +require 'active_support/core_ext/hash/except' + module ActionDispatch module Routing class Mapper -- cgit v1.2.3 From 146a5305d56b636d2fd2c2a09a58f5f3edc2d9c0 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Mon, 8 Mar 2010 15:57:07 -0800 Subject: Add memoizing to AD::Request --- actionpack/lib/action_dispatch/http/request.rb | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb index 56a2b9bf6a..ea9f0f99c2 100755 --- a/actionpack/lib/action_dispatch/http/request.rb +++ b/actionpack/lib/action_dispatch/http/request.rb @@ -30,6 +30,14 @@ module ActionDispatch METHOD end + def self.new(env) + if request = env["action_dispatch.request"] && request.instance_of?(self) + return request + end + + super + end + def key?(key) @env.key?(key) end -- cgit v1.2.3 From 056042eb829e0507ed605264d43a79ce88112288 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Mon, 8 Mar 2010 16:49:47 -0800 Subject: Simplify the action endpoint: * Remove ActionEndpoint in favor of passing a block to MiddlewareStack * Always create a Request; the performance win of RackDelegation is around the response; the Request object hit is limited to a single object allocation * #dispatch takes a Request --- actionpack/lib/action_controller/metal.rb | 34 ++++++---------------- .../lib/action_controller/metal/rack_delegation.rb | 5 +--- actionpack/lib/action_controller/middleware.rb | 3 +- actionpack/lib/action_dispatch/middleware/stack.rb | 6 +++- 4 files changed, 17 insertions(+), 31 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal.rb b/actionpack/lib/action_controller/metal.rb index 5e0ed201cb..eebd2c943a 100644 --- a/actionpack/lib/action_controller/metal.rb +++ b/actionpack/lib/action_controller/metal.rb @@ -34,7 +34,8 @@ module ActionController # and response object available. You might wish to control the # environment and response manually for performance reasons. - attr_internal :status, :headers, :content_type, :response + attr_internal :status, :headers, :content_type, :response, :request + delegate :session, :to => "@_request" def initialize(*) @_headers = {} @@ -66,8 +67,9 @@ module ActionController end # :api: private - def dispatch(name, env) - @_env = env + def dispatch(name, request) + @_request = request + @_env = request.env @_env['action_controller.instance'] = self process(name) to_a @@ -78,26 +80,6 @@ module ActionController response ? response.to_a : [status, headers, response_body] end - class ActionEndpoint - @@endpoints = Hash.new {|h,k| h[k] = Hash.new {|sh,sk| sh[sk] = {} } } - - def self.for(controller, action, stack) - @@endpoints[controller][action][stack] ||= begin - endpoint = new(controller, action) - stack.build(endpoint) - end - end - - def initialize(controller, action) - @controller, @action = controller, action - @_formats = [Mime::HTML] - end - - def call(env) - @controller.new.dispatch(@action, env) - end - end - class_attribute :middleware_stack self.middleware_stack = ActionDispatch::MiddlewareStack.new @@ -127,8 +109,10 @@ module ActionController # # ==== Returns # Proc:: A rack application - def self.action(name) - ActionEndpoint.for(self, name, middleware_stack) + def self.action(name, klass = ActionDispatch::Request) + middleware_stack.build do |env| + new.dispatch(name, klass.new(env)) + end end end end diff --git a/actionpack/lib/action_controller/metal/rack_delegation.rb b/actionpack/lib/action_controller/metal/rack_delegation.rb index bb55383631..37106733cb 100644 --- a/actionpack/lib/action_controller/metal/rack_delegation.rb +++ b/actionpack/lib/action_controller/metal/rack_delegation.rb @@ -6,14 +6,11 @@ module ActionController extend ActiveSupport::Concern included do - delegate :session, :to => "@_request" delegate :headers, :status=, :location=, :content_type=, :status, :location, :content_type, :to => "@_response" - attr_internal :request end - def dispatch(action, env) - @_request = ActionDispatch::Request.new(env) + def dispatch(action, request) @_response = ActionDispatch::Response.new @_response.request = request super diff --git a/actionpack/lib/action_controller/middleware.rb b/actionpack/lib/action_controller/middleware.rb index 17275793b7..2115b07b3e 100644 --- a/actionpack/lib/action_controller/middleware.rb +++ b/actionpack/lib/action_controller/middleware.rb @@ -6,7 +6,8 @@ module ActionController end def call(env) - @controller.build(@app).dispatch(:index, env) + request = ActionDispatch::Request.new(env) + @controller.build(@app).dispatch(:index, request) end end diff --git a/actionpack/lib/action_dispatch/middleware/stack.rb b/actionpack/lib/action_dispatch/middleware/stack.rb index c52c8c0e6a..5c5362ce4a 100644 --- a/actionpack/lib/action_dispatch/middleware/stack.rb +++ b/actionpack/lib/action_dispatch/middleware/stack.rb @@ -122,7 +122,11 @@ module ActionDispatch find_all { |middleware| middleware.active? } end - def build(app) + def build(app = nil, &blk) + app ||= blk + + raise "MiddlewareStack#build requires an app" unless app + active.reverse.inject(app) { |a, e| e.build(a) } end end -- cgit v1.2.3 From e4558e0dbfc87724fb3ce3fdc38aea3e49843aec Mon Sep 17 00:00:00 2001 From: wycats Date: Mon, 8 Mar 2010 18:48:58 -0800 Subject: Now that class_attribute creates an instance method, remove it to avoid deprecation warnings ;) --- actionpack/lib/action_dispatch/routing/url_for.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb index 0ab20dcb39..035b0ec4ca 100644 --- a/actionpack/lib/action_dispatch/routing/url_for.rb +++ b/actionpack/lib/action_dispatch/routing/url_for.rb @@ -90,9 +90,10 @@ module ActionDispatch class_attribute :default_url_options else mattr_accessor :default_url_options - remove_method :default_url_options end + remove_method :default_url_options + self.default_url_options = {} end -- cgit v1.2.3 From 514d3a47f4a6a7a46054b45cb6b78ba37d62618e Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Mon, 8 Mar 2010 21:37:56 -0800 Subject: Remove outdated, distracting commented code --- .../lib/action_dispatch/routing/route_set.rb | 25 ---------------------- 1 file changed, 25 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 550e54e955..8ebad1a9b8 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -168,31 +168,6 @@ module ActionDispatch selector = url_helper_name(name, kind) hash_access_method = hash_access_name(name, kind) - # We use module_eval to avoid leaks. - # - # def users_url(*args) - # if args.empty? || Hash === args.first - # options = hash_for_users_url(args.first || {}) - # else - # options = hash_for_users_url(args.extract_options!) - # default = default_url_options(options) if self.respond_to?(:default_url_options, true) - # options = (default ||= {}).merge(options) - # - # keys = [] - # keys -= options.keys if args.size < keys.size - 1 - # - # args = args.zip(keys).inject({}) do |h, (v, k)| - # h[k] = v - # h - # end - # - # # Tell url_for to skip default_url_options - # options[:use_defaults] = false - # options.merge!(args) - # end - # - # url_for(options) - # end @module.module_eval <<-END_EVAL, __FILE__, __LINE__ + 1 def #{selector}(*args) options = #{hash_access_method}(args.extract_options!) -- cgit v1.2.3 From c507e16dba844c7b066d145bfd5c5d23e7a9c5ad Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Mon, 8 Mar 2010 21:40:04 -0800 Subject: Reinstate default_url_options and remove url_options= writer --- actionpack/lib/action_dispatch/routing/url_for.rb | 66 +++++++---------------- actionpack/test/controller/base_test.rb | 42 +++++++-------- actionpack/test/template/url_helper_test.rb | 2 +- 3 files changed, 39 insertions(+), 71 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb index 035b0ec4ca..4629e7e002 100644 --- a/actionpack/lib/action_dispatch/routing/url_for.rb +++ b/actionpack/lib/action_dispatch/routing/url_for.rb @@ -85,43 +85,24 @@ module ActionDispatch extend ActiveSupport::Concern included do - # Including in a class uses an inheritable hash. Modules get a plain hash. - if respond_to?(:class_attribute) - class_attribute :default_url_options - else - mattr_accessor :default_url_options - end - - remove_method :default_url_options - - self.default_url_options = {} - end - - # def default_url_options(options = nil) - # self.class.default_url_options - # end + # TODO: with_routing extends @controller with url_helpers, trickling down to including this module which overrides its default_url_options + unless method_defined?(:default_url_options) + # Including in a class uses an inheritable hash. Modules get a plain hash. + if respond_to?(:class_attribute) + class_attribute :default_url_options + else + mattr_accessor :default_url_options + remove_method :default_url_options + end - def url_options - @url_options ||= begin - # self.class does not respond to default_url_options when the helpers are extended - # onto a singleton - self.class.respond_to?(:default_url_options) ? self.class.default_url_options : {} + self.default_url_options = {} end end - def url_options=(options) - defaults = self.class.respond_to?(:default_url_options) ? self.class.default_url_options : {} - @url_options = defaults.merge(options) + def url_options + default_url_options end - # def merge_options(options) #:nodoc: - # if respond_to?(:default_url_options) && (defaults = default_url_options(options)) - # defaults.merge(options) - # else - # options - # end - # end - # Generate a url based on the options provided, default_url_options and the # routes defined in routes.rb. The following options are supported: # @@ -145,23 +126,14 @@ module ActionDispatch # url_for :controller => 'tasks', :action => 'testing', :host=>'somehost.org', :anchor => 'ok', :only_path => true # => '/tasks/testing#ok' # url_for :controller => 'tasks', :action => 'testing', :trailing_slash=>true # => 'http://somehost.org/tasks/testing/' # url_for :controller => 'tasks', :action => 'testing', :host=>'somehost.org', :number => '33' # => 'http://somehost.org/tasks/testing?number=33' - def url_for(options = {}) - options ||= {} + def url_for(options = nil) case options - when String - options - when Hash - # Handle the deprecated instance level default_url_options - if respond_to?(:default_url_options, true) - ActiveSupport::Deprecation.warn "Overriding the #default_url_options method is deprecated. Instead, set self.url_options = { ... } in a before_filter." - if defaults = default_url_options(options) - options = defaults.merge(options) - end - end - - ActionController::UrlRewriter.rewrite(_router, url_options.merge(options)) - else - polymorphic_url(options) + when String + options + when nil, Hash + ActionController::UrlRewriter.rewrite(_router, url_options.merge(options || {})) + else + polymorphic_url(options) end end end diff --git a/actionpack/test/controller/base_test.rb b/actionpack/test/controller/base_test.rb index ade9a7fcba..3e9f8ae048 100644 --- a/actionpack/test/controller/base_test.rb +++ b/actionpack/test/controller/base_test.rb @@ -181,7 +181,7 @@ class UrlOptionsTest < ActionController::TestCase rescue_action_in_public! end - def test_default_url_options_are_used_if_set + def test_url_options_override with_routing do |set| set.draw do |map| match 'from_view', :to => 'url_options#from_view', :as => :from_view @@ -206,20 +206,18 @@ class DefaultUrlOptionsTest < ActionController::TestCase rescue_action_in_public! end - def test_default_url_options_are_used_if_set + def test_default_url_options_override with_routing do |set| set.draw do |map| match 'from_view', :to => 'default_url_options#from_view', :as => :from_view match ':controller/:action' end - assert_deprecated do - get :from_view, :route => "from_view_url" + get :from_view, :route => "from_view_url" - assert_equal 'http://www.override.com/from_view?locale=en', @response.body - assert_equal 'http://www.override.com/from_view?locale=en', @controller.send(:from_view_url) - assert_equal 'http://www.override.com/default_url_options/new?locale=en', @controller.url_for(:controller => 'default_url_options') - end + assert_equal 'http://www.override.com/from_view?locale=en', @response.body + assert_equal 'http://www.override.com/from_view?locale=en', @controller.send(:from_view_url) + assert_equal 'http://www.override.com/default_url_options/new?locale=en', @controller.url_for(:controller => 'default_url_options') end end @@ -232,21 +230,19 @@ class DefaultUrlOptionsTest < ActionController::TestCase match ':controller/:action' end - assert_deprecated do - get :from_view, :route => "description_path(1)" - - assert_equal '/en/descriptions/1', @response.body - assert_equal '/en/descriptions', @controller.send(:descriptions_path) - assert_equal '/pl/descriptions', @controller.send(:descriptions_path, "pl") - assert_equal '/pl/descriptions', @controller.send(:descriptions_path, :locale => "pl") - assert_equal '/pl/descriptions.xml', @controller.send(:descriptions_path, "pl", "xml") - assert_equal '/en/descriptions.xml', @controller.send(:descriptions_path, :format => "xml") - assert_equal '/en/descriptions/1', @controller.send(:description_path, 1) - assert_equal '/pl/descriptions/1', @controller.send(:description_path, "pl", 1) - assert_equal '/pl/descriptions/1', @controller.send(:description_path, 1, :locale => "pl") - assert_equal '/pl/descriptions/1.xml', @controller.send(:description_path, "pl", 1, "xml") - assert_equal '/en/descriptions/1.xml', @controller.send(:description_path, 1, :format => "xml") - end + get :from_view, :route => "description_path(1)" + + assert_equal '/en/descriptions/1', @response.body + assert_equal '/en/descriptions', @controller.send(:descriptions_path) + assert_equal '/pl/descriptions', @controller.send(:descriptions_path, "pl") + assert_equal '/pl/descriptions', @controller.send(:descriptions_path, :locale => "pl") + assert_equal '/pl/descriptions.xml', @controller.send(:descriptions_path, "pl", "xml") + assert_equal '/en/descriptions.xml', @controller.send(:descriptions_path, :format => "xml") + assert_equal '/en/descriptions/1', @controller.send(:description_path, 1) + assert_equal '/pl/descriptions/1', @controller.send(:description_path, "pl", 1) + assert_equal '/pl/descriptions/1', @controller.send(:description_path, 1, :locale => "pl") + assert_equal '/pl/descriptions/1.xml', @controller.send(:description_path, "pl", 1, "xml") + assert_equal '/en/descriptions/1.xml', @controller.send(:description_path, 1, :format => "xml") end end diff --git a/actionpack/test/template/url_helper_test.rb b/actionpack/test/template/url_helper_test.rb index 533a07b6f4..38ab5521fe 100644 --- a/actionpack/test/template/url_helper_test.rb +++ b/actionpack/test/template/url_helper_test.rb @@ -437,7 +437,7 @@ class UrlHelperControllerTest < ActionController::TestCase end with_url_helper_routing do - assert_deprecated { get :show_named_route, :kind => 'url' } + get :show_named_route, :kind => 'url' assert_equal 'http://testtwo.host/url_helper_controller_test/url_helper/show_named_route', @response.body end end -- cgit v1.2.3 From 00d6271d2b11a14065925529af0c1200406f8beb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Tue, 9 Mar 2010 13:12:11 +0100 Subject: Clean up the API required from ActionView::Template. --- actionpack/lib/abstract_controller/rendering.rb | 2 +- actionpack/lib/action_view/template.rb | 32 ++++++++++++------------- actionpack/lib/action_view/template/resolver.rb | 31 ++++++++++-------------- actionpack/lib/action_view/template/text.rb | 6 +---- actionpack/test/lib/fixture_template.rb | 8 ++++--- 5 files changed, 35 insertions(+), 44 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb index 5048754e33..5c34b83563 100644 --- a/actionpack/lib/abstract_controller/rendering.rb +++ b/actionpack/lib/abstract_controller/rendering.rb @@ -108,7 +108,7 @@ module AbstractController end def _with_template_hook(template) - self.formats = template.details[:formats] + self.formats = template.formats end end end diff --git a/actionpack/lib/action_view/template.rb b/actionpack/lib/action_view/template.rb index cd6b1930a1..b4fdb49d3b 100644 --- a/actionpack/lib/action_view/template.rb +++ b/actionpack/lib/action_view/template.rb @@ -16,23 +16,22 @@ module ActionView end extend Template::Handlers - attr_reader :source, :identifier, :handler, :mime_type, :formats, :details + + attr_reader :source, :identifier, :handler, :virtual_path, :formats def initialize(source, identifier, handler, details) @source = source @identifier = identifier @handler = handler - @details = details + + @partial = details[:partial] + @virtual_path = details[:virtual_path] @method_names = {} - format = details.delete(:format) || begin - # TODO: Clean this up - handler.respond_to?(:default_format) ? handler.default_format.to_sym.to_s : "html" - end - @mime_type = Mime::Type.lookup_by_extension(format.to_s) - @formats = [format.to_sym] - @formats << :html if format == :js - @details[:formats] = Array.wrap(format.to_sym) + format = details[:format] + format ||= handler.default_format.to_sym if handler.respond_to?(:default_format) + format ||= :html + @formats = [format.to_sym] end def render(view, locals, &block) @@ -47,19 +46,20 @@ module ActionView end end - # TODO: Figure out how to abstract this + def mime_type + @mime_type ||= Mime::Type.lookup_by_extension(@formats.first.to_s) if @formats.first + end + def variable_name - @variable_name ||= identifier[%r'_?(\w+)(\.\w+)*$', 1].to_sym + @variable_name ||= @virtual_path[%r'_?(\w+)(\.\w+)*$', 1].to_sym end - # TODO: Figure out how to abstract this def counter_name @counter_name ||= "#{variable_name}_counter".to_sym end - # TODO: kill hax def partial? - @details[:partial] + @partial end def inspect @@ -87,7 +87,7 @@ module ActionView source = <<-end_src def #{method_name}(local_assigns) - _old_virtual_path, @_virtual_path = @_virtual_path, #{@details[:virtual_path].inspect};_old_output_buffer = output_buffer;#{locals_code};#{code} + _old_virtual_path, @_virtual_path = @_virtual_path, #{@virtual_path.inspect};_old_output_buffer = output_buffer;#{locals_code};#{code} ensure @_virtual_path, self.output_buffer = _old_virtual_path, _old_output_buffer end diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb index 6e6c4c21ee..c43b357e9e 100644 --- a/actionpack/lib/action_view/template/resolver.rb +++ b/actionpack/lib/action_view/template/resolver.rb @@ -74,7 +74,7 @@ module ActionView def find_templates(name, prefix, partial, details) path = build_path(name, prefix, partial, details) - query(path, EXTENSION_ORDER.map { |ext| details[ext] }) + query(partial, path, EXTENSION_ORDER.map { |ext| details[ext] }) end def build_path(name, prefix, partial, details) @@ -84,34 +84,27 @@ module ActionView path end - def query(path, exts) + def query(partial, path, exts) query = File.join(@path, path) + exts.each do |ext| query << '{' << ext.map {|e| e && ".#{e}" }.join(',') << '}' end Dir[query].reject { |p| File.directory?(p) }.map do |p| - Template.new(File.read(p), File.expand_path(p), *path_to_details(p)) + handler, format = extract_handler_and_format(p) + Template.new(File.read(p), File.expand_path(p), handler, + :partial => partial, :virtual_path => path, :format => format) end end - # # TODO: fix me - # # :api: plugin - def path_to_details(path) - # [:erb, :format => :html, :locale => :en, :partial => true/false] - if m = path.match(%r'((^|.*/)(_)?[\w-]+)((?:\.[\w-]+)*)\.(\w+)$') - partial = m[3] == '_' - details = (m[4]||"").split('.').reject { |e| e.empty? } - handler = Template.handler_class_for_extension(m[5]) - - format = Mime[details.last] && details.pop.to_sym - locale = details.last && details.pop.to_sym + def extract_handler_and_format(path) + pieces = File.basename(path).split(".") + pieces.shift - virtual_path = (m[1].gsub("#{@path}/", "") << details.join(".")) - - return handler, :format => format, :locale => locale, :partial => partial, - :virtual_path => virtual_path - end + handler = Template.handler_class_for_extension(pieces.pop) + format = pieces.last && Mime[pieces.last] && pieces.pop.to_sym + [handler, format] end end diff --git a/actionpack/lib/action_view/template/text.rb b/actionpack/lib/action_view/template/text.rb index 5978a8a3ac..df394b0fb0 100644 --- a/actionpack/lib/action_view/template/text.rb +++ b/actionpack/lib/action_view/template/text.rb @@ -7,10 +7,6 @@ module ActionView #:nodoc: @content_type ||= Mime::TEXT end - def details - {:formats => [@content_type.to_sym]} - end - def identifier 'text template' end @@ -28,7 +24,7 @@ module ActionView #:nodoc: end def formats - [mime_type] + [@content_type.to_sym] end def partial? diff --git a/actionpack/test/lib/fixture_template.rb b/actionpack/test/lib/fixture_template.rb index a7f0490984..d287fae470 100644 --- a/actionpack/test/lib/fixture_template.rb +++ b/actionpack/test/lib/fixture_template.rb @@ -7,7 +7,7 @@ module ActionView #:nodoc: private - def query(path, exts) + def query(partial, path, exts) query = Regexp.escape(path) exts.each do |ext| query << '(?:' << ext.map {|e| e && Regexp.escape(".#{e}") }.join('|') << ')' @@ -15,9 +15,11 @@ module ActionView #:nodoc: templates = [] @hash.select { |k,v| k =~ /^#{query}$/ }.each do |path, source| - templates << Template.new(source, path, *path_to_details(path)) + handler, format = extract_handler_and_format(path) + templates << Template.new(source, path, handler, + :partial => partial, :virtual_path => path, :format => format) end - templates.sort_by {|t| -t.details.values.compact.size } + templates.sort_by {|t| -t.formats.size } end end -- cgit v1.2.3 From de79525d045b6ea2d83f325bdeeb9380510d045c Mon Sep 17 00:00:00 2001 From: wycats Date: Mon, 8 Mar 2010 21:08:31 -0800 Subject: Get rid of the instance-level URL rewriter --- actionpack/lib/action_controller/test_case.rb | 8 +++-- actionpack/lib/action_controller/url_rewriter.rb | 40 ++------------------- actionpack/test/controller/caching_test.rb | 2 +- actionpack/test/controller/url_rewriter_test.rb | 44 ++++++++---------------- actionpack/test/template/url_helper_test.rb | 2 -- 5 files changed, 25 insertions(+), 71 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb index 7e0a833dfa..c43e560ac1 100644 --- a/actionpack/lib/action_controller/test_case.rb +++ b/actionpack/lib/action_controller/test_case.rb @@ -339,9 +339,13 @@ module ActionController def build_request_uri(action, parameters) unless @request.env["PATH_INFO"] options = @controller.__send__(:url_options).merge(parameters) - options.update(:only_path => true, :action => action, :relative_url_root => nil) - rewriter = ActionController::UrlRewriter.new(@request, parameters) + options.update( + :only_path => true, + :action => action, + :relative_url_root => nil, + :_path_segments => @request.symbolized_path_parameters) + rewriter = ActionController::UrlRewriter url, query_string = rewriter.rewrite(@router, options).split("?", 2) @request.env["SCRIPT_NAME"] = @controller.config.relative_url_root diff --git a/actionpack/lib/action_controller/url_rewriter.rb b/actionpack/lib/action_controller/url_rewriter.rb index 981865517f..b387d49593 100644 --- a/actionpack/lib/action_controller/url_rewriter.rb +++ b/actionpack/lib/action_controller/url_rewriter.rb @@ -2,37 +2,16 @@ require 'active_support/core_ext/hash/except' module ActionController # Rewrites URLs for Base.redirect_to and Base.url_for in the controller. - class UrlRewriter #:nodoc: + module UrlRewriter #:nodoc: RESERVED_OPTIONS = [:anchor, :params, :only_path, :host, :protocol, :port, :trailing_slash, :skip_relative_url_root] - def initialize(request, parameters) - @request, @parameters = request, parameters - end - - def rewrite(router, options = {}) - options[:host] ||= @request.host_with_port - options[:protocol] ||= @request.protocol - - self.class.rewrite(router, options, @request.symbolized_path_parameters) do |options| - process_path_options(options) - end - end - - def to_str - "#{@request.protocol}, #{@request.host_with_port}, #{@request.path}, #{@parameters[:controller]}, #{@parameters[:action]}, #{@request.parameters.inspect}" - end - - alias_method :to_s, :to_str - # ROUTES TODO: Class method code smell - def self.rewrite(router, options, path_segments=nil) + def self.rewrite(router, options) handle_positional_args(options) rewritten_url = "" - # ROUTES TODO: Fix the tests - segments = options.delete(:_path_segments) - path_segments = path_segments ? path_segments.merge(segments || {}) : segments + path_segments = options.delete(:_path_segments) unless options[:only_path] rewritten_url << (options[:protocol] || "http") @@ -81,18 +60,5 @@ module ActionController end end - # Given a Hash of options, generates a route - def process_path_options(options) - options = options.symbolize_keys - options.update(options[:params].symbolize_keys) if options[:params] - - if (overwrite = options.delete(:overwrite_params)) - options.update(@parameters.symbolize_keys) - options.update(overwrite.symbolize_keys) - end - - options - end - end end diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index 11ef3cdd92..2be91893d4 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -64,7 +64,7 @@ class PageCachingTest < ActionController::TestCase @controller.cache_store = :file_store, FILE_STORE_PATH @params = {:controller => 'posts', :action => 'index', :only_path => true, :skip_relative_url_root => true} - @rewriter = ActionController::UrlRewriter.new(@request, @params) + @rewriter = ActionController::UrlRewriter FileUtils.rm_rf(File.dirname(FILE_STORE_PATH)) FileUtils.mkdir_p(FILE_STORE_PATH) diff --git a/actionpack/test/controller/url_rewriter_test.rb b/actionpack/test/controller/url_rewriter_test.rb index 199b824a7a..3bc8bec3fb 100644 --- a/actionpack/test/controller/url_rewriter_test.rb +++ b/actionpack/test/controller/url_rewriter_test.rb @@ -4,10 +4,24 @@ require 'controller/fake_controllers' ActionController::UrlRewriter class UrlRewriterTests < ActionController::TestCase + class Rewriter + def initialize(request) + @options = { + :host => request.host_with_port, + :protocol => request.protocol + } + end + + def rewrite(router, options) + options = @options.merge(options) + ActionController::UrlRewriter.rewrite(router, options) + end + end + def setup @request = ActionController::TestRequest.new @params = {} - @rewriter = ActionController::UrlRewriter.new(@request, @params) + @rewriter = Rewriter.new(@request) #.new(@request, @params) end def test_port @@ -61,34 +75,6 @@ class UrlRewriterTests < ActionController::TestCase ) end - def test_overwrite_params - @params[:controller] = 'hi' - @params[:action] = 'bye' - @params[:id] = '2' - - assert_equal '/hi/hi/2', @rewriter.rewrite(@router, :only_path => true, :overwrite_params => {:action => 'hi'}) - u = @rewriter.rewrite(@router, :only_path => false, :overwrite_params => {:action => 'hi'}) - assert_match %r(/hi/hi/2$), u - end - - def test_overwrite_removes_original - @params[:controller] = 'search' - @params[:action] = 'list' - @params[:list_page] = 1 - - assert_equal '/search/list?list_page=2', @rewriter.rewrite(@router, :only_path => true, :overwrite_params => {"list_page" => 2}) - u = @rewriter.rewrite(@router, :only_path => false, :overwrite_params => {:list_page => 2}) - assert_equal 'http://test.host/search/list?list_page=2', u - end - - def test_to_str - @params[:controller] = 'hi' - @params[:action] = 'bye' - @request.parameters[:id] = '2' - - assert_equal 'http://, test.host, /, hi, bye, {"id"=>"2"}', @rewriter.to_str - end - def test_trailing_slash options = {:controller => 'foo', :action => 'bar', :id => '3', :only_path => true} assert_equal '/foo/bar/3', @rewriter.rewrite(@router, options) diff --git a/actionpack/test/template/url_helper_test.rb b/actionpack/test/template/url_helper_test.rb index 38ab5521fe..165cb655da 100644 --- a/actionpack/test/template/url_helper_test.rb +++ b/actionpack/test/template/url_helper_test.rb @@ -122,7 +122,6 @@ class UrlHelperTest < ActionView::TestCase url = {:controller => 'weblog', :action => 'show'} @controller = ActionController::Base.new @controller.request = ActionController::TestRequest.new - @controller.url = ActionController::UrlRewriter.new(@controller.request, url) assert_dom_equal(%q{Test Link}, link_to('Test Link', url)) end @@ -131,7 +130,6 @@ class UrlHelperTest < ActionView::TestCase url = {:controller => 'weblog', :action => 'show', :host => 'www.example.com'} @controller = ActionController::Base.new @controller.request = ActionController::TestRequest.new - @controller.url = ActionController::UrlRewriter.new(@controller.request, url) assert_dom_equal(%q{Test Link}, link_to('Test Link', url)) end -- cgit v1.2.3 From 9444ac9312470696b6a5d73cd0044329211ec4c6 Mon Sep 17 00:00:00 2001 From: wycats Date: Tue, 9 Mar 2010 10:20:48 -0800 Subject: Refactor the RouteSet so it uses a Generator object instead of one huge method. --- actionpack/lib/action_controller/metal/url_for.rb | 1 - .../lib/action_dispatch/routing/route_set.rb | 196 ++++++++++++--------- 2 files changed, 109 insertions(+), 88 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/url_for.rb b/actionpack/lib/action_controller/metal/url_for.rb index f6b6cb2ff4..10c7ca9021 100644 --- a/actionpack/lib/action_controller/metal/url_for.rb +++ b/actionpack/lib/action_controller/metal/url_for.rb @@ -3,7 +3,6 @@ module ActionController extend ActiveSupport::Concern include ActionDispatch::Routing::UrlFor - include ActionController::RackDelegation def url_options super.reverse_merge( diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 8ebad1a9b8..e99e39269b 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -276,116 +276,138 @@ module ActionDispatch route end - def options_as_params(options) - # If an explicit :controller was given, always make :action explicit - # too, so that action expiry works as expected for things like - # - # generate({:controller => 'content'}, {:controller => 'content', :action => 'show'}) - # - # (the above is from the unit tests). In the above case, because the - # controller was explicitly given, but no action, the action is implied to - # be "index", not the recalled action of "show". - # - # great fun, eh? - - options_as_params = options.clone - options_as_params[:action] ||= 'index' if options[:controller] - options_as_params[:action] = options_as_params[:action].to_s if options_as_params[:action] - options_as_params - end + class Generator + attr_reader :options, :recall, :set, :script_name, :named_route + + def initialize(options, recall, set, extras = false) + @script_name = options.delete(:script_name) + @named_route = options.delete(:use_route) + @options = options.dup + @recall = recall.dup + @set = set + @extras = extras + + normalize_options! + normalize_controller_action_id! + use_relative_controller! + controller.sub!(%r{^/}, '') if controller + handle_nil_action! + end - def build_expiry(options, recall) - recall.inject({}) do |expiry, (key, recalled_value)| - expiry[key] = (options.key?(key) && options[key].to_param != recalled_value.to_param) - expiry + def controller + @controller ||= @options[:controller] end - end - # Generate the path indicated by the arguments, and return an array of - # the keys that were not used to generate it. - def extra_keys(options, recall={}) - generate_extras(options, recall).last - end + def current_controller + @recall[:controller] + end - def generate_extras(options, recall={}) - generate(options, recall, :generate_extras) - end + def use_recall_for(key) + if @recall[key] && (!@options.key?(key) || @options[key] == @recall[key]) + @options[key] = @recall.delete(key) + end + end - def generate(options, recall = {}, method = :generate) - options, recall = options.dup, recall.dup - script_name = options.delete(:script_name) - named_route = options.delete(:use_route) + def normalize_options! + # If an explicit :controller was given, always make :action explicit + # too, so that action expiry works as expected for things like + # + # generate({:controller => 'content'}, {:controller => 'content', :action => 'show'}) + # + # (the above is from the unit tests). In the above case, because the + # controller was explicitly given, but no action, the action is implied to + # be "index", not the recalled action of "show". - options = options_as_params(options) - expire_on = build_expiry(options, recall) + if options[:controller] + options[:action] ||= 'index' + options[:controller] = options[:controller].to_s + end - recall[:action] ||= 'index' if options[:controller] || recall[:controller] + if options[:action] + options[:action] = options[:action].to_s + end + end - if recall[:controller] && (!options.has_key?(:controller) || options[:controller] == recall[:controller]) - options[:controller] = recall.delete(:controller) + # This pulls :controller, :action, and :id out of the recall. + # The recall key is only used if there is no key in the options + # or if the key in the options is identical. If any of + # :controller, :action or :id is not found, don't pull any + # more keys from the recall. + def normalize_controller_action_id! + @recall[:action] ||= 'index' if current_controller + + use_recall_for(:controller) or return + use_recall_for(:action) or return + use_recall_for(:id) + end - if recall[:action] && (!options.has_key?(:action) || options[:action] == recall[:action]) - options[:action] = recall.delete(:action) + # if the current controller is "foo/bar/baz" and :controller => "baz/bat" + # is specified, the controller becomes "foo/baz/bat" + def use_relative_controller! + if !named_route && different_controller? + old_parts = current_controller.split('/') + size = controller.count("/") + 1 + parts = old_parts[0...-size] << controller + @controller = @options[:controller] = parts.join("/") + end + end - if recall[:id] && (!options.has_key?(:id) || options[:id] == recall[:id]) - options[:id] = recall.delete(:id) - end + # This handles the case of :action => nil being explicitly passed. + # It is identical to :action => "index" + def handle_nil_action! + if options.has_key?(:action) && options[:action].nil? + options[:action] = 'index' end + recall[:action] = options.delete(:action) if options[:action] == 'index' end - options[:controller] = options[:controller].to_s if options[:controller] + def generate + error = ActionController::RoutingError.new("No route matches #{options.inspect}") + path, params = @set.generate(:path_info, named_route, options, recall, opts) - if !named_route && expire_on[:controller] && options[:controller] && options[:controller][0] != ?/ - old_parts = recall[:controller].split('/') - new_parts = options[:controller].split('/') - parts = old_parts[0..-(new_parts.length + 1)] + new_parts - options[:controller] = parts.join('/') - end + raise error unless path - options[:controller] = options[:controller][1..-1] if options[:controller] && options[:controller][0] == ?/ + params.reject! {|k,v| !v } - merged = options.merge(recall) - if options.has_key?(:action) && options[:action].nil? - options.delete(:action) - recall[:action] = 'index' - end - recall[:action] = options.delete(:action) if options[:action] == 'index' - - opts = {} - opts[:parameterize] = lambda { |name, value| - if name == :controller - value - elsif value.is_a?(Array) - value.map { |v| Rack::Mount::Utils.escape_uri(v.to_param) }.join('/') - else - Rack::Mount::Utils.escape_uri(value.to_param) - end - } + return [path, params.keys] if @extras - unless result = @set.generate(:path_info, named_route, options, recall, opts) - raise ActionController::RoutingError, "No route matches #{options.inspect}" + path << "?#{params.to_query}" if params.any? + "#{script_name}#{path}" + rescue Rack::Mount::RoutingError + raise error end - path, params = result - params.each do |k, v| - if v - params[k] = v - else - params.delete(k) + def opts + parameterize = lambda do |name, value| + if name == :controller + value + elsif value.is_a?(Array) + value.map { |v| Rack::Mount::Utils.escape_uri(v.to_param) }.join('/') + else + Rack::Mount::Utils.escape_uri(value.to_param) + end end + {:parameterize => parameterize} end - if path && method == :generate_extras - [path, params.keys] - elsif path - path << "?#{params.to_query}" if params.any? - path = "#{script_name}#{path}" - path - else - raise ActionController::RoutingError, "No route matches #{options.inspect}" + def different_controller? + return false unless current_controller + controller.to_param != current_controller.to_param end - rescue Rack::Mount::RoutingError - raise ActionController::RoutingError, "No route matches #{options.inspect}" + end + + # Generate the path indicated by the arguments, and return an array of + # the keys that were not used to generate it. + def extra_keys(options, recall={}) + generate_extras(options, recall).last + end + + def generate_extras(options, recall={}) + generate(options, recall, true) + end + + def generate(options, recall = {}, extras = false) + Generator.new(options, recall, @set, extras).generate end def call(env) -- cgit v1.2.3 From ea4f8ef33f08a69a68f6b95f392e63ea9cc13602 Mon Sep 17 00:00:00 2001 From: Justin Ko Date: Tue, 9 Mar 2010 16:37:46 -0200 Subject: Reinstate dom_id in controllers. [#3040 state:committed] Signed-off-by: Santiago Pastorino Signed-off-by: Jeremy Kemper --- actionpack/lib/action_controller/base.rb | 1 + actionpack/test/controller/base_test.rb | 8 ++++++++ 2 files changed, 9 insertions(+) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index d00afa6d4e..fcd3cb9bd3 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -29,6 +29,7 @@ module ActionController include ActionController::Verification include ActionController::RequestForgeryProtection include ActionController::Streaming + include ActionController::RecordIdentifier include ActionController::HttpAuthentication::Basic::ControllerMethods include ActionController::HttpAuthentication::Digest::ControllerMethods diff --git a/actionpack/test/controller/base_test.rb b/actionpack/test/controller/base_test.rb index 3e9f8ae048..f047e7da30 100644 --- a/actionpack/test/controller/base_test.rb +++ b/actionpack/test/controller/base_test.rb @@ -76,6 +76,9 @@ class UrlOptionsController < ActionController::Base end end +class RecordIdentifierController < ActionController::Base +end + class ControllerClassTests < ActiveSupport::TestCase def test_controller_path assert_equal 'empty', EmptyController.controller_path @@ -102,6 +105,11 @@ class ControllerClassTests < ActiveSupport::TestCase assert_equal [:password], parameters end + + def test_record_identifier + assert_respond_to RecordIdentifierController.new, :dom_id + assert_respond_to RecordIdentifierController.new, :dom_class + end end class ControllerInstanceTests < Test::Unit::TestCase -- cgit v1.2.3 From 7db80f87e9c194713c2016820e39af6043ddf8d0 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 9 Mar 2010 20:50:35 -0600 Subject: Move AC::UrlRewriter onto route set --- actionpack/lib/action_controller.rb | 1 - actionpack/lib/action_controller/test_case.rb | 33 ++++++----- actionpack/lib/action_controller/url_rewriter.rb | 64 ---------------------- .../lib/action_dispatch/routing/route_set.rb | 56 +++++++++++++++++++ actionpack/lib/action_dispatch/routing/url_for.rb | 2 +- actionpack/test/controller/caching_test.rb | 5 +- actionpack/test/controller/url_rewriter_test.rb | 5 +- 7 files changed, 76 insertions(+), 90 deletions(-) delete mode 100644 actionpack/lib/action_controller/url_rewriter.rb (limited to 'actionpack') diff --git a/actionpack/lib/action_controller.rb b/actionpack/lib/action_controller.rb index 3b97f38498..536154fc6b 100644 --- a/actionpack/lib/action_controller.rb +++ b/actionpack/lib/action_controller.rb @@ -46,7 +46,6 @@ module ActionController eager_autoload do autoload :RecordIdentifier - autoload :UrlRewriter # TODO: Don't autoload exceptions, setup explicit # requires for files that need them diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb index c43e560ac1..072d289964 100644 --- a/actionpack/lib/action_controller/test_case.rb +++ b/actionpack/lib/action_controller/test_case.rb @@ -335,23 +335,22 @@ module ActionController @request.remote_addr = '208.77.188.166' # example.com end - private - def build_request_uri(action, parameters) - unless @request.env["PATH_INFO"] - options = @controller.__send__(:url_options).merge(parameters) - options.update( - :only_path => true, - :action => action, - :relative_url_root => nil, - :_path_segments => @request.symbolized_path_parameters) - - rewriter = ActionController::UrlRewriter - url, query_string = rewriter.rewrite(@router, options).split("?", 2) - - @request.env["SCRIPT_NAME"] = @controller.config.relative_url_root - @request.env["PATH_INFO"] = url - @request.env["QUERY_STRING"] = query_string || "" + private + def build_request_uri(action, parameters) + unless @request.env["PATH_INFO"] + options = @controller.__send__(:url_options).merge(parameters) + options.update( + :only_path => true, + :action => action, + :relative_url_root => nil, + :_path_segments => @request.symbolized_path_parameters) + + url, query_string = @router.rewrite(options).split("?", 2) + + @request.env["SCRIPT_NAME"] = @controller.config.relative_url_root + @request.env["PATH_INFO"] = url + @request.env["QUERY_STRING"] = query_string || "" + end end end - end end diff --git a/actionpack/lib/action_controller/url_rewriter.rb b/actionpack/lib/action_controller/url_rewriter.rb deleted file mode 100644 index b387d49593..0000000000 --- a/actionpack/lib/action_controller/url_rewriter.rb +++ /dev/null @@ -1,64 +0,0 @@ -require 'active_support/core_ext/hash/except' - -module ActionController - # Rewrites URLs for Base.redirect_to and Base.url_for in the controller. - module UrlRewriter #:nodoc: - RESERVED_OPTIONS = [:anchor, :params, :only_path, :host, :protocol, :port, :trailing_slash, :skip_relative_url_root] - - # ROUTES TODO: Class method code smell - def self.rewrite(router, options) - handle_positional_args(options) - - rewritten_url = "" - - path_segments = options.delete(:_path_segments) - - unless options[:only_path] - rewritten_url << (options[:protocol] || "http") - rewritten_url << "://" unless rewritten_url.match("://") - rewritten_url << rewrite_authentication(options) - - raise "Missing host to link to! Please provide :host parameter or set default_url_options[:host]" unless options[:host] - - rewritten_url << options[:host] - rewritten_url << ":#{options.delete(:port)}" if options.key?(:port) - end - - path_options = options.except(*RESERVED_OPTIONS) - path_options = yield(path_options) if block_given? - path = router.generate(path_options, path_segments || {}) - - # ROUTES TODO: This can be called directly, so script_name should probably be set in the router - rewritten_url << (options[:trailing_slash] ? path.sub(/\?|\z/) { "/" + $& } : path) - rewritten_url << "##{Rack::Utils.escape(options[:anchor].to_param.to_s)}" if options[:anchor] - - rewritten_url - end - - protected - - def self.handle_positional_args(options) - return unless args = options.delete(:_positional_args) - - keys = options.delete(:_positional_keys) - keys -= options.keys if args.size < keys.size - 1 # take format into account - - args = args.zip(keys).inject({}) do |h, (v, k)| - h[k] = v - h - end - - # Tell url_for to skip default_url_options - options.merge!(args) - end - - def self.rewrite_authentication(options) - if options[:user] && options[:password] - "#{Rack::Utils.escape(options.delete(:user))}:#{Rack::Utils.escape(options.delete(:password))}@" - else - "" - end - end - - end -end diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index e99e39269b..15c7cd00ba 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -410,6 +410,38 @@ module ActionDispatch Generator.new(options, recall, @set, extras).generate end + RESERVED_OPTIONS = [:anchor, :params, :only_path, :host, :protocol, :port, :trailing_slash, :skip_relative_url_root] + + # TODO: Terrible method name + def rewrite(options) + handle_positional_args(options) + + rewritten_url = "" + + path_segments = options.delete(:_path_segments) + + unless options[:only_path] + rewritten_url << (options[:protocol] || "http") + rewritten_url << "://" unless rewritten_url.match("://") + rewritten_url << rewrite_authentication(options) + + raise "Missing host to link to! Please provide :host parameter or set default_url_options[:host]" unless options[:host] + + rewritten_url << options[:host] + rewritten_url << ":#{options.delete(:port)}" if options.key?(:port) + end + + path_options = options.except(*RESERVED_OPTIONS) + path_options = yield(path_options) if block_given? + path = generate(path_options, path_segments || {}) + + # ROUTES TODO: This can be called directly, so script_name should probably be set in the router + rewritten_url << (options[:trailing_slash] ? path.sub(/\?|\z/) { "/" + $& } : path) + rewritten_url << "##{Rack::Utils.escape(options[:anchor].to_param.to_s)}" if options[:anchor] + + rewritten_url + end + def call(env) @set.call(env) end @@ -435,6 +467,30 @@ module ActionDispatch raise ActionController::RoutingError, "No route matches #{path.inspect}" end + + private + def handle_positional_args(options) + return unless args = options.delete(:_positional_args) + + keys = options.delete(:_positional_keys) + keys -= options.keys if args.size < keys.size - 1 # take format into account + + args = args.zip(keys).inject({}) do |h, (v, k)| + h[k] = v + h + end + + # Tell url_for to skip default_url_options + options.merge!(args) + end + + def rewrite_authentication(options) + if options[:user] && options[:password] + "#{Rack::Utils.escape(options.delete(:user))}:#{Rack::Utils.escape(options.delete(:password))}@" + else + "" + end + end end end end diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb index 4629e7e002..0ba04316d7 100644 --- a/actionpack/lib/action_dispatch/routing/url_for.rb +++ b/actionpack/lib/action_dispatch/routing/url_for.rb @@ -131,7 +131,7 @@ module ActionDispatch when String options when nil, Hash - ActionController::UrlRewriter.rewrite(_router, url_options.merge(options || {})) + _router.rewrite(url_options.merge(options || {})) else polymorphic_url(options) end diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index 2be91893d4..08efd5a48c 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -64,7 +64,6 @@ class PageCachingTest < ActionController::TestCase @controller.cache_store = :file_store, FILE_STORE_PATH @params = {:controller => 'posts', :action => 'index', :only_path => true, :skip_relative_url_root => true} - @rewriter = ActionController::UrlRewriter FileUtils.rm_rf(File.dirname(FILE_STORE_PATH)) FileUtils.mkdir_p(FILE_STORE_PATH) @@ -82,9 +81,9 @@ class PageCachingTest < ActionController::TestCase match '/', :to => 'posts#index', :as => :main end @params[:format] = 'rss' - assert_equal '/posts.rss', @rewriter.rewrite(@router, @params) + assert_equal '/posts.rss', @router.rewrite(@params) @params[:format] = nil - assert_equal '/', @rewriter.rewrite(@router, @params) + assert_equal '/', @router.rewrite(@params) end end diff --git a/actionpack/test/controller/url_rewriter_test.rb b/actionpack/test/controller/url_rewriter_test.rb index 3bc8bec3fb..cf775846df 100644 --- a/actionpack/test/controller/url_rewriter_test.rb +++ b/actionpack/test/controller/url_rewriter_test.rb @@ -1,8 +1,6 @@ require 'abstract_unit' require 'controller/fake_controllers' -ActionController::UrlRewriter - class UrlRewriterTests < ActionController::TestCase class Rewriter def initialize(request) @@ -13,8 +11,7 @@ class UrlRewriterTests < ActionController::TestCase end def rewrite(router, options) - options = @options.merge(options) - ActionController::UrlRewriter.rewrite(router, options) + router.rewrite(@options.merge(options)) end end -- cgit v1.2.3 From e38ea982ff8fea5b616297b458ca2c669de0d659 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 9 Mar 2010 20:57:43 -0600 Subject: Unused RouteSet#url_for is hogging a good method name --- actionpack/lib/action_dispatch/routing/route_set.rb | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 15c7cd00ba..aa1e25aa8b 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -235,31 +235,22 @@ module ActionDispatch named_routes.install(destinations, regenerate_code) end - def url_for - @url_for ||= begin - router = self - Module.new do - extend ActiveSupport::Concern - include UrlFor - - define_method(:_router) { router } - end - end - end - def url_helpers @url_helpers ||= begin router = self Module.new do extend ActiveSupport::Concern - include router.url_for + include UrlFor # ROUTES TODO: install_helpers isn't great... can we make a module with the stuff that # we can include? + # Yes plz - JP included do router.install_helpers(self) end + + define_method(:_router) { router } end end end -- cgit v1.2.3 From 4d2470f7daad8cebd0a69f5ea0509a41af0596b8 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 9 Mar 2010 21:00:24 -0600 Subject: RouteSet#rewrite => url_for --- actionpack/lib/action_controller/test_case.rb | 2 +- actionpack/lib/action_dispatch/routing/route_set.rb | 3 +-- actionpack/lib/action_dispatch/routing/url_for.rb | 2 +- actionpack/test/controller/caching_test.rb | 4 ++-- actionpack/test/controller/url_rewriter_test.rb | 2 +- 5 files changed, 6 insertions(+), 7 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb index 072d289964..cdb5db32aa 100644 --- a/actionpack/lib/action_controller/test_case.rb +++ b/actionpack/lib/action_controller/test_case.rb @@ -345,7 +345,7 @@ module ActionController :relative_url_root => nil, :_path_segments => @request.symbolized_path_parameters) - url, query_string = @router.rewrite(options).split("?", 2) + url, query_string = @router.url_for(options).split("?", 2) @request.env["SCRIPT_NAME"] = @controller.config.relative_url_root @request.env["PATH_INFO"] = url diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index aa1e25aa8b..2b9fc9e0de 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -403,8 +403,7 @@ module ActionDispatch RESERVED_OPTIONS = [:anchor, :params, :only_path, :host, :protocol, :port, :trailing_slash, :skip_relative_url_root] - # TODO: Terrible method name - def rewrite(options) + def url_for(options) handle_positional_args(options) rewritten_url = "" diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb index 0ba04316d7..7ebd5e44e9 100644 --- a/actionpack/lib/action_dispatch/routing/url_for.rb +++ b/actionpack/lib/action_dispatch/routing/url_for.rb @@ -131,7 +131,7 @@ module ActionDispatch when String options when nil, Hash - _router.rewrite(url_options.merge(options || {})) + _router.url_for(url_options.merge(options || {})) else polymorphic_url(options) end diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index 08efd5a48c..8a0c118d3c 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -81,9 +81,9 @@ class PageCachingTest < ActionController::TestCase match '/', :to => 'posts#index', :as => :main end @params[:format] = 'rss' - assert_equal '/posts.rss', @router.rewrite(@params) + assert_equal '/posts.rss', @router.url_for(@params) @params[:format] = nil - assert_equal '/', @router.rewrite(@params) + assert_equal '/', @router.url_for(@params) end end diff --git a/actionpack/test/controller/url_rewriter_test.rb b/actionpack/test/controller/url_rewriter_test.rb index cf775846df..7b46a48a1d 100644 --- a/actionpack/test/controller/url_rewriter_test.rb +++ b/actionpack/test/controller/url_rewriter_test.rb @@ -11,7 +11,7 @@ class UrlRewriterTests < ActionController::TestCase end def rewrite(router, options) - router.rewrite(@options.merge(options)) + router.url_for(@options.merge(options)) end end -- cgit v1.2.3 From 1cc2a61ea655fea246f4c3e22a9e4a494e99d952 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 9 Mar 2010 21:20:13 -0600 Subject: Allow default_url_options to be set on route set --- actionpack/lib/action_dispatch/routing/mapper.rb | 5 +++++ actionpack/lib/action_dispatch/routing/route_set.rb | 4 ++++ actionpack/test/dispatch/routing_test.rb | 4 ++++ 3 files changed, 13 insertions(+) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index ae4470d033..0b7b09ee7a 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -180,6 +180,11 @@ module ActionDispatch @set.add_route(*mapping) self end + + def default_url_options=(options) + @set.default_url_options = options + end + alias_method :default_url_options, :default_url_options= end module HttpHelpers diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 2b9fc9e0de..26f37161a7 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -186,6 +186,7 @@ module ActionDispatch attr_accessor :routes, :named_routes attr_accessor :disable_clear_and_finalize, :resources_path_names + attr_accessor :default_url_options def self.default_resources_path_names { :new => 'new', :edit => 'edit' } @@ -196,6 +197,7 @@ module ActionDispatch self.named_routes = NamedRouteCollection.new self.resources_path_names = self.class.default_resources_path_names.dup self.controller_namespaces = Set.new + self.default_url_options = {} @disable_clear_and_finalize = false clear! @@ -404,6 +406,8 @@ module ActionDispatch RESERVED_OPTIONS = [:anchor, :params, :only_path, :host, :protocol, :port, :trailing_slash, :skip_relative_url_root] def url_for(options) + options = default_url_options.merge(options || {}) + handle_positional_args(options) rewritten_url = "" diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb index b46276c453..f5fcf9b0df 100644 --- a/actionpack/test/dispatch/routing_test.rb +++ b/actionpack/test/dispatch/routing_test.rb @@ -15,6 +15,8 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest stub_controllers do |routes| Routes = routes Routes.draw do + default_url_options :host => "rubyonrails.org" + controller :sessions do get 'login' => :new, :as => :login post 'login' => :create @@ -189,6 +191,8 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest assert_equal '/login', url_for(:controller => 'sessions', :action => 'create', :only_path => true) assert_equal '/login', url_for(:controller => 'sessions', :action => 'new', :only_path => true) + + assert_equal 'http://rubyonrails.org/login', Routes.url_for(:controller => 'sessions', :action => 'create') end end -- cgit v1.2.3 From dcd110c724aa5111e67e7264e6bc76ebdda6d50f Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 9 Mar 2010 21:25:09 -0600 Subject: skip_relative_url_root url_for option is dead --- actionpack/lib/action_controller/caching/pages.rb | 6 +++--- actionpack/lib/action_dispatch/routing/route_set.rb | 2 +- actionpack/lib/action_dispatch/routing/url_for.rb | 2 -- actionpack/test/controller/caching_test.rb | 2 +- 4 files changed, 5 insertions(+), 7 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/caching/pages.rb b/actionpack/lib/action_controller/caching/pages.rb index 36a97d390c..fe95f0e0d7 100644 --- a/actionpack/lib/action_controller/caching/pages.rb +++ b/actionpack/lib/action_controller/caching/pages.rb @@ -121,10 +121,10 @@ module ActionController #:nodoc: if options.is_a?(Hash) if options[:action].is_a?(Array) options[:action].dup.each do |action| - self.class.expire_page(url_for(options.merge(:only_path => true, :skip_relative_url_root => true, :action => action))) + self.class.expire_page(url_for(options.merge(:only_path => true, :action => action))) end else - self.class.expire_page(url_for(options.merge(:only_path => true, :skip_relative_url_root => true))) + self.class.expire_page(url_for(options.merge(:only_path => true))) end else self.class.expire_page(options) @@ -139,7 +139,7 @@ module ActionController #:nodoc: path = case options when Hash - url_for(options.merge(:only_path => true, :skip_relative_url_root => true, :format => params[:format])) + url_for(options.merge(:only_path => true, :format => params[:format])) when String options else diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 26f37161a7..722be432c7 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -403,7 +403,7 @@ module ActionDispatch Generator.new(options, recall, @set, extras).generate end - RESERVED_OPTIONS = [:anchor, :params, :only_path, :host, :protocol, :port, :trailing_slash, :skip_relative_url_root] + RESERVED_OPTIONS = [:anchor, :params, :only_path, :host, :protocol, :port, :trailing_slash] def url_for(options) options = default_url_options.merge(options || {}) diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb index 7ebd5e44e9..ec78f53fa6 100644 --- a/actionpack/lib/action_dispatch/routing/url_for.rb +++ b/actionpack/lib/action_dispatch/routing/url_for.rb @@ -113,8 +113,6 @@ module ActionDispatch # provided either explicitly, or via +default_url_options+. # * :port - Optionally specify the port to connect to. # * :anchor - An anchor name to be appended to the path. - # * :skip_relative_url_root - If true, the url is not constructed using the - # +relative_url_root+ set in ActionController::Base.relative_url_root. # * :trailing_slash - If true, adds a trailing slash, as in "/archive/2009/" # # Any other key (:controller, :action, etc.) given to diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index 8a0c118d3c..a3c8fdbb6e 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -63,7 +63,7 @@ class PageCachingTest < ActionController::TestCase @controller = PageCachingTestController.new @controller.cache_store = :file_store, FILE_STORE_PATH - @params = {:controller => 'posts', :action => 'index', :only_path => true, :skip_relative_url_root => true} + @params = {:controller => 'posts', :action => 'index', :only_path => true} FileUtils.rm_rf(File.dirname(FILE_STORE_PATH)) FileUtils.mkdir_p(FILE_STORE_PATH) -- cgit v1.2.3 From 4464b8e87bedd69816d4658c9386cc360affb62e Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Tue, 9 Mar 2010 18:00:28 -0800 Subject: Deprecate block_called_from_erb? pending a solution for getting it into apps --- actionpack/lib/action_view/helpers.rb | 1 + .../lib/action_view/helpers/capture_helper.rb | 14 ++--- .../helpers/deprecated_block_helpers.rb | 35 +++++++++++++ .../lib/action_view/helpers/javascript_helper.rb | 8 +-- actionpack/lib/action_view/helpers/tag_helper.rb | 26 ++-------- .../lib/action_view/template/handlers/erb.rb | 46 +++++++++++++++-- actionpack/test/template/erb/tag_helper_test.rb | 60 ++++++++++++++++++++++ actionpack/test/template/javascript_helper_test.rb | 12 ----- actionpack/test/template/tag_helper_test.rb | 16 +++--- 9 files changed, 154 insertions(+), 64 deletions(-) create mode 100644 actionpack/lib/action_view/helpers/deprecated_block_helpers.rb create mode 100644 actionpack/test/template/erb/tag_helper_test.rb (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers.rb b/actionpack/lib/action_view/helpers.rb index b4f649385a..e359b0bdac 100644 --- a/actionpack/lib/action_view/helpers.rb +++ b/actionpack/lib/action_view/helpers.rb @@ -10,6 +10,7 @@ module ActionView #:nodoc: autoload :CsrfHelper, 'action_view/helpers/csrf_helper' autoload :DateHelper, 'action_view/helpers/date_helper' autoload :DebugHelper, 'action_view/helpers/debug_helper' + autoload :DeprecatedBlockHelpers, 'action_view/helpers/deprecated_block_helpers' autoload :FormHelper, 'action_view/helpers/form_helper' autoload :FormOptionsHelper, 'action_view/helpers/form_options_helper' autoload :FormTagHelper, 'action_view/helpers/form_tag_helper' diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb index 8c48300ed3..75fc2fddeb 100644 --- a/actionpack/lib/action_view/helpers/capture_helper.rb +++ b/actionpack/lib/action_view/helpers/capture_helper.rb @@ -30,14 +30,10 @@ module ActionView # <%= @greeting %> # # - def capture(*args, &block) - # Return captured buffer in erb. - if block_called_from_erb?(block) - with_output_buffer { block.call(*args) } - else - # Return block result otherwise, but protect buffer also. - with_output_buffer { return block.call(*args) } - end + def capture(*args) + value = nil + buffer = with_output_buffer { value = yield *args } + buffer.presence || value end # Calling content_for stores a block of markup in an identifier for later use. @@ -143,7 +139,7 @@ module ActionView # Defaults to a new empty string. def with_output_buffer(buf = nil) #:nodoc: unless buf - buf = ActiveSupport::SafeBuffer.new + buf = ActionView::OutputBuffer.new buf.force_encoding(output_buffer.encoding) if buf.respond_to?(:force_encoding) end self.output_buffer, old_buffer = buf, output_buffer diff --git a/actionpack/lib/action_view/helpers/deprecated_block_helpers.rb b/actionpack/lib/action_view/helpers/deprecated_block_helpers.rb new file mode 100644 index 0000000000..ffbffbf25e --- /dev/null +++ b/actionpack/lib/action_view/helpers/deprecated_block_helpers.rb @@ -0,0 +1,35 @@ +module ActionView + module Helpers + module DeprecatedBlockHelpers + extend ActiveSupport::Concern + + include ActionView::Helpers::TagHelper + include ActionView::Helpers::TextHelper + include ActionView::Helpers::JavaScriptHelper + + def content_tag(*, &block) + block_called_from_erb?(block) ? safe_concat(super) : super + end + + def javascript_tag(*, &block) + block_called_from_erb?(block) ? safe_concat(super) : super + end + + BLOCK_CALLED_FROM_ERB = 'defined? __in_erb_template' + + if RUBY_VERSION < '1.9.0' + # Check whether we're called from an erb template. + # We'd return a string in any other case, but erb <%= ... %> + # can't take an <% end %> later on, so we have to use <% ... %> + # and implicitly concat. + def block_called_from_erb?(block) + block && eval(BLOCK_CALLED_FROM_ERB, block) + end + else + def block_called_from_erb?(block) + block && eval(BLOCK_CALLED_FROM_ERB, block.binding) + end + end + end + end +end \ No newline at end of file diff --git a/actionpack/lib/action_view/helpers/javascript_helper.rb b/actionpack/lib/action_view/helpers/javascript_helper.rb index 2c73ff88f7..8dab3094dd 100644 --- a/actionpack/lib/action_view/helpers/javascript_helper.rb +++ b/actionpack/lib/action_view/helpers/javascript_helper.rb @@ -83,13 +83,7 @@ module ActionView content_or_options_with_block end - tag = content_tag(:script, javascript_cdata_section(content), html_options.merge(:type => Mime::JS)) - - if block_called_from_erb?(block) - safe_concat(tag) - else - tag - end + content_tag(:script, javascript_cdata_section(content), html_options.merge(:type => Mime::JS)) end def javascript_cdata_section(content) #:nodoc: diff --git a/actionpack/lib/action_view/helpers/tag_helper.rb b/actionpack/lib/action_view/helpers/tag_helper.rb index 513d72880c..d9d2588a2a 100644 --- a/actionpack/lib/action_view/helpers/tag_helper.rb +++ b/actionpack/lib/action_view/helpers/tag_helper.rb @@ -7,6 +7,9 @@ module ActionView module TagHelper include ERB::Util + extend ActiveSupport::Concern + include CaptureHelper + BOOLEAN_ATTRIBUTES = %w(disabled readonly multiple checked autobuffer autoplay controls loop selected hidden scoped async defer reversed ismap seemless muted required @@ -69,13 +72,7 @@ module ActionView def content_tag(name, content_or_options_with_block = nil, options = nil, escape = true, &block) if block_given? options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash) - content_tag = content_tag_string(name, capture(&block), options, escape) - - if block_called_from_erb?(block) - safe_concat(content_tag) - else - content_tag - end + content_tag_string(name, capture(&block), options, escape) else content_tag_string(name, content_or_options_with_block, options, escape) end @@ -109,21 +106,6 @@ module ActionView end private - BLOCK_CALLED_FROM_ERB = 'defined? __in_erb_template' - - if RUBY_VERSION < '1.9.0' - # Check whether we're called from an erb template. - # We'd return a string in any other case, but erb <%= ... %> - # can't take an <% end %> later on, so we have to use <% ... %> - # and implicitly concat. - def block_called_from_erb?(block) - block && eval(BLOCK_CALLED_FROM_ERB, block) - end - else - def block_called_from_erb?(block) - block && eval(BLOCK_CALLED_FROM_ERB, block.binding) - end - end def content_tag_string(name, content, options, escape = true) tag_options = tag_options(options, escape) if options diff --git a/actionpack/lib/action_view/template/handlers/erb.rb b/actionpack/lib/action_view/template/handlers/erb.rb index 4b7cec50f3..3fcae167ff 100644 --- a/actionpack/lib/action_view/template/handlers/erb.rb +++ b/actionpack/lib/action_view/template/handlers/erb.rb @@ -3,10 +3,46 @@ require 'active_support/core_ext/string/output_safety' require 'erubis' module ActionView + class OutputBuffer + def initialize + @buffer = ActiveSupport::SafeBuffer.new + end + + def safe_concat(value) + @buffer.safe_concat(value) + end + + def <<(value) + @buffer << value.to_s + end + + def length + @buffer.length + end + + def [](*args) + @buffer[*args] + end + + def to_s + @buffer.to_s + end + + def empty? + @buffer.empty? + end + + if "".respond_to?(:force_encoding) + def force_encoding(encoding) + @buffer.force_encoding(encoding) + end + end + end + module Template::Handlers class Erubis < ::Erubis::Eruby def add_preamble(src) - src << "@output_buffer = ActiveSupport::SafeBuffer.new;" + src << "@output_buffer = ActionView::OutputBuffer.new;" end def add_text(src, text) @@ -15,10 +51,10 @@ module ActionView end def add_expr_literal(src, code) - if code =~ /\s*raw\s+(.*)/ - src << "@output_buffer.safe_concat((" << $1 << ").to_s);" + if code =~ /(do|\{)(\s*\|[^|]*\|)?\s*\Z/ + src << '@output_buffer << ' << code else - src << '@output_buffer << ((' << code << ').to_s);' + src << '@output_buffer << (' << code << ');' end end @@ -42,7 +78,7 @@ module ActionView self.erb_trim_mode = '-' self.default_format = Mime::HTML - + cattr_accessor :erb_implementation self.erb_implementation = Erubis diff --git a/actionpack/test/template/erb/tag_helper_test.rb b/actionpack/test/template/erb/tag_helper_test.rb new file mode 100644 index 0000000000..d9ca828b43 --- /dev/null +++ b/actionpack/test/template/erb/tag_helper_test.rb @@ -0,0 +1,60 @@ +require "abstract_unit" + +module ERBTest + module SharedTagHelpers + extend ActiveSupport::Testing::Declarative + + def render_content(start, inside) + template = block_helper(start, inside) + ActionView::Template::Handlers::Erubis.new(template).evaluate(context.new) + end + + test "percent equals works for content_tag" do + assert_equal "
Hello world
", render_content("content_tag(:div)", "Hello world") + end + + test "percent equals works for javascript_tag" do + expected_output = "" + assert_equal expected_output, render_content("javascript_tag", "alert('Hello')") + end + + test "percent equals works for javascript_tag with options" do + expected_output = "" + assert_equal expected_output, render_content("javascript_tag(:id => 'the_js_tag')", "alert('Hello')") + end + end + + class TagHelperTest < ActiveSupport::TestCase + def context + Class.new do + include ActionView::Helpers::TagHelper + include ActionView::Helpers::JavaScriptHelper + + attr_accessor :output_buffer + end + end + + def block_helper(str, rest) + "<%= #{str} do %>#{rest}<% end %>" + end + + include SharedTagHelpers + end + + class DeprecatedTagHelperTest < ActiveSupport::TestCase + def context + Class.new do + include ActionView::Helpers::TagHelper + include ActionView::Helpers::JavaScriptHelper + include ActionView::Helpers::DeprecatedBlockHelpers + attr_accessor :output_buffer + end + end + + def block_helper(str, rest) + "<% __in_erb_template=true %><% #{str} do %>#{rest}<% end %>" + end + + include SharedTagHelpers + end +end \ No newline at end of file diff --git a/actionpack/test/template/javascript_helper_test.rb b/actionpack/test/template/javascript_helper_test.rb index 6604f1c095..f49b763881 100644 --- a/actionpack/test/template/javascript_helper_test.rb +++ b/actionpack/test/template/javascript_helper_test.rb @@ -74,18 +74,6 @@ class JavaScriptHelperTest < ActionView::TestCase javascript_tag("alert('hello')", :id => "the_js_tag") end - def test_javascript_tag_with_block_in_erb - __in_erb_template = '' - javascript_tag { concat "alert('hello')" } - assert_dom_equal "", output_buffer - end - - def test_javascript_tag_with_block_and_options_in_erb - __in_erb_template = '' - javascript_tag(:id => "the_js_tag") { concat "alert('hello')" } - assert_dom_equal "", output_buffer - end - def test_javascript_cdata_section assert_dom_equal "\n//\n", javascript_cdata_section("alert('hello')") end diff --git a/actionpack/test/template/tag_helper_test.rb b/actionpack/test/template/tag_helper_test.rb index 3858ffde40..256d9bdcde 100644 --- a/actionpack/test/template/tag_helper_test.rb +++ b/actionpack/test/template/tag_helper_test.rb @@ -42,15 +42,13 @@ class TagHelperTest < ActionView::TestCase end def test_content_tag_with_block_in_erb - __in_erb_template = '' - content_tag(:div) { concat "Hello world!" } - assert_dom_equal "
Hello world!
", output_buffer + buffer = content_tag(:div) { concat "Hello world!" } + assert_dom_equal "
Hello world!
", buffer end def test_content_tag_with_block_and_options_in_erb - __in_erb_template = '' - content_tag(:div, :class => "green") { concat "Hello world!" } - assert_dom_equal %(
Hello world!
), output_buffer + buffer = content_tag(:div, :class => "green") { concat "Hello world!" } + assert_dom_equal %(
Hello world!
), buffer end def test_content_tag_with_block_and_options_out_of_erb @@ -68,10 +66,10 @@ class TagHelperTest < ActionView::TestCase output_buffer end + # TAG TODO: Move this into a real template def test_content_tag_nested_in_content_tag_in_erb - __in_erb_template = true - content_tag("p") { concat content_tag("b", "Hello") } - assert_equal '

Hello

', output_buffer + buffer = content_tag("p") { concat content_tag("b", "Hello") } + assert_equal '

Hello

', buffer end def test_content_tag_with_escaped_array_class -- cgit v1.2.3 From 7b622786fcc5046a06989ec7a3cbf46f92e04dea Mon Sep 17 00:00:00 2001 From: wycats Date: Tue, 9 Mar 2010 23:41:39 -0800 Subject: Make form helpers work with <%= --- .../helpers/deprecated_block_helpers.rb | 17 +++ actionpack/lib/action_view/helpers/form_helper.rb | 23 +++- .../lib/action_view/helpers/form_options_helper.rb | 2 + .../lib/action_view/helpers/form_tag_helper.rb | 20 ++- .../lib/action_view/template/handlers/erb.rb | 8 ++ actionpack/test/template/date_helper_test.rb | 14 +- actionpack/test/template/erb/tag_helper_test.rb | 46 +++++-- actionpack/test/template/form_helper_test.rb | 144 +++++++++++---------- .../test/template/form_options_helper_test.rb | 22 ++-- actionpack/test/template/form_tag_helper_test.rb | 18 +-- 10 files changed, 188 insertions(+), 126 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/deprecated_block_helpers.rb b/actionpack/lib/action_view/helpers/deprecated_block_helpers.rb index ffbffbf25e..3d0657e873 100644 --- a/actionpack/lib/action_view/helpers/deprecated_block_helpers.rb +++ b/actionpack/lib/action_view/helpers/deprecated_block_helpers.rb @@ -6,6 +6,7 @@ module ActionView include ActionView::Helpers::TagHelper include ActionView::Helpers::TextHelper include ActionView::Helpers::JavaScriptHelper + include ActionView::Helpers::FormHelper def content_tag(*, &block) block_called_from_erb?(block) ? safe_concat(super) : super @@ -15,6 +16,22 @@ module ActionView block_called_from_erb?(block) ? safe_concat(super) : super end + def form_for(*, &block) + block_called_from_erb?(block) ? safe_concat(super) : super + end + + def form_tag(*, &block) + block_called_from_erb?(block) ? safe_concat(super) : super + end + + def fields_for(*, &block) + block_called_from_erb?(block) ? safe_concat(super) : super + end + + def field_set_tag(*, &block) + block_called_from_erb?(block) ? safe_concat(super) : super + end + BLOCK_CALLED_FROM_ERB = 'defined? __in_erb_template' if RUBY_VERSION < '1.9.0' diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index 742e873a49..48df26efaa 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -92,6 +92,10 @@ module ActionView # link:classes/ActionView/Helpers/DateHelper.html, and # link:classes/ActionView/Helpers/ActiveRecordHelper.html module FormHelper + extend ActiveSupport::Concern + + include FormTagHelper + # Creates a form and a scope around a specific model object that is used # as a base for questioning about values for the fields. # @@ -309,9 +313,9 @@ module ActionView options[:html][:remote] = true if options.delete(:remote) - safe_concat(form_tag(options.delete(:url) || {}, options.delete(:html) || {})) - fields_for(object_name, *(args << options), &proc) - safe_concat('') + output = form_tag(options.delete(:url) || {}, options.delete(:html) || {}) + output << fields_for(object_name, *(args << options), &proc) + output.safe_concat('') end def apply_form_for_options!(object_or_array, options) #:nodoc: @@ -528,7 +532,10 @@ module ActionView end builder = options[:builder] || ActionView::Base.default_form_builder - yield builder.new(object_name, object, self, options, block) + + with_output_buffer do + yield builder.new(object_name, object, self, options, block) + end end # Returns a label tag tailored for labelling an input field for a specified attribute (identified by +method+) on an object @@ -1183,9 +1190,11 @@ module ActionView if association.is_a?(Array) explicit_child_index = options[:child_index] - association.map do |child| - fields_for_nested_model("#{name}[#{explicit_child_index || nested_child_index(name)}]", child, options, block) - end.join + output = ActiveSupport::SafeBuffer.new + association.each do |child| + output << fields_for_nested_model("#{name}[#{explicit_child_index || nested_child_index(name)}]", child, options, block) + end + output elsif association fields_for_nested_model(name, association, options, block) end diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb index 7f74be27cb..7039ecd233 100644 --- a/actionpack/lib/action_view/helpers/form_options_helper.rb +++ b/actionpack/lib/action_view/helpers/form_options_helper.rb @@ -97,7 +97,9 @@ module ActionView # # module FormOptionsHelper + # ERB::Util can mask some helpers like textilize. Make sure to include them. include ERB::Util + include TextHelper # Create a select tag and a series of contained option tags for the provided object and method. # The option currently held by the object will be selected, provided that the object is available. diff --git a/actionpack/lib/action_view/helpers/form_tag_helper.rb b/actionpack/lib/action_view/helpers/form_tag_helper.rb index 7dcaee7e34..573733ffea 100644 --- a/actionpack/lib/action_view/helpers/form_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/form_tag_helper.rb @@ -10,6 +10,11 @@ module ActionView # NOTE: The HTML options disabled, readonly, and multiple can all be treated as booleans. So specifying # :disabled => true will give disabled="disabled". module FormTagHelper + extend ActiveSupport::Concern + + include UrlHelper + include TextHelper + # Starts a form tag that points the action to an url configured with url_for_options just like # ActionController::Base#url_for. The method for the form defaults to POST. # @@ -441,10 +446,10 @@ module ActionView # # =>

def field_set_tag(legend = nil, options = nil, &block) content = capture(&block) - safe_concat(tag(:fieldset, options, true)) - safe_concat(content_tag(:legend, legend)) unless legend.blank? - concat(content) - safe_concat("") + output = tag(:fieldset, options, true) + output.safe_concat(content_tag(:legend, legend)) unless legend.blank? + output.concat(content) + output.safe_concat("") end private @@ -477,9 +482,10 @@ module ActionView def form_tag_in_block(html_options, &block) content = capture(&block) - safe_concat(form_tag_html(html_options)) - concat(content) - safe_concat("") + output = ActiveSupport::SafeBuffer.new + output.safe_concat(form_tag_html(html_options)) + output << content + output.safe_concat("") end def token_tag diff --git a/actionpack/lib/action_view/template/handlers/erb.rb b/actionpack/lib/action_view/template/handlers/erb.rb index 3fcae167ff..937694ce8e 100644 --- a/actionpack/lib/action_view/template/handlers/erb.rb +++ b/actionpack/lib/action_view/template/handlers/erb.rb @@ -28,10 +28,18 @@ module ActionView @buffer.to_s end + def to_str + @buffer.to_str + end + def empty? @buffer.empty? end + def html_safe? + @buffer.html_safe? + end + if "".respond_to?(:force_encoding) def force_encoding(encoding) @buffer.force_encoding(encoding) diff --git a/actionpack/test/template/date_helper_test.rb b/actionpack/test/template/date_helper_test.rb index 9a2d490854..da2477b6f8 100644 --- a/actionpack/test/template/date_helper_test.rb +++ b/actionpack/test/template/date_helper_test.rb @@ -1250,7 +1250,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Date.new(2004, 6, 15) - fields_for :post, @post do |f| + output_buffer = fields_for :post, @post do |f| concat f.date_select(:written_on) end @@ -1266,7 +1266,7 @@ class DateHelperTest < ActionView::TestCase @post.written_on = Date.new(2004, 6, 15) id = 27 - fields_for :post, @post, :index => id do |f| + output_buffer = fields_for :post, @post, :index => id do |f| concat f.date_select(:written_on) end @@ -1282,7 +1282,7 @@ class DateHelperTest < ActionView::TestCase @post.written_on = Date.new(2004, 6, 15) id = nil - fields_for :post, @post, :index => id do |f| + output_buffer = fields_for :post, @post, :index => id do |f| concat f.date_select(:written_on) end @@ -1478,7 +1478,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Date.new(2004, 6, 15) - fields_for :post, @post do |f| + output_buffer = fields_for :post, @post do |f| concat f.date_select(:written_on, {}, :class => 'selector') end @@ -1642,7 +1642,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Time.local(2004, 6, 15, 15, 16, 35) - fields_for :post, @post do |f| + output_buffer = fields_for :post, @post do |f| concat f.time_select(:written_on, {}, :class => 'selector') end @@ -1816,7 +1816,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.updated_at = Time.local(2004, 6, 15, 16, 35) - fields_for :post, @post do |f| + output_buffer = fields_for :post, @post do |f| concat f.datetime_select(:updated_at, {}, :class => 'selector') end @@ -2052,7 +2052,7 @@ class DateHelperTest < ActionView::TestCase @post.updated_at = Time.local(2004, 6, 15, 16, 35) id = 456 - fields_for :post, @post, :index => id do |f| + output_buffer = fields_for :post, @post, :index => id do |f| concat f.datetime_select(:updated_at) end diff --git a/actionpack/test/template/erb/tag_helper_test.rb b/actionpack/test/template/erb/tag_helper_test.rb index d9ca828b43..b91539ef0b 100644 --- a/actionpack/test/template/erb/tag_helper_test.rb +++ b/actionpack/test/template/erb/tag_helper_test.rb @@ -1,6 +1,28 @@ require "abstract_unit" module ERBTest + class ViewContext + mock_controller = Class.new do + include SharedTestRoutes.url_helpers + end + + include ActionView::Helpers::TagHelper + include ActionView::Helpers::JavaScriptHelper + include ActionView::Helpers::FormHelper + + attr_accessor :output_buffer + + def protect_against_forgery?() false end + + define_method(:controller) do + mock_controller.new + end + end + + class DeprecatedViewContext < ViewContext + include ActionView::Helpers::DeprecatedBlockHelpers + end + module SharedTagHelpers extend ActiveSupport::Testing::Declarative @@ -22,16 +44,21 @@ module ERBTest expected_output = "" assert_equal expected_output, render_content("javascript_tag(:id => 'the_js_tag')", "alert('Hello')") end + + test "percent equals works with form tags" do + expected_output = "
hello
" + assert_equal expected_output, render_content("form_tag('foo')", "<%= 'hello' %>") + end + + test "percent equals works with fieldset tags" do + expected_output = "
foohello
" + assert_equal expected_output, render_content("field_set_tag('foo')", "<%= 'hello' %>") + end end class TagHelperTest < ActiveSupport::TestCase def context - Class.new do - include ActionView::Helpers::TagHelper - include ActionView::Helpers::JavaScriptHelper - - attr_accessor :output_buffer - end + ViewContext end def block_helper(str, rest) @@ -43,12 +70,7 @@ module ERBTest class DeprecatedTagHelperTest < ActiveSupport::TestCase def context - Class.new do - include ActionView::Helpers::TagHelper - include ActionView::Helpers::JavaScriptHelper - include ActionView::Helpers::DeprecatedBlockHelpers - attr_accessor :output_buffer - end + DeprecatedViewContext end def block_helper(str, rest) diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb index d143c39c9c..7c5ccfd6ed 100644 --- a/actionpack/test/template/form_helper_test.rb +++ b/actionpack/test/template/form_helper_test.rb @@ -4,6 +4,10 @@ require 'controller/fake_models' class FormHelperTest < ActionView::TestCase tests ActionView::Helpers::FormHelper + def form_for(*) + @output_buffer = super + end + def setup super @@ -590,9 +594,9 @@ class FormHelperTest < ActionView::TestCase def test_nested_fields_for form_for(:post, @post) do |f| - f.fields_for(:comment, @post) do |c| + concat f.fields_for(:comment, @post) { |c| concat c.text_field(:title) - end + } end expected = "
" + @@ -605,9 +609,9 @@ class FormHelperTest < ActionView::TestCase def test_nested_fields_for_with_nested_collections form_for('post[]', @post) do |f| concat f.text_field(:title) - f.fields_for('comment[]', @comment) do |c| + concat f.fields_for('comment[]', @comment) { |c| concat c.text_field(:name) - end + } end expected = "" + @@ -621,9 +625,9 @@ class FormHelperTest < ActionView::TestCase def test_nested_fields_for_with_index_and_parent_fields form_for('post', @post, :index => 1) do |c| concat c.text_field(:title) - c.fields_for('comment', @comment, :index => 1) do |r| + concat c.fields_for('comment', @comment, :index => 1) { |r| concat r.text_field(:name) - end + } end expected = "" + @@ -635,10 +639,10 @@ class FormHelperTest < ActionView::TestCase end def test_form_for_with_index_and_nested_fields_for - form_for(:post, @post, :index => 1) do |f| - f.fields_for(:comment, @post) do |c| + output_buffer = form_for(:post, @post, :index => 1) do |f| + concat f.fields_for(:comment, @post) { |c| concat c.text_field(:title) - end + } end expected = "" + @@ -650,9 +654,9 @@ class FormHelperTest < ActionView::TestCase def test_nested_fields_for_with_index_on_both form_for(:post, @post, :index => 1) do |f| - f.fields_for(:comment, @post, :index => 5) do |c| + concat f.fields_for(:comment, @post, :index => 5) { |c| concat c.text_field(:title) - end + } end expected = "" + @@ -664,9 +668,9 @@ class FormHelperTest < ActionView::TestCase def test_nested_fields_for_with_auto_index form_for("post[]", @post) do |f| - f.fields_for(:comment, @post) do |c| + concat f.fields_for(:comment, @post) { |c| concat c.text_field(:title) - end + } end expected = "" + @@ -678,9 +682,9 @@ class FormHelperTest < ActionView::TestCase def test_nested_fields_for_with_index_radio_button form_for(:post, @post) do |f| - f.fields_for(:comment, @post, :index => 5) do |c| + concat f.fields_for(:comment, @post, :index => 5) { |c| concat c.radio_button(:title, "hello") - end + } end expected = "" + @@ -692,9 +696,9 @@ class FormHelperTest < ActionView::TestCase def test_nested_fields_for_with_auto_index_on_both form_for("post[]", @post) do |f| - f.fields_for("comment[]", @post) do |c| + concat f.fields_for("comment[]", @post) { |c| concat c.text_field(:title) - end + } end expected = "" + @@ -705,16 +709,16 @@ class FormHelperTest < ActionView::TestCase end def test_nested_fields_for_with_index_and_auto_index - form_for("post[]", @post) do |f| - f.fields_for(:comment, @post, :index => 5) do |c| + output_buffer = form_for("post[]", @post) do |f| + concat f.fields_for(:comment, @post, :index => 5) { |c| concat c.text_field(:title) - end + } end - form_for(:post, @post, :index => 1) do |f| - f.fields_for("comment[]", @post) do |c| + output_buffer << form_for(:post, @post, :index => 1) do |f| + concat f.fields_for("comment[]", @post) { |c| concat c.text_field(:title) - end + } end expected = "" + @@ -732,9 +736,9 @@ class FormHelperTest < ActionView::TestCase form_for(:post, @post) do |f| concat f.text_field(:title) - f.fields_for(:author) do |af| + concat f.fields_for(:author) { |af| concat af.text_field(:name) - end + } end expected = '' + @@ -759,9 +763,9 @@ class FormHelperTest < ActionView::TestCase form_for(:post, @post) do |f| concat f.text_field(:title) - f.fields_for(:author) do |af| + concat f.fields_for(:author) { |af| concat af.text_field(:name) - end + } end expected = '' + @@ -778,10 +782,10 @@ class FormHelperTest < ActionView::TestCase form_for(:post, @post) do |f| concat f.text_field(:title) - f.fields_for(:author) do |af| + concat f.fields_for(:author) { |af| concat af.hidden_field(:id) concat af.text_field(:name) - end + } end expected = '' + @@ -799,9 +803,9 @@ class FormHelperTest < ActionView::TestCase form_for(:post, @post) do |f| concat f.text_field(:title) @post.comments.each do |comment| - f.fields_for(:comments, comment) do |cf| + concat f.fields_for(:comments, comment) { |cf| concat cf.text_field(:name) - end + } end end @@ -822,10 +826,10 @@ class FormHelperTest < ActionView::TestCase form_for(:post, @post) do |f| concat f.text_field(:title) @post.comments.each do |comment| - f.fields_for(:comments, comment) do |cf| + concat f.fields_for(:comments, comment) { |cf| concat cf.hidden_field(:id) concat cf.text_field(:name) - end + } end end @@ -846,9 +850,9 @@ class FormHelperTest < ActionView::TestCase form_for(:post, @post) do |f| concat f.text_field(:title) @post.comments.each do |comment| - f.fields_for(:comments, comment) do |cf| + concat f.fields_for(:comments, comment) { |cf| concat cf.text_field(:name) - end + } end end @@ -867,9 +871,9 @@ class FormHelperTest < ActionView::TestCase form_for(:post, @post) do |f| concat f.text_field(:title) @post.comments.each do |comment| - f.fields_for(:comments, comment) do |cf| + concat f.fields_for(:comments, comment) { |cf| concat cf.text_field(:name) - end + } end end @@ -903,9 +907,9 @@ class FormHelperTest < ActionView::TestCase form_for(:post, @post) do |f| concat f.text_field(:title) - f.fields_for(:comments, @post.comments) do |cf| + concat f.fields_for(:comments, @post.comments) { |cf| concat cf.text_field(:name) - end + } end expected = '' + @@ -925,9 +929,9 @@ class FormHelperTest < ActionView::TestCase form_for(:post, @post) do |f| concat f.text_field(:title) - f.fields_for(:comments, comments) do |cf| + concat f.fields_for(:comments, comments) { |cf| concat cf.text_field(:name) - end + } end expected = '' + @@ -947,10 +951,10 @@ class FormHelperTest < ActionView::TestCase form_for(:post, @post) do |f| concat f.text_field(:title) - f.fields_for(:comments) do |cf| + concat f.fields_for(:comments) { |cf| concat cf.text_field(:name) yielded_comments << cf.object - end + } end expected = '' + @@ -968,9 +972,9 @@ class FormHelperTest < ActionView::TestCase @post.comments = [] form_for(:post, @post) do |f| - f.fields_for(:comments, Comment.new(321), :child_index => 'abc') do |cf| + concat f.fields_for(:comments, Comment.new(321), :child_index => 'abc') { |cf| concat cf.text_field(:name) - end + } end expected = '' + @@ -988,24 +992,24 @@ class FormHelperTest < ActionView::TestCase @post.tags[0].relevances = [] @post.tags[1].relevances = [] form_for(:post, @post) do |f| - f.fields_for(:comments, @post.comments[0]) do |cf| + concat f.fields_for(:comments, @post.comments[0]) { |cf| concat cf.text_field(:name) - cf.fields_for(:relevances, CommentRelevance.new(314)) do |crf| + concat cf.fields_for(:relevances, CommentRelevance.new(314)) { |crf| concat crf.text_field(:value) - end - end - f.fields_for(:tags, @post.tags[0]) do |tf| + } + } + concat f.fields_for(:tags, @post.tags[0]) { |tf| concat tf.text_field(:value) - tf.fields_for(:relevances, TagRelevance.new(3141)) do |trf| + concat tf.fields_for(:relevances, TagRelevance.new(3141)) { |trf| concat trf.text_field(:value) - end - end - f.fields_for('tags', @post.tags[1]) do |tf| + } + } + concat f.fields_for('tags', @post.tags[1]) { |tf| concat tf.text_field(:value) - tf.fields_for(:relevances, TagRelevance.new(31415)) do |trf| + concat tf.fields_for(:relevances, TagRelevance.new(31415)) { |trf| concat trf.text_field(:value) - end - end + } + } end expected = '' + @@ -1027,7 +1031,7 @@ class FormHelperTest < ActionView::TestCase end def test_fields_for - fields_for(:post, @post) do |f| + output_buffer = fields_for(:post, @post) do |f| concat f.text_field(:title) concat f.text_area(:body) concat f.check_box(:secret) @@ -1043,7 +1047,7 @@ class FormHelperTest < ActionView::TestCase end def test_fields_for_with_index - fields_for("post[]", @post) do |f| + output_buffer = fields_for("post[]", @post) do |f| concat f.text_field(:title) concat f.text_area(:body) concat f.check_box(:secret) @@ -1059,7 +1063,7 @@ class FormHelperTest < ActionView::TestCase end def test_fields_for_with_nil_index_option_override - fields_for("post[]", @post, :index => nil) do |f| + output_buffer = fields_for("post[]", @post, :index => nil) do |f| concat f.text_field(:title) concat f.text_area(:body) concat f.check_box(:secret) @@ -1075,7 +1079,7 @@ class FormHelperTest < ActionView::TestCase end def test_fields_for_with_index_option_override - fields_for("post[]", @post, :index => "abc") do |f| + output_buffer = fields_for("post[]", @post, :index => "abc") do |f| concat f.text_field(:title) concat f.text_area(:body) concat f.check_box(:secret) @@ -1091,7 +1095,7 @@ class FormHelperTest < ActionView::TestCase end def test_fields_for_without_object - fields_for(:post) do |f| + output_buffer = fields_for(:post) do |f| concat f.text_field(:title) concat f.text_area(:body) concat f.check_box(:secret) @@ -1107,7 +1111,7 @@ class FormHelperTest < ActionView::TestCase end def test_fields_for_with_only_object - fields_for(@post) do |f| + output_buffer = fields_for(@post) do |f| concat f.text_field(:title) concat f.text_area(:body) concat f.check_box(:secret) @@ -1123,7 +1127,7 @@ class FormHelperTest < ActionView::TestCase end def test_fields_for_object_with_bracketed_name - fields_for("author[post]", @post) do |f| + output_buffer = fields_for("author[post]", @post) do |f| concat f.label(:title) concat f.text_field(:title) end @@ -1134,7 +1138,7 @@ class FormHelperTest < ActionView::TestCase end def test_fields_for_object_with_bracketed_name_and_index - fields_for("author[post]", @post, :index => 1) do |f| + output_buffer = fields_for("author[post]", @post, :index => 1) do |f| concat f.label(:title) concat f.text_field(:title) end @@ -1153,9 +1157,9 @@ class FormHelperTest < ActionView::TestCase concat post_form.text_field(:title) concat post_form.text_area(:body) - fields_for(:parent_post, @post) do |parent_fields| + concat fields_for(:parent_post, @post) { |parent_fields| concat parent_fields.check_box(:secret) - end + } end expected = @@ -1174,9 +1178,9 @@ class FormHelperTest < ActionView::TestCase concat post_form.text_field(:title) concat post_form.text_area(:body) - post_form.fields_for(@comment) do |comment_fields| + concat post_form.fields_for(@comment) { |comment_fields| concat comment_fields.text_field(:name) - end + } end expected = @@ -1273,7 +1277,7 @@ class FormHelperTest < ActionView::TestCase end def test_fields_for_with_labelled_builder - fields_for(:post, @post, :builder => LabelledFormBuilder) do |f| + output_buffer = fields_for(:post, @post, :builder => LabelledFormBuilder) do |f| concat f.text_field(:title) concat f.text_area(:body) concat f.check_box(:secret) diff --git a/actionpack/test/template/form_options_helper_test.rb b/actionpack/test/template/form_options_helper_test.rb index aa40e46aa8..5799e3db53 100644 --- a/actionpack/test/template/form_options_helper_test.rb +++ b/actionpack/test/template/form_options_helper_test.rb @@ -293,7 +293,7 @@ class FormOptionsHelperTest < ActionView::TestCase @post = Post.new @post.category = "" - fields_for :post, @post do |f| + output_buffer = fields_for :post, @post do |f| concat f.select(:category, %w( abe hest)) end @@ -307,7 +307,7 @@ class FormOptionsHelperTest < ActionView::TestCase @post = Post.new @post.category = "" - fields_for :post, @post, :index => 108 do |f| + output_buffer = fields_for :post, @post, :index => 108 do |f| concat f.select(:category, %w( abe hest)) end @@ -322,7 +322,7 @@ class FormOptionsHelperTest < ActionView::TestCase @post.category = "" def @post.to_param; 108; end - fields_for "post[]", @post do |f| + output_buffer = fields_for "post[]", @post do |f| concat f.select(:category, %w( abe hest)) end @@ -336,7 +336,7 @@ class FormOptionsHelperTest < ActionView::TestCase @post = Post.new options = "" - fields_for :post, @post do |f| + output_buffer = fields_for :post, @post do |f| concat f.select(:category, options, :prompt => 'The prompt') end @@ -462,7 +462,7 @@ class FormOptionsHelperTest < ActionView::TestCase @post = Post.new @post.author_name = "Babe" - fields_for :post, @post do |f| + output_buffer = fields_for :post, @post do |f| concat f.collection_select(:author_name, dummy_posts, :author_name, :author_name) end @@ -476,7 +476,7 @@ class FormOptionsHelperTest < ActionView::TestCase @post = Post.new @post.author_name = "Babe" - fields_for :post, @post, :index => 815 do |f| + output_buffer = fields_for :post, @post, :index => 815 do |f| concat f.collection_select(:author_name, dummy_posts, :author_name, :author_name) end @@ -491,7 +491,7 @@ class FormOptionsHelperTest < ActionView::TestCase @post.author_name = "Babe" def @post.to_param; 815; end - fields_for "post[]", @post do |f| + output_buffer = fields_for "post[]", @post do |f| concat f.collection_select(:author_name, dummy_posts, :author_name, :author_name) end @@ -570,7 +570,7 @@ class FormOptionsHelperTest < ActionView::TestCase def test_time_zone_select_under_fields_for @firm = Firm.new("D") - fields_for :firm, @firm do |f| + output_buffer = fields_for :firm, @firm do |f| concat f.time_zone_select(:time_zone) end @@ -589,7 +589,7 @@ class FormOptionsHelperTest < ActionView::TestCase def test_time_zone_select_under_fields_for_with_index @firm = Firm.new("D") - fields_for :firm, @firm, :index => 305 do |f| + output_buffer = fields_for :firm, @firm, :index => 305 do |f| concat f.time_zone_select(:time_zone) end @@ -609,7 +609,7 @@ class FormOptionsHelperTest < ActionView::TestCase @firm = Firm.new("D") def @firm.to_param; 305; end - fields_for "firm[]", @firm do |f| + output_buffer = fields_for "firm[]", @firm do |f| concat f.time_zone_select(:time_zone) end @@ -787,7 +787,7 @@ class FormOptionsHelperTest < ActionView::TestCase @post = Post.new @post.origin = 'dk' - fields_for :post, @post do |f| + output_buffer = fields_for :post, @post do |f| concat f.grouped_collection_select("origin", @continents, :countries, :continent_name, :country_id, :country_name) end diff --git a/actionpack/test/template/form_tag_helper_test.rb b/actionpack/test/template/form_tag_helper_test.rb index c7d4bc986c..868a35c476 100644 --- a/actionpack/test/template/form_tag_helper_test.rb +++ b/actionpack/test/template/form_tag_helper_test.rb @@ -59,16 +59,14 @@ class FormTagHelperTest < ActionView::TestCase end def test_form_tag_with_block_in_erb - __in_erb_template = '' - form_tag("http://example.com") { concat "Hello world!" } + output_buffer = form_tag("http://example.com") { concat "Hello world!" } expected = %(Hello world!) assert_dom_equal expected, output_buffer end def test_form_tag_with_block_and_method_in_erb - __in_erb_template = '' - form_tag("http://example.com", :method => :put) { concat "Hello world!" } + output_buffer = form_tag("http://example.com", :method => :put) { concat "Hello world!" } expected = %(
Hello world!
) assert_dom_equal expected, output_buffer @@ -332,26 +330,22 @@ class FormTagHelperTest < ActionView::TestCase end def test_field_set_tag_in_erb - __in_erb_template = '' - field_set_tag("Your details") { concat "Hello world!" } + output_buffer = field_set_tag("Your details") { concat "Hello world!" } expected = %(
Your detailsHello world!
) assert_dom_equal expected, output_buffer - self.output_buffer = ''.html_safe - field_set_tag { concat "Hello world!" } + output_buffer = field_set_tag { concat "Hello world!" } expected = %(
Hello world!
) assert_dom_equal expected, output_buffer - self.output_buffer = ''.html_safe - field_set_tag('') { concat "Hello world!" } + output_buffer = field_set_tag('') { concat "Hello world!" } expected = %(
Hello world!
) assert_dom_equal expected, output_buffer - self.output_buffer = ''.html_safe - field_set_tag('', :class => 'format') { concat "Hello world!" } + output_buffer = field_set_tag('', :class => 'format') { concat "Hello world!" } expected = %(
Hello world!
) assert_dom_equal expected, output_buffer -- cgit v1.2.3 From ec0973c2abeb80eb3c93c5df070592da56ef5b7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 10 Mar 2010 16:44:24 +0100 Subject: Remove uneeded methods. --- .../action_controller/metal/http_authentication.rb | 22 ++++------------------ .../lib/action_dispatch/http/mime_negotiation.rb | 15 --------------- 2 files changed, 4 insertions(+), 33 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/http_authentication.rb b/actionpack/lib/action_controller/metal/http_authentication.rb index f1355a83a3..6ec788f302 100644 --- a/actionpack/lib/action_controller/metal/http_authentication.rb +++ b/actionpack/lib/action_controller/metal/http_authentication.rb @@ -124,7 +124,7 @@ module ActionController end def authenticate(request, &login_procedure) - unless authorization(request).blank? + unless request.authorization.blank? login_procedure.call(*user_name_and_password(request)) end end @@ -133,15 +133,8 @@ module ActionController decode_credentials(request).split(/:/, 2) end - def authorization(request) - request.env['HTTP_AUTHORIZATION'] || - request.env['X-HTTP_AUTHORIZATION'] || - request.env['X_HTTP_AUTHORIZATION'] || - request.env['REDIRECT_X_HTTP_AUTHORIZATION'] - end - def decode_credentials(request) - ActiveSupport::Base64.decode64(authorization(request).split(' ', 2).last || '') + ActiveSupport::Base64.decode64(request.authorization.split(' ', 2).last || '') end def encode_credentials(user_name, password) @@ -176,14 +169,7 @@ module ActionController # Returns false on a valid response, true otherwise def authenticate(secret_key, request, realm, &password_procedure) - authorization(request) && validate_digest_response(secret_key, request, realm, &password_procedure) - end - - def authorization(request) - request.env['HTTP_AUTHORIZATION'] || - request.env['X-HTTP_AUTHORIZATION'] || - request.env['X_HTTP_AUTHORIZATION'] || - request.env['REDIRECT_X_HTTP_AUTHORIZATION'] + request.authorization && validate_digest_response(secret_key, request, realm, &password_procedure) end # Returns false unless the request credentials response value matches the expected value. @@ -226,7 +212,7 @@ module ActionController end def decode_credentials_header(request) - decode_credentials(authorization(request)) + decode_credentials(request.authorization) end def decode_credentials(header) diff --git a/actionpack/lib/action_dispatch/http/mime_negotiation.rb b/actionpack/lib/action_dispatch/http/mime_negotiation.rb index 40617e239a..fec250e928 100644 --- a/actionpack/lib/action_dispatch/http/mime_negotiation.rb +++ b/actionpack/lib/action_dispatch/http/mime_negotiation.rb @@ -67,21 +67,6 @@ module ActionDispatch @env["action_dispatch.request.formats"] = [Mime::Type.lookup_by_extension(parameters[:format])] end - # Returns a symbolized version of the :format parameter of the request. - # If no \format is given it returns :jsfor Ajax requests and :html - # otherwise. - def template_format - parameter_format = parameters[:format] - - if parameter_format - parameter_format - elsif xhr? - :js - else - :html - end - end - # Receives an array of mimes and return the first user sent mime that # matches the order array. # -- cgit v1.2.3 From 07cf49aadf3195db6ddefc58932efc88a6704a09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 10 Mar 2010 22:11:48 +0100 Subject: Optimize and clean up how details key get expired. --- actionpack/lib/abstract_controller.rb | 1 + actionpack/lib/abstract_controller/rendering.rb | 28 +++++++++++ actionpack/lib/abstract_controller/view_paths.rb | 3 +- actionpack/lib/action_view.rb | 1 + actionpack/lib/action_view/base.rb | 2 +- actionpack/lib/action_view/lookup_context.rb | 57 +++++++++++----------- actionpack/lib/action_view/template/resolver.rb | 5 ++ .../test/template/compiled_templates_test.rb | 3 -- actionpack/test/template/render_test.rb | 8 +-- 9 files changed, 71 insertions(+), 37 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller.rb b/actionpack/lib/abstract_controller.rb index 7028cd0379..2da4dc052c 100644 --- a/actionpack/lib/abstract_controller.rb +++ b/actionpack/lib/abstract_controller.rb @@ -7,6 +7,7 @@ require 'active_support/core_ext/class/attribute' require 'active_support/core_ext/module/attr_internal' require 'active_support/core_ext/module/delegation' require 'active_support/core_ext/module/anonymous' +require 'active_support/i18n' module AbstractController extend ActiveSupport::Autoload diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb index 5c34b83563..42f4939108 100644 --- a/actionpack/lib/abstract_controller/rendering.rb +++ b/actionpack/lib/abstract_controller/rendering.rb @@ -9,10 +9,38 @@ module AbstractController end end + # This is a class to fix I18n global state. Whenever you provide I18n.locale during a request, + # it will trigger the lookup_context and consequently expire the cache. + # TODO Add some deprecation warnings to remove I18n.locale from controllers + class I18nProxy < ::I18n::Config #:nodoc: + attr_reader :i18n_config, :lookup_context + + def initialize(i18n_config, lookup_context) + @i18n_config, @lookup_context = i18n_config, lookup_context + end + + def locale + @i18n_config.locale + end + + def locale=(value) + @i18n_config.locale = value + @lookup_context.update_details(:locale => @i18n_config.locale) + end + end + module Rendering extend ActiveSupport::Concern include AbstractController::ViewPaths + # Overwrite process to setup I18n proxy. + def process(*) #:nodoc: + old_config, I18n.config = I18n.config, I18nProxy.new(I18n.config, lookup_context) + super + ensure + I18n.config = old_config + end + # An instance of a view class. The default view class is ActionView::Base # # The view class must have the following methods: diff --git a/actionpack/lib/abstract_controller/view_paths.rb b/actionpack/lib/abstract_controller/view_paths.rb index 6513c0778e..c2a9f6336d 100644 --- a/actionpack/lib/abstract_controller/view_paths.rb +++ b/actionpack/lib/abstract_controller/view_paths.rb @@ -7,7 +7,8 @@ module AbstractController self._view_paths = ActionView::PathSet.new end - delegate :template_exists?, :view_paths, :formats, :formats=, :to => :lookup_context + delegate :template_exists?, :view_paths, :formats, :formats=, + :locale, :locale=, :to => :lookup_context # LookupContext is the object responsible to hold all information required to lookup # templates, i.e. view paths and details. Check ActionView::LookupContext for more diff --git a/actionpack/lib/action_view.rb b/actionpack/lib/action_view.rb index 7e9ac8720c..afe6386105 100644 --- a/actionpack/lib/action_view.rb +++ b/actionpack/lib/action_view.rb @@ -58,6 +58,7 @@ module ActionView autoload :TestCase, 'action_view/test_case' end +require 'active_support/i18n' require 'active_support/core_ext/string/output_safety' I18n.load_path << "#{File.dirname(__FILE__)}/action_view/locale/en.yml" diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 564ea6684c..ffe3060404 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -194,7 +194,7 @@ module ActionView #:nodoc: attr_accessor :base_path, :assigns, :template_extension, :lookup_context attr_internal :captures, :request, :layout, :controller, :template, :config - delegate :find, :exists?, :formats, :formats=, + delegate :find, :exists?, :formats, :formats=, :locale, :locale=, :view_paths, :view_paths=, :with_fallbacks, :update_details, :to => :lookup_context delegate :request_forgery_protection_token, :template, :params, :session, :cookies, :response, :headers, diff --git a/actionpack/lib/action_view/lookup_context.rb b/actionpack/lib/action_view/lookup_context.rb index 4a4dc0d06c..91885c7370 100644 --- a/actionpack/lib/action_view/lookup_context.rb +++ b/actionpack/lib/action_view/lookup_context.rb @@ -1,4 +1,5 @@ require 'active_support/core_ext/object/try' +require 'active_support/core_ext/object/blank' module ActionView # LookupContext is the object responsible to hold all information required to lookup @@ -14,16 +15,14 @@ module ActionView def self.register_detail(name, options = {}) registered_details[name] = lambda do |value| - value = (value.blank? || options[:accessible] == false) ? - Array(yield) : Array(value) + value = Array(value.presence || yield) value |= [nil] unless options[:allow_nil] == false value end end register_detail(:formats) { Mime::SET.symbols } - register_detail(:locale, :accessible => false) { [I18n.locale] } - register_detail(:handlers, :accessible => false) { Template::Handlers.extensions } + register_detail(:locale) { [I18n.locale] } class DetailsKey #:nodoc: attr_reader :details @@ -38,16 +37,12 @@ module ActionView def initialize(details) @details, @hash = details, details.hash end - - def outdated?(details) - @details != details - end end def initialize(view_paths, details = {}) + @details_key = nil self.view_paths = view_paths self.details = details - @details_key = nil end module ViewPaths @@ -60,18 +55,15 @@ module ActionView end def find(name, prefix = nil, partial = false) - key = details_key - @view_paths.find(name, prefix, partial || false, key.details, key) + @view_paths.find(name, prefix, partial || false, details, details_key) end def find_all(name, prefix = nil, partial = false) - key = details_key - @view_paths.find_all(name, prefix, partial || false, key.details, key) + @view_paths.find_all(name, prefix, partial || false, details, details_key) end def exists?(name, prefix = nil, partial = false) - key = details_key - @view_paths.exists?(name, prefix, partial || false, key.details, key) + @view_paths.exists?(name, prefix, partial || false, details, details_key) end # Add fallbacks to the view paths. Useful in cases you are rendering a file. @@ -89,25 +81,20 @@ module ActionView end module Details - def details - @details = normalize_details(@details) - end + attr_reader :details - def details=(new_details) - @details = new_details - details + def details=(details) + @details = normalize_details(details) + @details_key = nil if @details_key && @details_key.details != @details end - # TODO This is too expensive. Revisit this. def details_key - latest_details = self.details - @details_key = nil if @details_key.try(:outdated?, latest_details) - @details_key ||= DetailsKey.get(latest_details) + @details_key ||= DetailsKey.get(@details) end # Shortcut to read formats from details. def formats - self.details[:formats] + @details[:formats].compact end # Shortcut to set formats in details. @@ -115,11 +102,25 @@ module ActionView self.details = @details.merge(:formats => value) end + # Shortcut to read locale. + def locale + I18n.locale + end + + # Shortcut to set locale in details and I18n. + def locale=(value) + I18n.locale = value + + unless I18n.config.respond_to?(:lookup_context) + self.details = @details.merge(:locale => value) + end + end + # Update the details keys by merging the given hash into the current # details hash. If a block is given, the details are modified just during # the execution of the block and reverted to the previous value after. def update_details(new_details) - old_details = self.details + old_details = @details self.details = old_details.merge(new_details) if block_given? @@ -140,7 +141,7 @@ module ActionView self.class.registered_details.each do |k, v| details[k] = v.call(details[k]) end - details + details.freeze end end diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb index c43b357e9e..a43597e728 100644 --- a/actionpack/lib/action_view/template/resolver.rb +++ b/actionpack/lib/action_view/template/resolver.rb @@ -21,6 +21,7 @@ module ActionView # Normalizes the arguments and passes it on to find_template. def find_all(name, prefix=nil, partial=false, details={}, key=nil) name, prefix = normalize_name(name, prefix) + details = details.merge(:handlers => default_handlers) cached(key, prefix, name, partial) do find_templates(name, prefix, partial, details) @@ -33,6 +34,10 @@ module ActionView @caching ||= !defined?(Rails.application) || Rails.application.config.cache_classes end + def default_handlers + Template::Handlers.extensions + [nil] + end + # This is what child classes implement. No defaults are needed # because Resolver guarantees that the arguments are present and # normalized. diff --git a/actionpack/test/template/compiled_templates_test.rb b/actionpack/test/template/compiled_templates_test.rb index 0a3409064f..2c719757e4 100644 --- a/actionpack/test/template/compiled_templates_test.rb +++ b/actionpack/test/template/compiled_templates_test.rb @@ -14,9 +14,6 @@ class CompiledTemplatesTest < Test::Unit::TestCase assert_equal "two", render(:file => "test/render_file_with_locals_and_default.erb", :locals => { :secret => "two" }) end - # This is broken in 1.8.6 (not supported in Rails 3.0) because the cache uses a Hash - # key. Since Ruby 1.8.6 implements Hash#hash using the hash's object_id, it will never - # successfully get a cache hit here. def test_template_changes_are_not_reflected_with_cached_templates assert_equal "Hello world!", render(:file => "test/hello_world.erb") modify_template "test/hello_world.erb", "Goodbye world!" do diff --git a/actionpack/test/template/render_test.rb b/actionpack/test/template/render_test.rb index 37a3975a54..cea8ab1bce 100644 --- a/actionpack/test/template/render_test.rb +++ b/actionpack/test/template/render_test.rb @@ -33,17 +33,17 @@ module RenderTestCases end def test_render_file_with_localization - old_locale, I18n.locale = I18n.locale, :da + old_locale, @view.locale = @view.locale, :da assert_equal "Hey verden", @view.render(:file => "test/hello_world") ensure - I18n.locale = old_locale + @view.locale = old_locale end def test_render_file_with_dashed_locale - old_locale, I18n.locale = I18n.locale, :"pt-BR" + old_locale, @view.locale = @view.locale, :"pt-BR" assert_equal "Ola mundo", @view.render(:file => "test/hello_world") ensure - I18n.locale = old_locale + @view.locale = old_locale end def test_render_file_at_top_level -- cgit v1.2.3 From 6c027443b044276fd2a85b387b67a8dee940b320 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Thu, 11 Mar 2010 12:45:05 +0100 Subject: Add tests for lookup context. --- actionpack/lib/action_view/lookup_context.rb | 66 ++++---- .../test/controller/new_base/render_rjs_test.rb | 2 +- actionpack/test/lib/fixture_template.rb | 2 + actionpack/test/template/lookup_context_test.rb | 167 +++++++++++++++++++++ 4 files changed, 203 insertions(+), 34 deletions(-) create mode 100644 actionpack/test/template/lookup_context_test.rb (limited to 'actionpack') diff --git a/actionpack/lib/action_view/lookup_context.rb b/actionpack/lib/action_view/lookup_context.rb index 91885c7370..0bb73b590d 100644 --- a/actionpack/lib/action_view/lookup_context.rb +++ b/actionpack/lib/action_view/lookup_context.rb @@ -11,16 +11,26 @@ module ActionView @@fallbacks = [FileSystemResolver.new(""), FileSystemResolver.new("/")] mattr_accessor :registered_details - self.registered_details = {} + self.registered_details = [] def self.register_detail(name, options = {}) - registered_details[name] = lambda do |value| + self.registered_details << name + + Setters.send :define_method, :"#{name}=" do |value| value = Array(value.presence || yield) value |= [nil] unless options[:allow_nil] == false - value + + unless value == @details[name] + @details_key, @details = nil, @details.merge(name => value) + @details.freeze + end end end + # Holds raw setters for the registered details. + module Setters #:nodoc: + end + register_detail(:formats) { Mime::SET.symbols } register_detail(:locale) { [I18n.locale] } @@ -40,7 +50,7 @@ module ActionView end def initialize(view_paths, details = {}) - @details_key = nil + @details, @details_key = {}, nil self.view_paths = view_paths self.details = details end @@ -55,18 +65,18 @@ module ActionView end def find(name, prefix = nil, partial = false) - @view_paths.find(name, prefix, partial || false, details, details_key) + @view_paths.find(name, prefix, partial, details, details_key) end def find_all(name, prefix = nil, partial = false) - @view_paths.find_all(name, prefix, partial || false, details, details_key) + @view_paths.find_all(name, prefix, partial, details, details_key) end def exists?(name, prefix = nil, partial = false) - @view_paths.exists?(name, prefix, partial || false, details, details_key) + @view_paths.exists?(name, prefix, partial, details, details_key) end - # Add fallbacks to the view paths. Useful in cases you are rendering a file. + # Add fallbacks to the view paths. Useful in cases you are rendering a :file. def with_fallbacks added_resolvers = 0 self.class.fallbacks.each do |resolver| @@ -83,9 +93,8 @@ module ActionView module Details attr_reader :details - def details=(details) - @details = normalize_details(details) - @details_key = nil if @details_key && @details_key.details != @details + def details=(given_details) + registered_details.each { |key| send(:"#{key}=", given_details[key]) } end def details_key @@ -97,9 +106,10 @@ module ActionView @details[:formats].compact end - # Shortcut to set formats in details. - def formats=(value) - self.details = @details.merge(:formats => value) + # Overload formats= to reject [:"*/*"] values. + def formats=(value, freeze=true) + value = nil if value == [:"*/*"] + super(value) end # Shortcut to read locale. @@ -107,13 +117,14 @@ module ActionView I18n.locale end - # Shortcut to set locale in details and I18n. + # Overload locale= to also set the I18n.locale. If the current I18n.config object responds + # to i18n_config, it means that it's has a copy of the original I18n configuration and it's + # acting as proxy, which we need to skip. def locale=(value) - I18n.locale = value - - unless I18n.config.respond_to?(:lookup_context) - self.details = @details.merge(:locale => value) - end + value = value.first if value.is_a?(Array) + config = I18n.config.respond_to?(:i18n_config) ? I18n.config.i18n_config : I18n.config + config.locale = value if value + super(I18n.locale) end # Update the details keys by merging the given hash into the current @@ -127,24 +138,13 @@ module ActionView begin yield ensure - self.details = old_details + @details = old_details end end end - - protected - - def normalize_details(details) - details = details.dup - # TODO: Refactor this concern out of the resolver - details.delete(:formats) if details[:formats] == [:"*/*"] - self.class.registered_details.each do |k, v| - details[k] = v.call(details[k]) - end - details.freeze - end end + include Setters include Details include ViewPaths end diff --git a/actionpack/test/controller/new_base/render_rjs_test.rb b/actionpack/test/controller/new_base/render_rjs_test.rb index 8c47b38ab6..f4516ade63 100644 --- a/actionpack/test/controller/new_base/render_rjs_test.rb +++ b/actionpack/test/controller/new_base/render_rjs_test.rb @@ -17,7 +17,7 @@ module RenderRjs end def index_locale - old_locale, I18n.locale = I18n.locale, :da + self.locale = :da end end diff --git a/actionpack/test/lib/fixture_template.rb b/actionpack/test/lib/fixture_template.rb index d287fae470..eda76ddfd0 100644 --- a/actionpack/test/lib/fixture_template.rb +++ b/actionpack/test/lib/fixture_template.rb @@ -1,5 +1,7 @@ module ActionView #:nodoc: class FixtureResolver < PathResolver + attr_reader :hash + def initialize(hash = {}) super() @hash = hash diff --git a/actionpack/test/template/lookup_context_test.rb b/actionpack/test/template/lookup_context_test.rb new file mode 100644 index 0000000000..bf07735724 --- /dev/null +++ b/actionpack/test/template/lookup_context_test.rb @@ -0,0 +1,167 @@ +require "abstract_unit" +require "abstract_controller/rendering" + +ActionView::LookupContext::DetailsKey.class_eval do + def self.details_keys + @details_keys + end +end + +class LookupContextTest < ActiveSupport::TestCase + def setup + @lookup_context = ActionView::LookupContext.new(FIXTURE_LOAD_PATH, {}) + end + + def teardown + I18n.locale = :en + ActionView::LookupContext::DetailsKey.details_keys.clear + end + + test "process view paths on initialization" do + assert_kind_of ActionView::PathSet, @lookup_context.view_paths + end + + test "normalizes details on initialization" do + formats = Mime::SET + [nil] + locale = [I18n.locale, nil] + assert_equal Hash[:formats => formats, :locale => locale], @lookup_context.details + end + + test "allows me to set details" do + @lookup_context.details = { :formats => [:html], :locale => :pt } + assert_equal Hash[:formats => [:html, nil], :locale => [:pt, nil]], @lookup_context.details + end + + test "does not allow details to be modified in place" do + assert_raise TypeError do + @lookup_context.details.clear + end + end + + test "allows me to update an specific detail" do + @lookup_context.update_details(:locale => :pt) + assert_equal :pt, I18n.locale + formats = Mime::SET + [nil] + locale = [I18n.locale, nil] + assert_equal Hash[:formats => formats, :locale => locale], @lookup_context.details + end + + test "allows me to change some details to execute an specific block of code" do + formats = Mime::SET + [nil] + @lookup_context.update_details(:locale => :pt) do + assert_equal Hash[:formats => formats, :locale => [:pt, nil]], @lookup_context.details + end + assert_equal Hash[:formats => formats, :locale => [:en, nil]], @lookup_context.details + end + + test "provides getters and setters for formats" do + @lookup_context.formats = :html + assert_equal [:html], @lookup_context.formats + end + + test "handles */* formats" do + @lookup_context.formats = [:"*/*"] + assert_equal Mime::SET, @lookup_context.formats + end + + test "provides getters and setters for locale" do + @lookup_context.locale = :pt + assert_equal :pt, @lookup_context.locale + end + + test "changing lookup_context locale, changes I18n.locale" do + @lookup_context.locale = :pt + assert_equal :pt, I18n.locale + end + + test "delegates changing the locale to the I18n configuration object if it contains a lookup_context object" do + begin + I18n.config = AbstractController::I18nProxy.new(I18n.config, @lookup_context) + @lookup_context.locale = :pt + assert_equal :pt, I18n.locale + assert_equal :pt, @lookup_context.locale + ensure + I18n.config = I18n.config.i18n_config + end + + assert_equal :pt, I18n.locale + end + + test "find templates using the given view paths and configured details" do + template = @lookup_context.find("hello_world", "test") + assert_equal "Hello world!", template.source + + @lookup_context.locale = :da + template = @lookup_context.find("hello_world", "test") + assert_equal "Hey verden", template.source + end + + test "adds fallbacks to view paths when required" do + assert_equal 1, @lookup_context.view_paths.size + + @lookup_context.with_fallbacks do + assert_equal 3, @lookup_context.view_paths.size + assert @lookup_context.view_paths.include?(ActionView::FileSystemResolver.new("")) + assert @lookup_context.view_paths.include?(ActionView::FileSystemResolver.new("/")) + end + end + + test "add fallbacks just once in nested fallbacks calls" do + @lookup_context.with_fallbacks do + @lookup_context.with_fallbacks do + assert_equal 3, @lookup_context.view_paths.size + end + end + end + + test "generates a new details key for each details hash" do + keys = [] + keys << @lookup_context.details_key + assert_equal 1, keys.uniq.size + + @lookup_context.locale = :da + keys << @lookup_context.details_key + assert_equal 2, keys.uniq.size + + @lookup_context.locale = :en + keys << @lookup_context.details_key + assert_equal 2, keys.uniq.size + + @lookup_context.formats = :html + keys << @lookup_context.details_key + assert_equal 3, keys.uniq.size + + @lookup_context.formats = nil + keys << @lookup_context.details_key + assert_equal 3, keys.uniq.size + end + + test "gives the key forward to the resolver, so it can be used as cache key" do + @lookup_context.view_paths = ActionView::FixtureResolver.new("test/_foo.erb" => "Foo") + template = @lookup_context.find("foo", "test", true) + assert_equal "Foo", template.source + + # Now we are going to change the template, but it won't change the returned template + # since we will hit the cache. + @lookup_context.view_paths.first.hash["test/_foo.erb"] = "Bar" + template = @lookup_context.find("foo", "test", true) + assert_equal "Foo", template.source + + # This time we will change the locale. The updated template should be picked since + # lookup_context generated a new key after we changed the locale. + @lookup_context.locale = :da + template = @lookup_context.find("foo", "test", true) + assert_equal "Bar", template.source + + # Now we will change back the locale and it will still pick the old template. + # This is expected because lookup_context will reuse the previous key for :en locale. + @lookup_context.locale = :en + template = @lookup_context.find("foo", "test", true) + assert_equal "Foo", template.source + + # Finally, we can expire the cache. And the expected template will be used. + @lookup_context.view_paths.first.clear_cache + template = @lookup_context.find("foo", "test", true) + assert_equal "Bar", template.source + end +end \ No newline at end of file -- cgit v1.2.3 From 8b4dca109a307e807a34a86e51f41b5d8a7d75b2 Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Thu, 11 Mar 2010 10:08:18 -0800 Subject: ActionController::Base.request_forgery_protection_token should actually be the name of the token and not true. --- actionpack/lib/action_controller/metal/request_forgery_protection.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/request_forgery_protection.rb b/actionpack/lib/action_controller/metal/request_forgery_protection.rb index 6765314df2..39a809657b 100644 --- a/actionpack/lib/action_controller/metal/request_forgery_protection.rb +++ b/actionpack/lib/action_controller/metal/request_forgery_protection.rb @@ -12,7 +12,7 @@ module ActionController #:nodoc: included do # Sets the token parameter name for RequestForgery. Calling +protect_from_forgery+ # sets it to :authenticity_token by default. - config.request_forgery_protection_token ||= true + config.request_forgery_protection_token ||= :authenticity_token # Controls whether request forgergy protection is turned on or not. Turned off by default only in test mode. config.allow_forgery_protection ||= true -- cgit v1.2.3 From b27376773e8f51b03bd4cb2678764cd392455870 Mon Sep 17 00:00:00 2001 From: Eaden McKee Date: Fri, 12 Mar 2010 14:13:10 +1300 Subject: simplify alt tag generation for images [#2837 state:committed] Signed-off-by: Jeremy Kemper --- actionpack/lib/action_view/helpers/asset_tag_helper.rb | 4 ++-- actionpack/test/template/asset_tag_helper_test.rb | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb index de3d61ebbe..0c488b6793 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb @@ -11,7 +11,7 @@ module ActionView # the assets exist before linking to them: # # image_tag("rails.png") - # # => Rails src= + # # => Rails # stylesheet_link_tag("application") # # => # @@ -523,7 +523,7 @@ module ActionView options.symbolize_keys! src = options[:src] = path_to_image(source) - options[:alt] ||= File.basename(src, '.*').split('.').first.to_s.capitalize + options[:alt] ||= File.basename(src, '.*').capitalize if size = options.delete(:size) options[:width], options[:height] = size.split("x") if size =~ %r{^\d+x\d+$} diff --git a/actionpack/test/template/asset_tag_helper_test.rb b/actionpack/test/template/asset_tag_helper_test.rb index 50c3ab0b60..fe255246e0 100644 --- a/actionpack/test/template/asset_tag_helper_test.rb +++ b/actionpack/test/template/asset_tag_helper_test.rb @@ -141,13 +141,16 @@ class AssetTagHelperTest < ActionView::TestCase ImageLinkToTag = { %(image_tag("xml.png")) => %(Xml), - %(image_tag("..jpg")) => %(), + %(image_tag("..jpg")) => %(.), %(image_tag("rss.gif", :alt => "rss syndication")) => %(rss syndication), %(image_tag("gold.png", :size => "45x70")) => %(Gold), %(image_tag("gold.png", "size" => "45x70")) => %(Gold), %(image_tag("error.png", "size" => "45")) => %(Error), %(image_tag("error.png", "size" => "45 x 70")) => %(Error), %(image_tag("error.png", "size" => "x")) => %(Error), + %(image_tag("google.com.png")) => %(Google.com), + %(image_tag("slash..png")) => %(Slash.), + %(image_tag(".pdf.png")) => %(.pdf), %(image_tag("http://www.rubyonrails.com/images/rails.png")) => %(Rails), %(image_tag("mouse.png", :mouseover => "/images/mouse_over.png")) => %(Mouse), %(image_tag("mouse.png", :mouseover => image_path("mouse_over.png"))) => %(Mouse) -- cgit v1.2.3 From 698312de872b5410fa523f5164ef10518d8c92e9 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Thu, 11 Mar 2010 17:42:27 -0800 Subject: Delegate #encoding to SafeBuffer too --- actionpack/lib/action_view/template/handlers/erb.rb | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/template/handlers/erb.rb b/actionpack/lib/action_view/template/handlers/erb.rb index 937694ce8e..2ac68d38bd 100644 --- a/actionpack/lib/action_view/template/handlers/erb.rb +++ b/actionpack/lib/action_view/template/handlers/erb.rb @@ -41,6 +41,10 @@ module ActionView end if "".respond_to?(:force_encoding) + def encoding + @buffer.encoding + end + def force_encoding(encoding) @buffer.force_encoding(encoding) end -- cgit v1.2.3 From 47bc138fc1d9ddafab8e4cf9cac8865f2092c003 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Thu, 11 Mar 2010 17:32:26 -0800 Subject: Write strings to fragment cache, not outputbuffers --- actionpack/lib/action_controller/caching/fragments.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/caching/fragments.rb b/actionpack/lib/action_controller/caching/fragments.rb index 00a7f034d3..bb5ff95a67 100644 --- a/actionpack/lib/action_controller/caching/fragments.rb +++ b/actionpack/lib/action_controller/caching/fragments.rb @@ -41,7 +41,9 @@ module ActionController #:nodoc: else pos = buffer.length block.call - write_fragment(name, buffer[pos..-1], options) + content = buffer[pos..-1] + content = content.as_str if content.respond_to?(:as_str) + write_fragment(name, content, options) end else block.call -- cgit v1.2.3 From 5a7f7928a60749095dd890abfceff45a9912b8d2 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Thu, 11 Mar 2010 17:49:17 -0800 Subject: Fix test --- actionpack/test/template/asset_tag_helper_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/test/template/asset_tag_helper_test.rb b/actionpack/test/template/asset_tag_helper_test.rb index fe255246e0..d9a89959da 100644 --- a/actionpack/test/template/asset_tag_helper_test.rb +++ b/actionpack/test/template/asset_tag_helper_test.rb @@ -141,7 +141,7 @@ class AssetTagHelperTest < ActionView::TestCase ImageLinkToTag = { %(image_tag("xml.png")) => %(Xml), - %(image_tag("..jpg")) => %(.), + %(image_tag("..jpg")) => %(..jpg), %(image_tag("rss.gif", :alt => "rss syndication")) => %(rss syndication), %(image_tag("gold.png", :size => "45x70")) => %(Gold), %(image_tag("gold.png", "size" => "45x70")) => %(Gold), -- cgit v1.2.3 From 839362fa07de3f7bdf1fc1a361ff456cd02efc4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Fri, 12 Mar 2010 11:50:45 +0100 Subject: Make all AP tests pass for Ruby 1.9.1. --- actionpack/lib/action_view/lookup_context.rb | 19 +++++++++++-------- actionpack/test/dispatch/mount_test.rb | 8 ++++---- actionpack/test/lib/fixture_template.rb | 5 +++-- actionpack/test/template/lookup_context_test.rb | 4 +--- 4 files changed, 19 insertions(+), 17 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/lookup_context.rb b/actionpack/lib/action_view/lookup_context.rb index 0bb73b590d..27ee8b23c9 100644 --- a/actionpack/lib/action_view/lookup_context.rb +++ b/actionpack/lib/action_view/lookup_context.rb @@ -13,18 +13,21 @@ module ActionView mattr_accessor :registered_details self.registered_details = [] - def self.register_detail(name, options = {}) + def self.register_detail(name, options = {}, &block) self.registered_details << name - Setters.send :define_method, :"#{name}=" do |value| - value = Array(value.presence || yield) - value |= [nil] unless options[:allow_nil] == false + Setters.send :define_method, :"_#{name}_defaults", &block + Setters.module_eval <<-METHOD, __FILE__, __LINE__ + 1 + def #{name}=(value) + value = Array(value.presence || _#{name}_defaults) + #{"value << nil unless value.include?(nil)" unless options[:allow_nil] == false} - unless value == @details[name] - @details_key, @details = nil, @details.merge(name => value) - @details.freeze + unless value == @details[:#{name}] + @details_key, @details = nil, @details.merge(:#{name} => value) + @details.freeze + end end - end + METHOD end # Holds raw setters for the registered details. diff --git a/actionpack/test/dispatch/mount_test.rb b/actionpack/test/dispatch/mount_test.rb index f89e5fda07..00ca5ec9dc 100644 --- a/actionpack/test/dispatch/mount_test.rb +++ b/actionpack/test/dispatch/mount_test.rb @@ -1,12 +1,12 @@ require 'abstract_unit' class TestRoutingMount < ActionDispatch::IntegrationTest - SprocketsApp = lambda { |env| - [200, {"Content-Type" => "text/html"}, ["#{env["SCRIPT_NAME"]} -- #{env["PATH_INFO"]}"]] - } - Router = ActionDispatch::Routing::RouteSet.new Router.draw do + SprocketsApp = lambda { |env| + [200, {"Content-Type" => "text/html"}, ["#{env["SCRIPT_NAME"]} -- #{env["PATH_INFO"]}"]] + } + mount SprocketsApp, :at => "/sprockets" mount SprocketsApp => "/shorthand" diff --git a/actionpack/test/lib/fixture_template.rb b/actionpack/test/lib/fixture_template.rb index eda76ddfd0..02248d84ad 100644 --- a/actionpack/test/lib/fixture_template.rb +++ b/actionpack/test/lib/fixture_template.rb @@ -12,7 +12,7 @@ module ActionView #:nodoc: def query(partial, path, exts) query = Regexp.escape(path) exts.each do |ext| - query << '(?:' << ext.map {|e| e && Regexp.escape(".#{e}") }.join('|') << ')' + query << '(' << ext.map {|e| e && Regexp.escape(".#{e}") }.join('|') << ')' end templates = [] @@ -21,7 +21,8 @@ module ActionView #:nodoc: templates << Template.new(source, path, handler, :partial => partial, :virtual_path => path, :format => format) end - templates.sort_by {|t| -t.formats.size } + + templates.sort_by {|t| -t.identifier.match(/^#{query}$/).captures.reject(&:blank?).size } end end diff --git a/actionpack/test/template/lookup_context_test.rb b/actionpack/test/template/lookup_context_test.rb index bf07735724..697ebc694a 100644 --- a/actionpack/test/template/lookup_context_test.rb +++ b/actionpack/test/template/lookup_context_test.rb @@ -33,9 +33,7 @@ class LookupContextTest < ActiveSupport::TestCase end test "does not allow details to be modified in place" do - assert_raise TypeError do - @lookup_context.details.clear - end + assert @lookup_context.details.frozen? end test "allows me to update an specific detail" do -- cgit v1.2.3 From 4840acd485a4a6bcdd73338447af7e1340587e54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Fri, 12 Mar 2010 12:08:23 +0100 Subject: %= works for content_tag and does not require parenthesis on method call --- .../lib/action_view/template/handlers/erb.rb | 53 +++------------------- actionpack/test/template/erb/tag_helper_test.rb | 4 +- 2 files changed, 8 insertions(+), 49 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/template/handlers/erb.rb b/actionpack/lib/action_view/template/handlers/erb.rb index 2ac68d38bd..ac5902cc0e 100644 --- a/actionpack/lib/action_view/template/handlers/erb.rb +++ b/actionpack/lib/action_view/template/handlers/erb.rb @@ -3,52 +3,11 @@ require 'active_support/core_ext/string/output_safety' require 'erubis' module ActionView - class OutputBuffer - def initialize - @buffer = ActiveSupport::SafeBuffer.new - end - - def safe_concat(value) - @buffer.safe_concat(value) - end - + class OutputBuffer < ActiveSupport::SafeBuffer def <<(value) - @buffer << value.to_s - end - - def length - @buffer.length - end - - def [](*args) - @buffer[*args] - end - - def to_s - @buffer.to_s - end - - def to_str - @buffer.to_str - end - - def empty? - @buffer.empty? - end - - def html_safe? - @buffer.html_safe? - end - - if "".respond_to?(:force_encoding) - def encoding - @buffer.encoding - end - - def force_encoding(encoding) - @buffer.force_encoding(encoding) - end + super(value.to_s) end + alias :append= :<< end module Template::Handlers @@ -64,14 +23,14 @@ module ActionView def add_expr_literal(src, code) if code =~ /(do|\{)(\s*\|[^|]*\|)?\s*\Z/ - src << '@output_buffer << ' << code + src << '@output_buffer.append= ' << code else - src << '@output_buffer << (' << code << ');' + src << '@output_buffer.append= (' << code << ');' end end def add_expr_escaped(src, code) - src << '@output_buffer << ' << escaped_expr(code) << ';' + src << '@output_buffer.append= ' << escaped_expr(code) << ';' end def add_postamble(src) diff --git a/actionpack/test/template/erb/tag_helper_test.rb b/actionpack/test/template/erb/tag_helper_test.rb index b91539ef0b..cc96a43901 100644 --- a/actionpack/test/template/erb/tag_helper_test.rb +++ b/actionpack/test/template/erb/tag_helper_test.rb @@ -31,8 +31,8 @@ module ERBTest ActionView::Template::Handlers::Erubis.new(template).evaluate(context.new) end - test "percent equals works for content_tag" do - assert_equal "
Hello world
", render_content("content_tag(:div)", "Hello world") + test "percent equals works for content_tag and does not require parenthesis on method call" do + assert_equal "
Hello world
", render_content("content_tag :div", "Hello world") end test "percent equals works for javascript_tag" do -- cgit v1.2.3