From 92050f6c6f586b2a73aeb61da4f41b9822bbcf6d Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Mon, 2 Jun 2008 21:02:26 -0500 Subject: Ensure Rack processor reads CGI output_cookies for the session cookie. --- actionpack/lib/action_controller/dispatcher.rb | 2 +- actionpack/lib/action_controller/rack_process.rb | 10 +++-- actionpack/test/controller/rack_test.rb | 56 ++++++++++++++++++++++-- 3 files changed, 60 insertions(+), 8 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/dispatcher.rb b/actionpack/lib/action_controller/dispatcher.rb index b40f1ba9be..7162fb8b1f 100644 --- a/actionpack/lib/action_controller/dispatcher.rb +++ b/actionpack/lib/action_controller/dispatcher.rb @@ -125,7 +125,7 @@ module ActionController def call(env) @request = RackRequest.new(env) - @response = RackResponse.new + @response = RackResponse.new(@request) dispatch end diff --git a/actionpack/lib/action_controller/rack_process.rb b/actionpack/lib/action_controller/rack_process.rb index 16625519b6..d5fb78c44d 100644 --- a/actionpack/lib/action_controller/rack_process.rb +++ b/actionpack/lib/action_controller/rack_process.rb @@ -4,6 +4,7 @@ require 'action_controller/session/cookie_store' module ActionController #:nodoc: class RackRequest < AbstractRequest #:nodoc: attr_accessor :env, :session_options + attr_reader :cgi class SessionFixationAttempt < StandardError #:nodoc: end @@ -199,7 +200,8 @@ end_msg class RackResponse < AbstractResponse #:nodoc: attr_accessor :status - def initialize + def initialize(request) + @request = request @writer = lambda { |x| @body << x } @block = nil super() @@ -270,9 +272,9 @@ end_msg else cookies << cookie.to_s end - @output_cookies.each { |c| cookies << c.to_s } if @output_cookies + @request.cgi.output_cookies.each { |c| cookies << c.to_s } if @request.cgi.output_cookies - headers['Set-Cookie'] = [headers['Set-Cookie'], cookies].compact.join("\n") + headers['Set-Cookie'] = [headers['Set-Cookie'], cookies].flatten.compact end options.each { |k,v| headers[k] = v } @@ -283,6 +285,8 @@ end_msg end class CGIWrapper < ::CGI + attr_reader :output_cookies + def initialize(request, *args) @request = request @args = *args diff --git a/actionpack/test/controller/rack_test.rb b/actionpack/test/controller/rack_test.rb index cd4151783e..026b0195d1 100644 --- a/actionpack/test/controller/rack_test.rb +++ b/actionpack/test/controller/rack_test.rb @@ -3,7 +3,36 @@ require 'action_controller/rack_process' class BaseRackTest < Test::Unit::TestCase def setup - @env = {"HTTP_MAX_FORWARDS"=>"10", "SERVER_NAME"=>"glu.ttono.us:8007", "FCGI_ROLE"=>"RESPONDER", "HTTP_X_FORWARDED_HOST"=>"glu.ttono.us", "HTTP_ACCEPT_ENCODING"=>"gzip, deflate", "HTTP_USER_AGENT"=>"Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/312.5.1 (KHTML, like Gecko) Safari/312.3.1", "PATH_INFO"=>"", "HTTP_ACCEPT_LANGUAGE"=>"en", "HTTP_HOST"=>"glu.ttono.us:8007", "SERVER_PROTOCOL"=>"HTTP/1.1", "REDIRECT_URI"=>"/dispatch.fcgi", "SCRIPT_NAME"=>"/dispatch.fcgi", "SERVER_ADDR"=>"207.7.108.53", "REMOTE_ADDR"=>"207.7.108.53", "SERVER_SOFTWARE"=>"lighttpd/1.4.5", "HTTP_COOKIE"=>"_session_id=c84ace84796670c052c6ceb2451fb0f2; is_admin=yes", "HTTP_X_FORWARDED_SERVER"=>"glu.ttono.us", "REQUEST_URI"=>"/admin", "DOCUMENT_ROOT"=>"/home/kevinc/sites/typo/public", "SERVER_PORT"=>"8007", "QUERY_STRING"=>"", "REMOTE_PORT"=>"63137", "GATEWAY_INTERFACE"=>"CGI/1.1", "HTTP_X_FORWARDED_FOR"=>"65.88.180.234", "HTTP_ACCEPT"=>"*/*", "SCRIPT_FILENAME"=>"/home/kevinc/sites/typo/public/dispatch.fcgi", "REDIRECT_STATUS"=>"200", "REQUEST_METHOD"=>"GET"} + @env = { + "HTTP_MAX_FORWARDS" => "10", + "SERVER_NAME" => "glu.ttono.us:8007", + "FCGI_ROLE" => "RESPONDER", + "HTTP_X_FORWARDED_HOST" => "glu.ttono.us", + "HTTP_ACCEPT_ENCODING" => "gzip, deflate", + "HTTP_USER_AGENT" => "Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en)", + "PATH_INFO" => "", + "HTTP_ACCEPT_LANGUAGE" => "en", + "HTTP_HOST" => "glu.ttono.us:8007", + "SERVER_PROTOCOL" => "HTTP/1.1", + "REDIRECT_URI" => "/dispatch.fcgi", + "SCRIPT_NAME" => "/dispatch.fcgi", + "SERVER_ADDR" => "207.7.108.53", + "REMOTE_ADDR" => "207.7.108.53", + "SERVER_SOFTWARE" => "lighttpd/1.4.5", + "HTTP_COOKIE" => "_session_id=c84ace84796670c052c6ceb2451fb0f2; is_admin=yes", + "HTTP_X_FORWARDED_SERVER" => "glu.ttono.us", + "REQUEST_URI" => "/admin", + "DOCUMENT_ROOT" => "/home/kevinc/sites/typo/public", + "SERVER_PORT" => "8007", + "QUERY_STRING" => "", + "REMOTE_PORT" => "63137", + "GATEWAY_INTERFACE" => "CGI/1.1", + "HTTP_X_FORWARDED_FOR" => "65.88.180.234", + "HTTP_ACCEPT" => "*/*", + "SCRIPT_FILENAME" => "/home/kevinc/sites/typo/public/dispatch.fcgi", + "REDIRECT_STATUS" => "200", + "REQUEST_METHOD" => "GET" + } # some Nokia phone browsers omit the space after the semicolon separator. # some developers have grown accustomed to using comma in cookie values. @alt_cookie_fmt_request_hash = {"HTTP_COOKIE"=>"_session_id=c84ace847,96670c052c6ceb2451fb0f2;is_admin=yes"} @@ -118,7 +147,7 @@ end class RackResponseTest < BaseRackTest def setup super - @response = ActionController::RackResponse.new + @response = ActionController::RackResponse.new(@request) @output = StringIO.new('') end @@ -127,7 +156,7 @@ class RackResponseTest < BaseRackTest status, headers, body = @response.out(@output) assert_equal 200, status - assert_equal({"Content-Type" => "text/html", "Cache-Control" => "no-cache", "Set-Cookie" => ""}, headers) + assert_equal({"Content-Type" => "text/html", "Cache-Control" => "no-cache", "Set-Cookie" => []}, headers) parts = [] body.each { |part| parts << part } @@ -141,10 +170,29 @@ class RackResponseTest < BaseRackTest status, headers, body = @response.out(@output) assert_equal 200, status - assert_equal({"Content-Type" => "text/html", "Cache-Control" => "no-cache", "Set-Cookie" => ""}, headers) + assert_equal({"Content-Type" => "text/html", "Cache-Control" => "no-cache", "Set-Cookie" => []}, headers) parts = [] body.each { |part| parts << part } assert_equal ["0", "1", "2", "3", "4"], parts end + + def test_set_session_cookie + cookie = CGI::Cookie.new({"name" => "name", "value" => "Josh"}) + @request.cgi.send :instance_variable_set, '@output_cookies', [cookie] + + @response.body = "Hello, World!" + + status, headers, body = @response.out(@output) + assert_equal 200, status + assert_equal({ + "Content-Type" => "text/html", + "Cache-Control" => "no-cache", + "Set-Cookie" => ["name=Josh; path="] + }, headers) + + parts = [] + body.each { |part| parts << part } + assert_equal ["Hello, World!"], parts + end end -- cgit v1.2.3 From 933697a5fc5f4c56c4fd7fbbd31b8973df9c1054 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Mon, 2 Jun 2008 09:12:00 -0700 Subject: Try replacing _erbout with @output_buffer --- actionpack/lib/action_view/base.rb | 5 +- .../lib/action_view/helpers/capture_helper.rb | 56 ++++++---------------- .../lib/action_view/helpers/javascript_helper.rb | 2 +- actionpack/lib/action_view/helpers/tag_helper.rb | 2 +- actionpack/lib/action_view/helpers/text_helper.rb | 8 +++- .../lib/action_view/template_handlers/erb.rb | 6 +-- 6 files changed, 25 insertions(+), 54 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index f398756550..5fae2d4dd6 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -178,10 +178,7 @@ module ActionView #:nodoc: # that alert()s the caught exception (and then re-raises it). @@debug_rjs = false cattr_accessor :debug_rjs - - @@erb_variable = '_erbout' - cattr_accessor :erb_variable - + attr_internal :request delegate :request_forgery_protection_token, :template, :params, :session, :cookies, :response, :headers, diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb index 9ea06568cf..f9a73a4c8d 100644 --- a/actionpack/lib/action_view/helpers/capture_helper.rb +++ b/actionpack/lib/action_view/helpers/capture_helper.rb @@ -31,20 +31,13 @@ module ActionView # # def capture(*args, &block) - # execute the block - begin - buffer = eval(ActionView::Base.erb_variable, block.binding) - rescue - buffer = nil - end - - if buffer.nil? - capture_block(*args, &block).to_s - else - capture_erb_with_buffer(buffer, *args, &block).to_s - end + @output_buffer, old_buffer = '', @output_buffer + yield *args + @output_buffer + ensure + @output_buffer = old_buffer end - + # Calling content_for stores a block of markup in an identifier for later use. # You can make subsequent calls to the stored content in other templates or the layout # by passing the identifier as an argument to yield. @@ -121,40 +114,19 @@ module ActionView # named @content_for_#{name_of_the_content_block}. The preferred usage is now # <%= yield :footer %>. def content_for(name, content = nil, &block) - existing_content_for = instance_variable_get("@content_for_#{name}").to_s - new_content_for = existing_content_for + (block_given? ? capture(&block) : content) - instance_variable_set("@content_for_#{name}", new_content_for) + ivar = "@content_for_#{name}" + instance_variable_set("@content_for_#{name}", "#{instance_variable_get(ivar)}#{block_given? ? capture(&block) : content}") end private - def capture_block(*args, &block) - block.call(*args) - end - - def capture_erb(*args, &block) - buffer = eval(ActionView::Base.erb_variable, block.binding) - capture_erb_with_buffer(buffer, *args, &block) - end - - def capture_erb_with_buffer(buffer, *args, &block) - pos = buffer.length - block.call(*args) - - # extract the block - data = buffer[pos..-1] - - # replace it in the original with empty string - buffer[pos..-1] = '' - - data - end - def erb_content_for(name, &block) - eval "@content_for_#{name} = (@content_for_#{name} || '') + capture_erb(&block)" + ivar = "@content_for_#{name}" + instance_variable_set(ivar, "#{instance_variable_get(ivar)}#{capture(&block)}") end - - def block_content_for(name, &block) - eval "@content_for_#{name} = (@content_for_#{name} || '') + capture_block(&block)" + + def block_content_for(name) + ivar = "@content_for_#{name}" + instance_variable_set(ivar, "#{instance_variable_get(ivar)}#{yield}") end end end diff --git a/actionpack/lib/action_view/helpers/javascript_helper.rb b/actionpack/lib/action_view/helpers/javascript_helper.rb index 1ea3cbd74e..8c880dee2f 100644 --- a/actionpack/lib/action_view/helpers/javascript_helper.rb +++ b/actionpack/lib/action_view/helpers/javascript_helper.rb @@ -208,7 +208,7 @@ module ActionView private def block_is_within_action_view?(block) - eval("defined? _erbout", block.binding) + !@output_buffer.nil? end end diff --git a/actionpack/lib/action_view/helpers/tag_helper.rb b/actionpack/lib/action_view/helpers/tag_helper.rb index 999cbfb52a..df3d69c0d8 100644 --- a/actionpack/lib/action_view/helpers/tag_helper.rb +++ b/actionpack/lib/action_view/helpers/tag_helper.rb @@ -126,7 +126,7 @@ module ActionView end def block_is_within_action_view?(block) - eval("defined? _erbout", block.binding) + !@output_buffer.nil? end end end diff --git a/actionpack/lib/action_view/helpers/text_helper.rb b/actionpack/lib/action_view/helpers/text_helper.rb index 669a285424..4711b84ae7 100644 --- a/actionpack/lib/action_view/helpers/text_helper.rb +++ b/actionpack/lib/action_view/helpers/text_helper.rb @@ -25,8 +25,12 @@ module ActionView # end # # will either display "Logged in!" or a login link # %> - def concat(string, binding) - eval(ActionView::Base.erb_variable, binding) << string + def concat(string, binding = nil) + if @output_buffer + @output_buffer << string + else + string + end end if RUBY_VERSION < '1.9' diff --git a/actionpack/lib/action_view/template_handlers/erb.rb b/actionpack/lib/action_view/template_handlers/erb.rb index 15a9064461..d1416b89d1 100644 --- a/actionpack/lib/action_view/template_handlers/erb.rb +++ b/actionpack/lib/action_view/template_handlers/erb.rb @@ -43,13 +43,11 @@ module ActionView include Compilable def compile(template) - ::ERB.new(template.source, nil, @view.erb_trim_mode).src + ::ERB.new(template.source, nil, @view.erb_trim_mode, '@output_buffer').src end def cache_fragment(block, name = {}, options = nil) #:nodoc: - @view.fragment_for(block, name, options) do - eval(ActionView::Base.erb_variable, block.binding) - end + @view.fragment_for(block, name, options) { @view.output_buffer } end end end -- cgit v1.2.3 From 0bdb7d353b4ac6f5470884360f9a480a16bd709c Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Mon, 2 Jun 2008 13:32:58 -0700 Subject: Work with @output_buffer instead of _erbout --- actionpack/lib/action_view/base.rb | 11 +- .../lib/action_view/helpers/capture_helper.rb | 18 +- .../lib/action_view/template_handlers/builder.rb | 7 +- .../lib/action_view/template_handlers/erb.rb | 2 +- actionpack/test/controller/caching_test.rb | 4 +- actionpack/test/template/date_helper_test.rb | 12 +- actionpack/test/template/form_helper_test.rb | 260 ++++++++++----------- .../test/template/form_options_helper_test.rb | 18 +- actionpack/test/template/form_tag_helper_test.rb | 30 +-- actionpack/test/template/javascript_helper_test.rb | 12 +- actionpack/test/template/prototype_helper_test.rb | 26 +-- actionpack/test/template/record_tag_helper_test.rb | 14 +- actionpack/test/template/tag_helper_test.rb | 12 +- 13 files changed, 220 insertions(+), 206 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 5fae2d4dd6..7a603f150f 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -156,10 +156,12 @@ module ActionView #:nodoc: attr_reader :finder attr_accessor :base_path, :assigns, :template_extension, :first_render attr_accessor :controller - + attr_writer :template_format attr_accessor :current_render_extension + attr_accessor :output_buffer + # Specify trim mode for the ERB compiler. Defaults to '-'. # See ERb documentation for suitable values. @@erb_trim_mode = '-' @@ -313,9 +315,10 @@ If you are rendering a subtemplate, you must now use controller-like partial syn private def wrap_content_for_layout(content) - original_content_for_layout = @content_for_layout - @content_for_layout = content - returning(yield) { @content_for_layout = original_content_for_layout } + original_content_for_layout, @content_for_layout = @content_for_layout, content + yield + ensure + @content_for_layout = original_content_for_layout end # Evaluate the local assigns and pushes them to the view. diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb index f9a73a4c8d..837305d96c 100644 --- a/actionpack/lib/action_view/helpers/capture_helper.rb +++ b/actionpack/lib/action_view/helpers/capture_helper.rb @@ -31,11 +31,11 @@ module ActionView # # def capture(*args, &block) - @output_buffer, old_buffer = '', @output_buffer - yield *args - @output_buffer - ensure - @output_buffer = old_buffer + if @output_buffer + with_temporary_output_buffer { yield *args } + else + block.call(*args) + end end # Calling content_for stores a block of markup in an identifier for later use. @@ -119,6 +119,14 @@ module ActionView end private + def with_temporary_output_buffer + @output_buffer, old_buffer = '', @output_buffer + yield + @output_buffer + ensure + @output_buffer = old_buffer + end + def erb_content_for(name, &block) ivar = "@content_for_#{name}" instance_variable_set(ivar, "#{instance_variable_get(ivar)}#{capture(&block)}") diff --git a/actionpack/lib/action_view/template_handlers/builder.rb b/actionpack/lib/action_view/template_handlers/builder.rb index f76d89777a..ee02ce1a6f 100644 --- a/actionpack/lib/action_view/template_handlers/builder.rb +++ b/actionpack/lib/action_view/template_handlers/builder.rb @@ -11,10 +11,11 @@ module ActionView def compile(template) content_type_handler = (@view.send!(:controller).respond_to?(:response) ? "controller.response" : "controller") + "#{content_type_handler}.content_type ||= Mime::XML\n" + - "xml = ::Builder::XmlMarkup.new(:indent => 2)\n" + - template.source + - "\nxml.target!\n" + "xml = ::Builder::XmlMarkup.new(:indent => 2)\n" + + template.source + + "\nxml.target!\n" end def cache_fragment(block, name = {}, options = nil) diff --git a/actionpack/lib/action_view/template_handlers/erb.rb b/actionpack/lib/action_view/template_handlers/erb.rb index d1416b89d1..ad4ccc7c42 100644 --- a/actionpack/lib/action_view/template_handlers/erb.rb +++ b/actionpack/lib/action_view/template_handlers/erb.rb @@ -47,7 +47,7 @@ module ActionView end def cache_fragment(block, name = {}, options = nil) #:nodoc: - @view.fragment_for(block, name, options) { @view.output_buffer } + @view.fragment_for(block, name, options) { @view.response.template.output_buffer ||= '' } end end end diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index f9b6b87bc6..d0ee93cf3f 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -421,6 +421,8 @@ class FragmentCachingTest < Test::Unit::TestCase @controller.request = @request @controller.response = @response @controller.send(:initialize_current_url) + @controller.send(:initialize_template_class, @response) + @controller.send(:assign_shortcuts, @request, @response) end def test_fragment_cache_key @@ -510,7 +512,7 @@ class FragmentCachingTest < Test::Unit::TestCase def test_cache_erb_fragment @store.write('views/expensive', 'fragment content') - _erbout = 'generated till now -> ' + @controller.template.output_buffer = 'generated till now -> ' assert_equal( 'generated till now -> fragment content', ActionView::TemplateHandlers::ERB.new(@controller).cache_fragment(Proc.new{ }, 'expensive')) diff --git a/actionpack/test/template/date_helper_test.rb b/actionpack/test/template/date_helper_test.rb index 0a7b19ba96..3399b03dd2 100755 --- a/actionpack/test/template/date_helper_test.rb +++ b/actionpack/test/template/date_helper_test.rb @@ -1002,17 +1002,17 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Date.new(2004, 6, 15) - _erbout = '' + @output_buffer = '' fields_for :post, @post do |f| - _erbout.concat f.date_select(:written_on) + @output_buffer.concat f.date_select(:written_on) end expected = "\n" expected << "\n" expected << "\n" - assert_dom_equal(expected, _erbout) + assert_dom_equal(expected, @output_buffer) end def test_date_select_with_index @@ -1287,10 +1287,10 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.updated_at = Time.local(2004, 6, 15, 16, 35) - _erbout = '' + @output_buffer = '' fields_for :post, @post do |f| - _erbout.concat f.datetime_select(:updated_at) + @output_buffer.concat f.datetime_select(:updated_at) end expected = "\n" @@ -1299,7 +1299,7 @@ class DateHelperTest < ActionView::TestCase expected << " — \n" expected << " : \n" - assert_dom_equal(expected, _erbout) + assert_dom_equal(expected, @output_buffer) end def test_date_select_with_zero_value_and_no_start_year diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb index af99e6243d..65984fac44 100644 --- a/actionpack/test/template/form_helper_test.rb +++ b/actionpack/test/template/form_helper_test.rb @@ -337,14 +337,14 @@ class FormHelperTest < ActionView::TestCase end def test_form_for - _erbout = '' + @output_buffer = '' form_for(:post, @post, :html => { :id => 'create-post' }) do |f| - _erbout.concat f.label(:title) - _erbout.concat f.text_field(:title) - _erbout.concat f.text_area(:body) - _erbout.concat f.check_box(:secret) - _erbout.concat f.submit('Create post') + @output_buffer.concat f.label(:title) + @output_buffer.concat f.text_field(:title) + @output_buffer.concat f.text_area(:body) + @output_buffer.concat f.check_box(:secret) + @output_buffer.concat f.submit('Create post') end expected = @@ -357,16 +357,16 @@ class FormHelperTest < ActionView::TestCase "" + "" - assert_dom_equal expected, _erbout + assert_dom_equal expected, @output_buffer end def test_form_for_with_method - _erbout = '' + @output_buffer = '' form_for(:post, @post, :html => { :id => 'create-post', :method => :put }) do |f| - _erbout.concat f.text_field(:title) - _erbout.concat f.text_area(:body) - _erbout.concat f.check_box(:secret) + @output_buffer.concat f.text_field(:title) + @output_buffer.concat f.text_area(:body) + @output_buffer.concat f.check_box(:secret) end expected = @@ -378,16 +378,16 @@ class FormHelperTest < ActionView::TestCase "" + "" - assert_dom_equal expected, _erbout + assert_dom_equal expected, @output_buffer end def test_form_for_without_object - _erbout = '' + @output_buffer = '' form_for(:post, :html => { :id => 'create-post' }) do |f| - _erbout.concat f.text_field(:title) - _erbout.concat f.text_area(:body) - _erbout.concat f.check_box(:secret) + @output_buffer.concat f.text_field(:title) + @output_buffer.concat f.text_area(:body) + @output_buffer.concat f.check_box(:secret) end expected = @@ -398,17 +398,17 @@ class FormHelperTest < ActionView::TestCase "" + "" - assert_dom_equal expected, _erbout + assert_dom_equal expected, @output_buffer end def test_form_for_with_index - _erbout = '' + @output_buffer = '' form_for("post[]", @post) do |f| - _erbout.concat f.label(:title) - _erbout.concat f.text_field(:title) - _erbout.concat f.text_area(:body) - _erbout.concat f.check_box(:secret) + @output_buffer.concat f.label(:title) + @output_buffer.concat f.text_field(:title) + @output_buffer.concat f.text_area(:body) + @output_buffer.concat f.check_box(:secret) end expected = @@ -420,16 +420,16 @@ class FormHelperTest < ActionView::TestCase "" + "" - assert_dom_equal expected, _erbout + assert_dom_equal expected, @output_buffer end def test_form_for_with_nil_index_option_override - _erbout = '' + @output_buffer = '' form_for("post[]", @post, :index => nil) do |f| - _erbout.concat f.text_field(:title) - _erbout.concat f.text_area(:body) - _erbout.concat f.check_box(:secret) + @output_buffer.concat f.text_field(:title) + @output_buffer.concat f.text_area(:body) + @output_buffer.concat f.check_box(:secret) end expected = @@ -440,14 +440,14 @@ class FormHelperTest < ActionView::TestCase "" + "" - assert_dom_equal expected, _erbout + assert_dom_equal expected, @output_buffer end def test_nested_fields_for - _erbout = '' + @output_buffer = '' form_for(:post, @post) do |f| f.fields_for(:comment, @post) do |c| - _erbout.concat c.text_field(:title) + @output_buffer.concat c.text_field(:title) end end @@ -455,16 +455,16 @@ class FormHelperTest < ActionView::TestCase "" + "" - assert_dom_equal expected, _erbout + assert_dom_equal expected, @output_buffer end def test_fields_for - _erbout = '' + @output_buffer = '' fields_for(:post, @post) do |f| - _erbout.concat f.text_field(:title) - _erbout.concat f.text_area(:body) - _erbout.concat f.check_box(:secret) + @output_buffer.concat f.text_field(:title) + @output_buffer.concat f.text_area(:body) + @output_buffer.concat f.check_box(:secret) end expected = @@ -473,16 +473,16 @@ class FormHelperTest < ActionView::TestCase "" + "" - assert_dom_equal expected, _erbout + assert_dom_equal expected, @output_buffer end def test_fields_for_with_index - _erbout = '' + @output_buffer = '' fields_for("post[]", @post) do |f| - _erbout.concat f.text_field(:title) - _erbout.concat f.text_area(:body) - _erbout.concat f.check_box(:secret) + @output_buffer.concat f.text_field(:title) + @output_buffer.concat f.text_area(:body) + @output_buffer.concat f.check_box(:secret) end expected = @@ -491,16 +491,16 @@ class FormHelperTest < ActionView::TestCase "" + "" - assert_dom_equal expected, _erbout + assert_dom_equal expected, @output_buffer end def test_fields_for_with_nil_index_option_override - _erbout = '' + @output_buffer = '' fields_for("post[]", @post, :index => nil) do |f| - _erbout.concat f.text_field(:title) - _erbout.concat f.text_area(:body) - _erbout.concat f.check_box(:secret) + @output_buffer.concat f.text_field(:title) + @output_buffer.concat f.text_area(:body) + @output_buffer.concat f.check_box(:secret) end expected = @@ -509,16 +509,16 @@ class FormHelperTest < ActionView::TestCase "" + "" - assert_dom_equal expected, _erbout + assert_dom_equal expected, @output_buffer end def test_fields_for_with_index_option_override - _erbout = '' + @output_buffer = '' fields_for("post[]", @post, :index => "abc") do |f| - _erbout.concat f.text_field(:title) - _erbout.concat f.text_area(:body) - _erbout.concat f.check_box(:secret) + @output_buffer.concat f.text_field(:title) + @output_buffer.concat f.text_area(:body) + @output_buffer.concat f.check_box(:secret) end expected = @@ -527,15 +527,15 @@ class FormHelperTest < ActionView::TestCase "" + "" - assert_dom_equal expected, _erbout + assert_dom_equal expected, @output_buffer end def test_fields_for_without_object - _erbout = '' + @output_buffer = '' fields_for(:post) do |f| - _erbout.concat f.text_field(:title) - _erbout.concat f.text_area(:body) - _erbout.concat f.check_box(:secret) + @output_buffer.concat f.text_field(:title) + @output_buffer.concat f.text_area(:body) + @output_buffer.concat f.check_box(:secret) end expected = @@ -544,15 +544,15 @@ class FormHelperTest < ActionView::TestCase "" + "" - assert_dom_equal expected, _erbout + assert_dom_equal expected, @output_buffer end def test_fields_for_with_only_object - _erbout = '' + @output_buffer = '' fields_for(@post) do |f| - _erbout.concat f.text_field(:title) - _erbout.concat f.text_area(:body) - _erbout.concat f.check_box(:secret) + @output_buffer.concat f.text_field(:title) + @output_buffer.concat f.text_area(:body) + @output_buffer.concat f.check_box(:secret) end expected = @@ -561,31 +561,31 @@ class FormHelperTest < ActionView::TestCase "" + "" - assert_dom_equal expected, _erbout + assert_dom_equal expected, @output_buffer end def test_fields_for_object_with_bracketed_name - _erbout = '' + @output_buffer = '' fields_for("author[post]", @post) do |f| - _erbout.concat f.label(:title) - _erbout.concat f.text_field(:title) + @output_buffer.concat f.label(:title) + @output_buffer.concat f.text_field(:title) end assert_dom_equal "" + "", - _erbout + @output_buffer end def test_fields_for_object_with_bracketed_name_and_index - _erbout = '' + @output_buffer = '' fields_for("author[post]", @post, :index => 1) do |f| - _erbout.concat f.label(:title) - _erbout.concat f.text_field(:title) + @output_buffer.concat f.label(:title) + @output_buffer.concat f.text_field(:title) end assert_dom_equal "" + "", - _erbout + @output_buffer end def test_form_builder_does_not_have_form_for_method @@ -593,14 +593,14 @@ class FormHelperTest < ActionView::TestCase end def test_form_for_and_fields_for - _erbout = '' + @output_buffer = '' form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form| - _erbout.concat post_form.text_field(:title) - _erbout.concat post_form.text_area(:body) + @output_buffer.concat post_form.text_field(:title) + @output_buffer.concat post_form.text_area(:body) fields_for(:parent_post, @post) do |parent_fields| - _erbout.concat parent_fields.check_box(:secret) + @output_buffer.concat parent_fields.check_box(:secret) end end @@ -612,18 +612,18 @@ class FormHelperTest < ActionView::TestCase "" + "" - assert_dom_equal expected, _erbout + assert_dom_equal expected, @output_buffer end def test_form_for_and_fields_for_with_object - _erbout = '' + @output_buffer = '' form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form| - _erbout.concat post_form.text_field(:title) - _erbout.concat post_form.text_area(:body) + @output_buffer.concat post_form.text_field(:title) + @output_buffer.concat post_form.text_area(:body) post_form.fields_for(@comment) do |comment_fields| - _erbout.concat comment_fields.text_field(:name) + @output_buffer.concat comment_fields.text_field(:name) end end @@ -634,7 +634,7 @@ class FormHelperTest < ActionView::TestCase "" + "" - assert_dom_equal expected, _erbout + assert_dom_equal expected, @output_buffer end class LabelledFormBuilder < ActionView::Helpers::FormBuilder @@ -649,12 +649,12 @@ class FormHelperTest < ActionView::TestCase end def test_form_for_with_labelled_builder - _erbout = '' + @output_buffer = '' form_for(:post, @post, :builder => LabelledFormBuilder) do |f| - _erbout.concat f.text_field(:title) - _erbout.concat f.text_area(:body) - _erbout.concat f.check_box(:secret) + @output_buffer.concat f.text_field(:title) + @output_buffer.concat f.text_area(:body) + @output_buffer.concat f.check_box(:secret) end expected = @@ -665,18 +665,18 @@ class FormHelperTest < ActionView::TestCase "
" + "" - assert_dom_equal expected, _erbout + assert_dom_equal expected, @output_buffer end def test_default_form_builder old_default_form_builder, ActionView::Base.default_form_builder = ActionView::Base.default_form_builder, LabelledFormBuilder - _erbout = '' + @output_buffer = '' form_for(:post, @post) do |f| - _erbout.concat f.text_field(:title) - _erbout.concat f.text_area(:body) - _erbout.concat f.check_box(:secret) + @output_buffer.concat f.text_field(:title) + @output_buffer.concat f.text_area(:body) + @output_buffer.concat f.check_box(:secret) end expected = @@ -687,17 +687,17 @@ class FormHelperTest < ActionView::TestCase "
" + "" - assert_dom_equal expected, _erbout + assert_dom_equal expected, @output_buffer ensure ActionView::Base.default_form_builder = old_default_form_builder end def test_default_form_builder_with_active_record_helpers - _erbout = '' + @output_buffer = '' form_for(:post, @post) do |f| - _erbout.concat f.error_message_on('author_name') - _erbout.concat f.error_messages + @output_buffer.concat f.error_message_on('author_name') + @output_buffer.concat f.error_messages end expected = %(
) + @@ -705,7 +705,7 @@ class FormHelperTest < ActionView::TestCase %(

1 error prohibited this post from being saved

There were problems with the following fields:

  • Author name can't be empty
) + %(
) - assert_dom_equal expected, _erbout + assert_dom_equal expected, @output_buffer end @@ -713,10 +713,10 @@ class FormHelperTest < ActionView::TestCase post = @post @post = nil - _erbout = '' + @output_buffer = '' form_for(:post, post) do |f| - _erbout.concat f.error_message_on('author_name') - _erbout.concat f.error_messages + @output_buffer.concat f.error_message_on('author_name') + @output_buffer.concat f.error_messages end expected = %(
) + @@ -724,19 +724,19 @@ class FormHelperTest < ActionView::TestCase %(

1 error prohibited this post from being saved

There were problems with the following fields:

  • Author name can't be empty
) + %(
) - assert_dom_equal expected, _erbout + assert_dom_equal expected, @output_buffer end # Perhaps this test should be moved to prototype helper tests. def test_remote_form_for_with_labelled_builder self.extend ActionView::Helpers::PrototypeHelper - _erbout = '' + @output_buffer = '' remote_form_for(:post, @post, :builder => LabelledFormBuilder) do |f| - _erbout.concat f.text_field(:title) - _erbout.concat f.text_area(:body) - _erbout.concat f.check_box(:secret) + @output_buffer.concat f.text_field(:title) + @output_buffer.concat f.text_area(:body) + @output_buffer.concat f.check_box(:secret) end expected = @@ -747,16 +747,16 @@ class FormHelperTest < ActionView::TestCase "
" + "" - assert_dom_equal expected, _erbout + assert_dom_equal expected, @output_buffer end def test_fields_for_with_labelled_builder - _erbout = '' + @output_buffer = '' fields_for(:post, @post, :builder => LabelledFormBuilder) do |f| - _erbout.concat f.text_field(:title) - _erbout.concat f.text_area(:body) - _erbout.concat f.check_box(:secret) + @output_buffer.concat f.text_field(:title) + @output_buffer.concat f.text_area(:body) + @output_buffer.concat f.check_box(:secret) end expected = @@ -765,28 +765,28 @@ class FormHelperTest < ActionView::TestCase " " + "
" - assert_dom_equal expected, _erbout + assert_dom_equal expected, @output_buffer end def test_form_for_with_html_options_adds_options_to_form_tag - _erbout = '' + @output_buffer = '' form_for(:post, @post, :html => {:id => 'some_form', :class => 'some_class'}) do |f| end expected = "
" - assert_dom_equal expected, _erbout + assert_dom_equal expected, @output_buffer end def test_form_for_with_string_url_option - _erbout = '' + @output_buffer = '' form_for(:post, @post, :url => 'http://www.otherdomain.com') do |f| end - assert_equal '
', _erbout + assert_equal '
', @output_buffer end def test_form_for_with_hash_url_option - _erbout = '' + @output_buffer = '' form_for(:post, @post, :url => {:controller => 'controller', :action => 'action'}) do |f| end @@ -795,25 +795,25 @@ class FormHelperTest < ActionView::TestCase end def test_form_for_with_record_url_option - _erbout = '' + @output_buffer = '' form_for(:post, @post, :url => @post) do |f| end expected = "
" - assert_equal expected, _erbout + assert_equal expected, @output_buffer end def test_form_for_with_existing_object - _erbout = '' + @output_buffer = '' form_for(@post) do |f| end expected = "
" - assert_equal expected, _erbout + assert_equal expected, @output_buffer end def test_form_for_with_new_object - _erbout = '' + @output_buffer = '' post = Post.new post.new_record = true @@ -822,64 +822,64 @@ class FormHelperTest < ActionView::TestCase form_for(post) do |f| end expected = "
" - assert_equal expected, _erbout + assert_equal expected, @output_buffer end def test_form_for_with_existing_object_in_list @post.new_record = false @comment.save - _erbout = '' + @output_buffer = '' form_for([@post, @comment]) {} expected = %(
) - assert_dom_equal expected, _erbout + assert_dom_equal expected, @output_buffer end def test_form_for_with_new_object_in_list @post.new_record = false - _erbout = '' + @output_buffer = '' form_for([@post, @comment]) {} expected = %(
) - assert_dom_equal expected, _erbout + assert_dom_equal expected, @output_buffer end def test_form_for_with_existing_object_and_namespace_in_list @post.new_record = false @comment.save - _erbout = '' + @output_buffer = '' form_for([:admin, @post, @comment]) {} expected = %(
) - assert_dom_equal expected, _erbout + assert_dom_equal expected, @output_buffer end def test_form_for_with_new_object_and_namespace_in_list @post.new_record = false - _erbout = '' + @output_buffer = '' form_for([:admin, @post, @comment]) {} expected = %(
) - assert_dom_equal expected, _erbout + assert_dom_equal expected, @output_buffer end def test_form_for_with_existing_object_and_custom_url - _erbout = '' + @output_buffer = '' form_for(@post, :url => "/super_posts") do |f| end expected = "
" - assert_equal expected, _erbout + assert_equal expected, @output_buffer end def test_remote_form_for_with_html_options_adds_options_to_form_tag self.extend ActionView::Helpers::PrototypeHelper - _erbout = '' + @output_buffer = '' remote_form_for(:post, @post, :html => {:id => 'some_form', :class => 'some_class'}) do |f| end expected = "
" - assert_dom_equal expected, _erbout + assert_dom_equal expected, @output_buffer end diff --git a/actionpack/test/template/form_options_helper_test.rb b/actionpack/test/template/form_options_helper_test.rb index 48a26deea9..3c9fb297c3 100644 --- a/actionpack/test/template/form_options_helper_test.rb +++ b/actionpack/test/template/form_options_helper_test.rb @@ -231,15 +231,15 @@ class FormOptionsHelperTest < ActionView::TestCase @post = Post.new @post.category = "" - _erbout = '' + @output_buffer = '' fields_for :post, @post do |f| - _erbout.concat f.select(:category, %w( abe hest)) + @output_buffer.concat f.select(:category, %w( abe hest)) end assert_dom_equal( "", - _erbout + @output_buffer ) end @@ -353,15 +353,15 @@ class FormOptionsHelperTest < ActionView::TestCase @post = Post.new @post.author_name = "Babe" - _erbout = '' + @output_buffer = '' fields_for :post, @post do |f| - _erbout.concat f.collection_select(:author_name, @posts, :author_name, :author_name) + @output_buffer.concat f.collection_select(:author_name, @posts, :author_name, :author_name) end assert_dom_equal( "", - _erbout + @output_buffer ) end @@ -1195,10 +1195,10 @@ COUNTRIES def test_time_zone_select_under_fields_for @firm = Firm.new("D") - _erbout = '' + @output_buffer = '' fields_for :firm, @firm do |f| - _erbout.concat f.time_zone_select(:time_zone) + @output_buffer.concat f.time_zone_select(:time_zone) end assert_dom_equal( @@ -1209,7 +1209,7 @@ COUNTRIES "\n" + "" + "", - _erbout + @output_buffer ) end diff --git a/actionpack/test/template/form_tag_helper_test.rb b/actionpack/test/template/form_tag_helper_test.rb index 73a8bd4d87..b281db18bd 100644 --- a/actionpack/test/template/form_tag_helper_test.rb +++ b/actionpack/test/template/form_tag_helper_test.rb @@ -43,19 +43,19 @@ class FormTagHelperTest < ActionView::TestCase end def test_form_tag_with_block - _erbout = '' - form_tag("http://example.com") { _erbout.concat "Hello world!" } + @output_buffer = '' + form_tag("http://example.com") { @output_buffer.concat "Hello world!" } expected = %(
Hello world!
) - assert_dom_equal expected, _erbout + assert_dom_equal expected, @output_buffer end def test_form_tag_with_block_and_method - _erbout = '' - form_tag("http://example.com", :method => :put) { _erbout.concat "Hello world!" } + @output_buffer = '' + form_tag("http://example.com", :method => :put) { @output_buffer.concat "Hello world!" } expected = %(
Hello world!
) - assert_dom_equal expected, _erbout + assert_dom_equal expected, @output_buffer end def test_hidden_field_tag @@ -234,23 +234,23 @@ class FormTagHelperTest < ActionView::TestCase end def test_field_set_tag - _erbout = '' - field_set_tag("Your details") { _erbout.concat "Hello world!" } + @output_buffer = '' + field_set_tag("Your details") { @output_buffer.concat "Hello world!" } expected = %(
Your detailsHello world!
) - assert_dom_equal expected, _erbout + assert_dom_equal expected, @output_buffer - _erbout = '' - field_set_tag { _erbout.concat "Hello world!" } + @output_buffer = '' + field_set_tag { @output_buffer.concat "Hello world!" } expected = %(
Hello world!
) - assert_dom_equal expected, _erbout + assert_dom_equal expected, @output_buffer - _erbout = '' - field_set_tag('') { _erbout.concat "Hello world!" } + @output_buffer = '' + field_set_tag('') { @output_buffer.concat "Hello world!" } expected = %(
Hello world!
) - assert_dom_equal expected, _erbout + assert_dom_equal expected, @output_buffer end def protect_against_forgery? diff --git a/actionpack/test/template/javascript_helper_test.rb b/actionpack/test/template/javascript_helper_test.rb index f18adb990c..f136f56777 100644 --- a/actionpack/test/template/javascript_helper_test.rb +++ b/actionpack/test/template/javascript_helper_test.rb @@ -92,15 +92,15 @@ class JavaScriptHelperTest < ActionView::TestCase end def test_javascript_tag_with_block - _erbout = '' - javascript_tag { _erbout.concat "alert('hello')" } - assert_dom_equal "", _erbout + @output_buffer = '' + javascript_tag { @output_buffer.concat "alert('hello')" } + assert_dom_equal "", @output_buffer end def test_javascript_tag_with_block_and_options - _erbout = '' - javascript_tag(:id => "the_js_tag") { _erbout.concat "alert('hello')" } - assert_dom_equal "", _erbout + @output_buffer = '' + javascript_tag(:id => "the_js_tag") { @output_buffer.concat "alert('hello')" } + assert_dom_equal "", @output_buffer end def test_javascript_cdata_section diff --git a/actionpack/test/template/prototype_helper_test.rb b/actionpack/test/template/prototype_helper_test.rb index 53a250f9d5..dd6f6ab741 100644 --- a/actionpack/test/template/prototype_helper_test.rb +++ b/actionpack/test/template/prototype_helper_test.rb @@ -118,52 +118,52 @@ class PrototypeHelperTest < PrototypeHelperBaseTest end def test_form_remote_tag_with_block - _erbout = '' - form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }) { _erbout.concat "Hello world!" } - assert_dom_equal %(
Hello world!
), _erbout + @output_buffer = '' + form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }) { @output_buffer.concat "Hello world!" } + assert_dom_equal %(
Hello world!
), @output_buffer end def test_remote_form_for_with_record_identification_with_new_record - _erbout = '' + @output_buffer = '' remote_form_for(@record, {:html => { :id => 'create-author' }}) {} expected = %(
) - assert_dom_equal expected, _erbout + assert_dom_equal expected, @output_buffer end def test_remote_form_for_with_record_identification_without_html_options - _erbout = '' + @output_buffer = '' remote_form_for(@record) {} expected = %(
) - assert_dom_equal expected, _erbout + assert_dom_equal expected, @output_buffer end def test_remote_form_for_with_record_identification_with_existing_record @record.save - _erbout = '' + @output_buffer = '' remote_form_for(@record) {} expected = %(
) - assert_dom_equal expected, _erbout + assert_dom_equal expected, @output_buffer end def test_remote_form_for_with_new_object_in_list - _erbout = '' + @output_buffer = '' remote_form_for([@author, @article]) {} expected = %(
) - assert_dom_equal expected, _erbout + assert_dom_equal expected, @output_buffer end def test_remote_form_for_with_existing_object_in_list @author.save @article.save - _erbout = '' + @output_buffer = '' remote_form_for([@author, @article]) {} expected = %(
) - assert_dom_equal expected, _erbout + assert_dom_equal expected, @output_buffer end def test_on_callbacks diff --git a/actionpack/test/template/record_tag_helper_test.rb b/actionpack/test/template/record_tag_helper_test.rb index 0afbb54f57..c39e5c69bf 100644 --- a/actionpack/test/template/record_tag_helper_test.rb +++ b/actionpack/test/template/record_tag_helper_test.rb @@ -17,37 +17,37 @@ class RecordTagHelperTest < ActionView::TestCase end def test_content_tag_for - _erbout = '' + @output_buffer = '' expected = %(
  • ) actual = content_tag_for(:li, @post, :class => 'bar') { } assert_dom_equal expected, actual end def test_content_tag_for_prefix - _erbout = '' + @output_buffer = '' expected = %(
      ) actual = content_tag_for(:ul, @post, :archived) { } assert_dom_equal expected, actual end def test_content_tag_for_with_extra_html_tags - _erbout = '' + @output_buffer = '' expected = %() actual = content_tag_for(:tr, @post, {:class => "bar", :style => "background-color: #f0f0f0"}) { } assert_dom_equal expected, actual end def test_block_works_with_content_tag_for - _erbout = '' + @output_buffer = '' expected = %(#{@post.body}) - actual = content_tag_for(:tr, @post) { _erbout.concat @post.body } + actual = content_tag_for(:tr, @post) { @output_buffer.concat @post.body } assert_dom_equal expected, actual end def test_div_for - _erbout = '' + @output_buffer = '' expected = %(
      #{@post.body}
      ) - actual = div_for(@post, :class => "bar") { _erbout.concat @post.body } + actual = div_for(@post, :class => "bar") { @output_buffer.concat @post.body } assert_dom_equal expected, actual end diff --git a/actionpack/test/template/tag_helper_test.rb b/actionpack/test/template/tag_helper_test.rb index 4da6116095..7db04d178f 100644 --- a/actionpack/test/template/tag_helper_test.rb +++ b/actionpack/test/template/tag_helper_test.rb @@ -35,15 +35,15 @@ class TagHelperTest < ActionView::TestCase end def test_content_tag_with_block - _erbout = '' - content_tag(:div) { _erbout.concat "Hello world!" } - assert_dom_equal "
      Hello world!
      ", _erbout + @output_buffer = '' + content_tag(:div) { @output_buffer.concat "Hello world!" } + assert_dom_equal "
      Hello world!
      ", @output_buffer end def test_content_tag_with_block_and_options - _erbout = '' - content_tag(:div, :class => "green") { _erbout.concat "Hello world!" } - assert_dom_equal %(
      Hello world!
      ), _erbout + @output_buffer = '' + content_tag(:div, :class => "green") { @output_buffer.concat "Hello world!" } + assert_dom_equal %(
      Hello world!
      ), @output_buffer end def test_content_tag_with_block_and_options_outside_of_action_view -- cgit v1.2.3 From 4d4c8e298f5396e6b8ace0a10d7f991594aace2d Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Mon, 2 Jun 2008 13:49:14 -0700 Subject: Don't pass block binding to concat --- actionpack/lib/action_view/base.rb | 2 +- actionpack/lib/action_view/helpers/form_helper.rb | 4 ++-- actionpack/lib/action_view/helpers/form_tag_helper.rb | 14 +++++++------- actionpack/lib/action_view/helpers/javascript_helper.rb | 8 +------- actionpack/lib/action_view/helpers/prototype_helper.rb | 4 ++-- actionpack/lib/action_view/helpers/record_tag_helper.rb | 5 ++--- actionpack/lib/action_view/helpers/tag_helper.rb | 7 ++----- actionpack/lib/action_view/helpers/text_helper.rb | 8 ++++---- 8 files changed, 21 insertions(+), 31 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 7a603f150f..ad114acc6c 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -257,7 +257,7 @@ If you are rendering a subtemplate, you must now use controller-like partial syn if partial_layout = options.delete(:layout) if block_given? wrap_content_for_layout capture(&block) do - concat(render(options.merge(:partial => partial_layout)), block.binding) + concat(render(options.merge(:partial => partial_layout))) end else wrap_content_for_layout render(options) do diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index 0791feb9ac..63a932320e 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -249,9 +249,9 @@ module ActionView args.unshift object end - concat(form_tag(options.delete(:url) || {}, options.delete(:html) || {}), proc.binding) + concat(form_tag(options.delete(:url) || {}, options.delete(:html) || {})) fields_for(object_name, *(args << options), &proc) - concat('', proc.binding) + concat('') end def apply_form_for_options!(object_or_array, options) #:nodoc: diff --git a/actionpack/lib/action_view/helpers/form_tag_helper.rb b/actionpack/lib/action_view/helpers/form_tag_helper.rb index ca58f4ba26..3a97f1390f 100644 --- a/actionpack/lib/action_view/helpers/form_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/form_tag_helper.rb @@ -407,10 +407,10 @@ module ActionView # # =>
      Your details

      def field_set_tag(legend = nil, &block) content = capture(&block) - concat(tag(:fieldset, {}, true), block.binding) - concat(content_tag(:legend, legend), block.binding) unless legend.blank? - concat(content, block.binding) - concat("", block.binding) + concat(tag(:fieldset, {}, true)) + concat(content_tag(:legend, legend)) unless legend.blank? + concat(content) + concat("") end private @@ -442,9 +442,9 @@ module ActionView def form_tag_in_block(html_options, &block) content = capture(&block) - concat(form_tag_html(html_options), block.binding) - concat(content, block.binding) - concat("", block.binding) + concat(form_tag_html(html_options)) + concat(content) + concat("") end def token_tag diff --git a/actionpack/lib/action_view/helpers/javascript_helper.rb b/actionpack/lib/action_view/helpers/javascript_helper.rb index 8c880dee2f..a2f2577636 100644 --- a/actionpack/lib/action_view/helpers/javascript_helper.rb +++ b/actionpack/lib/action_view/helpers/javascript_helper.rb @@ -179,13 +179,7 @@ module ActionView content = content_or_options_with_block end - javascript_tag = content_tag("script", javascript_cdata_section(content), html_options.merge(:type => Mime::JS)) - - if block_given? && block_is_within_action_view?(block) - concat(javascript_tag, block.binding) - else - javascript_tag - end + concat(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/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb index 602832e470..ed2abba17a 100644 --- a/actionpack/lib/action_view/helpers/prototype_helper.rb +++ b/actionpack/lib/action_view/helpers/prototype_helper.rb @@ -382,9 +382,9 @@ module ActionView args.unshift object end - concat(form_remote_tag(options), proc.binding) + concat(form_remote_tag(options)) fields_for(object_name, *(args << options), &proc) - concat('', proc.binding) + concat('') end alias_method :form_remote_for, :remote_form_for diff --git a/actionpack/lib/action_view/helpers/record_tag_helper.rb b/actionpack/lib/action_view/helpers/record_tag_helper.rb index 66c596f3a9..9bb235175e 100644 --- a/actionpack/lib/action_view/helpers/record_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/record_tag_helper.rb @@ -51,9 +51,8 @@ module ActionView prefix = args.first.is_a?(Hash) ? nil : args.shift options = args.first.is_a?(Hash) ? args.shift : {} concat content_tag(tag_name, capture(&block), - options.merge({ :class => "#{dom_class(record)} #{options[:class]}".strip, :id => dom_id(record, prefix) })), - block.binding + options.merge({ :class => "#{dom_class(record)} #{options[:class]}".strip, :id => dom_id(record, prefix) })) end end end -end \ No newline at end of file +end diff --git a/actionpack/lib/action_view/helpers/tag_helper.rb b/actionpack/lib/action_view/helpers/tag_helper.rb index df3d69c0d8..e669620381 100644 --- a/actionpack/lib/action_view/helpers/tag_helper.rb +++ b/actionpack/lib/action_view/helpers/tag_helper.rb @@ -66,12 +66,9 @@ 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 = capture(&block) - content_tag = content_tag_string(name, content, options, escape) - block_is_within_action_view?(block) ? concat(content_tag, block.binding) : content_tag + concat(content_tag_string(name, capture(&block), options, escape)) else - content = content_or_options_with_block - content_tag_string(name, content, options, escape) + content_tag_string(name, content_or_options_with_block, options, escape) end end diff --git a/actionpack/lib/action_view/helpers/text_helper.rb b/actionpack/lib/action_view/helpers/text_helper.rb index 4711b84ae7..3be4843386 100644 --- a/actionpack/lib/action_view/helpers/text_helper.rb +++ b/actionpack/lib/action_view/helpers/text_helper.rb @@ -15,17 +15,17 @@ module ActionView # # ==== Examples # <% - # concat "hello", binding + # concat "hello" # # is the equivalent of <%= "hello" %> # # if (logged_in == true): - # concat "Logged in!", binding + # concat "Logged in!" # else - # concat link_to('login', :action => login), binding + # concat link_to('login', :action => login) # end # # will either display "Logged in!" or a login link # %> - def concat(string, binding = nil) + def concat(string) if @output_buffer @output_buffer << string else -- cgit v1.2.3 From f55ad960d22337d0d92a93724f1cc3ad45200836 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Tue, 3 Jun 2008 01:10:00 -0700 Subject: Stack @output_buffer for nested rendering --- actionpack/lib/action_view/template_handlers/compilable.rb | 4 ++-- actionpack/test/controller/caching_test.rb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/template_handlers/compilable.rb b/actionpack/lib/action_view/template_handlers/compilable.rb index 25bd0fea7f..28c72172a0 100644 --- a/actionpack/lib/action_view/template_handlers/compilable.rb +++ b/actionpack/lib/action_view/template_handlers/compilable.rb @@ -106,7 +106,7 @@ module ActionView locals_code << "#{key} = local_assigns[:#{key}]\n" end - "def #{render_symbol}(local_assigns)\n#{locals_code}#{body}\nend" + "def #{render_symbol}(local_assigns)\nold_output_buffer = @output_buffer;#{locals_code}#{body}\nensure\n@output_buffer = old_output_buffer\nend" end # Return true if the given template was compiled for a superset of the keys in local_assigns @@ -125,4 +125,4 @@ module ActionView end end -end \ No newline at end of file +end diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index d0ee93cf3f..8b3ddc7603 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -512,7 +512,7 @@ class FragmentCachingTest < Test::Unit::TestCase def test_cache_erb_fragment @store.write('views/expensive', 'fragment content') - @controller.template.output_buffer = 'generated till now -> ' + @controller.response.template.output_buffer = 'generated till now -> ' assert_equal( 'generated till now -> fragment content', ActionView::TemplateHandlers::ERB.new(@controller).cache_fragment(Proc.new{ }, 'expensive')) -- cgit v1.2.3 From c08547d2266c75f0a82d06dd91c6d0500740e12e Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 3 Jun 2008 13:32:53 -0500 Subject: Namespace Inflector, Dependencies, OrderedOptions, and TimeZone under ActiveSupport [#238 state:resolved] --- actionpack/lib/action_controller/dispatcher.rb | 2 +- actionpack/lib/action_controller/routing.rb | 2 +- actionpack/test/controller/dispatcher_test.rb | 4 ++-- actionpack/test/controller/integration_upload_test.rb | 2 +- actionpack/test/controller/routing_test.rb | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/dispatcher.rb b/actionpack/lib/action_controller/dispatcher.rb index 7162fb8b1f..fe4f6b4a7e 100644 --- a/actionpack/lib/action_controller/dispatcher.rb +++ b/actionpack/lib/action_controller/dispatcher.rb @@ -141,7 +141,7 @@ module ActionController # be reloaded on the next request without restarting the server. def cleanup_application ActiveRecord::Base.reset_subclasses if defined?(ActiveRecord) - Dependencies.clear + ActiveSupport::Dependencies.clear ActiveRecord::Base.clear_reloadable_connections! if defined?(ActiveRecord) end diff --git a/actionpack/lib/action_controller/routing.rb b/actionpack/lib/action_controller/routing.rb index 6aa266513d..8846dcc504 100644 --- a/actionpack/lib/action_controller/routing.rb +++ b/actionpack/lib/action_controller/routing.rb @@ -369,7 +369,7 @@ module ActionController Routes = RouteSet.new - ::Inflector.module_eval do + ActiveSupport::Inflector.module_eval do # Ensures that routes are reloaded when Rails inflections are updated. def inflections_with_route_reloading(&block) returning(inflections_without_route_reloading(&block)) { diff --git a/actionpack/test/controller/dispatcher_test.rb b/actionpack/test/controller/dispatcher_test.rb index eea0813ed5..911fcab67b 100644 --- a/actionpack/test/controller/dispatcher_test.rb +++ b/actionpack/test/controller/dispatcher_test.rb @@ -27,14 +27,14 @@ class DispatcherTest < Test::Unit::TestCase def test_clears_dependencies_after_dispatch_if_in_loading_mode ActionController::Routing::Routes.expects(:reload).once - Dependencies.expects(:clear).once + ActiveSupport::Dependencies.expects(:clear).once dispatch(@output, false) end def test_leaves_dependencies_after_dispatch_if_not_in_loading_mode ActionController::Routing::Routes.expects(:reload).never - Dependencies.expects(:clear).never + ActiveSupport::Dependencies.expects(:clear).never dispatch end diff --git a/actionpack/test/controller/integration_upload_test.rb b/actionpack/test/controller/integration_upload_test.rb index 33df1131cb..4af9b7e697 100644 --- a/actionpack/test/controller/integration_upload_test.rb +++ b/actionpack/test/controller/integration_upload_test.rb @@ -28,7 +28,7 @@ class SessionUploadTest < ActionController::IntegrationTest # end def test_post_with_upload uses_mocha "test_post_with_upload" do - Dependencies.stubs(:load?).returns(false) + ActiveSupport::Dependencies.stubs(:load?).returns(false) with_routing do |set| set.draw do |map| map.update 'update', :controller => "upload_test", :action => "update", :method => :post diff --git a/actionpack/test/controller/routing_test.rb b/actionpack/test/controller/routing_test.rb index 5e5503fd52..068d71a8f8 100644 --- a/actionpack/test/controller/routing_test.rb +++ b/actionpack/test/controller/routing_test.rb @@ -2392,10 +2392,10 @@ uses_mocha 'route loading' do end def test_adding_inflections_forces_reload - Inflector::Inflections.instance.expects(:uncountable).with('equipment') + ActiveSupport::Inflector::Inflections.instance.expects(:uncountable).with('equipment') routes.expects(:reload!) - Inflector.inflections { |inflect| inflect.uncountable('equipment') } + ActiveSupport::Inflector.inflections { |inflect| inflect.uncountable('equipment') } end def test_load_with_configuration -- cgit v1.2.3 From d54d90f2b590c763fe710482a9b993923fe03ec0 Mon Sep 17 00:00:00 2001 From: josevalim Date: Tue, 3 Jun 2008 14:02:51 -0500 Subject: Allow caches_action to accept a layout option [#198 state:resolved] Signed-off-by: Joshua Peek --- actionpack/CHANGELOG | 2 ++ actionpack/lib/action_controller/caching/actions.rb | 20 +++++++++++++++++--- actionpack/test/controller/caching_test.rb | 15 +++++++++++++++ 3 files changed, 34 insertions(+), 3 deletions(-) (limited to 'actionpack') diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index 9622029362..ba2b16849c 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -1,3 +1,5 @@ +* Allow caches_action to accept a layout option [José Valim] + * Added Rack processor [Ezra Zygmuntowicz, Josh Peek] diff --git a/actionpack/lib/action_controller/caching/actions.rb b/actionpack/lib/action_controller/caching/actions.rb index 1ef9e60a21..c4b0a97a33 100644 --- a/actionpack/lib/action_controller/caching/actions.rb +++ b/actionpack/lib/action_controller/caching/actions.rb @@ -40,6 +40,8 @@ module ActionController #:nodoc: # controller.send(:list_url, c.params[:id]) } # end # + # If you pass :layout => false, it will only cache your action content. It is useful when your layout has dynamic information. + # module Actions def self.included(base) #:nodoc: base.extend(ClassMethods) @@ -54,7 +56,8 @@ module ActionController #:nodoc: def caches_action(*actions) return unless cache_configured? options = actions.extract_options! - around_filter(ActionCacheFilter.new(:cache_path => options.delete(:cache_path)), {:only => actions}.merge(options)) + cache_filter = ActionCacheFilter.new(:layout => options.delete(:layout), :cache_path => options.delete(:cache_path)) + around_filter(cache_filter, {:only => actions}.merge(options)) end end @@ -81,7 +84,9 @@ module ActionController #:nodoc: if cache = controller.read_fragment(cache_path.path) controller.rendered_action_cache = true set_content_type!(controller, cache_path.extension) - controller.send!(:render_for_text, cache) + options = { :text => cache } + options.merge!(:layout => true) if cache_layout? + controller.send!(:render, options) false else controller.action_cache_path = cache_path @@ -90,7 +95,8 @@ module ActionController #:nodoc: def after(controller) return if controller.rendered_action_cache || !caching_allowed(controller) - controller.write_fragment(controller.action_cache_path.path, controller.response.body) + action_content = cache_layout? ? content_for_layout(controller) : controller.response.body + controller.write_fragment(controller.action_cache_path.path, action_content) end private @@ -105,6 +111,14 @@ module ActionController #:nodoc: def caching_allowed(controller) controller.request.get? && controller.response.headers['Status'].to_i == 200 end + + def cache_layout? + @options[:layout] == false + end + + def content_for_layout(controller) + controller.response.layout && controller.response.template.instance_variable_get('@content_for_layout') + end end class ActionCachePath diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index f9b6b87bc6..c6d61bb504 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -156,6 +156,7 @@ class ActionCachingTestController < ActionController::Base caches_action :show, :cache_path => 'http://test.host/custom/show' caches_action :edit, :cache_path => Proc.new { |c| c.params[:id] ? "http://test.host/#{c.params[:id]};edit" : "http://test.host/edit" } caches_action :with_layout + caches_action :layout_false, :layout => false layout 'talk_from_action.erb' @@ -181,6 +182,7 @@ class ActionCachingTestController < ActionController::Base alias_method :show, :index alias_method :edit, :index alias_method :destroy, :index + alias_method :layout_false, :with_layout def expire expire_action :controller => 'action_caching_test', :action => 'index' @@ -263,6 +265,19 @@ class ActionCacheTest < Test::Unit::TestCase assert_equal @response.body, read_fragment('hostname.com/action_caching_test/with_layout') end + def test_action_cache_with_layout_and_layout_cache_false + get :layout_false + cached_time = content_to_cache + assert_not_equal cached_time, @response.body + assert fragment_exist?('hostname.com/action_caching_test/layout_false') + reset! + + get :layout_false + assert_not_equal cached_time, @response.body + + assert_equal cached_time, read_fragment('hostname.com/action_caching_test/layout_false') + end + def test_action_cache_conditional_options @request.env['HTTP_ACCEPT'] = 'application/json' get :index -- cgit v1.2.3 From 025515b234d8380f195e3de3818d076302605b12 Mon Sep 17 00:00:00 2001 From: Gabe da Silveira Date: Mon, 2 Jun 2008 19:57:35 -0300 Subject: Fix assert_redirected_to for nested controllers and named routes [#308 state:resolved] Signed-off-by: Michael Koziarski --- .../assertions/response_assertions.rb | 2 +- .../test/controller/action_pack_assertions_test.rb | 23 +++++++++++++++++++--- 2 files changed, 21 insertions(+), 4 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/assertions/response_assertions.rb b/actionpack/lib/action_controller/assertions/response_assertions.rb index c5fc6c7966..3deda0b45a 100644 --- a/actionpack/lib/action_controller/assertions/response_assertions.rb +++ b/actionpack/lib/action_controller/assertions/response_assertions.rb @@ -97,7 +97,7 @@ module ActionController value['controller'] = value['controller'].to_s if key == :actual && value['controller'].first != '/' && !value['controller'].include?('/') new_controller_path = ActionController::Routing.controller_relative_to(value['controller'], @controller.class.controller_path) - value['controller'] = new_controller_path if value['controller'] != new_controller_path && ActionController::Routing.possible_controllers.include?(new_controller_path) + value['controller'] = new_controller_path if value['controller'] != new_controller_path && ActionController::Routing.possible_controllers.include?(new_controller_path) && @response.redirected_to.is_a?(Hash) end value['controller'] = value['controller'][1..-1] if value['controller'].first == '/' # strip leading hash end diff --git a/actionpack/test/controller/action_pack_assertions_test.rb b/actionpack/test/controller/action_pack_assertions_test.rb index f152b1d19c..c25e9e1df6 100644 --- a/actionpack/test/controller/action_pack_assertions_test.rb +++ b/actionpack/test/controller/action_pack_assertions_test.rb @@ -137,6 +137,9 @@ class AssertResponseWithUnexpectedErrorController < ActionController::Base end end +class UserController < ActionController::Base +end + module Admin class InnerModuleController < ActionController::Base def index @@ -174,7 +177,7 @@ class ActionPackAssertionsControllerTest < Test::Unit::TestCase # let's get this party started def setup ActionController::Routing::Routes.reload - ActionController::Routing.use_controllers!(%w(action_pack_assertions admin/inner_module content admin/user)) + ActionController::Routing.use_controllers!(%w(action_pack_assertions admin/inner_module user content admin/user)) @controller = ActionPackAssertionsController.new @request, @response = ActionController::TestRequest.new, ActionController::TestResponse.new end @@ -268,7 +271,7 @@ class ActionPackAssertionsControllerTest < Test::Unit::TestCase assert_redirected_to admin_inner_module_path end end - + def test_assert_redirected_to_top_level_named_route_from_nested_controller with_routing do |set| set.draw do |map| @@ -277,11 +280,25 @@ class ActionPackAssertionsControllerTest < Test::Unit::TestCase end @controller = Admin::InnerModuleController.new process :redirect_to_top_level_named_route - # passes -> assert_redirected_to "http://test.host/action_pack_assertions/foo" + # 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" end end + def test_assert_redirected_to_top_level_named_route_with_same_controller_name_in_both_namespaces + 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 + map.top_level '/user/:id', :controller => 'user', :action => 'index' + map.connect ':controller/:action/:id' + 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') + end + end + # -- standard request/response object testing -------------------------------- # make sure that the template objects exist -- cgit v1.2.3 From edfa195e2ace7b4fb8195333c6e44e6bf8986c11 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Tue, 3 Jun 2008 18:11:47 -0500 Subject: Fixed Request#remote_ip to only raise hell if the HTTP_CLIENT_IP and HTTP_X_FORWARDED_FOR doesnt match (not just if theyre both present) [Mark Imbriaco, Bradford Folkens] --- actionpack/CHANGELOG | 4 ++++ actionpack/lib/action_controller/request.rb | 9 +++++---- actionpack/test/controller/request_test.rb | 3 +++ 3 files changed, 12 insertions(+), 4 deletions(-) (limited to 'actionpack') diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index ba2b16849c..861597701c 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -1,3 +1,7 @@ +*Edge* + +* Fixed Request#remote_ip to only raise hell if the HTTP_CLIENT_IP and HTTP_X_FORWARDED_FOR doesn't match (not just if they're both present) [Mark Imbriaco, Bradford Folkens] + * Allow caches_action to accept a layout option [José Valim] * Added Rack processor [Ezra Zygmuntowicz, Josh Peek] diff --git a/actionpack/lib/action_controller/request.rb b/actionpack/lib/action_controller/request.rb index a35b904194..9b02f2c8a1 100755 --- a/actionpack/lib/action_controller/request.rb +++ b/actionpack/lib/action_controller/request.rb @@ -134,14 +134,15 @@ module ActionController # REMOTE_ADDR is a proxy. HTTP_X_FORWARDED_FOR may be a comma- # delimited list in the case of multiple chained proxies; the last # address which is not trusted is the originating IP. - def remote_ip if TRUSTED_PROXIES !~ @env['REMOTE_ADDR'] return @env['REMOTE_ADDR'] end + remote_ips = @env['HTTP_X_FORWARDED_FOR'] && @env['HTTP_X_FORWARDED_FOR'].split(',') + if @env.include? 'HTTP_CLIENT_IP' - if @env.include? 'HTTP_X_FORWARDED_FOR' + if remote_ips && !remote_ips.include?(@env['HTTP_CLIENT_IP']) # We don't know which came from the proxy, and which from the user raise ActionControllerError.new(< 1 && TRUSTED_PROXIES =~ remote_ips.last.strip remote_ips.pop end diff --git a/actionpack/test/controller/request_test.rb b/actionpack/test/controller/request_test.rb index 82ddfec8e8..2bd489b2c7 100644 --- a/actionpack/test/controller/request_test.rb +++ b/actionpack/test/controller/request_test.rb @@ -59,6 +59,9 @@ class RequestTest < Test::Unit::TestCase assert_match /HTTP_X_FORWARDED_FOR="9.9.9.9, 3.4.5.6, 10.0.0.1, 172.31.4.4"/, e.message assert_match /HTTP_CLIENT_IP="8.8.8.8"/, e.message + @request.env['HTTP_X_FORWARDED_FOR'] = '8.8.8.8, 9.9.9.9' + assert_equal '8.8.8.8', @request.remote_ip + @request.env.delete 'HTTP_CLIENT_IP' @request.env.delete 'HTTP_X_FORWARDED_FOR' end -- cgit v1.2.3 From 30a0ebb3eb9fd4c8e4401bcaa4887eb1ce95defa Mon Sep 17 00:00:00 2001 From: Sean Huber Date: Thu, 29 May 2008 10:49:38 -0700 Subject: Add RJS#page.reload. [#277 state:resolved] Signed-off-by: Pratik Naik --- actionpack/CHANGELOG | 2 ++ actionpack/lib/action_view/helpers/prototype_helper.rb | 10 ++++++++++ actionpack/test/template/prototype_helper_test.rb | 5 +++++ 3 files changed, 17 insertions(+) (limited to 'actionpack') diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index 861597701c..66af5fd745 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -1,5 +1,7 @@ *Edge* +* Added page.reload functionality. Resolves #277. [Sean Huber] + * Fixed Request#remote_ip to only raise hell if the HTTP_CLIENT_IP and HTTP_X_FORWARDED_FOR doesn't match (not just if they're both present) [Mark Imbriaco, Bradford Folkens] * Allow caches_action to accept a layout option [José Valim] diff --git a/actionpack/lib/action_view/helpers/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb index 602832e470..5a1012954e 100644 --- a/actionpack/lib/action_view/helpers/prototype_helper.rb +++ b/actionpack/lib/action_view/helpers/prototype_helper.rb @@ -868,6 +868,16 @@ module ActionView record "window.location.href = #{url.inspect}" end + # Reloads the browser's current +location+ using JavaScript + # + # Examples: + # + # # Generates: window.location.reload(); + # page.reload + def reload + record 'window.location.reload()' + end + # Calls the JavaScript +function+, optionally with the given +arguments+. # # If a block is given, the block will be passed to a new JavaScriptGenerator; diff --git a/actionpack/test/template/prototype_helper_test.rb b/actionpack/test/template/prototype_helper_test.rb index 53a250f9d5..b63d8a368c 100644 --- a/actionpack/test/template/prototype_helper_test.rb +++ b/actionpack/test/template/prototype_helper_test.rb @@ -347,6 +347,11 @@ class JavaScriptGeneratorTest < PrototypeHelperBaseTest @generator.redirect_to("http://www.example.com/welcome?a=b&c=d") end + def test_reload + assert_equal 'window.location.reload();', + @generator.reload + end + def test_delay @generator.delay(20) do @generator.hide('foo') -- cgit v1.2.3 From c4d570c2eb6b7bd0a529e20a1055754183d50c23 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Wed, 4 Jun 2008 22:32:09 -0500 Subject: Use CGI::Cookie::parse for request cookies until we officially deprecated CGI. --- actionpack/lib/action_controller/rack_process.rb | 42 +++--------------------- actionpack/test/controller/rack_test.rb | 8 ++--- 2 files changed, 8 insertions(+), 42 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/rack_process.rb b/actionpack/lib/action_controller/rack_process.rb index d5fb78c44d..37b56dabca 100644 --- a/actionpack/lib/action_controller/rack_process.rb +++ b/actionpack/lib/action_controller/rack_process.rb @@ -49,21 +49,12 @@ module ActionController #:nodoc: def cookies return {} unless @env["HTTP_COOKIE"] - if @env["rack.request.cookie_string"] == @env["HTTP_COOKIE"] - @env["rack.request.cookie_hash"] - else + unless @env["rack.request.cookie_string"] == @env["HTTP_COOKIE"] @env["rack.request.cookie_string"] = @env["HTTP_COOKIE"] - # According to RFC 2109: - # If multiple cookies satisfy the criteria above, they are ordered in - # the Cookie header such that those with more specific Path attributes - # precede those with less specific. Ordering with respect to other - # attributes (e.g., Domain) is unspecified. - @env["rack.request.cookie_hash"] = - parse_query(@env["rack.request.cookie_string"], ';,').inject({}) { |h, (k,v)| - h[k] = Array === v ? v.first : v - h - } + @env["rack.request.cookie_hash"] = CGI::Cookie::parse(@env["rack.request.cookie_string"]) end + + @env["rack.request.cookie_hash"] end def host_with_port_without_standard_port_handling @@ -170,31 +161,6 @@ end_msg def session_options_with_string_keys @session_options_with_string_keys ||= DEFAULT_SESSION_OPTIONS.merge(@session_options).stringify_keys end - - # From Rack::Utils - def parse_query(qs, d = '&;') - params = {} - (qs || '').split(/[#{d}] */n).inject(params) { |h,p| - k, v = unescape(p).split('=',2) - if cur = params[k] - if cur.class == Array - params[k] << v - else - params[k] = [cur, v] - end - else - params[k] = v - end - } - - return params - end - - def unescape(s) - s.tr('+', ' ').gsub(/((?:%[0-9a-fA-F]{2})+)/n){ - [$1.delete('%')].pack('H*') - } - end end class RackResponse < AbstractResponse #:nodoc: diff --git a/actionpack/test/controller/rack_test.rb b/actionpack/test/controller/rack_test.rb index 026b0195d1..856f24bbdb 100644 --- a/actionpack/test/controller/rack_test.rb +++ b/actionpack/test/controller/rack_test.rb @@ -33,10 +33,10 @@ class BaseRackTest < Test::Unit::TestCase "REDIRECT_STATUS" => "200", "REQUEST_METHOD" => "GET" } + @request = ActionController::RackRequest.new(@env) # some Nokia phone browsers omit the space after the semicolon separator. # some developers have grown accustomed to using comma in cookie values. - @alt_cookie_fmt_request_hash = {"HTTP_COOKIE"=>"_session_id=c84ace847,96670c052c6ceb2451fb0f2;is_admin=yes"} - @request = ActionController::RackRequest.new(@env) + @alt_cookie_fmt_request = ActionController::RackRequest.new(@env.merge({"HTTP_COOKIE"=>"_session_id=c84ace847,96670c052c6ceb2451fb0f2;is_admin=yes"})) end def default_test; end @@ -100,11 +100,11 @@ class RackRequestTest < BaseRackTest end def test_cookie_syntax_resilience - cookies = CGI::Cookie::parse(@env["HTTP_COOKIE"]); + cookies = @request.cookies assert_equal ["c84ace84796670c052c6ceb2451fb0f2"], cookies["_session_id"], cookies.inspect assert_equal ["yes"], cookies["is_admin"], cookies.inspect - alt_cookies = CGI::Cookie::parse(@alt_cookie_fmt_request_hash["HTTP_COOKIE"]); + alt_cookies = @alt_cookie_fmt_request.cookies assert_equal ["c84ace847,96670c052c6ceb2451fb0f2"], alt_cookies["_session_id"], alt_cookies.inspect assert_equal ["yes"], alt_cookies["is_admin"], alt_cookies.inspect end -- cgit v1.2.3 From 2e0765a00361781fb9bff2a7ca8996eab1f01bd4 Mon Sep 17 00:00:00 2001 From: Frederick Cheung Date: Thu, 5 Jun 2008 20:48:42 +0100 Subject: Make partial counter start from 0. Signed-off-by: Pratik Naik --- actionpack/lib/action_view/partial_template.rb | 2 +- actionpack/test/controller/new_render_test.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/partial_template.rb b/actionpack/lib/action_view/partial_template.rb index 1fb3aaee02..0b374db888 100644 --- a/actionpack/lib/action_view/partial_template.rb +++ b/actionpack/lib/action_view/partial_template.rb @@ -22,10 +22,10 @@ module ActionView #:nodoc: end def render_member(object) - @locals[@counter_name] += 1 @locals[:object] = @locals[@variable_name] = object template = render_template + @locals[@counter_name] += 1 @locals.delete(@variable_name) @locals.delete(:object) diff --git a/actionpack/test/controller/new_render_test.rb b/actionpack/test/controller/new_render_test.rb index 6e2c6d90c6..3b439a3b18 100644 --- a/actionpack/test/controller/new_render_test.rb +++ b/actionpack/test/controller/new_render_test.rb @@ -742,7 +742,7 @@ EOS def test_partial_collection_with_counter get :partial_collection_with_counter - assert_equal "david1mary2", @response.body + assert_equal "david0mary1", @response.body end def test_partial_collection_with_locals @@ -762,7 +762,7 @@ EOS def test_partial_collection_shorthand_with_different_types_of_records get :partial_collection_shorthand_with_different_types_of_records - assert_equal "Bonjour bad customer: mark1Bonjour good customer: craig2Bonjour bad customer: john3Bonjour good customer: zach4Bonjour good customer: brandon5Bonjour bad customer: dan6", @response.body + assert_equal "Bonjour bad customer: mark0Bonjour good customer: craig1Bonjour bad customer: john2Bonjour good customer: zach3Bonjour good customer: brandon4Bonjour bad customer: dan5", @response.body end def test_empty_partial_collection -- cgit v1.2.3 From 1dbfe9766e00282c56523f6969550494bbffbbf4 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Thu, 5 Jun 2008 23:27:27 +0100 Subject: Ensure render :file works inside templates --- actionpack/lib/action_view/base.rb | 3 ++- actionpack/test/controller/new_render_test.rb | 10 ++++++++++ .../test/fixtures/test/render_file_from_template.html.erb | 1 + 3 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 actionpack/test/fixtures/test/render_file_from_template.html.erb (limited to 'actionpack') diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index f398756550..b2fcbfa554 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -253,6 +253,7 @@ If you are rendering a subtemplate, you must now use controller-like partial syn elsif options == :update update_page(&block) elsif options.is_a?(Hash) + use_full_path = options[:use_full_path] options = options.reverse_merge(:locals => {}, :use_full_path => true) if partial_layout = options.delete(:layout) @@ -266,7 +267,7 @@ If you are rendering a subtemplate, you must now use controller-like partial syn end end elsif options[:file] - render_file(options[:file], options[:use_full_path], options[:locals]) + render_file(options[:file], use_full_path || false, options[:locals]) elsif options[:partial] && options[:collection] render_partial_collection(options[:partial], options[:collection], options[:spacer_template], options[:locals]) elsif options[:partial] diff --git a/actionpack/test/controller/new_render_test.rb b/actionpack/test/controller/new_render_test.rb index 3b439a3b18..6b83b8337e 100644 --- a/actionpack/test/controller/new_render_test.rb +++ b/actionpack/test/controller/new_render_test.rb @@ -68,6 +68,11 @@ class NewRenderTestController < ActionController::Base path = File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_ivar.erb') render :file => path end + + def render_file_from_template + @secret = 'in the sauce' + @path = File.expand_path(File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_ivar.erb')) + end def render_file_with_locals path = File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_locals.erb') @@ -531,6 +536,11 @@ class NewRenderTest < Test::Unit::TestCase get :render_file_with_locals assert_equal "The secret is in the sauce\n", @response.body end + + def test_render_file_from_template + get :render_file_from_template + assert_equal "The secret is in the sauce\n", @response.body + end def test_attempt_to_access_object_method assert_raises(ActionController::UnknownAction, "No action responded to [clone]") { get :clone } diff --git a/actionpack/test/fixtures/test/render_file_from_template.html.erb b/actionpack/test/fixtures/test/render_file_from_template.html.erb new file mode 100644 index 0000000000..fde9f4bb64 --- /dev/null +++ b/actionpack/test/fixtures/test/render_file_from_template.html.erb @@ -0,0 +1 @@ +<%= render :file => @path %> \ No newline at end of file -- cgit v1.2.3 From c1a98209da7422965f5dd4f475603b8a3cc887e4 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Fri, 6 Jun 2008 03:03:30 -0700 Subject: Cache RecordIdentifier methods in Class#model_name wrapper --- .../lib/action_controller/record_identifier.rb | 45 ++++++++++++++++------ 1 file changed, 34 insertions(+), 11 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/record_identifier.rb b/actionpack/lib/action_controller/record_identifier.rb index 643ff7e5f4..77fe5cbe2a 100644 --- a/actionpack/lib/action_controller/record_identifier.rb +++ b/actionpack/lib/action_controller/record_identifier.rb @@ -1,3 +1,19 @@ +class Class + def model_name + @model_name ||= ModelName.new(name) + end + + class ModelName + attr_reader :singular, :plural, :path + + def initialize(name) + @singular = name.underscore.tr('/', '_').freeze + @plural = @singular.pluralize.freeze + @path = "#{name.tableize}/#{name.demodulize.underscore}".freeze + end + end +end + module ActionController # The record identifier encapsulates a number of naming conventions for dealing with records, like Active Records or # Active Resources or pretty much any other model type that has an id. These patterns are then used to try elevate @@ -31,18 +47,21 @@ module ActionController module RecordIdentifier extend self + JOIN = '_'.freeze + NEW = 'new'.freeze + # Returns plural/singular for a record or class. Example: # # partial_path(post) # => "posts/post" # partial_path(Person) # => "people/person" # partial_path(Person, "admin/games") # => "admin/people/person" def partial_path(record_or_class, controller_path = nil) - klass = class_from_record_or_class(record_or_class) + name = model_name_from_record_or_class(record_or_class) if controller_path && controller_path.include?("/") - "#{File.dirname(controller_path)}/#{klass.name.tableize}/#{klass.name.demodulize.underscore}" + "#{File.dirname(controller_path)}/#{name.path}" else - "#{klass.name.tableize}/#{klass.name.demodulize.underscore}" + name.path end end @@ -56,7 +75,8 @@ module ActionController # dom_class(post, :edit) # => "edit_post" # dom_class(Person, :edit) # => "edit_person" def dom_class(record_or_class, prefix = nil) - [ prefix, singular_class_name(record_or_class) ].compact * '_' + singular = singular_class_name(record_or_class) + prefix ? "#{prefix}#{JOIN}#{singular}" : singular end # The DOM id convention is to use the singular form of an object or class with the id following an underscore. @@ -69,8 +89,11 @@ module ActionController # # dom_id(Post.new(:id => 45), :edit) # => "edit_post_45" def dom_id(record, prefix = nil) - prefix ||= 'new' unless record.id - [ prefix, singular_class_name(record), record.id ].compact * '_' + if record_id = record.id + "#{dom_class(record, prefix)}#{JOIN}#{record_id}" + else + dom_class(record, prefix || NEW) + end end # Returns the plural class name of a record or class. Examples: @@ -78,7 +101,7 @@ module ActionController # plural_class_name(post) # => "posts" # plural_class_name(Highrise::Person) # => "highrise_people" def plural_class_name(record_or_class) - singular_class_name(record_or_class).pluralize + model_name_from_record_or_class(record_or_class).plural end # Returns the singular class name of a record or class. Examples: @@ -86,12 +109,12 @@ module ActionController # singular_class_name(post) # => "post" # singular_class_name(Highrise::Person) # => "highrise_person" def singular_class_name(record_or_class) - class_from_record_or_class(record_or_class).name.underscore.tr('/', '_') + model_name_from_record_or_class(record_or_class).singular end private - def class_from_record_or_class(record_or_class) - record_or_class.is_a?(Class) ? record_or_class : record_or_class.class + def model_name_from_record_or_class(record_or_class) + (record_or_class.is_a?(Class) ? record_or_class : record_or_class.class).model_name end end -end \ No newline at end of file +end -- cgit v1.2.3 From 566d717d783f56563cd602198be2177c972c9a81 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Fri, 6 Jun 2008 03:38:05 -0700 Subject: Move Class::ModelName to Active Support module core_ext --- .../lib/action_controller/record_identifier.rb | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/record_identifier.rb b/actionpack/lib/action_controller/record_identifier.rb index 77fe5cbe2a..f69c3d6163 100644 --- a/actionpack/lib/action_controller/record_identifier.rb +++ b/actionpack/lib/action_controller/record_identifier.rb @@ -1,19 +1,3 @@ -class Class - def model_name - @model_name ||= ModelName.new(name) - end - - class ModelName - attr_reader :singular, :plural, :path - - def initialize(name) - @singular = name.underscore.tr('/', '_').freeze - @plural = @singular.pluralize.freeze - @path = "#{name.tableize}/#{name.demodulize.underscore}".freeze - end - end -end - module ActionController # The record identifier encapsulates a number of naming conventions for dealing with records, like Active Records or # Active Resources or pretty much any other model type that has an id. These patterns are then used to try elevate @@ -59,9 +43,9 @@ module ActionController name = model_name_from_record_or_class(record_or_class) if controller_path && controller_path.include?("/") - "#{File.dirname(controller_path)}/#{name.path}" + "#{File.dirname(controller_path)}/#{name.partial_path}" else - name.path + name.partial_path end end -- cgit v1.2.3 From e2c49e6a59f1b969a526586a3dd4dfd9c6f12b10 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Fri, 6 Jun 2008 04:13:09 -0700 Subject: Drop a string conversion from the often-called tag_options helper --- actionpack/lib/action_view/helpers/tag_helper.rb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/tag_helper.rb b/actionpack/lib/action_view/helpers/tag_helper.rb index 999cbfb52a..ba43b5e8ef 100644 --- a/actionpack/lib/action_view/helpers/tag_helper.rb +++ b/actionpack/lib/action_view/helpers/tag_helper.rb @@ -1,5 +1,6 @@ require 'cgi' require 'erb' +require 'set' module ActionView module Helpers #:nodoc: @@ -8,7 +9,8 @@ module ActionView module TagHelper include ERB::Util - BOOLEAN_ATTRIBUTES = Set.new(%w(disabled readonly multiple)) + BOOLEAN_ATTRIBUTES = %w(disabled readonly multiple).to_set + BOOLEAN_ATTRIBUTES.merge(BOOLEAN_ATTRIBUTES.map(&:to_sym)) # Returns an empty HTML tag of type +name+ which by default is XHTML # compliant. Set +open+ to true to create an open tag compatible @@ -37,7 +39,7 @@ module ActionView # tag("img", { :src => "open & shut.png" }, false, false) # # => def tag(name, options = nil, open = false, escape = true) - "<#{name}#{tag_options(options, escape) if options}" + (open ? ">" : " />") + "<#{name}#{tag_options(options, escape) if options}#{open ? ">" : " />"}" end # Returns an HTML block tag of type +name+ surrounding the +content+. Add @@ -114,7 +116,6 @@ module ActionView if escape options.each do |key, value| next unless value - key = key.to_s value = BOOLEAN_ATTRIBUTES.include?(key) ? key : escape_once(value) attrs << %(#{key}="#{value}") end -- cgit v1.2.3 From e732a405ab7d0d04f8a254764970c9dcda988f01 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Fri, 6 Jun 2008 17:59:41 -0700 Subject: javascript_tag should only concat when block_given? --- actionpack/lib/action_view/helpers/javascript_helper.rb | 17 ++++++++++------- actionpack/test/template/javascript_helper_test.rb | 4 ++++ 2 files changed, 14 insertions(+), 7 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/javascript_helper.rb b/actionpack/lib/action_view/helpers/javascript_helper.rb index a2f2577636..85b205c264 100644 --- a/actionpack/lib/action_view/helpers/javascript_helper.rb +++ b/actionpack/lib/action_view/helpers/javascript_helper.rb @@ -172,14 +172,17 @@ module ActionView # alert('All is good') # <% end -%> def javascript_tag(content_or_options_with_block = nil, html_options = {}, &block) - if block_given? - html_options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash) - content = capture(&block) - else - content = content_or_options_with_block - end + content = + if block_given? + html_options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash) + capture(&block) + else + content_or_options_with_block + end + + tag = content_tag("script", javascript_cdata_section(content), html_options.merge(:type => Mime::JS)) - concat(content_tag("script", javascript_cdata_section(content), html_options.merge(:type => Mime::JS))) + block_given? ? concat(tag) : tag end def javascript_cdata_section(content) #:nodoc: diff --git a/actionpack/test/template/javascript_helper_test.rb b/actionpack/test/template/javascript_helper_test.rb index f136f56777..4924074c3e 100644 --- a/actionpack/test/template/javascript_helper_test.rb +++ b/actionpack/test/template/javascript_helper_test.rb @@ -82,8 +82,12 @@ class JavaScriptHelperTest < ActionView::TestCase end def test_javascript_tag + @output_buffer = 'foo' + assert_dom_equal "", javascript_tag("alert('hello')") + + assert_equal 'foo', @output_buffer, 'javascript_tag without a block should not concat to @output_buffer' end def test_javascript_tag_with_options -- cgit v1.2.3 From 26ec1be24a820327d00e22fb65764a3dc06977e2 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Fri, 6 Jun 2008 18:00:01 -0700 Subject: concat should ignore nil --- actionpack/lib/action_view/helpers/text_helper.rb | 2 +- actionpack/test/template/text_helper_test.rb | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/text_helper.rb b/actionpack/lib/action_view/helpers/text_helper.rb index 3be4843386..f81f7eded6 100644 --- a/actionpack/lib/action_view/helpers/text_helper.rb +++ b/actionpack/lib/action_view/helpers/text_helper.rb @@ -26,7 +26,7 @@ module ActionView # # will either display "Logged in!" or a login link # %> def concat(string) - if @output_buffer + if @output_buffer && string @output_buffer << string else string diff --git a/actionpack/test/template/text_helper_test.rb b/actionpack/test/template/text_helper_test.rb index 62cdca03d1..0f5c62acad 100644 --- a/actionpack/test/template/text_helper_test.rb +++ b/actionpack/test/template/text_helper_test.rb @@ -11,6 +11,14 @@ class TextHelperTest < ActionView::TestCase @_cycles = nil if (defined? @_cycles) end + def test_concat + @output_buffer = 'foo' + concat 'bar' + assert_equal 'foobar', @output_buffer + assert_nothing_raised { concat nil } + assert_equal 'foobar', @output_buffer + end + def test_simple_format assert_equal "

      ", simple_format(nil) -- cgit v1.2.3 From fe9d2ad6e84626d34f1850ef4668a87787d5c6b0 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Fri, 6 Jun 2008 18:01:14 -0700 Subject: Remove some internal dead code that supported content_for --- actionpack/lib/action_view/helpers/capture_helper.rb | 20 +++++--------------- actionpack/test/controller/capture_test.rb | 20 +------------------- actionpack/test/fixtures/test/block_content_for.erb | 2 -- actionpack/test/fixtures/test/erb_content_for.erb | 2 -- 4 files changed, 6 insertions(+), 38 deletions(-) delete mode 100644 actionpack/test/fixtures/test/block_content_for.erb delete mode 100644 actionpack/test/fixtures/test/erb_content_for.erb (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb index 837305d96c..25e62f78fb 100644 --- a/actionpack/lib/action_view/helpers/capture_helper.rb +++ b/actionpack/lib/action_view/helpers/capture_helper.rb @@ -32,7 +32,7 @@ module ActionView # def capture(*args, &block) if @output_buffer - with_temporary_output_buffer { yield *args } + with_output_buffer { block.call(*args) } else block.call(*args) end @@ -115,27 +115,17 @@ module ActionView # <%= yield :footer %>. def content_for(name, content = nil, &block) ivar = "@content_for_#{name}" - instance_variable_set("@content_for_#{name}", "#{instance_variable_get(ivar)}#{block_given? ? capture(&block) : content}") + content = capture(&block) if block_given? + instance_variable_set(ivar, "#{instance_variable_get(ivar)}#{content}") end private - def with_temporary_output_buffer - @output_buffer, old_buffer = '', @output_buffer + def with_output_buffer(buf = '') + @output_buffer, old_buffer = buf, @output_buffer yield - @output_buffer ensure @output_buffer = old_buffer end - - def erb_content_for(name, &block) - ivar = "@content_for_#{name}" - instance_variable_set(ivar, "#{instance_variable_get(ivar)}#{capture(&block)}") - end - - def block_content_for(name) - ivar = "@content_for_#{name}" - instance_variable_set(ivar, "#{instance_variable_get(ivar)}#{yield}") - end end end end diff --git a/actionpack/test/controller/capture_test.rb b/actionpack/test/controller/capture_test.rb index aaafea3920..2604844b84 100644 --- a/actionpack/test/controller/capture_test.rb +++ b/actionpack/test/controller/capture_test.rb @@ -11,16 +11,8 @@ class CaptureController < ActionController::Base def content_for_with_parameter render :layout => "talk_from_action" end - - def content_for_concatenated - render :layout => "talk_from_action" - end - def erb_content_for - render :layout => "talk_from_action" - end - - def block_content_for + def content_for_concatenated render :layout => "talk_from_action" end @@ -62,21 +54,11 @@ class CaptureTest < Test::Unit::TestCase assert_equal expected_content_for_output, @response.body end - def test_erb_content_for - get :erb_content_for - assert_equal expected_content_for_output, @response.body - end - def test_should_set_content_for_with_parameter get :content_for_with_parameter assert_equal expected_content_for_output, @response.body end - def test_block_content_for - get :block_content_for - assert_equal expected_content_for_output, @response.body - end - def test_non_erb_block_content_for get :non_erb_block_content_for assert_equal expected_content_for_output, @response.body diff --git a/actionpack/test/fixtures/test/block_content_for.erb b/actionpack/test/fixtures/test/block_content_for.erb deleted file mode 100644 index 9510337365..0000000000 --- a/actionpack/test/fixtures/test/block_content_for.erb +++ /dev/null @@ -1,2 +0,0 @@ -<% block_content_for :title do 'Putting stuff in the title!' end %> -Great stuff! \ No newline at end of file diff --git a/actionpack/test/fixtures/test/erb_content_for.erb b/actionpack/test/fixtures/test/erb_content_for.erb deleted file mode 100644 index c3bdd13643..0000000000 --- a/actionpack/test/fixtures/test/erb_content_for.erb +++ /dev/null @@ -1,2 +0,0 @@ -<% erb_content_for :title do %>Putting stuff in the title!<% end %> -Great stuff! \ No newline at end of file -- cgit v1.2.3 From 5eb893f72d189a7ad82c9a6f45873e2317f202d5 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Fri, 6 Jun 2008 22:02:23 -0700 Subject: Don't use deprecated String#each --- actionpack/lib/action_controller/rack_process.rb | 2 ++ 1 file changed, 2 insertions(+) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/rack_process.rb b/actionpack/lib/action_controller/rack_process.rb index 37b56dabca..9b4aa9b7cf 100644 --- a/actionpack/lib/action_controller/rack_process.rb +++ b/actionpack/lib/action_controller/rack_process.rb @@ -189,6 +189,8 @@ end_msg if @body.respond_to?(:call) @writer = lambda { |x| callback.call(x) } @body.call(self, self) + elsif @body.is_a?(String) + @body.each_line(&callback) else @body.each(&callback) end -- cgit v1.2.3 From 5b53a0695904afb6a576fe5a9badbf14261909b5 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Fri, 6 Jun 2008 22:02:48 -0700 Subject: Ensure we have an array to collect --- actionpack/lib/action_controller/routing/segments.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/routing/segments.rb b/actionpack/lib/action_controller/routing/segments.rb index 864e068004..f0ad066bad 100644 --- a/actionpack/lib/action_controller/routing/segments.rb +++ b/actionpack/lib/action_controller/routing/segments.rb @@ -249,7 +249,7 @@ module ActionController end def extract_value - "#{local_name} = hash[:#{key}] && hash[:#{key}].collect { |path_component| URI.escape(path_component.to_param, ActionController::Routing::Segment::UNSAFE_PCHAR) }.to_param #{"|| #{default.inspect}" if default}" + "#{local_name} = hash[:#{key}] && Array(hash[:#{key}]).collect { |path_component| URI.escape(path_component.to_param, ActionController::Routing::Segment::UNSAFE_PCHAR) }.to_param #{"|| #{default.inspect}" if default}" end def default -- cgit v1.2.3 From 63679733d8217b69e242a00083abfc4cd8a9dca0 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Sat, 7 Jun 2008 17:48:44 -0700 Subject: Changelog: More efficient concat and capture helpers. Remove ActionView::Base.erb_variable. --- actionpack/CHANGELOG | 2 ++ 1 file changed, 2 insertions(+) (limited to 'actionpack') diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index 66af5fd745..8265b5b04f 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -1,5 +1,7 @@ *Edge* +* More efficient concat and capture helpers. Remove ActionView::Base.erb_variable. [Jeremy Kemper] + * Added page.reload functionality. Resolves #277. [Sean Huber] * Fixed Request#remote_ip to only raise hell if the HTTP_CLIENT_IP and HTTP_X_FORWARDED_FOR doesn't match (not just if they're both present) [Mark Imbriaco, Bradford Folkens] -- cgit v1.2.3 From d5539958a892ece562ba3dcb36df12e046bd4879 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Sat, 7 Jun 2008 23:42:05 -0500 Subject: Wrap CGIResponse, LegacyRouteSet, Route, RouteSet and RouteLoading tests inside mocha block. --- actionpack/test/controller/cgi_test.rb | 50 +- actionpack/test/controller/routing_test.rb | 3315 ++++++++++++++-------------- 2 files changed, 1669 insertions(+), 1696 deletions(-) (limited to 'actionpack') diff --git a/actionpack/test/controller/cgi_test.rb b/actionpack/test/controller/cgi_test.rb index f0f3a4b826..1b1ded4615 100755 --- a/actionpack/test/controller/cgi_test.rb +++ b/actionpack/test/controller/cgi_test.rb @@ -115,35 +115,37 @@ class CgiRequestNeedsRewoundTest < BaseCgiTest end end -class CgiResponseTest < BaseCgiTest - def setup - super - @fake_cgi.expects(:header).returns("HTTP/1.0 200 OK\nContent-Type: text/html\n") - @response = ActionController::CgiResponse.new(@fake_cgi) - @output = StringIO.new('') - end - - def test_simple_output - @response.body = "Hello, World!" +uses_mocha 'CGI Response' do + class CgiResponseTest < BaseCgiTest + def setup + super + @fake_cgi.expects(:header).returns("HTTP/1.0 200 OK\nContent-Type: text/html\n") + @response = ActionController::CgiResponse.new(@fake_cgi) + @output = StringIO.new('') + end - @response.out(@output) - assert_equal "HTTP/1.0 200 OK\nContent-Type: text/html\nHello, World!", @output.string - end + def test_simple_output + @response.body = "Hello, World!" - def test_head_request - @fake_cgi.env_table['REQUEST_METHOD'] = 'HEAD' - @response.body = "Hello, World!" + @response.out(@output) + assert_equal "HTTP/1.0 200 OK\nContent-Type: text/html\nHello, World!", @output.string + end - @response.out(@output) - assert_equal "HTTP/1.0 200 OK\nContent-Type: text/html\n", @output.string - end + def test_head_request + @fake_cgi.env_table['REQUEST_METHOD'] = 'HEAD' + @response.body = "Hello, World!" - def test_streaming_block - @response.body = Proc.new do |response, output| - 5.times { |n| output.write(n) } + @response.out(@output) + assert_equal "HTTP/1.0 200 OK\nContent-Type: text/html\n", @output.string end - @response.out(@output) - assert_equal "HTTP/1.0 200 OK\nContent-Type: text/html\n01234", @output.string + def test_streaming_block + @response.body = Proc.new do |response, output| + 5.times { |n| output.write(n) } + end + + @response.out(@output) + assert_equal "HTTP/1.0 200 OK\nContent-Type: text/html\n01234", @output.string + end end end diff --git a/actionpack/test/controller/routing_test.rb b/actionpack/test/controller/routing_test.rb index 068d71a8f8..07c13ebbf7 100644 --- a/actionpack/test/controller/routing_test.rb +++ b/actionpack/test/controller/routing_test.rb @@ -59,647 +59,30 @@ class UriReservedCharactersRoutingTest < Test::Unit::TestCase end end -class LegacyRouteSetTests < Test::Unit::TestCase - attr_reader :rs - def setup - # These tests assume optimisation is on, so re-enable it. - ActionController::Base.optimise_named_routes = true - - @rs = ::ActionController::Routing::RouteSet.new - @rs.draw {|m| m.connect ':controller/:action/:id' } - - ActionController::Routing.use_controllers! %w(content admin/user admin/news_feed) - end - - def test_default_setup - assert_equal({:controller => "content", :action => 'index'}, rs.recognize_path("/content")) - assert_equal({:controller => "content", :action => 'list'}, rs.recognize_path("/content/list")) - assert_equal({:controller => "content", :action => 'show', :id => '10'}, rs.recognize_path("/content/show/10")) - - assert_equal({:controller => "admin/user", :action => 'show', :id => '10'}, rs.recognize_path("/admin/user/show/10")) - - assert_equal '/admin/user/show/10', rs.generate(:controller => 'admin/user', :action => 'show', :id => 10) - - assert_equal '/admin/user/show', rs.generate({:action => 'show'}, {:controller => 'admin/user', :action => 'list', :id => '10'}) - assert_equal '/admin/user/list/10', rs.generate({}, {:controller => 'admin/user', :action => 'list', :id => '10'}) - - assert_equal '/admin/stuff', rs.generate({:controller => 'stuff'}, {:controller => 'admin/user', :action => 'list', :id => '10'}) - assert_equal '/stuff', rs.generate({:controller => '/stuff'}, {:controller => 'admin/user', :action => 'list', :id => '10'}) - end - - def test_ignores_leading_slash - @rs.draw {|m| m.connect '/:controller/:action/:id'} - test_default_setup - end - - def test_time_recognition - # We create many routes to make situation more realistic - @rs = ::ActionController::Routing::RouteSet.new - @rs.draw { |map| - map.frontpage '', :controller => 'search', :action => 'new' - map.resources :videos do |video| - video.resources :comments - video.resource :file, :controller => 'video_file' - video.resource :share, :controller => 'video_shares' - video.resource :abuse, :controller => 'video_abuses' - end - map.resources :abuses, :controller => 'video_abuses' - map.resources :video_uploads - map.resources :video_visits - - map.resources :users do |user| - user.resource :settings - user.resources :videos - end - map.resources :channels do |channel| - channel.resources :videos, :controller => 'channel_videos' - end - map.resource :session - map.resource :lost_password - map.search 'search', :controller => 'search' - map.resources :pages - map.connect ':controller/:action/:id' - } - n = 1000 - if RunTimeTests - GC.start - rectime = Benchmark.realtime do - n.times do - rs.recognize_path("/videos/1234567", {:method => :get}) - rs.recognize_path("/videos/1234567/abuse", {:method => :get}) - rs.recognize_path("/users/1234567/settings", {:method => :get}) - rs.recognize_path("/channels/1234567", {:method => :get}) - rs.recognize_path("/session/new", {:method => :get}) - rs.recognize_path("/admin/user/show/10", {:method => :get}) - end - end - puts "\n\nRecognition (#{rs.routes.size} routes):" - per_url = rectime / (n * 6) - puts "#{per_url * 1000} ms/url" - puts "#{1 / per_url} url/s\n\n" - end - end - def test_time_generation - n = 5000 - if RunTimeTests - GC.start - pairs = [ - [{:controller => 'content', :action => 'index'}, {:controller => 'content', :action => 'show'}], - [{:controller => 'content'}, {:controller => 'content', :action => 'index'}], - [{:controller => 'content', :action => 'list'}, {:controller => 'content', :action => 'index'}], - [{:controller => 'content', :action => 'show', :id => '10'}, {:controller => 'content', :action => 'list'}], - [{:controller => 'admin/user', :action => 'index'}, {:controller => 'admin/user', :action => 'show'}], - [{:controller => 'admin/user'}, {:controller => 'admin/user', :action => 'index'}], - [{:controller => 'admin/user', :action => 'list'}, {:controller => 'admin/user', :action => 'index'}], - [{:controller => 'admin/user', :action => 'show', :id => '10'}, {:controller => 'admin/user', :action => 'list'}], - ] - p = nil - gentime = Benchmark.realtime do - n.times do - pairs.each {|(a, b)| rs.generate(a, b)} - end - end - - puts "\n\nGeneration (RouteSet): (#{(n * 8)} urls)" - per_url = gentime / (n * 8) - puts "#{per_url * 1000} ms/url" - puts "#{1 / per_url} url/s\n\n" - end - end - - def test_route_with_colon_first - rs.draw do |map| - map.connect '/:controller/:action/:id', :action => 'index', :id => nil - map.connect ':url', :controller => 'tiny_url', :action => 'translate' - end - end - - def test_route_with_regexp_for_controller - rs.draw do |map| - map.connect ':controller/:admintoken/:action/:id', :controller => /admin\/.+/ - map.connect ':controller/:action/:id' - end - assert_equal({:controller => "admin/user", :admintoken => "foo", :action => "index"}, - rs.recognize_path("/admin/user/foo")) - assert_equal({:controller => "content", :action => "foo"}, rs.recognize_path("/content/foo")) - assert_equal '/admin/user/foo', rs.generate(:controller => "admin/user", :admintoken => "foo", :action => "index") - assert_equal '/content/foo', rs.generate(:controller => "content", :action => "foo") - end - - def test_route_with_regexp_and_dot - rs.draw do |map| - map.connect ':controller/:action/:file', - :controller => /admin|user/, - :action => /upload|download/, - :defaults => {:file => nil}, - :requirements => {:file => %r{[^/]+(\.[^/]+)?}} - end - # Without a file extension - assert_equal '/user/download/file', - rs.generate(:controller => "user", :action => "download", :file => "file") - assert_equal( - {:controller => "user", :action => "download", :file => "file"}, - rs.recognize_path("/user/download/file")) - - # Now, let's try a file with an extension, really a dot (.) - assert_equal '/user/download/file.jpg', - rs.generate( - :controller => "user", :action => "download", :file => "file.jpg") - assert_equal( - {:controller => "user", :action => "download", :file => "file.jpg"}, - rs.recognize_path("/user/download/file.jpg")) - end - - def test_basic_named_route - rs.add_named_route :home, '', :controller => 'content', :action => 'list' - x = setup_for_named_route - assert_equal("http://named.route.test/", - x.send(:home_url)) - end - - def test_basic_named_route_with_relative_url_root - rs.add_named_route :home, '', :controller => 'content', :action => 'list' - x = setup_for_named_route - x.relative_url_root="/foo" - assert_equal("http://named.route.test/foo/", - x.send(:home_url)) - assert_equal "/foo/", x.send(:home_path) - end - - def test_named_route_with_option - rs.add_named_route :page, 'page/:title', :controller => 'content', :action => 'show_page' - x = setup_for_named_route - assert_equal("http://named.route.test/page/new%20stuff", - x.send(:page_url, :title => 'new stuff')) - end - - def test_named_route_with_default - rs.add_named_route :page, 'page/:title', :controller => 'content', :action => 'show_page', :title => 'AboutPage' - x = setup_for_named_route - assert_equal("http://named.route.test/page/AboutRails", - x.send(:page_url, :title => "AboutRails")) - - end - - def test_named_route_with_nested_controller - rs.add_named_route :users, 'admin/user', :controller => 'admin/user', :action => 'index' - x = setup_for_named_route - assert_equal("http://named.route.test/admin/user", - x.send(:users_url)) - end - - uses_mocha "named route optimisation" do - def test_optimised_named_route_call_never_uses_url_for - rs.add_named_route :users, 'admin/user', :controller => '/admin/user', :action => 'index' - rs.add_named_route :user, 'admin/user/:id', :controller=>'/admin/user', :action=>'show' - x = setup_for_named_route - x.expects(:url_for).never - x.send(:users_url) - x.send(:users_path) - x.send(:user_url, 2, :foo=>"bar") - x.send(:user_path, 3, :bar=>"foo") - end - - def test_optimised_named_route_with_host - rs.add_named_route :pages, 'pages', :controller => 'content', :action => 'show_page', :host => 'foo.com' - x = setup_for_named_route - x.expects(:url_for).with(:host => 'foo.com', :only_path => false, :controller => 'content', :action => 'show_page', :use_route => :pages).once - x.send(:pages_url) - end - end - - def setup_for_named_route - klass = Class.new(MockController) - rs.install_helpers(klass) - klass.new(rs) - end - - def test_named_route_without_hash - rs.draw do |map| - map.normal ':controller/:action/:id' - end - end - - def test_named_route_root - rs.draw do |map| - map.root :controller => "hello" - end - x = setup_for_named_route - assert_equal("http://named.route.test/", x.send(:root_url)) - assert_equal("/", x.send(:root_path)) - end - - def test_named_route_with_regexps - rs.draw do |map| - map.article 'page/:year/:month/:day/:title', :controller => 'page', :action => 'show', - :year => /\d+/, :month => /\d+/, :day => /\d+/ - map.connect ':controller/:action/:id' - end - x = setup_for_named_route - # assert_equal( - # {:controller => 'page', :action => 'show', :title => 'hi', :use_route => :article, :only_path => false}, - # x.send(:article_url, :title => 'hi') - # ) - assert_equal( - "http://named.route.test/page/2005/6/10/hi", - x.send(:article_url, :title => 'hi', :day => 10, :year => 2005, :month => 6) - ) - end - - def test_changing_controller - assert_equal '/admin/stuff/show/10', rs.generate( - {:controller => 'stuff', :action => 'show', :id => 10}, - {:controller => 'admin/user', :action => 'index'} - ) - end - - def test_paths_escaped - rs.draw do |map| - map.path 'file/*path', :controller => 'content', :action => 'show_file' - map.connect ':controller/:action/:id' - end - - # No + to space in URI escaping, only for query params. - results = rs.recognize_path "/file/hello+world/how+are+you%3F" - assert results, "Recognition should have succeeded" - assert_equal ['hello+world', 'how+are+you?'], results[:path] - - # Use %20 for space instead. - results = rs.recognize_path "/file/hello%20world/how%20are%20you%3F" - assert results, "Recognition should have succeeded" - assert_equal ['hello world', 'how are you?'], results[:path] - - results = rs.recognize_path "/file" - assert results, "Recognition should have succeeded" - assert_equal [], results[:path] - end - - def test_paths_slashes_unescaped_with_ordered_parameters - rs.add_named_route :path, '/file/*path', :controller => 'content' - - # No / to %2F in URI, only for query params. - x = setup_for_named_route - assert_equal("/file/hello/world", x.send(:path_path, 'hello/world')) - end - - def test_non_controllers_cannot_be_matched - rs.draw do |map| - map.connect ':controller/:action/:id' - end - assert_raises(ActionController::RoutingError) { rs.recognize_path("/not_a/show/10") } - end - - def test_paths_do_not_accept_defaults - assert_raises(ActionController::RoutingError) do - rs.draw do |map| - map.path 'file/*path', :controller => 'content', :action => 'show_file', :path => %w(fake default) - map.connect ':controller/:action/:id' - end - end - - rs.draw do |map| - map.path 'file/*path', :controller => 'content', :action => 'show_file', :path => [] - map.connect ':controller/:action/:id' - end - end - - def test_should_list_options_diff_when_routing_requirements_dont_match - rs.draw do |map| - map.post 'post/:id', :controller=> 'post', :action=> 'show', :requirements => {:id => /\d+/} - end - exception = assert_raise(ActionController::RoutingError) { rs.generate(:controller => 'post', :action => 'show', :bad_param => "foo", :use_route => "post") } - assert_match /^post_url failed to generate/, exception.message - from_match = exception.message.match(/from \{[^\}]+\}/).to_s - assert_match /:bad_param=>"foo"/, from_match - assert_match /:action=>"show"/, from_match - assert_match /:controller=>"post"/, from_match - - expected_match = exception.message.match(/expected: \{[^\}]+\}/).to_s - assert_no_match /:bad_param=>"foo"/, expected_match - assert_match /:action=>"show"/, expected_match - assert_match /:controller=>"post"/, expected_match - - diff_match = exception.message.match(/diff: \{[^\}]+\}/).to_s - assert_match /:bad_param=>"foo"/, diff_match - assert_no_match /:action=>"show"/, diff_match - assert_no_match /:controller=>"post"/, diff_match - end - - # this specifies the case where your formerly would get a very confusing error message with an empty diff - def test_should_have_better_error_message_when_options_diff_is_empty - rs.draw do |map| - map.content '/content/:query', :controller => 'content', :action => 'show' - end - - exception = assert_raise(ActionController::RoutingError) { rs.generate(:controller => 'content', :action => 'show', :use_route => "content") } - assert_match %r[:action=>"show"], exception.message - assert_match %r[:controller=>"content"], exception.message - assert_match %r[you may have ambiguous routes, or you may need to supply additional parameters for this route], exception.message - assert_match %r[content_url has the following required parameters: \["content", :query\] - are they all satisfied?], exception.message - end - - def test_dynamic_path_allowed - rs.draw do |map| - map.connect '*path', :controller => 'content', :action => 'show_file' - end - - assert_equal '/pages/boo', rs.generate(:controller => 'content', :action => 'show_file', :path => %w(pages boo)) - end - - def test_dynamic_recall_paths_allowed - rs.draw do |map| - map.connect '*path', :controller => 'content', :action => 'show_file' - end - - recall_path = ActionController::Routing::PathSegment::Result.new(%w(pages boo)) - assert_equal '/pages/boo', rs.generate({}, :controller => 'content', :action => 'show_file', :path => recall_path) - end - - def test_backwards - rs.draw do |map| - map.connect 'page/:id/:action', :controller => 'pages', :action => 'show' - map.connect ':controller/:action/:id' - end - - assert_equal '/page/20', rs.generate({:id => 20}, {:controller => 'pages', :action => 'show'}) - assert_equal '/page/20', rs.generate(:controller => 'pages', :id => 20, :action => 'show') - assert_equal '/pages/boo', rs.generate(:controller => 'pages', :action => 'boo') - end - - def test_route_with_fixnum_default - rs.draw do |map| - map.connect 'page/:id', :controller => 'content', :action => 'show_page', :id => 1 - map.connect ':controller/:action/:id' - end - - assert_equal '/page', rs.generate(:controller => 'content', :action => 'show_page') - assert_equal '/page', rs.generate(:controller => 'content', :action => 'show_page', :id => 1) - assert_equal '/page', rs.generate(:controller => 'content', :action => 'show_page', :id => '1') - assert_equal '/page/10', rs.generate(:controller => 'content', :action => 'show_page', :id => 10) - - assert_equal({:controller => "content", :action => 'show_page', :id => '1'}, rs.recognize_path("/page")) - assert_equal({:controller => "content", :action => 'show_page', :id => '1'}, rs.recognize_path("/page/1")) - assert_equal({:controller => "content", :action => 'show_page', :id => '10'}, rs.recognize_path("/page/10")) - end - - # For newer revision - def test_route_with_text_default - rs.draw do |map| - map.connect 'page/:id', :controller => 'content', :action => 'show_page', :id => 1 - map.connect ':controller/:action/:id' - end - - assert_equal '/page/foo', rs.generate(:controller => 'content', :action => 'show_page', :id => 'foo') - assert_equal({:controller => "content", :action => 'show_page', :id => 'foo'}, rs.recognize_path("/page/foo")) - - token = "\321\202\320\265\320\272\321\201\321\202" # 'text' in russian - escaped_token = CGI::escape(token) - - assert_equal '/page/' + escaped_token, rs.generate(:controller => 'content', :action => 'show_page', :id => token) - assert_equal({:controller => "content", :action => 'show_page', :id => token}, rs.recognize_path("/page/#{escaped_token}")) - end - - def test_action_expiry - assert_equal '/content', rs.generate({:controller => 'content'}, {:controller => 'content', :action => 'show'}) - end - - def test_recognition_with_uppercase_controller_name - assert_equal({:controller => "content", :action => 'index'}, rs.recognize_path("/Content")) - assert_equal({:controller => "content", :action => 'list'}, rs.recognize_path("/ConTent/list")) - assert_equal({:controller => "content", :action => 'show', :id => '10'}, rs.recognize_path("/CONTENT/show/10")) - - # these used to work, before the routes rewrite, but support for this was pulled in the new version... - #assert_equal({'controller' => "admin/news_feed", 'action' => 'index'}, rs.recognize_path("Admin/NewsFeed")) - #assert_equal({'controller' => "admin/news_feed", 'action' => 'index'}, rs.recognize_path("Admin/News_Feed")) - end - - def test_requirement_should_prevent_optional_id - rs.draw do |map| - map.post 'post/:id', :controller=> 'post', :action=> 'show', :requirements => {:id => /\d+/} - end - - assert_equal '/post/10', rs.generate(:controller => 'post', :action => 'show', :id => 10) - - assert_raises ActionController::RoutingError do - rs.generate(:controller => 'post', :action => 'show') - end - end - - def test_both_requirement_and_optional - rs.draw do |map| - map.blog('test/:year', :controller => 'post', :action => 'show', - :defaults => { :year => nil }, - :requirements => { :year => /\d{4}/ } - ) - map.connect ':controller/:action/:id' - end - - assert_equal '/test', rs.generate(:controller => 'post', :action => 'show') - assert_equal '/test', rs.generate(:controller => 'post', :action => 'show', :year => nil) - - x = setup_for_named_route - assert_equal("http://named.route.test/test", - x.send(:blog_url)) - end - - def test_set_to_nil_forgets - rs.draw do |map| - map.connect 'pages/:year/:month/:day', :controller => 'content', :action => 'list_pages', :month => nil, :day => nil - map.connect ':controller/:action/:id' - end - - assert_equal '/pages/2005', - rs.generate(:controller => 'content', :action => 'list_pages', :year => 2005) - assert_equal '/pages/2005/6', - rs.generate(:controller => 'content', :action => 'list_pages', :year => 2005, :month => 6) - assert_equal '/pages/2005/6/12', - rs.generate(:controller => 'content', :action => 'list_pages', :year => 2005, :month => 6, :day => 12) - - assert_equal '/pages/2005/6/4', - rs.generate({:day => 4}, {:controller => 'content', :action => 'list_pages', :year => '2005', :month => '6', :day => '12'}) - - assert_equal '/pages/2005/6', - rs.generate({:day => nil}, {:controller => 'content', :action => 'list_pages', :year => '2005', :month => '6', :day => '12'}) - - assert_equal '/pages/2005', - rs.generate({:day => nil, :month => nil}, {:controller => 'content', :action => 'list_pages', :year => '2005', :month => '6', :day => '12'}) - end - - def test_url_with_no_action_specified - rs.draw do |map| - map.connect '', :controller => 'content' - map.connect ':controller/:action/:id' - end - - assert_equal '/', rs.generate(:controller => 'content', :action => 'index') - assert_equal '/', rs.generate(:controller => 'content') - end - - def test_named_url_with_no_action_specified - rs.draw do |map| - map.home '', :controller => 'content' - map.connect ':controller/:action/:id' - end - - assert_equal '/', rs.generate(:controller => 'content', :action => 'index') - assert_equal '/', rs.generate(:controller => 'content') - - x = setup_for_named_route - assert_equal("http://named.route.test/", - x.send(:home_url)) - end - - def test_url_generated_when_forgetting_action - [{:controller => 'content', :action => 'index'}, {:controller => 'content'}].each do |hash| - rs.draw do |map| - map.home '', hash - map.connect ':controller/:action/:id' - end - assert_equal '/', rs.generate({:action => nil}, {:controller => 'content', :action => 'hello'}) - assert_equal '/', rs.generate({:controller => 'content'}) - assert_equal '/content/hi', rs.generate({:controller => 'content', :action => 'hi'}) - end - end - - def test_named_route_method - rs.draw do |map| - map.categories 'categories', :controller => 'content', :action => 'categories' - map.connect ':controller/:action/:id' - end - - assert_equal '/categories', rs.generate(:controller => 'content', :action => 'categories') - assert_equal '/content/hi', rs.generate({:controller => 'content', :action => 'hi'}) - end - - def test_named_routes_array - test_named_route_method - assert_equal [:categories], rs.named_routes.names - end - - def test_nil_defaults - rs.draw do |map| - map.connect 'journal', - :controller => 'content', - :action => 'list_journal', - :date => nil, :user_id => nil - map.connect ':controller/:action/:id' - end - - assert_equal '/journal', rs.generate(:controller => 'content', :action => 'list_journal', :date => nil, :user_id => nil) - end - - def setup_request_method_routes_for(method) - @request = ActionController::TestRequest.new - @request.env["REQUEST_METHOD"] = method - @request.request_uri = "/match" - - rs.draw do |r| - r.connect '/match', :controller => 'books', :action => 'get', :conditions => { :method => :get } - r.connect '/match', :controller => 'books', :action => 'post', :conditions => { :method => :post } - r.connect '/match', :controller => 'books', :action => 'put', :conditions => { :method => :put } - r.connect '/match', :controller => 'books', :action => 'delete', :conditions => { :method => :delete } - end - end - - %w(GET POST PUT DELETE).each do |request_method| - define_method("test_request_method_recognized_with_#{request_method}") do - begin - Object.const_set(:BooksController, Class.new(ActionController::Base)) - - setup_request_method_routes_for(request_method) - - assert_nothing_raised { rs.recognize(@request) } - assert_equal request_method.downcase, @request.path_parameters[:action] - ensure - Object.send(:remove_const, :BooksController) rescue nil - end - end - end - - def test_subpath_recognized - Object.const_set(:SubpathBooksController, Class.new(ActionController::Base)) - - rs.draw do |r| - r.connect '/books/:id/edit', :controller => 'subpath_books', :action => 'edit' - r.connect '/items/:id/:action', :controller => 'subpath_books' - r.connect '/posts/new/:action', :controller => 'subpath_books' - r.connect '/posts/:id', :controller => 'subpath_books', :action => "show" - end - - hash = rs.recognize_path "/books/17/edit" - assert_not_nil hash - assert_equal %w(subpath_books 17 edit), [hash[:controller], hash[:id], hash[:action]] - - hash = rs.recognize_path "/items/3/complete" - assert_not_nil hash - assert_equal %w(subpath_books 3 complete), [hash[:controller], hash[:id], hash[:action]] - - hash = rs.recognize_path "/posts/new/preview" - assert_not_nil hash - assert_equal %w(subpath_books preview), [hash[:controller], hash[:action]] - - hash = rs.recognize_path "/posts/7" - assert_not_nil hash - assert_equal %w(subpath_books show 7), [hash[:controller], hash[:action], hash[:id]] - ensure - Object.send(:remove_const, :SubpathBooksController) rescue nil - end - - def test_subpath_generated - Object.const_set(:SubpathBooksController, Class.new(ActionController::Base)) - - rs.draw do |r| - r.connect '/books/:id/edit', :controller => 'subpath_books', :action => 'edit' - r.connect '/items/:id/:action', :controller => 'subpath_books' - r.connect '/posts/new/:action', :controller => 'subpath_books' - end - - assert_equal "/books/7/edit", rs.generate(:controller => "subpath_books", :id => 7, :action => "edit") - assert_equal "/items/15/complete", rs.generate(:controller => "subpath_books", :id => 15, :action => "complete") - assert_equal "/posts/new/preview", rs.generate(:controller => "subpath_books", :action => "preview") - ensure - Object.send(:remove_const, :SubpathBooksController) rescue nil - end - - def test_failed_requirements_raises_exception_with_violated_requirements - rs.draw do |r| - r.foo_with_requirement 'foos/:id', :controller=>'foos', :requirements=>{:id=>/\d+/} - end - - x = setup_for_named_route - assert_raises(ActionController::RoutingError) do - x.send(:foo_with_requirement_url, "I am Against the requirements") - end - end -end - class SegmentTest < Test::Unit::TestCase - def test_first_segment_should_interpolate_for_structure s = ROUTING::Segment.new def s.interpolation_statement(array) 'hello' end assert_equal 'hello', s.continue_string_structure([]) end - + def test_interpolation_statement s = ROUTING::StaticSegment.new s.value = "Hello" assert_equal "Hello", eval(s.interpolation_statement([])) assert_equal "HelloHello", eval(s.interpolation_statement([s])) - + s2 = ROUTING::StaticSegment.new s2.value = "-" assert_equal "Hello-Hello", eval(s.interpolation_statement([s, s2])) - + s3 = ROUTING::StaticSegment.new s3.value = "World" assert_equal "Hello-World", eval(s3.interpolation_statement([s, s2])) end - end class StaticSegmentTest < Test::Unit::TestCase - def test_interpolation_chunk_should_respect_raw s = ROUTING::StaticSegment.new s.value = 'Hello World' @@ -713,28 +96,26 @@ class StaticSegmentTest < Test::Unit::TestCase def test_regexp_chunk_should_escape_specials s = ROUTING::StaticSegment.new - + s.value = 'Hello*World' assert_equal 'Hello\*World', s.regexp_chunk - + s.value = 'HelloWorld' assert_equal 'HelloWorld', s.regexp_chunk end - + def test_regexp_chunk_should_add_question_mark_for_optionals s = ROUTING::StaticSegment.new s.value = "/" s.is_optional = true assert_equal "/?", s.regexp_chunk - + s.value = "hello" assert_equal "(?:hello)?", s.regexp_chunk end - end class DynamicSegmentTest < Test::Unit::TestCase - def segment unless @segment @segment = ROUTING::DynamicSegment.new @@ -742,126 +123,126 @@ class DynamicSegmentTest < Test::Unit::TestCase end @segment end - + def test_extract_value s = ROUTING::DynamicSegment.new s.key = :a - + hash = {:a => '10', :b => '20'} assert_equal '10', eval(s.extract_value) - + hash = {:b => '20'} assert_equal nil, eval(s.extract_value) - + s.default = '20' assert_equal '20', eval(s.extract_value) end - + def test_default_local_name assert_equal 'a_value', segment.local_name, "Unexpected name -- all value_check tests will fail!" end - + def test_presence_value_check a_value = 10 assert eval(segment.value_check) end - + def test_regexp_value_check_rejects_nil segment.regexp = /\d+/ a_value = nil assert ! eval(segment.value_check) end - + def test_optional_regexp_value_check_should_accept_nil segment.regexp = /\d+/ segment.is_optional = true a_value = nil assert eval(segment.value_check) end - + def test_regexp_value_check_rejects_no_match segment.regexp = /\d+/ - + a_value = "Hello20World" assert ! eval(segment.value_check) - + a_value = "20Hi" assert ! eval(segment.value_check) end - + def test_regexp_value_check_accepts_match segment.regexp = /\d+/ - + a_value = "30" assert eval(segment.value_check) end - + def test_value_check_fails_on_nil a_value = nil assert ! eval(segment.value_check) end - + def test_optional_value_needs_no_check segment.is_optional = true a_value = nil assert_equal nil, segment.value_check end - + def test_regexp_value_check_should_accept_match_with_default segment.regexp = /\d+/ segment.default = '200' - + a_value = '100' assert eval(segment.value_check) end - + def test_expiry_should_not_trigger_once_expired expired = true hash = merged = {:a => 2, :b => 3} options = {:b => 3} expire_on = Hash.new { raise 'No!!!' } - + eval(segment.expiry_statement) rescue RuntimeError flunk "Expiry check should not have occurred!" end - + def test_expiry_should_occur_according_to_expire_on expired = false hash = merged = {:a => 2, :b => 3} options = {:b => 3} - + expire_on = {:b => true, :a => false} eval(segment.expiry_statement) assert !expired assert_equal({:a => 2, :b => 3}, hash) - + expire_on = {:b => true, :a => true} eval(segment.expiry_statement) assert expired assert_equal({:b => 3}, hash) end - + def test_extraction_code_should_return_on_nil hash = merged = {:b => 3} options = {:b => 3} a_value = nil - + # Local jump because of return inside eval. assert_raises(LocalJumpError) { eval(segment.extraction_code) } end - + def test_extraction_code_should_return_on_mismatch segment.regexp = /\d+/ hash = merged = {:a => 'Hi', :b => '3'} options = {:b => '3'} a_value = nil - + # Local jump because of return inside eval. assert_raises(LocalJumpError) { eval(segment.extraction_code) } end - + def test_extraction_code_should_accept_value_and_set_local hash = merged = {:a => 'Hi', :b => '3'} options = {:b => '3'} @@ -871,45 +252,45 @@ class DynamicSegmentTest < Test::Unit::TestCase eval(segment.extraction_code) assert_equal 'Hi', a_value end - + def test_extraction_should_work_without_value_check segment.default = 'hi' hash = merged = {:b => '3'} options = {:b => '3'} a_value = nil expired = true - + eval(segment.extraction_code) assert_equal 'hi', a_value end - + def test_extraction_code_should_perform_expiry expired = false hash = merged = {:a => 'Hi', :b => '3'} options = {:b => '3'} expire_on = {:a => true} a_value = nil - + eval(segment.extraction_code) assert_equal 'Hi', a_value assert expired assert_equal options, hash end - + def test_interpolation_chunk_should_replace_value a_value = 'Hi' assert_equal a_value, eval(%("#{segment.interpolation_chunk}")) end - + def test_interpolation_chunk_should_accept_nil a_value = nil assert_equal '', eval(%("#{segment.interpolation_chunk('a_value')}")) end - + def test_value_regexp_should_be_nil_without_regexp assert_equal nil, segment.value_regexp end - + def test_value_regexp_should_match_exacly segment.regexp = /\d+/ assert_no_match segment.value_regexp, "Hello 10 World" @@ -917,12 +298,12 @@ class DynamicSegmentTest < Test::Unit::TestCase assert_no_match segment.value_regexp, "10 World" assert_match segment.value_regexp, "10" end - + def test_regexp_chunk_should_return_string segment.regexp = /\d+/ assert_kind_of String, segment.regexp_chunk end - + def test_build_pattern_non_optional_with_no_captures # Non optional a_segment = ROUTING::DynamicSegment.new @@ -958,284 +339,43 @@ class DynamicSegmentTest < Test::Unit::TestCase end class ControllerSegmentTest < Test::Unit::TestCase - def test_regexp_should_only_match_possible_controllers ActionController::Routing.with_controllers %w(admin/accounts admin/users account pages) do cs = ROUTING::ControllerSegment.new :controller regexp = %r{\A#{cs.regexp_chunk}\Z} - + ActionController::Routing.possible_controllers.each do |name| assert_match regexp, name assert_no_match regexp, "#{name}_fake" - + match = regexp.match name assert_equal name, match[1] end end end - end -uses_mocha 'RouteTest' do - - 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}" - - host = options.delete(:host) || "named.route.test" - anchor = "##{options.delete(:anchor)}" if options.key?(:anchor) - - path = routes.generate(options) - - only_path ? "#{path}#{anchor}" : "http://#{host}#{port_string}#{path}#{anchor}" - end - - def request - @request ||= MockRequest.new(:host => "named.route.test", :method => :get) - end - - def relative_url_root=(value) - request.relative_url_root=value - end +class RouteBuilderTest < Test::Unit::TestCase + def builder + @builder ||= ROUTING::RouteBuilder.new end - class MockRequest - attr_accessor :path, :path_parameters, :host, :subdomains, :domain, - :method, :relative_url_root - - def initialize(values={}) - values.each { |key, value| send("#{key}=", value) } - if values[:host] - subdomain, self.domain = values[:host].split(/\./, 2) - self.subdomains = [subdomain] - end - end - - def protocol - "http://" - end - - def host_with_port - (subdomains * '.') + '.' + domain - end + def build(path, options) + builder.build(path, options) end -class RouteTest < Test::Unit::TestCase + def test_options_should_not_be_modified + requirements1 = { :id => /\w+/, :controller => /(?:[a-z](?:-?[a-z]+)*)/ } + requirements2 = requirements1.dup - def setup - @route = ROUTING::Route.new - end + assert_equal requirements1, requirements2 - def slash_segment(is_optional = false) - returning ROUTING::DividerSegment.new('/') do |s| - s.is_optional = is_optional + with_options(:controller => 'folder', + :requirements => requirements2) do |m| + m.build 'folders/new', :action => 'new' end - end - - def default_route - unless defined?(@default_route) - @default_route = ROUTING::Route.new - - @default_route.segments << (s = ROUTING::StaticSegment.new) - s.value = '/' - s.raw = true - - @default_route.segments << (s = ROUTING::DynamicSegment.new) - s.key = :controller - - @default_route.segments << slash_segment(:optional) - @default_route.segments << (s = ROUTING::DynamicSegment.new) - s.key = :action - s.default = 'index' - s.is_optional = true - - @default_route.segments << slash_segment(:optional) - @default_route.segments << (s = ROUTING::DynamicSegment.new) - s.key = :id - s.is_optional = true - - @default_route.segments << slash_segment(:optional) - end - @default_route - end - - def test_default_route_recognition - expected = {:controller => 'accounts', :action => 'show', :id => '10'} - assert_equal expected, default_route.recognize('/accounts/show/10') - assert_equal expected, default_route.recognize('/accounts/show/10/') - - expected[:id] = 'jamis' - assert_equal expected, default_route.recognize('/accounts/show/jamis/') - - expected.delete :id - assert_equal expected, default_route.recognize('/accounts/show') - assert_equal expected, default_route.recognize('/accounts/show/') - - expected[:action] = 'index' - assert_equal expected, default_route.recognize('/accounts/') - assert_equal expected, default_route.recognize('/accounts') - - assert_equal nil, default_route.recognize('/') - assert_equal nil, default_route.recognize('/accounts/how/goood/it/is/to/be/free') - end - - def test_default_route_should_omit_default_action - o = {:controller => 'accounts', :action => 'index'} - assert_equal '/accounts', default_route.generate(o, o, {}) - end - - def test_default_route_should_include_default_action_when_id_present - o = {:controller => 'accounts', :action => 'index', :id => '20'} - assert_equal '/accounts/index/20', default_route.generate(o, o, {}) - end - - def test_default_route_should_work_with_action_but_no_id - o = {:controller => 'accounts', :action => 'list_all'} - assert_equal '/accounts/list_all', default_route.generate(o, o, {}) - end - - def test_default_route_should_uri_escape_pluses - expected = { :controller => 'accounts', :action => 'show', :id => 'hello world' } - assert_equal expected, default_route.recognize('/accounts/show/hello world') - assert_equal expected, default_route.recognize('/accounts/show/hello%20world') - assert_equal '/accounts/show/hello%20world', default_route.generate(expected, expected, {}) - - expected[:id] = 'hello+world' - assert_equal expected, default_route.recognize('/accounts/show/hello+world') - assert_equal expected, default_route.recognize('/accounts/show/hello%2Bworld') - assert_equal '/accounts/show/hello+world', default_route.generate(expected, expected, {}) - end - - def test_matches_controller_and_action - # requirement_for should only be called for the action and controller _once_ - @route.expects(:requirement_for).with(:controller).times(1).returns('pages') - @route.expects(:requirement_for).with(:action).times(1).returns('show') - - @route.requirements = {:controller => 'pages', :action => 'show'} - assert @route.matches_controller_and_action?('pages', 'show') - assert !@route.matches_controller_and_action?('not_pages', 'show') - assert !@route.matches_controller_and_action?('pages', 'not_show') - end - - def test_parameter_shell - page_url = ROUTING::Route.new - page_url.requirements = {:controller => 'pages', :action => 'show', :id => /\d+/} - assert_equal({:controller => 'pages', :action => 'show'}, page_url.parameter_shell) - end - - def test_defaults - route = ROUTING::RouteBuilder.new.build '/users/:id.:format', :controller => "users", :action => "show", :format => "html" - assert_equal( - { :controller => "users", :action => "show", :format => "html" }, - route.defaults) - end - - def test_builder_complains_without_controller - assert_raises(ArgumentError) do - ROUTING::RouteBuilder.new.build '/contact', :contoller => "contact", :action => "index" - end - end - - def test_significant_keys_for_default_route - keys = default_route.significant_keys.sort_by {|k| k.to_s } - assert_equal [:action, :controller, :id], keys - end - - def test_significant_keys - user_url = ROUTING::Route.new - user_url.segments << (s = ROUTING::StaticSegment.new) - s.value = '/' - s.raw = true - - user_url.segments << (s = ROUTING::StaticSegment.new) - s.value = 'user' - - user_url.segments << (s = ROUTING::StaticSegment.new) - s.value = '/' - s.raw = true - s.is_optional = true - - user_url.segments << (s = ROUTING::DynamicSegment.new) - s.key = :user - - user_url.segments << (s = ROUTING::StaticSegment.new) - s.value = '/' - s.raw = true - s.is_optional = true - - user_url.requirements = {:controller => 'users', :action => 'show'} - - keys = user_url.significant_keys.sort_by { |k| k.to_s } - assert_equal [:action, :controller, :user], keys - end - - def test_build_empty_query_string - assert_equal '', @route.build_query_string({}) - end - - def test_build_query_string_with_nil_value - assert_equal '', @route.build_query_string({:x => nil}) - end - def test_simple_build_query_string - assert_equal '?x=1&y=2', order_query_string(@route.build_query_string(:x => '1', :y => '2')) - end - - def test_convert_ints_build_query_string - assert_equal '?x=1&y=2', order_query_string(@route.build_query_string(:x => 1, :y => 2)) - end - - def test_escape_spaces_build_query_string - assert_equal '?x=hello+world&y=goodbye+world', order_query_string(@route.build_query_string(:x => 'hello world', :y => 'goodbye world')) - end - - def test_expand_array_build_query_string - assert_equal '?x%5B%5D=1&x%5B%5D=2', order_query_string(@route.build_query_string(:x => [1, 2])) - end - - def test_escape_spaces_build_query_string_selected_keys - assert_equal '?x=hello+world', order_query_string(@route.build_query_string({:x => 'hello world', :y => 'goodbye world'}, [:x])) - end - - private - def order_query_string(qs) - '?' + qs[1..-1].split('&').sort.join('&') - end -end - -end # uses_mocha - -class RouteBuilderTest < Test::Unit::TestCase - - def builder - @builder ||= ROUTING::RouteBuilder.new - end - - def build(path, options) - builder.build(path, options) - end - - def test_options_should_not_be_modified - requirements1 = { :id => /\w+/, :controller => /(?:[a-z](?:-?[a-z]+)*)/ } - requirements2 = requirements1.dup - - assert_equal requirements1, requirements2 - - with_options(:controller => 'folder', - :requirements => requirements2) do |m| - m.build 'folders/new', :action => 'new' - end - - assert_equal requirements1, requirements2 + assert_equal requirements1, requirements2 end def test_segment_for_static @@ -1244,7 +384,7 @@ class RouteBuilderTest < Test::Unit::TestCase assert_kind_of ROUTING::StaticSegment, segment assert_equal 'ulysses', segment.value end - + def test_segment_for_action segment, rest = builder.segment_for ':action' assert_equal '', rest @@ -1252,7 +392,7 @@ class RouteBuilderTest < Test::Unit::TestCase assert_equal :action, segment.key assert_equal 'index', segment.default end - + def test_segment_for_dynamic segment, rest = builder.segment_for ':login' assert_equal '', rest @@ -1261,7 +401,7 @@ class RouteBuilderTest < Test::Unit::TestCase assert_equal nil, segment.default assert ! segment.optional? end - + def test_segment_for_with_rest segment, rest = builder.segment_for ':login/:action' assert_equal :login, segment.key @@ -1273,105 +413,104 @@ class RouteBuilderTest < Test::Unit::TestCase assert_equal :action, segment.key assert_equal '', rest end - + def test_segments_for segments = builder.segments_for_route_path '/:controller/:action/:id' - + assert_kind_of ROUTING::DividerSegment, segments[0] assert_equal '/', segments[2].value - + assert_kind_of ROUTING::DynamicSegment, segments[1] assert_equal :controller, segments[1].key - + assert_kind_of ROUTING::DividerSegment, segments[2] assert_equal '/', segments[2].value - + assert_kind_of ROUTING::DynamicSegment, segments[3] assert_equal :action, segments[3].key - + assert_kind_of ROUTING::DividerSegment, segments[4] assert_equal '/', segments[4].value - + assert_kind_of ROUTING::DynamicSegment, segments[5] assert_equal :id, segments[5].key end - + def test_segment_for_action s, r = builder.segment_for(':action/something/else') assert_equal '/something/else', r assert_equal :action, s.key end - + def test_action_default_should_not_trigger_on_prefix s, r = builder.segment_for ':action_name/something/else' assert_equal '/something/else', r assert_equal :action_name, s.key assert_equal nil, s.default end - + def test_divide_route_options segments = builder.segments_for_route_path '/cars/:action/:person/:car/' defaults, requirements = builder.divide_route_options(segments, :action => 'buy', :person => /\w+/, :car => /\w+/, :defaults => {:person => nil, :car => nil} ) - + assert_equal({:action => 'buy', :person => nil, :car => nil}, defaults) assert_equal({:person => /\w+/, :car => /\w+/}, requirements) end - + def test_assign_route_options segments = builder.segments_for_route_path '/cars/:action/:person/:car/' defaults = {:action => 'buy', :person => nil, :car => nil} requirements = {:person => /\w+/, :car => /\w+/} - + route_requirements = builder.assign_route_options(segments, defaults, requirements) assert_equal({}, route_requirements) - + assert_equal :action, segments[3].key assert_equal 'buy', segments[3].default - + assert_equal :person, segments[5].key assert_equal %r/\w+/, segments[5].regexp assert segments[5].optional? - + assert_equal :car, segments[7].key assert_equal %r/\w+/, segments[7].regexp assert segments[7].optional? end - + def test_assign_route_options_with_anchor_chars segments = builder.segments_for_route_path '/cars/:action/:person/:car/' defaults = {:action => 'buy', :person => nil, :car => nil} requirements = {:person => /\w+/, :car => /^\w+$/} - + assert_raises ArgumentError do route_requirements = builder.assign_route_options(segments, defaults, requirements) end - + requirements[:car] = /[^\/]+/ route_requirements = builder.assign_route_options(segments, defaults, requirements) end - def test_optional_segments_preceding_required_segments segments = builder.segments_for_route_path '/cars/:action/:person/:car/' defaults = {:action => 'buy', :person => nil, :car => "model-t"} assert builder.assign_route_options(segments, defaults, {}).empty? - + 0.upto(1) { |i| assert !segments[i].optional?, "segment #{i} is optional and it shouldn't be" } assert segments[2].optional? - + assert_equal nil, builder.warn_output # should only warn on the :person segment end - + def test_segmentation_of_dot_path segments = builder.segments_for_route_path '/books/:action.rss' assert builder.assign_route_options(segments, {}, {}).empty? assert_equal 6, segments.length # "/", "books", "/", ":action", ".", "rss" assert !segments.any? { |seg| seg.optional? } end - + def test_segmentation_of_dynamic_dot_path segments = builder.segments_for_route_path '/books/:action.:format' assert builder.assign_route_options(segments, {}, {}).empty? @@ -1379,56 +518,56 @@ class RouteBuilderTest < Test::Unit::TestCase assert !segments.any? { |seg| seg.optional? } assert_kind_of ROUTING::DynamicSegment, segments.last end - + def test_assignment_of_default_options segments = builder.segments_for_route_path '/:controller/:action/:id/' action, id = segments[-4], segments[-2] - + assert_equal :action, action.key assert_equal :id, id.key assert ! action.optional? assert ! id.optional? - + builder.assign_default_route_options(segments) - + assert_equal 'index', action.default assert action.optional? assert id.optional? end - + def test_assignment_of_default_options_respects_existing_defaults segments = builder.segments_for_route_path '/:controller/:action/:id/' action, id = segments[-4], segments[-2] - + assert_equal :action, action.key assert_equal :id, id.key action.default = 'show' action.is_optional = true - + id.default = 'Welcome' id.is_optional = true - + builder.assign_default_route_options(segments) - + assert_equal 'show', action.default assert action.optional? assert_equal 'Welcome', id.default assert id.optional? end - + def test_assignment_of_default_options_respects_regexps segments = builder.segments_for_route_path '/:controller/:action/:id/' action = segments[-4] - + assert_equal :action, action.key action.regexp = /show|in/ # Use 'in' to check partial matches - + builder.assign_default_route_options(segments) - + assert_equal nil, action.default assert ! action.optional? end - + def test_assignment_of_is_optional_when_default segments = builder.segments_for_route_path '/books/:action.rss' assert_equal segments[3].key, :action @@ -1436,44 +575,44 @@ class RouteBuilderTest < Test::Unit::TestCase builder.ensure_required_segments(segments) assert ! segments[3].optional? end - + def test_is_optional_is_assigned_to_default_segments segments = builder.segments_for_route_path '/books/:action' builder.assign_route_options(segments, {:action => 'index'}, {}) - + assert_equal segments[3].key, :action assert segments[3].optional? assert_kind_of ROUTING::DividerSegment, segments[2] assert segments[2].optional? end - + # XXX is optional not being set right? # /blah/:defaulted_segment <-- is the second slash optional? it should be. - + def test_route_build ActionController::Routing.with_controllers %w(users pages) do r = builder.build '/:controller/:action/:id/', :action => nil - + [0, 2, 4].each do |i| assert_kind_of ROUTING::DividerSegment, r.segments[i] assert_equal '/', r.segments[i].value assert r.segments[i].optional? if i > 1 end - + assert_kind_of ROUTING::DynamicSegment, r.segments[1] assert_equal :controller, r.segments[1].key assert_equal nil, r.segments[1].default - + assert_kind_of ROUTING::DynamicSegment, r.segments[3] assert_equal :action, r.segments[3].key assert_equal 'index', r.segments[3].default - + assert_kind_of ROUTING::DynamicSegment, r.segments[5] assert_equal :id, r.segments[5].key assert r.segments[5].optional? end end - + def test_slashes_are_implied routes = [ builder.build('/:controller/:action/:id/', :action => nil), @@ -1487,668 +626,1627 @@ class RouteBuilderTest < Test::Unit::TestCase assert_equal expected, found, "Route #{i + 1} has #{found} segments, expected #{expected}" end end - end +class RoutingTest < Test::Unit::TestCase + def test_possible_controllers + true_controller_paths = ActionController::Routing.controller_paths + ActionController::Routing.use_controllers! nil + silence_warnings do + Object.send(:const_set, :RAILS_ROOT, File.dirname(__FILE__) + '/controller_fixtures') + end -class RouteSetTest < Test::Unit::TestCase + ActionController::Routing.controller_paths = [ + RAILS_ROOT, RAILS_ROOT + '/app/controllers', RAILS_ROOT + '/vendor/plugins/bad_plugin/lib' + ] - def set - @set ||= ROUTING::RouteSet.new + assert_equal ["admin/user", "plugin", "user"], ActionController::Routing.possible_controllers.sort + ensure + if true_controller_paths + ActionController::Routing.controller_paths = true_controller_paths + end + ActionController::Routing.use_controllers! nil + Object.send(:remove_const, :RAILS_ROOT) rescue nil end - def request - @request ||= MockRequest.new(:host => "named.routes.test", :method => :get) - end + def test_possible_controllers_are_reset_on_each_load + true_possible_controllers = ActionController::Routing.possible_controllers + true_controller_paths = ActionController::Routing.controller_paths - def test_generate_extras - set.draw { |m| m.connect ':controller/:action/:id' } - path, extras = set.generate_extras(:controller => "foo", :action => "bar", :id => 15, :this => "hello", :that => "world") - assert_equal "/foo/bar/15", path - assert_equal %w(that this), extras.map(&:to_s).sort - end + ActionController::Routing.use_controllers! nil + root = File.dirname(__FILE__) + '/controller_fixtures' - def test_extra_keys - set.draw { |m| m.connect ':controller/:action/:id' } - extras = set.extra_keys(:controller => "foo", :action => "bar", :id => 15, :this => "hello", :that => "world") - assert_equal %w(that this), extras.map(&:to_s).sort - end - - def test_generate_extras_not_first - set.draw do |map| - map.connect ':controller/:action/:id.:format' - map.connect ':controller/:action/:id' - end - path, extras = set.generate_extras(:controller => "foo", :action => "bar", :id => 15, :this => "hello", :that => "world") - assert_equal "/foo/bar/15", path - assert_equal %w(that this), extras.map(&:to_s).sort - end - - def test_generate_not_first - set.draw do |map| - map.connect ':controller/:action/:id.:format' - map.connect ':controller/:action/:id' - end - assert_equal "/foo/bar/15?this=hello", set.generate(:controller => "foo", :action => "bar", :id => 15, :this => "hello") - end - - def test_extra_keys_not_first - set.draw do |map| - map.connect ':controller/:action/:id.:format' - map.connect ':controller/:action/:id' - end - extras = set.extra_keys(:controller => "foo", :action => "bar", :id => 15, :this => "hello", :that => "world") - assert_equal %w(that this), extras.map(&:to_s).sort - end + ActionController::Routing.controller_paths = [] + assert_equal [], ActionController::Routing.possible_controllers - def test_draw - assert_equal 0, set.routes.size - set.draw do |map| - map.connect '/hello/world', :controller => 'a', :action => 'b' - end - assert_equal 1, set.routes.size - end - - def test_named_draw - assert_equal 0, set.routes.size - set.draw do |map| - map.hello '/hello/world', :controller => 'a', :action => 'b' - end - assert_equal 1, set.routes.size - assert_equal set.routes.first, set.named_routes[:hello] - end - - def test_later_named_routes_take_precedence - set.draw do |map| - map.hello '/hello/world', :controller => 'a', :action => 'b' - map.hello '/hello', :controller => 'a', :action => 'b' - end - assert_equal set.routes.last, set.named_routes[:hello] - end + ActionController::Routing::Routes.load! + ActionController::Routing.controller_paths = [ + root, root + '/app/controllers', root + '/vendor/plugins/bad_plugin/lib' + ] - def setup_named_route_test - set.draw do |map| - map.show '/people/:id', :controller => 'people', :action => 'show' - map.index '/people', :controller => 'people', :action => 'index' - map.multi '/people/go/:foo/:bar/joe/:id', :controller => 'people', :action => 'multi' - map.users '/admin/users', :controller => 'admin/users', :action => 'index' - end + assert_equal ["admin/user", "plugin", "user"], ActionController::Routing.possible_controllers.sort + ensure + ActionController::Routing.controller_paths = true_controller_paths + ActionController::Routing.use_controllers! true_possible_controllers + Object.send(:remove_const, :RAILS_ROOT) rescue nil - klass = Class.new(MockController) - set.install_helpers(klass) - klass.new(set) + ActionController::Routing::Routes.clear! + ActionController::Routing::Routes.load_routes! end - def test_named_route_hash_access_method - controller = setup_named_route_test + def test_with_controllers + c = %w(admin/accounts admin/users account pages) + ActionController::Routing.with_controllers c do + assert_equal c, ActionController::Routing.possible_controllers + end + end - assert_equal( - { :controller => 'people', :action => 'show', :id => 5, :use_route => :show, :only_path => false }, - controller.send(:hash_for_show_url, :id => 5)) + def test_normalize_unix_paths + load_paths = %w(. config/../app/controllers config/../app//helpers script/../config/../vendor/rails/actionpack/lib vendor/rails/railties/builtin/rails_info app/models lib script/../config/../foo/bar/../../app/models .foo/../.bar foo.bar/../config) + paths = ActionController::Routing.normalize_paths(load_paths) + assert_equal %w(vendor/rails/railties/builtin/rails_info vendor/rails/actionpack/lib app/controllers app/helpers app/models config .bar lib .), paths + end - assert_equal( - { :controller => 'people', :action => 'index', :use_route => :index, :only_path => false }, - controller.send(:hash_for_index_url)) - - assert_equal( - { :controller => 'people', :action => 'show', :id => 5, :use_route => :show, :only_path => true }, - controller.send(:hash_for_show_path, :id => 5) - ) + def test_normalize_windows_paths + load_paths = %w(. config\\..\\app\\controllers config\\..\\app\\\\helpers script\\..\\config\\..\\vendor\\rails\\actionpack\\lib vendor\\rails\\railties\\builtin\\rails_info app\\models lib script\\..\\config\\..\\foo\\bar\\..\\..\\app\\models .foo\\..\\.bar foo.bar\\..\\config) + paths = ActionController::Routing.normalize_paths(load_paths) + assert_equal %w(vendor\\rails\\railties\\builtin\\rails_info vendor\\rails\\actionpack\\lib app\\controllers app\\helpers app\\models config .bar lib .), paths end - def test_named_route_url_method - controller = setup_named_route_test - - assert_equal "http://named.route.test/people/5", controller.send(:show_url, :id => 5) - assert_equal "/people/5", controller.send(:show_path, :id => 5) - - assert_equal "http://named.route.test/people", controller.send(:index_url) - assert_equal "/people", controller.send(:index_path) + def test_routing_helper_module + assert_kind_of Module, ActionController::Routing::Helpers - assert_equal "http://named.route.test/admin/users", controller.send(:users_url) - assert_equal '/admin/users', controller.send(:users_path) - assert_equal '/admin/users', set.generate(controller.send(:hash_for_users_url), {:controller => 'users', :action => 'index'}) + h = ActionController::Routing::Helpers + c = Class.new + assert ! c.ancestors.include?(h) + ActionController::Routing::Routes.install_helpers c + assert c.ancestors.include?(h) end +end - def test_named_route_url_method_with_anchor - controller = setup_named_route_test +uses_mocha 'LegacyRouteSet, Route, RouteSet and RouteLoading' do + class MockController + attr_accessor :routes - assert_equal "http://named.route.test/people/5#location", controller.send(:show_url, :id => 5, :anchor => 'location') - assert_equal "/people/5#location", controller.send(:show_path, :id => 5, :anchor => 'location') + def initialize(routes) + self.routes = routes + end - assert_equal "http://named.route.test/people#location", controller.send(:index_url, :anchor => 'location') - assert_equal "/people#location", controller.send(:index_path, :anchor => 'location') + def url_for(options) + only_path = options.delete(:only_path) - assert_equal "http://named.route.test/admin/users#location", controller.send(:users_url, :anchor => 'location') - assert_equal '/admin/users#location', controller.send(:users_path, :anchor => 'location') + port = options.delete(:port) || 80 + port_string = port == 80 ? '' : ":#{port}" - assert_equal "http://named.route.test/people/go/7/hello/joe/5#location", - controller.send(:multi_url, 7, "hello", 5, :anchor => 'location') + host = options.delete(:host) || "named.route.test" + anchor = "##{options.delete(:anchor)}" if options.key?(:anchor) - assert_equal "http://named.route.test/people/go/7/hello/joe/5?baz=bar#location", - controller.send(:multi_url, 7, "hello", 5, :baz => "bar", :anchor => 'location') + path = routes.generate(options) - assert_equal "http://named.route.test/people?baz=bar#location", - controller.send(:index_url, :baz => "bar", :anchor => 'location') - end - - def test_named_route_url_method_with_port - controller = setup_named_route_test - assert_equal "http://named.route.test:8080/people/5", controller.send(:show_url, 5, :port=>8080) - end - - def test_named_route_url_method_with_host - controller = setup_named_route_test - assert_equal "http://some.example.com/people/5", controller.send(:show_url, 5, :host=>"some.example.com") - end - + only_path ? "#{path}#{anchor}" : "http://#{host}#{port_string}#{path}#{anchor}" + end - def test_named_route_url_method_with_ordered_parameters - controller = setup_named_route_test - assert_equal "http://named.route.test/people/go/7/hello/joe/5", - controller.send(:multi_url, 7, "hello", 5) - end + def request + @request ||= MockRequest.new(:host => "named.route.test", :method => :get) + end - def test_named_route_url_method_with_ordered_parameters_and_hash - controller = setup_named_route_test - assert_equal "http://named.route.test/people/go/7/hello/joe/5?baz=bar", - controller.send(:multi_url, 7, "hello", 5, :baz => "bar") - end - - def test_named_route_url_method_with_no_positional_arguments - controller = setup_named_route_test - assert_equal "http://named.route.test/people?baz=bar", - controller.send(:index_url, :baz => "bar") + def relative_url_root=(value) + request.relative_url_root=value + end end - - def test_draw_default_route - ActionController::Routing.with_controllers(['users']) do - set.draw do |map| - map.connect '/:controller/:action/:id' - end - assert_equal 1, set.routes.size - route = set.routes.first + class MockRequest + attr_accessor :path, :path_parameters, :host, :subdomains, :domain, + :method, :relative_url_root - assert route.segments.last.optional? + def initialize(values={}) + values.each { |key, value| send("#{key}=", value) } + if values[:host] + subdomain, self.domain = values[:host].split(/\./, 2) + self.subdomains = [subdomain] + end + end - assert_equal '/users/show/10', set.generate(:controller => 'users', :action => 'show', :id => 10) - assert_equal '/users/index/10', set.generate(:controller => 'users', :id => 10) + def protocol + "http://" + end - assert_equal({:controller => 'users', :action => 'index', :id => '10'}, set.recognize_path('/users/index/10')) - assert_equal({:controller => 'users', :action => 'index', :id => '10'}, set.recognize_path('/users/index/10/')) + def host_with_port + (subdomains * '.') + '.' + domain end end - def test_draw_default_route_with_default_controller - ActionController::Routing.with_controllers(['users']) do - set.draw do |map| - map.connect '/:controller/:action/:id', :controller => 'users' - end - assert_equal({:controller => 'users', :action => 'index'}, set.recognize_path('/')) + class LegacyRouteSetTests < Test::Unit::TestCase + attr_reader :rs + + def setup + # These tests assume optimisation is on, so re-enable it. + ActionController::Base.optimise_named_routes = true + + @rs = ::ActionController::Routing::RouteSet.new + @rs.draw {|m| m.connect ':controller/:action/:id' } + + ActionController::Routing.use_controllers! %w(content admin/user admin/news_feed) end - end - def test_route_with_parameter_shell - ActionController::Routing.with_controllers(['users', 'pages']) do - set.draw do |map| - map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+/ - map.connect '/:controller/:action/:id' - end + def test_default_setup + assert_equal({:controller => "content", :action => 'index'}, rs.recognize_path("/content")) + assert_equal({:controller => "content", :action => 'list'}, rs.recognize_path("/content/list")) + assert_equal({:controller => "content", :action => 'show', :id => '10'}, rs.recognize_path("/content/show/10")) - assert_equal({:controller => 'pages', :action => 'index'}, set.recognize_path('/pages')) - assert_equal({:controller => 'pages', :action => 'index'}, set.recognize_path('/pages/index')) - assert_equal({:controller => 'pages', :action => 'list'}, set.recognize_path('/pages/list')) + assert_equal({:controller => "admin/user", :action => 'show', :id => '10'}, rs.recognize_path("/admin/user/show/10")) - assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, set.recognize_path('/pages/show/10')) - assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, set.recognize_path('/page/10')) + assert_equal '/admin/user/show/10', rs.generate(:controller => 'admin/user', :action => 'show', :id => 10) + + assert_equal '/admin/user/show', rs.generate({:action => 'show'}, {:controller => 'admin/user', :action => 'list', :id => '10'}) + assert_equal '/admin/user/list/10', rs.generate({}, {:controller => 'admin/user', :action => 'list', :id => '10'}) + + assert_equal '/admin/stuff', rs.generate({:controller => 'stuff'}, {:controller => 'admin/user', :action => 'list', :id => '10'}) + assert_equal '/stuff', rs.generate({:controller => '/stuff'}, {:controller => 'admin/user', :action => 'list', :id => '10'}) end - end - def test_route_requirements_with_anchor_chars_are_invalid - assert_raises ArgumentError do - set.draw do |map| - map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /^\d+/ - end + def test_ignores_leading_slash + @rs.draw {|m| m.connect '/:controller/:action/:id'} + test_default_setup end - assert_raises ArgumentError do - set.draw do |map| - map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\A\d+/ + + def test_time_recognition + # We create many routes to make situation more realistic + @rs = ::ActionController::Routing::RouteSet.new + @rs.draw { |map| + map.frontpage '', :controller => 'search', :action => 'new' + map.resources :videos do |video| + video.resources :comments + video.resource :file, :controller => 'video_file' + video.resource :share, :controller => 'video_shares' + video.resource :abuse, :controller => 'video_abuses' + end + map.resources :abuses, :controller => 'video_abuses' + map.resources :video_uploads + map.resources :video_visits + + map.resources :users do |user| + user.resource :settings + user.resources :videos + end + map.resources :channels do |channel| + channel.resources :videos, :controller => 'channel_videos' + end + map.resource :session + map.resource :lost_password + map.search 'search', :controller => 'search' + map.resources :pages + map.connect ':controller/:action/:id' + } + n = 1000 + if RunTimeTests + GC.start + rectime = Benchmark.realtime do + n.times do + rs.recognize_path("/videos/1234567", {:method => :get}) + rs.recognize_path("/videos/1234567/abuse", {:method => :get}) + rs.recognize_path("/users/1234567/settings", {:method => :get}) + rs.recognize_path("/channels/1234567", {:method => :get}) + rs.recognize_path("/session/new", {:method => :get}) + rs.recognize_path("/admin/user/show/10", {:method => :get}) + end + end + puts "\n\nRecognition (#{rs.routes.size} routes):" + per_url = rectime / (n * 6) + puts "#{per_url * 1000} ms/url" + puts "#{1 / per_url} url/s\n\n" end end - assert_raises ArgumentError do - set.draw do |map| - map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+$/ + def test_time_generation + n = 5000 + if RunTimeTests + GC.start + pairs = [ + [{:controller => 'content', :action => 'index'}, {:controller => 'content', :action => 'show'}], + [{:controller => 'content'}, {:controller => 'content', :action => 'index'}], + [{:controller => 'content', :action => 'list'}, {:controller => 'content', :action => 'index'}], + [{:controller => 'content', :action => 'show', :id => '10'}, {:controller => 'content', :action => 'list'}], + [{:controller => 'admin/user', :action => 'index'}, {:controller => 'admin/user', :action => 'show'}], + [{:controller => 'admin/user'}, {:controller => 'admin/user', :action => 'index'}], + [{:controller => 'admin/user', :action => 'list'}, {:controller => 'admin/user', :action => 'index'}], + [{:controller => 'admin/user', :action => 'show', :id => '10'}, {:controller => 'admin/user', :action => 'list'}], + ] + p = nil + gentime = Benchmark.realtime do + n.times do + pairs.each {|(a, b)| rs.generate(a, b)} + end + end + + puts "\n\nGeneration (RouteSet): (#{(n * 8)} urls)" + per_url = gentime / (n * 8) + puts "#{per_url * 1000} ms/url" + puts "#{1 / per_url} url/s\n\n" end end - assert_raises ArgumentError do - set.draw do |map| - map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+\Z/ + + def test_route_with_colon_first + rs.draw do |map| + map.connect '/:controller/:action/:id', :action => 'index', :id => nil + map.connect ':url', :controller => 'tiny_url', :action => 'translate' end end - assert_raises ArgumentError do - set.draw do |map| - map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+\z/ + + def test_route_with_regexp_for_controller + rs.draw do |map| + map.connect ':controller/:admintoken/:action/:id', :controller => /admin\/.+/ + map.connect ':controller/:action/:id' end + assert_equal({:controller => "admin/user", :admintoken => "foo", :action => "index"}, + rs.recognize_path("/admin/user/foo")) + assert_equal({:controller => "content", :action => "foo"}, rs.recognize_path("/content/foo")) + assert_equal '/admin/user/foo', rs.generate(:controller => "admin/user", :admintoken => "foo", :action => "index") + assert_equal '/content/foo', rs.generate(:controller => "content", :action => "foo") end - assert_nothing_raised do - set.draw do |map| - map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+/, :name => /^(david|jamis)/ - end - assert_raises ActionController::RoutingError do - set.generate :controller => 'pages', :action => 'show', :id => 10 + + def test_route_with_regexp_and_dot + rs.draw do |map| + map.connect ':controller/:action/:file', + :controller => /admin|user/, + :action => /upload|download/, + :defaults => {:file => nil}, + :requirements => {:file => %r{[^/]+(\.[^/]+)?}} end + # Without a file extension + assert_equal '/user/download/file', + rs.generate(:controller => "user", :action => "download", :file => "file") + assert_equal( + {:controller => "user", :action => "download", :file => "file"}, + rs.recognize_path("/user/download/file")) + + # Now, let's try a file with an extension, really a dot (.) + assert_equal '/user/download/file.jpg', + rs.generate( + :controller => "user", :action => "download", :file => "file.jpg") + assert_equal( + {:controller => "user", :action => "download", :file => "file.jpg"}, + rs.recognize_path("/user/download/file.jpg")) + end + + def test_basic_named_route + rs.add_named_route :home, '', :controller => 'content', :action => 'list' + x = setup_for_named_route + assert_equal("http://named.route.test/", + x.send(:home_url)) end - end - def test_non_path_route_requirements_match_all - set.draw do |map| - map.connect 'page/37s', :controller => 'pages', :action => 'show', :name => /(jamis|david)/ - end - assert_equal '/page/37s', set.generate(:controller => 'pages', :action => 'show', :name => 'jamis') - assert_raises ActionController::RoutingError do - set.generate(:controller => 'pages', :action => 'show', :name => 'not_jamis') - end - assert_raises ActionController::RoutingError do - set.generate(:controller => 'pages', :action => 'show', :name => 'nor_jamis_and_david') - end - end - - def test_recognize_with_encoded_id_and_regex - set.draw do |map| - map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /[a-zA-Z0-9\+]+/ + def test_basic_named_route_with_relative_url_root + rs.add_named_route :home, '', :controller => 'content', :action => 'list' + x = setup_for_named_route + x.relative_url_root="/foo" + assert_equal("http://named.route.test/foo/", + x.send(:home_url)) + assert_equal "/foo/", x.send(:home_path) end - assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, set.recognize_path('/page/10')) - assert_equal({:controller => 'pages', :action => 'show', :id => 'hello+world'}, set.recognize_path('/page/hello+world')) - end - - def test_recognize_with_conditions - Object.const_set(:PeopleController, Class.new) - - set.draw do |map| - map.with_options(:controller => "people") do |people| - people.people "/people", :action => "index", :conditions => { :method => :get } - people.connect "/people", :action => "create", :conditions => { :method => :post } - people.person "/people/:id", :action => "show", :conditions => { :method => :get } - people.connect "/people/:id", :action => "update", :conditions => { :method => :put } - people.connect "/people/:id", :action => "destroy", :conditions => { :method => :delete } - end + def test_named_route_with_option + rs.add_named_route :page, 'page/:title', :controller => 'content', :action => 'show_page' + x = setup_for_named_route + assert_equal("http://named.route.test/page/new%20stuff", + x.send(:page_url, :title => 'new stuff')) end - request.path = "/people" - request.method = :get - assert_nothing_raised { set.recognize(request) } - assert_equal("index", request.path_parameters[:action]) - - request.method = :post - assert_nothing_raised { set.recognize(request) } - assert_equal("create", request.path_parameters[:action]) - - request.method = :put - assert_nothing_raised { set.recognize(request) } - assert_equal("update", request.path_parameters[:action]) + def test_named_route_with_default + rs.add_named_route :page, 'page/:title', :controller => 'content', :action => 'show_page', :title => 'AboutPage' + x = setup_for_named_route + assert_equal("http://named.route.test/page/AboutRails", + x.send(:page_url, :title => "AboutRails")) - begin - request.method = :bacon - set.recognize(request) - flunk 'Should have raised NotImplemented' - rescue ActionController::NotImplemented => e - assert_equal [:get, :post, :put, :delete], e.allowed_methods end - request.path = "/people/5" - request.method = :get - assert_nothing_raised { set.recognize(request) } - assert_equal("show", request.path_parameters[:action]) - assert_equal("5", request.path_parameters[:id]) + def test_named_route_with_nested_controller + rs.add_named_route :users, 'admin/user', :controller => 'admin/user', :action => 'index' + x = setup_for_named_route + assert_equal("http://named.route.test/admin/user", + x.send(:users_url)) + end - request.method = :put - assert_nothing_raised { set.recognize(request) } - assert_equal("update", request.path_parameters[:action]) - assert_equal("5", request.path_parameters[:id]) + def test_optimised_named_route_call_never_uses_url_for + rs.add_named_route :users, 'admin/user', :controller => '/admin/user', :action => 'index' + rs.add_named_route :user, 'admin/user/:id', :controller=>'/admin/user', :action=>'show' + x = setup_for_named_route + x.expects(:url_for).never + x.send(:users_url) + x.send(:users_path) + x.send(:user_url, 2, :foo=>"bar") + x.send(:user_path, 3, :bar=>"foo") + end + + def test_optimised_named_route_with_host + rs.add_named_route :pages, 'pages', :controller => 'content', :action => 'show_page', :host => 'foo.com' + x = setup_for_named_route + x.expects(:url_for).with(:host => 'foo.com', :only_path => false, :controller => 'content', :action => 'show_page', :use_route => :pages).once + x.send(:pages_url) + end + + def setup_for_named_route + klass = Class.new(MockController) + rs.install_helpers(klass) + klass.new(rs) + end + + def test_named_route_without_hash + rs.draw do |map| + map.normal ':controller/:action/:id' + end + end + + def test_named_route_root + rs.draw do |map| + map.root :controller => "hello" + end + x = setup_for_named_route + assert_equal("http://named.route.test/", x.send(:root_url)) + assert_equal("/", x.send(:root_path)) + end + + def test_named_route_with_regexps + rs.draw do |map| + map.article 'page/:year/:month/:day/:title', :controller => 'page', :action => 'show', + :year => /\d+/, :month => /\d+/, :day => /\d+/ + map.connect ':controller/:action/:id' + end + x = setup_for_named_route + # assert_equal( + # {:controller => 'page', :action => 'show', :title => 'hi', :use_route => :article, :only_path => false}, + # x.send(:article_url, :title => 'hi') + # ) + assert_equal( + "http://named.route.test/page/2005/6/10/hi", + x.send(:article_url, :title => 'hi', :day => 10, :year => 2005, :month => 6) + ) + end + + def test_changing_controller + assert_equal '/admin/stuff/show/10', rs.generate( + {:controller => 'stuff', :action => 'show', :id => 10}, + {:controller => 'admin/user', :action => 'index'} + ) + end + + def test_paths_escaped + rs.draw do |map| + map.path 'file/*path', :controller => 'content', :action => 'show_file' + map.connect ':controller/:action/:id' + end + + # No + to space in URI escaping, only for query params. + results = rs.recognize_path "/file/hello+world/how+are+you%3F" + assert results, "Recognition should have succeeded" + assert_equal ['hello+world', 'how+are+you?'], results[:path] + + # Use %20 for space instead. + results = rs.recognize_path "/file/hello%20world/how%20are%20you%3F" + assert results, "Recognition should have succeeded" + assert_equal ['hello world', 'how are you?'], results[:path] + + results = rs.recognize_path "/file" + assert results, "Recognition should have succeeded" + assert_equal [], results[:path] + end + + def test_paths_slashes_unescaped_with_ordered_parameters + rs.add_named_route :path, '/file/*path', :controller => 'content' + + # No / to %2F in URI, only for query params. + x = setup_for_named_route + assert_equal("/file/hello/world", x.send(:path_path, 'hello/world')) + end + + def test_non_controllers_cannot_be_matched + rs.draw do |map| + map.connect ':controller/:action/:id' + end + assert_raises(ActionController::RoutingError) { rs.recognize_path("/not_a/show/10") } + end + + def test_paths_do_not_accept_defaults + assert_raises(ActionController::RoutingError) do + rs.draw do |map| + map.path 'file/*path', :controller => 'content', :action => 'show_file', :path => %w(fake default) + map.connect ':controller/:action/:id' + end + end + + rs.draw do |map| + map.path 'file/*path', :controller => 'content', :action => 'show_file', :path => [] + map.connect ':controller/:action/:id' + end + end + + def test_should_list_options_diff_when_routing_requirements_dont_match + rs.draw do |map| + map.post 'post/:id', :controller=> 'post', :action=> 'show', :requirements => {:id => /\d+/} + end + exception = assert_raise(ActionController::RoutingError) { rs.generate(:controller => 'post', :action => 'show', :bad_param => "foo", :use_route => "post") } + assert_match /^post_url failed to generate/, exception.message + from_match = exception.message.match(/from \{[^\}]+\}/).to_s + assert_match /:bad_param=>"foo"/, from_match + assert_match /:action=>"show"/, from_match + assert_match /:controller=>"post"/, from_match + + expected_match = exception.message.match(/expected: \{[^\}]+\}/).to_s + assert_no_match /:bad_param=>"foo"/, expected_match + assert_match /:action=>"show"/, expected_match + assert_match /:controller=>"post"/, expected_match + + diff_match = exception.message.match(/diff: \{[^\}]+\}/).to_s + assert_match /:bad_param=>"foo"/, diff_match + assert_no_match /:action=>"show"/, diff_match + assert_no_match /:controller=>"post"/, diff_match + end + + # this specifies the case where your formerly would get a very confusing error message with an empty diff + def test_should_have_better_error_message_when_options_diff_is_empty + rs.draw do |map| + map.content '/content/:query', :controller => 'content', :action => 'show' + end + + exception = assert_raise(ActionController::RoutingError) { rs.generate(:controller => 'content', :action => 'show', :use_route => "content") } + assert_match %r[:action=>"show"], exception.message + assert_match %r[:controller=>"content"], exception.message + assert_match %r[you may have ambiguous routes, or you may need to supply additional parameters for this route], exception.message + assert_match %r[content_url has the following required parameters: \["content", :query\] - are they all satisfied?], exception.message + end + + def test_dynamic_path_allowed + rs.draw do |map| + map.connect '*path', :controller => 'content', :action => 'show_file' + end + + assert_equal '/pages/boo', rs.generate(:controller => 'content', :action => 'show_file', :path => %w(pages boo)) + end + + def test_dynamic_recall_paths_allowed + rs.draw do |map| + map.connect '*path', :controller => 'content', :action => 'show_file' + end + + recall_path = ActionController::Routing::PathSegment::Result.new(%w(pages boo)) + assert_equal '/pages/boo', rs.generate({}, :controller => 'content', :action => 'show_file', :path => recall_path) + end + + def test_backwards + rs.draw do |map| + map.connect 'page/:id/:action', :controller => 'pages', :action => 'show' + map.connect ':controller/:action/:id' + end + + assert_equal '/page/20', rs.generate({:id => 20}, {:controller => 'pages', :action => 'show'}) + assert_equal '/page/20', rs.generate(:controller => 'pages', :id => 20, :action => 'show') + assert_equal '/pages/boo', rs.generate(:controller => 'pages', :action => 'boo') + end + + def test_route_with_fixnum_default + rs.draw do |map| + map.connect 'page/:id', :controller => 'content', :action => 'show_page', :id => 1 + map.connect ':controller/:action/:id' + end + + assert_equal '/page', rs.generate(:controller => 'content', :action => 'show_page') + assert_equal '/page', rs.generate(:controller => 'content', :action => 'show_page', :id => 1) + assert_equal '/page', rs.generate(:controller => 'content', :action => 'show_page', :id => '1') + assert_equal '/page/10', rs.generate(:controller => 'content', :action => 'show_page', :id => 10) + + assert_equal({:controller => "content", :action => 'show_page', :id => '1'}, rs.recognize_path("/page")) + assert_equal({:controller => "content", :action => 'show_page', :id => '1'}, rs.recognize_path("/page/1")) + assert_equal({:controller => "content", :action => 'show_page', :id => '10'}, rs.recognize_path("/page/10")) + end + + # For newer revision + def test_route_with_text_default + rs.draw do |map| + map.connect 'page/:id', :controller => 'content', :action => 'show_page', :id => 1 + map.connect ':controller/:action/:id' + end + + assert_equal '/page/foo', rs.generate(:controller => 'content', :action => 'show_page', :id => 'foo') + assert_equal({:controller => "content", :action => 'show_page', :id => 'foo'}, rs.recognize_path("/page/foo")) + + token = "\321\202\320\265\320\272\321\201\321\202" # 'text' in russian + escaped_token = CGI::escape(token) + + assert_equal '/page/' + escaped_token, rs.generate(:controller => 'content', :action => 'show_page', :id => token) + assert_equal({:controller => "content", :action => 'show_page', :id => token}, rs.recognize_path("/page/#{escaped_token}")) + end + + def test_action_expiry + assert_equal '/content', rs.generate({:controller => 'content'}, {:controller => 'content', :action => 'show'}) + end + + def test_recognition_with_uppercase_controller_name + assert_equal({:controller => "content", :action => 'index'}, rs.recognize_path("/Content")) + assert_equal({:controller => "content", :action => 'list'}, rs.recognize_path("/ConTent/list")) + assert_equal({:controller => "content", :action => 'show', :id => '10'}, rs.recognize_path("/CONTENT/show/10")) + + # these used to work, before the routes rewrite, but support for this was pulled in the new version... + #assert_equal({'controller' => "admin/news_feed", 'action' => 'index'}, rs.recognize_path("Admin/NewsFeed")) + #assert_equal({'controller' => "admin/news_feed", 'action' => 'index'}, rs.recognize_path("Admin/News_Feed")) + end + + def test_requirement_should_prevent_optional_id + rs.draw do |map| + map.post 'post/:id', :controller=> 'post', :action=> 'show', :requirements => {:id => /\d+/} + end + + assert_equal '/post/10', rs.generate(:controller => 'post', :action => 'show', :id => 10) + + assert_raises ActionController::RoutingError do + rs.generate(:controller => 'post', :action => 'show') + end + end + + def test_both_requirement_and_optional + rs.draw do |map| + map.blog('test/:year', :controller => 'post', :action => 'show', + :defaults => { :year => nil }, + :requirements => { :year => /\d{4}/ } + ) + map.connect ':controller/:action/:id' + end + + assert_equal '/test', rs.generate(:controller => 'post', :action => 'show') + assert_equal '/test', rs.generate(:controller => 'post', :action => 'show', :year => nil) + + x = setup_for_named_route + assert_equal("http://named.route.test/test", + x.send(:blog_url)) + end + + def test_set_to_nil_forgets + rs.draw do |map| + map.connect 'pages/:year/:month/:day', :controller => 'content', :action => 'list_pages', :month => nil, :day => nil + map.connect ':controller/:action/:id' + end + + assert_equal '/pages/2005', + rs.generate(:controller => 'content', :action => 'list_pages', :year => 2005) + assert_equal '/pages/2005/6', + rs.generate(:controller => 'content', :action => 'list_pages', :year => 2005, :month => 6) + assert_equal '/pages/2005/6/12', + rs.generate(:controller => 'content', :action => 'list_pages', :year => 2005, :month => 6, :day => 12) + + assert_equal '/pages/2005/6/4', + rs.generate({:day => 4}, {:controller => 'content', :action => 'list_pages', :year => '2005', :month => '6', :day => '12'}) + + assert_equal '/pages/2005/6', + rs.generate({:day => nil}, {:controller => 'content', :action => 'list_pages', :year => '2005', :month => '6', :day => '12'}) + + assert_equal '/pages/2005', + rs.generate({:day => nil, :month => nil}, {:controller => 'content', :action => 'list_pages', :year => '2005', :month => '6', :day => '12'}) + end + + def test_url_with_no_action_specified + rs.draw do |map| + map.connect '', :controller => 'content' + map.connect ':controller/:action/:id' + end + + assert_equal '/', rs.generate(:controller => 'content', :action => 'index') + assert_equal '/', rs.generate(:controller => 'content') + end + + def test_named_url_with_no_action_specified + rs.draw do |map| + map.home '', :controller => 'content' + map.connect ':controller/:action/:id' + end + + assert_equal '/', rs.generate(:controller => 'content', :action => 'index') + assert_equal '/', rs.generate(:controller => 'content') + + x = setup_for_named_route + assert_equal("http://named.route.test/", + x.send(:home_url)) + end + + def test_url_generated_when_forgetting_action + [{:controller => 'content', :action => 'index'}, {:controller => 'content'}].each do |hash| + rs.draw do |map| + map.home '', hash + map.connect ':controller/:action/:id' + end + assert_equal '/', rs.generate({:action => nil}, {:controller => 'content', :action => 'hello'}) + assert_equal '/', rs.generate({:controller => 'content'}) + assert_equal '/content/hi', rs.generate({:controller => 'content', :action => 'hi'}) + end + end + + def test_named_route_method + rs.draw do |map| + map.categories 'categories', :controller => 'content', :action => 'categories' + map.connect ':controller/:action/:id' + end + + assert_equal '/categories', rs.generate(:controller => 'content', :action => 'categories') + assert_equal '/content/hi', rs.generate({:controller => 'content', :action => 'hi'}) + end + + def test_named_routes_array + test_named_route_method + assert_equal [:categories], rs.named_routes.names + end + + def test_nil_defaults + rs.draw do |map| + map.connect 'journal', + :controller => 'content', + :action => 'list_journal', + :date => nil, :user_id => nil + map.connect ':controller/:action/:id' + end + + assert_equal '/journal', rs.generate(:controller => 'content', :action => 'list_journal', :date => nil, :user_id => nil) + end + + def setup_request_method_routes_for(method) + @request = ActionController::TestRequest.new + @request.env["REQUEST_METHOD"] = method + @request.request_uri = "/match" + + rs.draw do |r| + r.connect '/match', :controller => 'books', :action => 'get', :conditions => { :method => :get } + r.connect '/match', :controller => 'books', :action => 'post', :conditions => { :method => :post } + r.connect '/match', :controller => 'books', :action => 'put', :conditions => { :method => :put } + r.connect '/match', :controller => 'books', :action => 'delete', :conditions => { :method => :delete } + end + end + + %w(GET POST PUT DELETE).each do |request_method| + define_method("test_request_method_recognized_with_#{request_method}") do + begin + Object.const_set(:BooksController, Class.new(ActionController::Base)) + + setup_request_method_routes_for(request_method) + + assert_nothing_raised { rs.recognize(@request) } + assert_equal request_method.downcase, @request.path_parameters[:action] + ensure + Object.send(:remove_const, :BooksController) rescue nil + end + end + end + + def test_subpath_recognized + Object.const_set(:SubpathBooksController, Class.new(ActionController::Base)) + + rs.draw do |r| + r.connect '/books/:id/edit', :controller => 'subpath_books', :action => 'edit' + r.connect '/items/:id/:action', :controller => 'subpath_books' + r.connect '/posts/new/:action', :controller => 'subpath_books' + r.connect '/posts/:id', :controller => 'subpath_books', :action => "show" + end + + hash = rs.recognize_path "/books/17/edit" + assert_not_nil hash + assert_equal %w(subpath_books 17 edit), [hash[:controller], hash[:id], hash[:action]] + + hash = rs.recognize_path "/items/3/complete" + assert_not_nil hash + assert_equal %w(subpath_books 3 complete), [hash[:controller], hash[:id], hash[:action]] + + hash = rs.recognize_path "/posts/new/preview" + assert_not_nil hash + assert_equal %w(subpath_books preview), [hash[:controller], hash[:action]] + + hash = rs.recognize_path "/posts/7" + assert_not_nil hash + assert_equal %w(subpath_books show 7), [hash[:controller], hash[:action], hash[:id]] + ensure + Object.send(:remove_const, :SubpathBooksController) rescue nil + end + + def test_subpath_generated + Object.const_set(:SubpathBooksController, Class.new(ActionController::Base)) + + rs.draw do |r| + r.connect '/books/:id/edit', :controller => 'subpath_books', :action => 'edit' + r.connect '/items/:id/:action', :controller => 'subpath_books' + r.connect '/posts/new/:action', :controller => 'subpath_books' + end + + assert_equal "/books/7/edit", rs.generate(:controller => "subpath_books", :id => 7, :action => "edit") + assert_equal "/items/15/complete", rs.generate(:controller => "subpath_books", :id => 15, :action => "complete") + assert_equal "/posts/new/preview", rs.generate(:controller => "subpath_books", :action => "preview") + ensure + Object.send(:remove_const, :SubpathBooksController) rescue nil + end + + def test_failed_requirements_raises_exception_with_violated_requirements + rs.draw do |r| + r.foo_with_requirement 'foos/:id', :controller=>'foos', :requirements=>{:id=>/\d+/} + end + + x = setup_for_named_route + assert_raises(ActionController::RoutingError) do + x.send(:foo_with_requirement_url, "I am Against the requirements") + end + end + end + + class RouteTest < Test::Unit::TestCase + def setup + @route = ROUTING::Route.new + end + + def slash_segment(is_optional = false) + returning ROUTING::DividerSegment.new('/') do |s| + s.is_optional = is_optional + end + end + + def default_route + unless defined?(@default_route) + @default_route = ROUTING::Route.new + + @default_route.segments << (s = ROUTING::StaticSegment.new) + s.value = '/' + s.raw = true + + @default_route.segments << (s = ROUTING::DynamicSegment.new) + s.key = :controller + + @default_route.segments << slash_segment(:optional) + @default_route.segments << (s = ROUTING::DynamicSegment.new) + s.key = :action + s.default = 'index' + s.is_optional = true + + @default_route.segments << slash_segment(:optional) + @default_route.segments << (s = ROUTING::DynamicSegment.new) + s.key = :id + s.is_optional = true + + @default_route.segments << slash_segment(:optional) + end + @default_route + end + + def test_default_route_recognition + expected = {:controller => 'accounts', :action => 'show', :id => '10'} + assert_equal expected, default_route.recognize('/accounts/show/10') + assert_equal expected, default_route.recognize('/accounts/show/10/') + + expected[:id] = 'jamis' + assert_equal expected, default_route.recognize('/accounts/show/jamis/') + + expected.delete :id + assert_equal expected, default_route.recognize('/accounts/show') + assert_equal expected, default_route.recognize('/accounts/show/') + + expected[:action] = 'index' + assert_equal expected, default_route.recognize('/accounts/') + assert_equal expected, default_route.recognize('/accounts') + + assert_equal nil, default_route.recognize('/') + assert_equal nil, default_route.recognize('/accounts/how/goood/it/is/to/be/free') + end + + def test_default_route_should_omit_default_action + o = {:controller => 'accounts', :action => 'index'} + assert_equal '/accounts', default_route.generate(o, o, {}) + end + + def test_default_route_should_include_default_action_when_id_present + o = {:controller => 'accounts', :action => 'index', :id => '20'} + assert_equal '/accounts/index/20', default_route.generate(o, o, {}) + end + + def test_default_route_should_work_with_action_but_no_id + o = {:controller => 'accounts', :action => 'list_all'} + assert_equal '/accounts/list_all', default_route.generate(o, o, {}) + end + + def test_default_route_should_uri_escape_pluses + expected = { :controller => 'accounts', :action => 'show', :id => 'hello world' } + assert_equal expected, default_route.recognize('/accounts/show/hello world') + assert_equal expected, default_route.recognize('/accounts/show/hello%20world') + assert_equal '/accounts/show/hello%20world', default_route.generate(expected, expected, {}) + + expected[:id] = 'hello+world' + assert_equal expected, default_route.recognize('/accounts/show/hello+world') + assert_equal expected, default_route.recognize('/accounts/show/hello%2Bworld') + assert_equal '/accounts/show/hello+world', default_route.generate(expected, expected, {}) + end + + def test_matches_controller_and_action + # requirement_for should only be called for the action and controller _once_ + @route.expects(:requirement_for).with(:controller).times(1).returns('pages') + @route.expects(:requirement_for).with(:action).times(1).returns('show') + + @route.requirements = {:controller => 'pages', :action => 'show'} + assert @route.matches_controller_and_action?('pages', 'show') + assert !@route.matches_controller_and_action?('not_pages', 'show') + assert !@route.matches_controller_and_action?('pages', 'not_show') + end + + def test_parameter_shell + page_url = ROUTING::Route.new + page_url.requirements = {:controller => 'pages', :action => 'show', :id => /\d+/} + assert_equal({:controller => 'pages', :action => 'show'}, page_url.parameter_shell) + end + + def test_defaults + route = ROUTING::RouteBuilder.new.build '/users/:id.:format', :controller => "users", :action => "show", :format => "html" + assert_equal( + { :controller => "users", :action => "show", :format => "html" }, + route.defaults) + end + + def test_builder_complains_without_controller + assert_raises(ArgumentError) do + ROUTING::RouteBuilder.new.build '/contact', :contoller => "contact", :action => "index" + end + end + + def test_significant_keys_for_default_route + keys = default_route.significant_keys.sort_by {|k| k.to_s } + assert_equal [:action, :controller, :id], keys + end + + def test_significant_keys + user_url = ROUTING::Route.new + user_url.segments << (s = ROUTING::StaticSegment.new) + s.value = '/' + s.raw = true + + user_url.segments << (s = ROUTING::StaticSegment.new) + s.value = 'user' + + user_url.segments << (s = ROUTING::StaticSegment.new) + s.value = '/' + s.raw = true + s.is_optional = true + + user_url.segments << (s = ROUTING::DynamicSegment.new) + s.key = :user + + user_url.segments << (s = ROUTING::StaticSegment.new) + s.value = '/' + s.raw = true + s.is_optional = true + + user_url.requirements = {:controller => 'users', :action => 'show'} + + keys = user_url.significant_keys.sort_by { |k| k.to_s } + assert_equal [:action, :controller, :user], keys + end + + def test_build_empty_query_string + assert_equal '', @route.build_query_string({}) + end + + def test_build_query_string_with_nil_value + assert_equal '', @route.build_query_string({:x => nil}) + end + + def test_simple_build_query_string + assert_equal '?x=1&y=2', order_query_string(@route.build_query_string(:x => '1', :y => '2')) + end + + def test_convert_ints_build_query_string + assert_equal '?x=1&y=2', order_query_string(@route.build_query_string(:x => 1, :y => 2)) + end + + def test_escape_spaces_build_query_string + assert_equal '?x=hello+world&y=goodbye+world', order_query_string(@route.build_query_string(:x => 'hello world', :y => 'goodbye world')) + end + + def test_expand_array_build_query_string + assert_equal '?x%5B%5D=1&x%5B%5D=2', order_query_string(@route.build_query_string(:x => [1, 2])) + end + + def test_escape_spaces_build_query_string_selected_keys + assert_equal '?x=hello+world', order_query_string(@route.build_query_string({:x => 'hello world', :y => 'goodbye world'}, [:x])) + end + + private + def order_query_string(qs) + '?' + qs[1..-1].split('&').sort.join('&') + end + end + + class RouteSetTest < Test::Unit::TestCase + def set + @set ||= ROUTING::RouteSet.new + end + + def request + @request ||= MockRequest.new(:host => "named.routes.test", :method => :get) + end + + def test_generate_extras + set.draw { |m| m.connect ':controller/:action/:id' } + path, extras = set.generate_extras(:controller => "foo", :action => "bar", :id => 15, :this => "hello", :that => "world") + assert_equal "/foo/bar/15", path + assert_equal %w(that this), extras.map(&:to_s).sort + end + + def test_extra_keys + set.draw { |m| m.connect ':controller/:action/:id' } + extras = set.extra_keys(:controller => "foo", :action => "bar", :id => 15, :this => "hello", :that => "world") + assert_equal %w(that this), extras.map(&:to_s).sort + end + + def test_generate_extras_not_first + set.draw do |map| + map.connect ':controller/:action/:id.:format' + map.connect ':controller/:action/:id' + end + path, extras = set.generate_extras(:controller => "foo", :action => "bar", :id => 15, :this => "hello", :that => "world") + assert_equal "/foo/bar/15", path + assert_equal %w(that this), extras.map(&:to_s).sort + end + + def test_generate_not_first + set.draw do |map| + map.connect ':controller/:action/:id.:format' + map.connect ':controller/:action/:id' + end + assert_equal "/foo/bar/15?this=hello", set.generate(:controller => "foo", :action => "bar", :id => 15, :this => "hello") + end + + def test_extra_keys_not_first + set.draw do |map| + map.connect ':controller/:action/:id.:format' + map.connect ':controller/:action/:id' + end + extras = set.extra_keys(:controller => "foo", :action => "bar", :id => 15, :this => "hello", :that => "world") + assert_equal %w(that this), extras.map(&:to_s).sort + end + + def test_draw + assert_equal 0, set.routes.size + set.draw do |map| + map.connect '/hello/world', :controller => 'a', :action => 'b' + end + assert_equal 1, set.routes.size + end + + def test_named_draw + assert_equal 0, set.routes.size + set.draw do |map| + map.hello '/hello/world', :controller => 'a', :action => 'b' + end + assert_equal 1, set.routes.size + assert_equal set.routes.first, set.named_routes[:hello] + end + + def test_later_named_routes_take_precedence + set.draw do |map| + map.hello '/hello/world', :controller => 'a', :action => 'b' + map.hello '/hello', :controller => 'a', :action => 'b' + end + assert_equal set.routes.last, set.named_routes[:hello] + end + + def setup_named_route_test + set.draw do |map| + map.show '/people/:id', :controller => 'people', :action => 'show' + map.index '/people', :controller => 'people', :action => 'index' + map.multi '/people/go/:foo/:bar/joe/:id', :controller => 'people', :action => 'multi' + map.users '/admin/users', :controller => 'admin/users', :action => 'index' + end + + klass = Class.new(MockController) + set.install_helpers(klass) + klass.new(set) + end + + def test_named_route_hash_access_method + controller = setup_named_route_test + + assert_equal( + { :controller => 'people', :action => 'show', :id => 5, :use_route => :show, :only_path => false }, + controller.send(:hash_for_show_url, :id => 5)) + + assert_equal( + { :controller => 'people', :action => 'index', :use_route => :index, :only_path => false }, + controller.send(:hash_for_index_url)) + + assert_equal( + { :controller => 'people', :action => 'show', :id => 5, :use_route => :show, :only_path => true }, + controller.send(:hash_for_show_path, :id => 5) + ) + end + + def test_named_route_url_method + controller = setup_named_route_test + + assert_equal "http://named.route.test/people/5", controller.send(:show_url, :id => 5) + assert_equal "/people/5", controller.send(:show_path, :id => 5) + + assert_equal "http://named.route.test/people", controller.send(:index_url) + assert_equal "/people", controller.send(:index_path) + + assert_equal "http://named.route.test/admin/users", controller.send(:users_url) + assert_equal '/admin/users', controller.send(:users_path) + assert_equal '/admin/users', set.generate(controller.send(:hash_for_users_url), {:controller => 'users', :action => 'index'}) + end + + def test_named_route_url_method_with_anchor + controller = setup_named_route_test + + assert_equal "http://named.route.test/people/5#location", controller.send(:show_url, :id => 5, :anchor => 'location') + assert_equal "/people/5#location", controller.send(:show_path, :id => 5, :anchor => 'location') + + assert_equal "http://named.route.test/people#location", controller.send(:index_url, :anchor => 'location') + assert_equal "/people#location", controller.send(:index_path, :anchor => 'location') + + assert_equal "http://named.route.test/admin/users#location", controller.send(:users_url, :anchor => 'location') + assert_equal '/admin/users#location', controller.send(:users_path, :anchor => 'location') + + assert_equal "http://named.route.test/people/go/7/hello/joe/5#location", + controller.send(:multi_url, 7, "hello", 5, :anchor => 'location') + + assert_equal "http://named.route.test/people/go/7/hello/joe/5?baz=bar#location", + controller.send(:multi_url, 7, "hello", 5, :baz => "bar", :anchor => 'location') + + assert_equal "http://named.route.test/people?baz=bar#location", + controller.send(:index_url, :baz => "bar", :anchor => 'location') + end + + def test_named_route_url_method_with_port + controller = setup_named_route_test + assert_equal "http://named.route.test:8080/people/5", controller.send(:show_url, 5, :port=>8080) + end + + def test_named_route_url_method_with_host + controller = setup_named_route_test + assert_equal "http://some.example.com/people/5", controller.send(:show_url, 5, :host=>"some.example.com") + end + + def test_named_route_url_method_with_ordered_parameters + controller = setup_named_route_test + assert_equal "http://named.route.test/people/go/7/hello/joe/5", + controller.send(:multi_url, 7, "hello", 5) + end + + def test_named_route_url_method_with_ordered_parameters_and_hash + controller = setup_named_route_test + assert_equal "http://named.route.test/people/go/7/hello/joe/5?baz=bar", + controller.send(:multi_url, 7, "hello", 5, :baz => "bar") + end + + def test_named_route_url_method_with_no_positional_arguments + controller = setup_named_route_test + assert_equal "http://named.route.test/people?baz=bar", + controller.send(:index_url, :baz => "bar") + end + + def test_draw_default_route + ActionController::Routing.with_controllers(['users']) do + set.draw do |map| + map.connect '/:controller/:action/:id' + end + + assert_equal 1, set.routes.size + route = set.routes.first + + assert route.segments.last.optional? + + assert_equal '/users/show/10', set.generate(:controller => 'users', :action => 'show', :id => 10) + assert_equal '/users/index/10', set.generate(:controller => 'users', :id => 10) + + assert_equal({:controller => 'users', :action => 'index', :id => '10'}, set.recognize_path('/users/index/10')) + assert_equal({:controller => 'users', :action => 'index', :id => '10'}, set.recognize_path('/users/index/10/')) + end + end + + def test_draw_default_route_with_default_controller + ActionController::Routing.with_controllers(['users']) do + set.draw do |map| + map.connect '/:controller/:action/:id', :controller => 'users' + end + assert_equal({:controller => 'users', :action => 'index'}, set.recognize_path('/')) + end + end + + def test_route_with_parameter_shell + ActionController::Routing.with_controllers(['users', 'pages']) do + set.draw do |map| + map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+/ + map.connect '/:controller/:action/:id' + end + + assert_equal({:controller => 'pages', :action => 'index'}, set.recognize_path('/pages')) + assert_equal({:controller => 'pages', :action => 'index'}, set.recognize_path('/pages/index')) + assert_equal({:controller => 'pages', :action => 'list'}, set.recognize_path('/pages/list')) + + assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, set.recognize_path('/pages/show/10')) + assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, set.recognize_path('/page/10')) + end + end + + def test_route_requirements_with_anchor_chars_are_invalid + assert_raises ArgumentError do + set.draw do |map| + map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /^\d+/ + end + end + assert_raises ArgumentError do + set.draw do |map| + map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\A\d+/ + end + end + assert_raises ArgumentError do + set.draw do |map| + map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+$/ + end + end + assert_raises ArgumentError do + set.draw do |map| + map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+\Z/ + end + end + assert_raises ArgumentError do + set.draw do |map| + map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+\z/ + end + end + assert_nothing_raised do + set.draw do |map| + map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+/, :name => /^(david|jamis)/ + end + assert_raises ActionController::RoutingError do + set.generate :controller => 'pages', :action => 'show', :id => 10 + end + end + end + + def test_non_path_route_requirements_match_all + set.draw do |map| + map.connect 'page/37s', :controller => 'pages', :action => 'show', :name => /(jamis|david)/ + end + assert_equal '/page/37s', set.generate(:controller => 'pages', :action => 'show', :name => 'jamis') + assert_raises ActionController::RoutingError do + set.generate(:controller => 'pages', :action => 'show', :name => 'not_jamis') + end + assert_raises ActionController::RoutingError do + set.generate(:controller => 'pages', :action => 'show', :name => 'nor_jamis_and_david') + end + end + + def test_recognize_with_encoded_id_and_regex + set.draw do |map| + map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /[a-zA-Z0-9\+]+/ + end + + assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, set.recognize_path('/page/10')) + assert_equal({:controller => 'pages', :action => 'show', :id => 'hello+world'}, set.recognize_path('/page/hello+world')) + end + + def test_recognize_with_conditions + Object.const_set(:PeopleController, Class.new) + + set.draw do |map| + map.with_options(:controller => "people") do |people| + people.people "/people", :action => "index", :conditions => { :method => :get } + people.connect "/people", :action => "create", :conditions => { :method => :post } + people.person "/people/:id", :action => "show", :conditions => { :method => :get } + people.connect "/people/:id", :action => "update", :conditions => { :method => :put } + people.connect "/people/:id", :action => "destroy", :conditions => { :method => :delete } + end + end - request.method = :delete - assert_nothing_raised { set.recognize(request) } - assert_equal("destroy", request.path_parameters[:action]) - assert_equal("5", request.path_parameters[:id]) + request.path = "/people" + request.method = :get + assert_nothing_raised { set.recognize(request) } + assert_equal("index", request.path_parameters[:action]) - begin request.method = :post - set.recognize(request) - flunk 'Should have raised MethodNotAllowed' - rescue ActionController::MethodNotAllowed => e - assert_equal [:get, :put, :delete], e.allowed_methods + assert_nothing_raised { set.recognize(request) } + assert_equal("create", request.path_parameters[:action]) + + request.method = :put + assert_nothing_raised { set.recognize(request) } + assert_equal("update", request.path_parameters[:action]) + + begin + request.method = :bacon + set.recognize(request) + flunk 'Should have raised NotImplemented' + rescue ActionController::NotImplemented => e + assert_equal [:get, :post, :put, :delete], e.allowed_methods + end + + request.path = "/people/5" + request.method = :get + assert_nothing_raised { set.recognize(request) } + assert_equal("show", request.path_parameters[:action]) + assert_equal("5", request.path_parameters[:id]) + + request.method = :put + assert_nothing_raised { set.recognize(request) } + assert_equal("update", request.path_parameters[:action]) + assert_equal("5", request.path_parameters[:id]) + + request.method = :delete + assert_nothing_raised { set.recognize(request) } + assert_equal("destroy", request.path_parameters[:action]) + assert_equal("5", request.path_parameters[:id]) + + begin + request.method = :post + set.recognize(request) + flunk 'Should have raised MethodNotAllowed' + rescue ActionController::MethodNotAllowed => e + assert_equal [:get, :put, :delete], e.allowed_methods + end + + ensure + Object.send(:remove_const, :PeopleController) end - ensure - Object.send(:remove_const, :PeopleController) - end - - def test_recognize_with_alias_in_conditions - Object.const_set(:PeopleController, Class.new) + def test_recognize_with_alias_in_conditions + Object.const_set(:PeopleController, Class.new) + + set.draw do |map| + map.people "/people", :controller => 'people', :action => "index", + :conditions => { :method => :get } + map.root :people + end - set.draw do |map| - map.people "/people", :controller => 'people', :action => "index", - :conditions => { :method => :get } - map.root :people + request.path = "/people" + request.method = :get + assert_nothing_raised { set.recognize(request) } + assert_equal("people", request.path_parameters[:controller]) + assert_equal("index", request.path_parameters[:action]) + + request.path = "/" + request.method = :get + assert_nothing_raised { set.recognize(request) } + assert_equal("people", request.path_parameters[:controller]) + assert_equal("index", request.path_parameters[:action]) + ensure + Object.send(:remove_const, :PeopleController) end - request.path = "/people" - request.method = :get - assert_nothing_raised { set.recognize(request) } - assert_equal("people", request.path_parameters[:controller]) - assert_equal("index", request.path_parameters[:action]) + def test_typo_recognition + Object.const_set(:ArticlesController, Class.new) - request.path = "/" - request.method = :get - assert_nothing_raised { set.recognize(request) } - assert_equal("people", request.path_parameters[:controller]) - assert_equal("index", request.path_parameters[:action]) - ensure - Object.send(:remove_const, :PeopleController) - end - - def test_typo_recognition - Object.const_set(:ArticlesController, Class.new) - - set.draw do |map| - map.connect 'articles/:year/:month/:day/:title', - :controller => 'articles', :action => 'permalink', - :year => /\d{4}/, :day => /\d{1,2}/, :month => /\d{1,2}/ - end - - request.path = "/articles/2005/11/05/a-very-interesting-article" - request.method = :get - assert_nothing_raised { set.recognize(request) } - assert_equal("permalink", request.path_parameters[:action]) - assert_equal("2005", request.path_parameters[:year]) - assert_equal("11", request.path_parameters[:month]) - assert_equal("05", request.path_parameters[:day]) - assert_equal("a-very-interesting-article", request.path_parameters[:title]) - - ensure - Object.send(:remove_const, :ArticlesController) - end + set.draw do |map| + map.connect 'articles/:year/:month/:day/:title', + :controller => 'articles', :action => 'permalink', + :year => /\d{4}/, :day => /\d{1,2}/, :month => /\d{1,2}/ + end - def test_routing_traversal_does_not_load_extra_classes - assert !Object.const_defined?("Profiler__"), "Profiler should not be loaded" - set.draw do |map| - map.connect '/profile', :controller => 'profile' + request.path = "/articles/2005/11/05/a-very-interesting-article" + request.method = :get + assert_nothing_raised { set.recognize(request) } + assert_equal("permalink", request.path_parameters[:action]) + assert_equal("2005", request.path_parameters[:year]) + assert_equal("11", request.path_parameters[:month]) + assert_equal("05", request.path_parameters[:day]) + assert_equal("a-very-interesting-article", request.path_parameters[:title]) + + ensure + Object.send(:remove_const, :ArticlesController) end - request.path = '/profile' + def test_routing_traversal_does_not_load_extra_classes + assert !Object.const_defined?("Profiler__"), "Profiler should not be loaded" + set.draw do |map| + map.connect '/profile', :controller => 'profile' + end + + request.path = '/profile' - set.recognize(request) rescue nil - - assert !Object.const_defined?("Profiler__"), "Profiler should not be loaded" - end + set.recognize(request) rescue nil + + assert !Object.const_defined?("Profiler__"), "Profiler should not be loaded" + end - def test_recognize_with_conditions_and_format - Object.const_set(:PeopleController, Class.new) + def test_recognize_with_conditions_and_format + Object.const_set(:PeopleController, Class.new) - set.draw do |map| - map.with_options(:controller => "people") do |people| - people.person "/people/:id", :action => "show", :conditions => { :method => :get } - people.connect "/people/:id", :action => "update", :conditions => { :method => :put } - people.connect "/people/:id.:_format", :action => "show", :conditions => { :method => :get } + set.draw do |map| + map.with_options(:controller => "people") do |people| + people.person "/people/:id", :action => "show", :conditions => { :method => :get } + people.connect "/people/:id", :action => "update", :conditions => { :method => :put } + people.connect "/people/:id.:_format", :action => "show", :conditions => { :method => :get } + end end + + request.path = "/people/5" + request.method = :get + assert_nothing_raised { set.recognize(request) } + assert_equal("show", request.path_parameters[:action]) + assert_equal("5", request.path_parameters[:id]) + + request.method = :put + assert_nothing_raised { set.recognize(request) } + assert_equal("update", request.path_parameters[:action]) + + request.path = "/people/5.png" + request.method = :get + assert_nothing_raised { set.recognize(request) } + assert_equal("show", request.path_parameters[:action]) + assert_equal("5", request.path_parameters[:id]) + assert_equal("png", request.path_parameters[:_format]) + ensure + Object.send(:remove_const, :PeopleController) end - request.path = "/people/5" - request.method = :get - assert_nothing_raised { set.recognize(request) } - assert_equal("show", request.path_parameters[:action]) - assert_equal("5", request.path_parameters[:id]) + def test_generate_with_default_action + set.draw do |map| + map.connect "/people", :controller => "people" + map.connect "/people/list", :controller => "people", :action => "list" + end + + url = set.generate(:controller => "people", :action => "list") + assert_equal "/people/list", url + end - request.method = :put - assert_nothing_raised { set.recognize(request) } - assert_equal("update", request.path_parameters[:action]) + def test_root_map + Object.const_set(:PeopleController, Class.new) - request.path = "/people/5.png" - request.method = :get - assert_nothing_raised { set.recognize(request) } - assert_equal("show", request.path_parameters[:action]) - assert_equal("5", request.path_parameters[:id]) - assert_equal("png", request.path_parameters[:_format]) - ensure - Object.send(:remove_const, :PeopleController) - end + set.draw { |map| map.root :controller => "people" } - def test_generate_with_default_action - set.draw do |map| - map.connect "/people", :controller => "people" - map.connect "/people/list", :controller => "people", :action => "list" + request.path = "" + request.method = :get + assert_nothing_raised { set.recognize(request) } + assert_equal("people", request.path_parameters[:controller]) + assert_equal("index", request.path_parameters[:action]) + ensure + Object.send(:remove_const, :PeopleController) end - url = set.generate(:controller => "people", :action => "list") - assert_equal "/people/list", url - end - - def test_root_map - Object.const_set(:PeopleController, Class.new) + def test_namespace + Object.const_set(:Api, Module.new { |m| m.const_set(:ProductsController, Class.new) }) - set.draw { |map| map.root :controller => "people" } + set.draw do |map| - request.path = "" - request.method = :get - assert_nothing_raised { set.recognize(request) } - assert_equal("people", request.path_parameters[:controller]) - assert_equal("index", request.path_parameters[:action]) - ensure - Object.send(:remove_const, :PeopleController) - end - - - def test_namespace - Object.const_set(:Api, Module.new { |m| m.const_set(:ProductsController, Class.new) }) + map.namespace 'api' do |api| + api.route 'inventory', :controller => "products", :action => 'inventory' + end - set.draw do |map| - - map.namespace 'api' do |api| - api.route 'inventory', :controller => "products", :action => 'inventory' end - + + request.path = "/api/inventory" + request.method = :get + assert_nothing_raised { set.recognize(request) } + assert_equal("api/products", request.path_parameters[:controller]) + assert_equal("inventory", request.path_parameters[:action]) + ensure + Object.send(:remove_const, :Api) end - request.path = "/api/inventory" - request.method = :get - assert_nothing_raised { set.recognize(request) } - assert_equal("api/products", request.path_parameters[:controller]) - assert_equal("inventory", request.path_parameters[:action]) - ensure - Object.send(:remove_const, :Api) - end - + def test_namespaced_root_map + Object.const_set(:Api, Module.new { |m| m.const_set(:ProductsController, Class.new) }) - def test_namespaced_root_map - Object.const_set(:Api, Module.new { |m| m.const_set(:ProductsController, Class.new) }) + set.draw do |map| + + map.namespace 'api' do |api| + api.root :controller => "products" + end - set.draw do |map| - - map.namespace 'api' do |api| - api.root :controller => "products" end - + + request.path = "/api" + request.method = :get + assert_nothing_raised { set.recognize(request) } + assert_equal("api/products", request.path_parameters[:controller]) + assert_equal("index", request.path_parameters[:action]) + ensure + Object.send(:remove_const, :Api) end - request.path = "/api" - request.method = :get - assert_nothing_raised { set.recognize(request) } - assert_equal("api/products", request.path_parameters[:controller]) - assert_equal("index", request.path_parameters[:action]) - ensure - Object.send(:remove_const, :Api) - end + def test_generate_finds_best_fit + set.draw do |map| + map.connect "/people", :controller => "people", :action => "index" + map.connect "/ws/people", :controller => "people", :action => "index", :ws => true + end - def test_generate_finds_best_fit - set.draw do |map| - map.connect "/people", :controller => "people", :action => "index" - map.connect "/ws/people", :controller => "people", :action => "index", :ws => true + url = set.generate(:controller => "people", :action => "index", :ws => true) + assert_equal "/ws/people", url end - url = set.generate(:controller => "people", :action => "index", :ws => true) - assert_equal "/ws/people", url - end + def test_generate_changes_controller_module + set.draw { |map| map.connect ':controller/:action/:id' } + current = { :controller => "bling/bloop", :action => "bap", :id => 9 } + url = set.generate({:controller => "foo/bar", :action => "baz", :id => 7}, current) + assert_equal "/foo/bar/baz/7", url + end - def test_generate_changes_controller_module - set.draw { |map| map.connect ':controller/:action/:id' } - current = { :controller => "bling/bloop", :action => "bap", :id => 9 } - url = set.generate({:controller => "foo/bar", :action => "baz", :id => 7}, current) - assert_equal "/foo/bar/baz/7", url - end + def test_id_is_not_impossibly_sticky + set.draw do |map| + map.connect 'foo/:number', :controller => "people", :action => "index" + map.connect ':controller/:action/:id' + end - def test_id_is_not_impossibly_sticky - set.draw do |map| - map.connect 'foo/:number', :controller => "people", :action => "index" - map.connect ':controller/:action/:id' + url = set.generate({:controller => "people", :action => "index", :number => 3}, + {:controller => "people", :action => "index", :id => "21"}) + assert_equal "/foo/3", url end - url = set.generate({:controller => "people", :action => "index", :number => 3}, - {:controller => "people", :action => "index", :id => "21"}) - assert_equal "/foo/3", url - end + def test_id_is_sticky_when_it_ought_to_be + set.draw do |map| + map.connect ':controller/:id/:action' + end - def test_id_is_sticky_when_it_ought_to_be - set.draw do |map| - map.connect ':controller/:id/:action' + url = set.generate({:action => "destroy"}, {:controller => "people", :action => "show", :id => "7"}) + assert_equal "/people/7/destroy", url end - url = set.generate({:action => "destroy"}, {:controller => "people", :action => "show", :id => "7"}) - assert_equal "/people/7/destroy", url - end + def test_use_static_path_when_possible + set.draw do |map| + map.connect 'about', :controller => "welcome", :action => "about" + map.connect ':controller/:action/:id' + end - def test_use_static_path_when_possible - set.draw do |map| - map.connect 'about', :controller => "welcome", :action => "about" - map.connect ':controller/:action/:id' + url = set.generate({:controller => "welcome", :action => "about"}, + {:controller => "welcome", :action => "get", :id => "7"}) + assert_equal "/about", url end - url = set.generate({:controller => "welcome", :action => "about"}, - {:controller => "welcome", :action => "get", :id => "7"}) - assert_equal "/about", url - end + def test_generate + set.draw { |map| map.connect ':controller/:action/:id' } - def test_generate - set.draw { |map| map.connect ':controller/:action/:id' } + args = { :controller => "foo", :action => "bar", :id => "7", :x => "y" } + assert_equal "/foo/bar/7?x=y", set.generate(args) + assert_equal ["/foo/bar/7", [:x]], set.generate_extras(args) + assert_equal [:x], set.extra_keys(args) + end - args = { :controller => "foo", :action => "bar", :id => "7", :x => "y" } - assert_equal "/foo/bar/7?x=y", set.generate(args) - assert_equal ["/foo/bar/7", [:x]], set.generate_extras(args) - assert_equal [:x], set.extra_keys(args) - end + def test_named_routes_are_never_relative_to_modules + set.draw do |map| + map.connect "/connection/manage/:action", :controller => 'connection/manage' + map.connect "/connection/connection", :controller => "connection/connection" + map.family_connection "/connection", :controller => "connection" + end - def test_named_routes_are_never_relative_to_modules - set.draw do |map| - map.connect "/connection/manage/:action", :controller => 'connection/manage' - map.connect "/connection/connection", :controller => "connection/connection" - map.family_connection "/connection", :controller => "connection" - end + url = set.generate({:controller => "connection"}, {:controller => 'connection/manage'}) + assert_equal "/connection/connection", url - url = set.generate({:controller => "connection"}, {:controller => 'connection/manage'}) - assert_equal "/connection/connection", url + url = set.generate({:use_route => :family_connection, :controller => "connection"}, {:controller => 'connection/manage'}) + assert_equal "/connection", url + end - url = set.generate({:use_route => :family_connection, :controller => "connection"}, {:controller => 'connection/manage'}) - assert_equal "/connection", url - end - - def test_action_left_off_when_id_is_recalled - set.draw do |map| - map.connect ':controller/:action/:id' + def test_action_left_off_when_id_is_recalled + set.draw do |map| + map.connect ':controller/:action/:id' + end + assert_equal '/post', set.generate( + {:controller => 'post', :action => 'index'}, + {:controller => 'post', :action => 'show', :id => '10'} + ) end - assert_equal '/post', set.generate( - {:controller => 'post', :action => 'index'}, - {:controller => 'post', :action => 'show', :id => '10'} - ) - end - - def test_query_params_will_be_shown_when_recalled - set.draw do |map| - map.connect 'show_post/:parameter', :controller => 'post', :action => 'show' - map.connect ':controller/:action/:id' + + def test_query_params_will_be_shown_when_recalled + set.draw do |map| + map.connect 'show_post/:parameter', :controller => 'post', :action => 'show' + map.connect ':controller/:action/:id' + end + assert_equal '/post/edit?parameter=1', set.generate( + {:action => 'edit', :parameter => 1}, + {:controller => 'post', :action => 'show', :parameter => 1} + ) end - assert_equal '/post/edit?parameter=1', set.generate( - {:action => 'edit', :parameter => 1}, - {:controller => 'post', :action => 'show', :parameter => 1} - ) - end - def test_expiry_determination_should_consider_values_with_to_param - set.draw { |map| map.connect 'projects/:project_id/:controller/:action' } - assert_equal '/projects/1/post/show', set.generate( - {:action => 'show', :project_id => 1}, - {:controller => 'post', :action => 'show', :project_id => '1'}) - end + def test_expiry_determination_should_consider_values_with_to_param + set.draw { |map| map.connect 'projects/:project_id/:controller/:action' } + assert_equal '/projects/1/post/show', set.generate( + {:action => 'show', :project_id => 1}, + {:controller => 'post', :action => 'show', :project_id => '1'}) + end - def test_generate_all - set.draw do |map| - map.connect 'show_post/:id', :controller => 'post', :action => 'show' - map.connect ':controller/:action/:id' + def test_generate_all + set.draw do |map| + map.connect 'show_post/:id', :controller => 'post', :action => 'show' + map.connect ':controller/:action/:id' + end + all = set.generate( + {:action => 'show', :id => 10, :generate_all => true}, + {:controller => 'post', :action => 'show'} + ) + assert_equal 2, all.length + assert_equal '/show_post/10', all.first + assert_equal '/post/show/10', all.last end - all = set.generate( - {:action => 'show', :id => 10, :generate_all => true}, - {:controller => 'post', :action => 'show'} - ) - assert_equal 2, all.length - assert_equal '/show_post/10', all.first - assert_equal '/post/show/10', all.last - end - - def test_named_route_in_nested_resource - set.draw do |map| - map.resources :projects do |project| - project.milestones 'milestones', :controller => 'milestones', :action => 'index' - end - end - - request.path = "/projects/1/milestones" - request.method = :get - assert_nothing_raised { set.recognize(request) } - assert_equal("milestones", request.path_parameters[:controller]) - assert_equal("index", request.path_parameters[:action]) - end - - def test_setting_root_in_namespace_using_symbol - assert_nothing_raised do + + def test_named_route_in_nested_resource set.draw do |map| - map.namespace :admin do |admin| - admin.root :controller => 'home' + map.resources :projects do |project| + project.milestones 'milestones', :controller => 'milestones', :action => 'index' end end + + request.path = "/projects/1/milestones" + request.method = :get + assert_nothing_raised { set.recognize(request) } + assert_equal("milestones", request.path_parameters[:controller]) + assert_equal("index", request.path_parameters[:action]) end - end - - def test_setting_root_in_namespace_using_string - assert_nothing_raised do - set.draw do |map| - map.namespace 'admin' do |admin| - admin.root :controller => 'home' + + def test_setting_root_in_namespace_using_symbol + assert_nothing_raised do + set.draw do |map| + map.namespace :admin do |admin| + admin.root :controller => 'home' + end end end end - end - def test_route_requirements_with_unsupported_regexp_options_must_error - assert_raises ArgumentError do + def test_setting_root_in_namespace_using_string + assert_nothing_raised do + set.draw do |map| + map.namespace 'admin' do |admin| + admin.root :controller => 'home' + end + end + end + end + + def test_route_requirements_with_unsupported_regexp_options_must_error + assert_raises ArgumentError do + set.draw do |map| + map.connect 'page/:name', :controller => 'pages', + :action => 'show', + :requirements => {:name => /(david|jamis)/m} + end + end + end + + def test_route_requirements_with_supported_options_must_not_error + assert_nothing_raised do + set.draw do |map| + map.connect 'page/:name', :controller => 'pages', + :action => 'show', + :requirements => {:name => /(david|jamis)/i} + end + end + assert_nothing_raised do + set.draw do |map| + map.connect 'page/:name', :controller => 'pages', + :action => 'show', + :requirements => {:name => / # Desperately overcommented regexp + ( #Either + david #The Creator + | #Or + jamis #The Deployer + )/x} + end + end + end + + def test_route_requirement_recognize_with_ignore_case set.draw do |map| map.connect 'page/:name', :controller => 'pages', :action => 'show', - :requirements => {:name => /(david|jamis)/m} + :requirements => {:name => /(david|jamis)/i} + end + assert_equal({:controller => 'pages', :action => 'show', :name => 'jamis'}, set.recognize_path('/page/jamis')) + assert_raises ActionController::RoutingError do + set.recognize_path('/page/davidjamis') end + assert_equal({:controller => 'pages', :action => 'show', :name => 'DAVID'}, set.recognize_path('/page/DAVID')) end - end - def test_route_requirements_with_supported_options_must_not_error - assert_nothing_raised do + def test_route_requirement_generate_with_ignore_case set.draw do |map| map.connect 'page/:name', :controller => 'pages', :action => 'show', :requirements => {:name => /(david|jamis)/i} end + url = set.generate({:controller => 'pages', :action => 'show', :name => 'david'}) + assert_equal "/page/david", url + assert_raises ActionController::RoutingError do + url = set.generate({:controller => 'pages', :action => 'show', :name => 'davidjamis'}) + end + url = set.generate({:controller => 'pages', :action => 'show', :name => 'JAMIS'}) + assert_equal "/page/JAMIS", url end - assert_nothing_raised do + + def test_route_requirement_recognize_with_extended_syntax set.draw do |map| map.connect 'page/:name', :controller => 'pages', :action => 'show', @@ -2159,194 +2257,68 @@ class RouteSetTest < Test::Unit::TestCase jamis #The Deployer )/x} end + assert_equal({:controller => 'pages', :action => 'show', :name => 'jamis'}, set.recognize_path('/page/jamis')) + assert_equal({:controller => 'pages', :action => 'show', :name => 'david'}, set.recognize_path('/page/david')) + assert_raises ActionController::RoutingError do + set.recognize_path('/page/david #The Creator') + end + assert_raises ActionController::RoutingError do + set.recognize_path('/page/David') + end end - end - - def test_route_requirement_recognize_with_ignore_case - set.draw do |map| - map.connect 'page/:name', :controller => 'pages', - :action => 'show', - :requirements => {:name => /(david|jamis)/i} - end - assert_equal({:controller => 'pages', :action => 'show', :name => 'jamis'}, set.recognize_path('/page/jamis')) - assert_raises ActionController::RoutingError do - set.recognize_path('/page/davidjamis') - end - assert_equal({:controller => 'pages', :action => 'show', :name => 'DAVID'}, set.recognize_path('/page/DAVID')) - end - - def test_route_requirement_generate_with_ignore_case - set.draw do |map| - map.connect 'page/:name', :controller => 'pages', - :action => 'show', - :requirements => {:name => /(david|jamis)/i} - end - url = set.generate({:controller => 'pages', :action => 'show', :name => 'david'}) - assert_equal "/page/david", url - assert_raises ActionController::RoutingError do - url = set.generate({:controller => 'pages', :action => 'show', :name => 'davidjamis'}) - end - url = set.generate({:controller => 'pages', :action => 'show', :name => 'JAMIS'}) - assert_equal "/page/JAMIS", url - end - def test_route_requirement_recognize_with_extended_syntax - set.draw do |map| - map.connect 'page/:name', :controller => 'pages', - :action => 'show', - :requirements => {:name => / # Desperately overcommented regexp - ( #Either - david #The Creator - | #Or - jamis #The Deployer - )/x} - end - assert_equal({:controller => 'pages', :action => 'show', :name => 'jamis'}, set.recognize_path('/page/jamis')) - assert_equal({:controller => 'pages', :action => 'show', :name => 'david'}, set.recognize_path('/page/david')) - assert_raises ActionController::RoutingError do - set.recognize_path('/page/david #The Creator') - end - assert_raises ActionController::RoutingError do - set.recognize_path('/page/David') + def test_route_requirement_generate_with_extended_syntax + set.draw do |map| + map.connect 'page/:name', :controller => 'pages', + :action => 'show', + :requirements => {:name => / # Desperately overcommented regexp + ( #Either + david #The Creator + | #Or + jamis #The Deployer + )/x} + end + url = set.generate({:controller => 'pages', :action => 'show', :name => 'david'}) + assert_equal "/page/david", url + assert_raises ActionController::RoutingError do + url = set.generate({:controller => 'pages', :action => 'show', :name => 'davidjamis'}) + end + assert_raises ActionController::RoutingError do + url = set.generate({:controller => 'pages', :action => 'show', :name => 'JAMIS'}) + end end - end - def test_route_requirement_generate_with_extended_syntax - set.draw do |map| - map.connect 'page/:name', :controller => 'pages', - :action => 'show', - :requirements => {:name => / # Desperately overcommented regexp - ( #Either - david #The Creator - | #Or - jamis #The Deployer - )/x} - end - url = set.generate({:controller => 'pages', :action => 'show', :name => 'david'}) - assert_equal "/page/david", url - assert_raises ActionController::RoutingError do - url = set.generate({:controller => 'pages', :action => 'show', :name => 'davidjamis'}) - end - assert_raises ActionController::RoutingError do + def test_route_requirement_generate_with_xi_modifiers + set.draw do |map| + map.connect 'page/:name', :controller => 'pages', + :action => 'show', + :requirements => {:name => / # Desperately overcommented regexp + ( #Either + david #The Creator + | #Or + jamis #The Deployer + )/xi} + end url = set.generate({:controller => 'pages', :action => 'show', :name => 'JAMIS'}) - end - end - - def test_route_requirement_generate_with_xi_modifiers - set.draw do |map| - map.connect 'page/:name', :controller => 'pages', - :action => 'show', - :requirements => {:name => / # Desperately overcommented regexp - ( #Either - david #The Creator - | #Or - jamis #The Deployer - )/xi} - end - url = set.generate({:controller => 'pages', :action => 'show', :name => 'JAMIS'}) - assert_equal "/page/JAMIS", url - end - - def test_route_requirement_recognize_with_xi_modifiers - set.draw do |map| - map.connect 'page/:name', :controller => 'pages', - :action => 'show', - :requirements => {:name => / # Desperately overcommented regexp - ( #Either - david #The Creator - | #Or - jamis #The Deployer - )/xi} - end - assert_equal({:controller => 'pages', :action => 'show', :name => 'JAMIS'}, set.recognize_path('/page/JAMIS')) - end - - -end - -class RoutingTest < Test::Unit::TestCase - - def test_possible_controllers - true_controller_paths = ActionController::Routing.controller_paths - - ActionController::Routing.use_controllers! nil - - silence_warnings do - Object.send(:const_set, :RAILS_ROOT, File.dirname(__FILE__) + '/controller_fixtures') + assert_equal "/page/JAMIS", url end - ActionController::Routing.controller_paths = [ - RAILS_ROOT, RAILS_ROOT + '/app/controllers', RAILS_ROOT + '/vendor/plugins/bad_plugin/lib' - ] - - assert_equal ["admin/user", "plugin", "user"], ActionController::Routing.possible_controllers.sort - ensure - if true_controller_paths - ActionController::Routing.controller_paths = true_controller_paths - end - ActionController::Routing.use_controllers! nil - Object.send(:remove_const, :RAILS_ROOT) rescue nil - end - - def test_possible_controllers_are_reset_on_each_load - true_possible_controllers = ActionController::Routing.possible_controllers - true_controller_paths = ActionController::Routing.controller_paths - - ActionController::Routing.use_controllers! nil - root = File.dirname(__FILE__) + '/controller_fixtures' - - ActionController::Routing.controller_paths = [] - assert_equal [], ActionController::Routing.possible_controllers - - ActionController::Routing::Routes.load! - ActionController::Routing.controller_paths = [ - root, root + '/app/controllers', root + '/vendor/plugins/bad_plugin/lib' - ] - - assert_equal ["admin/user", "plugin", "user"], ActionController::Routing.possible_controllers.sort - ensure - ActionController::Routing.controller_paths = true_controller_paths - ActionController::Routing.use_controllers! true_possible_controllers - Object.send(:remove_const, :RAILS_ROOT) rescue nil - - ActionController::Routing::Routes.clear! - ActionController::Routing::Routes.load_routes! - end - - def test_with_controllers - c = %w(admin/accounts admin/users account pages) - ActionController::Routing.with_controllers c do - assert_equal c, ActionController::Routing.possible_controllers + def test_route_requirement_recognize_with_xi_modifiers + set.draw do |map| + map.connect 'page/:name', :controller => 'pages', + :action => 'show', + :requirements => {:name => / # Desperately overcommented regexp + ( #Either + david #The Creator + | #Or + jamis #The Deployer + )/xi} + end + assert_equal({:controller => 'pages', :action => 'show', :name => 'JAMIS'}, set.recognize_path('/page/JAMIS')) end end - def test_normalize_unix_paths - load_paths = %w(. config/../app/controllers config/../app//helpers script/../config/../vendor/rails/actionpack/lib vendor/rails/railties/builtin/rails_info app/models lib script/../config/../foo/bar/../../app/models .foo/../.bar foo.bar/../config) - paths = ActionController::Routing.normalize_paths(load_paths) - assert_equal %w(vendor/rails/railties/builtin/rails_info vendor/rails/actionpack/lib app/controllers app/helpers app/models config .bar lib .), paths - end - - def test_normalize_windows_paths - load_paths = %w(. config\\..\\app\\controllers config\\..\\app\\\\helpers script\\..\\config\\..\\vendor\\rails\\actionpack\\lib vendor\\rails\\railties\\builtin\\rails_info app\\models lib script\\..\\config\\..\\foo\\bar\\..\\..\\app\\models .foo\\..\\.bar foo.bar\\..\\config) - paths = ActionController::Routing.normalize_paths(load_paths) - assert_equal %w(vendor\\rails\\railties\\builtin\\rails_info vendor\\rails\\actionpack\\lib app\\controllers app\\helpers app\\models config .bar lib .), paths - end - - def test_routing_helper_module - assert_kind_of Module, ActionController::Routing::Helpers - - h = ActionController::Routing::Helpers - c = Class.new - assert ! c.ancestors.include?(h) - ActionController::Routing::Routes.install_helpers c - assert c.ancestors.include?(h) - end - -end - -uses_mocha 'route loading' do class RouteLoadingTest < Test::Unit::TestCase - def setup routes.instance_variable_set '@routes_last_modified', nil silence_warnings { Object.const_set :RAILS_ROOT, '.' } @@ -2397,7 +2369,7 @@ uses_mocha 'route loading' do ActiveSupport::Inflector.inflections { |inflect| inflect.uncountable('equipment') } end - + def test_load_with_configuration routes.configuration_file = "foobarbaz" File.expects(:stat).returns(@stat) @@ -2407,9 +2379,8 @@ uses_mocha 'route loading' do end private - def routes - ActionController::Routing::Routes - end - + def routes + ActionController::Routing::Routes + end end end -- cgit v1.2.3 From 56f5c5582c97b60a89ce44f5dfccba0b5aed4357 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Sun, 8 Jun 2008 01:32:57 -0700 Subject: Missed add: deprecated erb_variable test --- actionpack/test/template/deprecated_erb_variable_test.rb | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 actionpack/test/template/deprecated_erb_variable_test.rb (limited to 'actionpack') diff --git a/actionpack/test/template/deprecated_erb_variable_test.rb b/actionpack/test/template/deprecated_erb_variable_test.rb new file mode 100644 index 0000000000..b07c590164 --- /dev/null +++ b/actionpack/test/template/deprecated_erb_variable_test.rb @@ -0,0 +1,9 @@ +require 'abstract_unit' + +class DeprecatedErbVariableTest < ActionView::TestCase + def test_setting_erb_variable_warns + assert_deprecated 'erb_variable' do + ActionView::Base.erb_variable = '_erbout' + end + end +end -- cgit v1.2.3 From b336ce9e062e4de0d20aa359b08e86fe83b6dd89 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Sun, 8 Jun 2008 01:36:33 -0700 Subject: Revert "Missed add: deprecated erb_variable test" This reverts commit 56f5c5582c97b60a89ce44f5dfccba0b5aed4357. --- actionpack/test/template/deprecated_erb_variable_test.rb | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 actionpack/test/template/deprecated_erb_variable_test.rb (limited to 'actionpack') diff --git a/actionpack/test/template/deprecated_erb_variable_test.rb b/actionpack/test/template/deprecated_erb_variable_test.rb deleted file mode 100644 index b07c590164..0000000000 --- a/actionpack/test/template/deprecated_erb_variable_test.rb +++ /dev/null @@ -1,9 +0,0 @@ -require 'abstract_unit' - -class DeprecatedErbVariableTest < ActionView::TestCase - def test_setting_erb_variable_warns - assert_deprecated 'erb_variable' do - ActionView::Base.erb_variable = '_erbout' - end - end -end -- cgit v1.2.3 From 8bf74c30fe276606214850ae2de76fe0efb08d94 Mon Sep 17 00:00:00 2001 From: rick Date: Sun, 8 Jun 2008 22:26:30 -0400 Subject: change some more TimeZone references to ActiveSupport::TimeZone --- actionpack/lib/action_view/helpers/form_options_helper.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb index e0a097e367..90bd99a861 100644 --- a/actionpack/lib/action_view/helpers/form_options_helper.rb +++ b/actionpack/lib/action_view/helpers/form_options_helper.rb @@ -304,7 +304,7 @@ module ActionView # # NOTE: Only the option tags are returned, you have to wrap this call in # a regular HTML select tag. - def time_zone_options_for_select(selected = nil, priority_zones = nil, model = TimeZone) + def time_zone_options_for_select(selected = nil, priority_zones = nil, model = ActiveSupport::TimeZone) zone_options = "" zones = model.all @@ -417,7 +417,7 @@ module ActionView value = value(object) content_tag("select", add_options( - time_zone_options_for_select(value || options[:default], priority_zones, options[:model] || TimeZone), + time_zone_options_for_select(value || options[:default], priority_zones, options[:model] || ActiveSupport::TimeZone), options, value ), html_options ) -- cgit v1.2.3 From ff5f155f8dc1d2ba363718c3e17f99719399eab5 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Sun, 8 Jun 2008 20:05:39 -0700 Subject: Use output_buffer reader and writer methods exclusively instead of hitting the instance variable so others can override the methods. --- .../lib/action_view/helpers/capture_helper.rb | 6 +- .../lib/action_view/helpers/javascript_helper.rb | 5 - actionpack/lib/action_view/helpers/tag_helper.rb | 4 - actionpack/lib/action_view/helpers/text_helper.rb | 4 +- .../action_view/template_handlers/compilable.rb | 2 +- actionpack/lib/action_view/test_case.rb | 5 + actionpack/test/template/date_helper_test.rb | 12 +- actionpack/test/template/form_helper_test.rb | 251 ++++++++------------- .../test/template/form_options_helper_test.rb | 24 +- actionpack/test/template/form_tag_helper_test.rb | 29 ++- actionpack/test/template/javascript_helper_test.rb | 14 +- actionpack/test/template/prototype_helper_test.rb | 20 +- actionpack/test/template/record_tag_helper_test.rb | 9 +- actionpack/test/template/tag_helper_test.rb | 10 +- actionpack/test/template/text_helper_test.rb | 6 +- 15 files changed, 159 insertions(+), 242 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb index 25e62f78fb..ab453fadf2 100644 --- a/actionpack/lib/action_view/helpers/capture_helper.rb +++ b/actionpack/lib/action_view/helpers/capture_helper.rb @@ -31,7 +31,7 @@ module ActionView # # def capture(*args, &block) - if @output_buffer + if output_buffer with_output_buffer { block.call(*args) } else block.call(*args) @@ -121,10 +121,10 @@ module ActionView private def with_output_buffer(buf = '') - @output_buffer, old_buffer = buf, @output_buffer + self.output_buffer, old_buffer = buf, output_buffer yield ensure - @output_buffer = old_buffer + self.output_buffer = old_buffer end end end diff --git a/actionpack/lib/action_view/helpers/javascript_helper.rb b/actionpack/lib/action_view/helpers/javascript_helper.rb index 85b205c264..7404a251e4 100644 --- a/actionpack/lib/action_view/helpers/javascript_helper.rb +++ b/actionpack/lib/action_view/helpers/javascript_helper.rb @@ -202,11 +202,6 @@ module ActionView end js_option end - - private - def block_is_within_action_view?(block) - !@output_buffer.nil? - end end JavascriptHelper = JavaScriptHelper unless const_defined? :JavascriptHelper diff --git a/actionpack/lib/action_view/helpers/tag_helper.rb b/actionpack/lib/action_view/helpers/tag_helper.rb index a8a5987b1f..e1abec1847 100644 --- a/actionpack/lib/action_view/helpers/tag_helper.rb +++ b/actionpack/lib/action_view/helpers/tag_helper.rb @@ -122,10 +122,6 @@ module ActionView " #{attrs.sort * ' '}" unless attrs.empty? end end - - def block_is_within_action_view?(block) - !@output_buffer.nil? - end end end end diff --git a/actionpack/lib/action_view/helpers/text_helper.rb b/actionpack/lib/action_view/helpers/text_helper.rb index f81f7eded6..85a3672678 100644 --- a/actionpack/lib/action_view/helpers/text_helper.rb +++ b/actionpack/lib/action_view/helpers/text_helper.rb @@ -26,8 +26,8 @@ module ActionView # # will either display "Logged in!" or a login link # %> def concat(string) - if @output_buffer && string - @output_buffer << string + if output_buffer && string + output_buffer << string else string end diff --git a/actionpack/lib/action_view/template_handlers/compilable.rb b/actionpack/lib/action_view/template_handlers/compilable.rb index 28c72172a0..1aef81ba1a 100644 --- a/actionpack/lib/action_view/template_handlers/compilable.rb +++ b/actionpack/lib/action_view/template_handlers/compilable.rb @@ -106,7 +106,7 @@ module ActionView locals_code << "#{key} = local_assigns[:#{key}]\n" end - "def #{render_symbol}(local_assigns)\nold_output_buffer = @output_buffer;#{locals_code}#{body}\nensure\n@output_buffer = old_output_buffer\nend" + "def #{render_symbol}(local_assigns)\nold_output_buffer = output_buffer;#{locals_code}#{body}\nensure\nself.output_buffer = old_output_buffer\nend" end # Return true if the given template was compiled for a superset of the keys in local_assigns diff --git a/actionpack/lib/action_view/test_case.rb b/actionpack/lib/action_view/test_case.rb index 16fedd9732..1a3c93c283 100644 --- a/actionpack/lib/action_view/test_case.rb +++ b/actionpack/lib/action_view/test_case.rb @@ -37,6 +37,8 @@ module ActionView if helper_class && !self.class.ancestors.include?(helper_class) self.class.send(:include, helper_class) end + + self.output_buffer = '' end class TestController < ActionController::Base @@ -48,6 +50,9 @@ module ActionView end end + protected + attr_accessor :output_buffer + private def method_missing(selector, *args) controller = TestController.new diff --git a/actionpack/test/template/date_helper_test.rb b/actionpack/test/template/date_helper_test.rb index 3399b03dd2..11b3bdb3fa 100755 --- a/actionpack/test/template/date_helper_test.rb +++ b/actionpack/test/template/date_helper_test.rb @@ -1002,17 +1002,15 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Date.new(2004, 6, 15) - @output_buffer = '' - fields_for :post, @post do |f| - @output_buffer.concat f.date_select(:written_on) + concat f.date_select(:written_on) end expected = "\n" expected << "\n" expected << "\n" - assert_dom_equal(expected, @output_buffer) + assert_dom_equal(expected, output_buffer) end def test_date_select_with_index @@ -1287,10 +1285,8 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.updated_at = Time.local(2004, 6, 15, 16, 35) - @output_buffer = '' - fields_for :post, @post do |f| - @output_buffer.concat f.datetime_select(:updated_at) + concat f.datetime_select(:updated_at) end expected = "\n" @@ -1299,7 +1295,7 @@ class DateHelperTest < ActionView::TestCase expected << " — \n" expected << " : \n" - assert_dom_equal(expected, @output_buffer) + assert_dom_equal(expected, output_buffer) end def test_date_select_with_zero_value_and_no_start_year diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb index 65984fac44..39649c3622 100644 --- a/actionpack/test/template/form_helper_test.rb +++ b/actionpack/test/template/form_helper_test.rb @@ -337,14 +337,12 @@ class FormHelperTest < ActionView::TestCase end def test_form_for - @output_buffer = '' - form_for(:post, @post, :html => { :id => 'create-post' }) do |f| - @output_buffer.concat f.label(:title) - @output_buffer.concat f.text_field(:title) - @output_buffer.concat f.text_area(:body) - @output_buffer.concat f.check_box(:secret) - @output_buffer.concat f.submit('Create post') + concat f.label(:title) + concat f.text_field(:title) + concat f.text_area(:body) + concat f.check_box(:secret) + concat f.submit('Create post') end expected = @@ -357,16 +355,14 @@ class FormHelperTest < ActionView::TestCase "" + "" - assert_dom_equal expected, @output_buffer + assert_dom_equal expected, output_buffer end def test_form_for_with_method - @output_buffer = '' - form_for(:post, @post, :html => { :id => 'create-post', :method => :put }) do |f| - @output_buffer.concat f.text_field(:title) - @output_buffer.concat f.text_area(:body) - @output_buffer.concat f.check_box(:secret) + concat f.text_field(:title) + concat f.text_area(:body) + concat f.check_box(:secret) end expected = @@ -378,16 +374,14 @@ class FormHelperTest < ActionView::TestCase "" + "" - assert_dom_equal expected, @output_buffer + assert_dom_equal expected, output_buffer end def test_form_for_without_object - @output_buffer = '' - form_for(:post, :html => { :id => 'create-post' }) do |f| - @output_buffer.concat f.text_field(:title) - @output_buffer.concat f.text_area(:body) - @output_buffer.concat f.check_box(:secret) + concat f.text_field(:title) + concat f.text_area(:body) + concat f.check_box(:secret) end expected = @@ -398,17 +392,15 @@ class FormHelperTest < ActionView::TestCase "" + "" - assert_dom_equal expected, @output_buffer + assert_dom_equal expected, output_buffer end def test_form_for_with_index - @output_buffer = '' - form_for("post[]", @post) do |f| - @output_buffer.concat f.label(:title) - @output_buffer.concat f.text_field(:title) - @output_buffer.concat f.text_area(:body) - @output_buffer.concat f.check_box(:secret) + concat f.label(:title) + concat f.text_field(:title) + concat f.text_area(:body) + concat f.check_box(:secret) end expected = @@ -420,16 +412,14 @@ class FormHelperTest < ActionView::TestCase "" + "" - assert_dom_equal expected, @output_buffer + assert_dom_equal expected, output_buffer end def test_form_for_with_nil_index_option_override - @output_buffer = '' - form_for("post[]", @post, :index => nil) do |f| - @output_buffer.concat f.text_field(:title) - @output_buffer.concat f.text_area(:body) - @output_buffer.concat f.check_box(:secret) + concat f.text_field(:title) + concat f.text_area(:body) + concat f.check_box(:secret) end expected = @@ -440,14 +430,13 @@ class FormHelperTest < ActionView::TestCase "" + "" - assert_dom_equal expected, @output_buffer + assert_dom_equal expected, output_buffer end def test_nested_fields_for - @output_buffer = '' form_for(:post, @post) do |f| f.fields_for(:comment, @post) do |c| - @output_buffer.concat c.text_field(:title) + concat c.text_field(:title) end end @@ -455,16 +444,14 @@ class FormHelperTest < ActionView::TestCase "" + "" - assert_dom_equal expected, @output_buffer + assert_dom_equal expected, output_buffer end def test_fields_for - @output_buffer = '' - fields_for(:post, @post) do |f| - @output_buffer.concat f.text_field(:title) - @output_buffer.concat f.text_area(:body) - @output_buffer.concat f.check_box(:secret) + concat f.text_field(:title) + concat f.text_area(:body) + concat f.check_box(:secret) end expected = @@ -473,16 +460,14 @@ class FormHelperTest < ActionView::TestCase "" + "" - assert_dom_equal expected, @output_buffer + assert_dom_equal expected, output_buffer end def test_fields_for_with_index - @output_buffer = '' - fields_for("post[]", @post) do |f| - @output_buffer.concat f.text_field(:title) - @output_buffer.concat f.text_area(:body) - @output_buffer.concat f.check_box(:secret) + concat f.text_field(:title) + concat f.text_area(:body) + concat f.check_box(:secret) end expected = @@ -491,16 +476,14 @@ class FormHelperTest < ActionView::TestCase "" + "" - assert_dom_equal expected, @output_buffer + assert_dom_equal expected, output_buffer end def test_fields_for_with_nil_index_option_override - @output_buffer = '' - fields_for("post[]", @post, :index => nil) do |f| - @output_buffer.concat f.text_field(:title) - @output_buffer.concat f.text_area(:body) - @output_buffer.concat f.check_box(:secret) + concat f.text_field(:title) + concat f.text_area(:body) + concat f.check_box(:secret) end expected = @@ -509,16 +492,14 @@ class FormHelperTest < ActionView::TestCase "" + "" - assert_dom_equal expected, @output_buffer + assert_dom_equal expected, output_buffer end def test_fields_for_with_index_option_override - @output_buffer = '' - fields_for("post[]", @post, :index => "abc") do |f| - @output_buffer.concat f.text_field(:title) - @output_buffer.concat f.text_area(:body) - @output_buffer.concat f.check_box(:secret) + concat f.text_field(:title) + concat f.text_area(:body) + concat f.check_box(:secret) end expected = @@ -527,15 +508,14 @@ class FormHelperTest < ActionView::TestCase "" + "" - assert_dom_equal expected, @output_buffer + assert_dom_equal expected, output_buffer end def test_fields_for_without_object - @output_buffer = '' fields_for(:post) do |f| - @output_buffer.concat f.text_field(:title) - @output_buffer.concat f.text_area(:body) - @output_buffer.concat f.check_box(:secret) + concat f.text_field(:title) + concat f.text_area(:body) + concat f.check_box(:secret) end expected = @@ -544,15 +524,14 @@ class FormHelperTest < ActionView::TestCase "" + "" - assert_dom_equal expected, @output_buffer + assert_dom_equal expected, output_buffer end def test_fields_for_with_only_object - @output_buffer = '' fields_for(@post) do |f| - @output_buffer.concat f.text_field(:title) - @output_buffer.concat f.text_area(:body) - @output_buffer.concat f.check_box(:secret) + concat f.text_field(:title) + concat f.text_area(:body) + concat f.check_box(:secret) end expected = @@ -561,31 +540,29 @@ class FormHelperTest < ActionView::TestCase "" + "" - assert_dom_equal expected, @output_buffer + assert_dom_equal expected, output_buffer end def test_fields_for_object_with_bracketed_name - @output_buffer = '' fields_for("author[post]", @post) do |f| - @output_buffer.concat f.label(:title) - @output_buffer.concat f.text_field(:title) + concat f.label(:title) + concat f.text_field(:title) end assert_dom_equal "" + "", - @output_buffer + output_buffer end def test_fields_for_object_with_bracketed_name_and_index - @output_buffer = '' fields_for("author[post]", @post, :index => 1) do |f| - @output_buffer.concat f.label(:title) - @output_buffer.concat f.text_field(:title) + concat f.label(:title) + concat f.text_field(:title) end assert_dom_equal "" + "", - @output_buffer + output_buffer end def test_form_builder_does_not_have_form_for_method @@ -593,14 +570,12 @@ class FormHelperTest < ActionView::TestCase end def test_form_for_and_fields_for - @output_buffer = '' - form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form| - @output_buffer.concat post_form.text_field(:title) - @output_buffer.concat post_form.text_area(:body) + concat post_form.text_field(:title) + concat post_form.text_area(:body) fields_for(:parent_post, @post) do |parent_fields| - @output_buffer.concat parent_fields.check_box(:secret) + concat parent_fields.check_box(:secret) end end @@ -612,18 +587,16 @@ class FormHelperTest < ActionView::TestCase "" + "" - assert_dom_equal expected, @output_buffer + assert_dom_equal expected, output_buffer end def test_form_for_and_fields_for_with_object - @output_buffer = '' - form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form| - @output_buffer.concat post_form.text_field(:title) - @output_buffer.concat post_form.text_area(:body) + concat post_form.text_field(:title) + concat post_form.text_area(:body) post_form.fields_for(@comment) do |comment_fields| - @output_buffer.concat comment_fields.text_field(:name) + concat comment_fields.text_field(:name) end end @@ -634,7 +607,7 @@ class FormHelperTest < ActionView::TestCase "" + "" - assert_dom_equal expected, @output_buffer + assert_dom_equal expected, output_buffer end class LabelledFormBuilder < ActionView::Helpers::FormBuilder @@ -649,12 +622,10 @@ class FormHelperTest < ActionView::TestCase end def test_form_for_with_labelled_builder - @output_buffer = '' - form_for(:post, @post, :builder => LabelledFormBuilder) do |f| - @output_buffer.concat f.text_field(:title) - @output_buffer.concat f.text_area(:body) - @output_buffer.concat f.check_box(:secret) + concat f.text_field(:title) + concat f.text_area(:body) + concat f.check_box(:secret) end expected = @@ -665,18 +636,17 @@ class FormHelperTest < ActionView::TestCase "
      " + "" - assert_dom_equal expected, @output_buffer + assert_dom_equal expected, output_buffer end def test_default_form_builder old_default_form_builder, ActionView::Base.default_form_builder = ActionView::Base.default_form_builder, LabelledFormBuilder - @output_buffer = '' form_for(:post, @post) do |f| - @output_buffer.concat f.text_field(:title) - @output_buffer.concat f.text_area(:body) - @output_buffer.concat f.check_box(:secret) + concat f.text_field(:title) + concat f.text_area(:body) + concat f.check_box(:secret) end expected = @@ -687,17 +657,15 @@ class FormHelperTest < ActionView::TestCase "
      " + "" - assert_dom_equal expected, @output_buffer + assert_dom_equal expected, output_buffer ensure ActionView::Base.default_form_builder = old_default_form_builder end def test_default_form_builder_with_active_record_helpers - - @output_buffer = '' form_for(:post, @post) do |f| - @output_buffer.concat f.error_message_on('author_name') - @output_buffer.concat f.error_messages + concat f.error_message_on('author_name') + concat f.error_messages end expected = %(
      ) + @@ -705,7 +673,7 @@ class FormHelperTest < ActionView::TestCase %(

      1 error prohibited this post from being saved

      There were problems with the following fields:

      • Author name can't be empty
      ) + %(
      ) - assert_dom_equal expected, @output_buffer + assert_dom_equal expected, output_buffer end @@ -713,10 +681,9 @@ class FormHelperTest < ActionView::TestCase post = @post @post = nil - @output_buffer = '' form_for(:post, post) do |f| - @output_buffer.concat f.error_message_on('author_name') - @output_buffer.concat f.error_messages + concat f.error_message_on('author_name') + concat f.error_messages end expected = %(
      ) + @@ -724,19 +691,18 @@ class FormHelperTest < ActionView::TestCase %(

      1 error prohibited this post from being saved

      There were problems with the following fields:

      • Author name can't be empty
      ) + %(
      ) - assert_dom_equal expected, @output_buffer + assert_dom_equal expected, output_buffer end # Perhaps this test should be moved to prototype helper tests. def test_remote_form_for_with_labelled_builder self.extend ActionView::Helpers::PrototypeHelper - @output_buffer = '' remote_form_for(:post, @post, :builder => LabelledFormBuilder) do |f| - @output_buffer.concat f.text_field(:title) - @output_buffer.concat f.text_area(:body) - @output_buffer.concat f.check_box(:secret) + concat f.text_field(:title) + concat f.text_area(:body) + concat f.check_box(:secret) end expected = @@ -747,16 +713,14 @@ class FormHelperTest < ActionView::TestCase "
      " + "" - assert_dom_equal expected, @output_buffer + assert_dom_equal expected, output_buffer end def test_fields_for_with_labelled_builder - @output_buffer = '' - fields_for(:post, @post, :builder => LabelledFormBuilder) do |f| - @output_buffer.concat f.text_field(:title) - @output_buffer.concat f.text_area(:body) - @output_buffer.concat f.check_box(:secret) + concat f.text_field(:title) + concat f.text_area(:body) + concat f.check_box(:secret) end expected = @@ -765,29 +729,23 @@ class FormHelperTest < ActionView::TestCase " " + "
      " - assert_dom_equal expected, @output_buffer + assert_dom_equal expected, output_buffer end def test_form_for_with_html_options_adds_options_to_form_tag - @output_buffer = '' - form_for(:post, @post, :html => {:id => 'some_form', :class => 'some_class'}) do |f| end expected = "
      " - assert_dom_equal expected, @output_buffer + assert_dom_equal expected, output_buffer end def test_form_for_with_string_url_option - @output_buffer = '' - form_for(:post, @post, :url => 'http://www.otherdomain.com') do |f| end - assert_equal '
      ', @output_buffer + assert_equal '
      ', output_buffer end def test_form_for_with_hash_url_option - @output_buffer = '' - form_for(:post, @post, :url => {:controller => 'controller', :action => 'action'}) do |f| end assert_equal 'controller', @controller.url_for_options[:controller] @@ -795,26 +753,20 @@ class FormHelperTest < ActionView::TestCase end def test_form_for_with_record_url_option - @output_buffer = '' - form_for(:post, @post, :url => @post) do |f| end expected = "
      " - assert_equal expected, @output_buffer + assert_equal expected, output_buffer end def test_form_for_with_existing_object - @output_buffer = '' - form_for(@post) do |f| end expected = "
      " - assert_equal expected, @output_buffer + assert_equal expected, output_buffer end def test_form_for_with_new_object - @output_buffer = '' - post = Post.new post.new_record = true def post.id() nil end @@ -822,64 +774,61 @@ class FormHelperTest < ActionView::TestCase form_for(post) do |f| end expected = "
      " - assert_equal expected, @output_buffer + assert_equal expected, output_buffer end def test_form_for_with_existing_object_in_list @post.new_record = false @comment.save - @output_buffer = '' + form_for([@post, @comment]) {} expected = %(
      ) - assert_dom_equal expected, @output_buffer + assert_dom_equal expected, output_buffer end def test_form_for_with_new_object_in_list @post.new_record = false - @output_buffer = '' + form_for([@post, @comment]) {} expected = %(
      ) - assert_dom_equal expected, @output_buffer + assert_dom_equal expected, output_buffer end def test_form_for_with_existing_object_and_namespace_in_list @post.new_record = false @comment.save - @output_buffer = '' + form_for([:admin, @post, @comment]) {} expected = %(
      ) - assert_dom_equal expected, @output_buffer + assert_dom_equal expected, output_buffer end def test_form_for_with_new_object_and_namespace_in_list @post.new_record = false - @output_buffer = '' + form_for([:admin, @post, @comment]) {} expected = %(
      ) - assert_dom_equal expected, @output_buffer + assert_dom_equal expected, output_buffer end def test_form_for_with_existing_object_and_custom_url - @output_buffer = '' - form_for(@post, :url => "/super_posts") do |f| end expected = "
      " - assert_equal expected, @output_buffer + assert_equal expected, output_buffer end def test_remote_form_for_with_html_options_adds_options_to_form_tag self.extend ActionView::Helpers::PrototypeHelper - @output_buffer = '' remote_form_for(:post, @post, :html => {:id => 'some_form', :class => 'some_class'}) do |f| end expected = "
      " - assert_dom_equal expected, @output_buffer + assert_dom_equal expected, output_buffer end diff --git a/actionpack/test/template/form_options_helper_test.rb b/actionpack/test/template/form_options_helper_test.rb index 3c9fb297c3..4fb2be9d3f 100644 --- a/actionpack/test/template/form_options_helper_test.rb +++ b/actionpack/test/template/form_options_helper_test.rb @@ -230,16 +230,14 @@ class FormOptionsHelperTest < ActionView::TestCase def test_select_under_fields_for @post = Post.new @post.category = "" - - @output_buffer = '' - + fields_for :post, @post do |f| - @output_buffer.concat f.select(:category, %w( abe hest)) + concat f.select(:category, %w( abe hest)) end assert_dom_equal( "", - @output_buffer + output_buffer ) end @@ -352,16 +350,14 @@ class FormOptionsHelperTest < ActionView::TestCase @post = Post.new @post.author_name = "Babe" - - @output_buffer = '' - + fields_for :post, @post do |f| - @output_buffer.concat f.collection_select(:author_name, @posts, :author_name, :author_name) + concat f.collection_select(:author_name, @posts, :author_name, :author_name) end assert_dom_equal( "", - @output_buffer + output_buffer ) end @@ -1194,11 +1190,9 @@ COUNTRIES def test_time_zone_select_under_fields_for @firm = Firm.new("D") - - @output_buffer = '' - + fields_for :firm, @firm do |f| - @output_buffer.concat f.time_zone_select(:time_zone) + concat f.time_zone_select(:time_zone) end assert_dom_equal( @@ -1209,7 +1203,7 @@ COUNTRIES "\n" + "" + "", - @output_buffer + output_buffer ) end diff --git a/actionpack/test/template/form_tag_helper_test.rb b/actionpack/test/template/form_tag_helper_test.rb index b281db18bd..47b3605849 100644 --- a/actionpack/test/template/form_tag_helper_test.rb +++ b/actionpack/test/template/form_tag_helper_test.rb @@ -43,19 +43,17 @@ class FormTagHelperTest < ActionView::TestCase end def test_form_tag_with_block - @output_buffer = '' - form_tag("http://example.com") { @output_buffer.concat "Hello world!" } + form_tag("http://example.com") { concat "Hello world!" } expected = %(
      Hello world!
      ) - assert_dom_equal expected, @output_buffer + assert_dom_equal expected, output_buffer end def test_form_tag_with_block_and_method - @output_buffer = '' - form_tag("http://example.com", :method => :put) { @output_buffer.concat "Hello world!" } + form_tag("http://example.com", :method => :put) { concat "Hello world!" } expected = %(
      Hello world!
      ) - assert_dom_equal expected, @output_buffer + assert_dom_equal expected, output_buffer end def test_hidden_field_tag @@ -234,23 +232,22 @@ class FormTagHelperTest < ActionView::TestCase end def test_field_set_tag - @output_buffer = '' - field_set_tag("Your details") { @output_buffer.concat "Hello world!" } + field_set_tag("Your details") { concat "Hello world!" } expected = %(
      Your detailsHello world!
      ) - assert_dom_equal expected, @output_buffer + assert_dom_equal expected, output_buffer - @output_buffer = '' - field_set_tag { @output_buffer.concat "Hello world!" } + self.output_buffer = '' + field_set_tag { concat "Hello world!" } expected = %(
      Hello world!
      ) - assert_dom_equal expected, @output_buffer - - @output_buffer = '' - field_set_tag('') { @output_buffer.concat "Hello world!" } + assert_dom_equal expected, output_buffer + + self.output_buffer = '' + field_set_tag('') { concat "Hello world!" } expected = %(
      Hello world!
      ) - assert_dom_equal expected, @output_buffer + assert_dom_equal expected, output_buffer end def protect_against_forgery? diff --git a/actionpack/test/template/javascript_helper_test.rb b/actionpack/test/template/javascript_helper_test.rb index 4924074c3e..8c649ea544 100644 --- a/actionpack/test/template/javascript_helper_test.rb +++ b/actionpack/test/template/javascript_helper_test.rb @@ -82,12 +82,12 @@ class JavaScriptHelperTest < ActionView::TestCase end def test_javascript_tag - @output_buffer = 'foo' + self.output_buffer = 'foo' assert_dom_equal "", javascript_tag("alert('hello')") - assert_equal 'foo', @output_buffer, 'javascript_tag without a block should not concat to @output_buffer' + assert_equal 'foo', output_buffer, 'javascript_tag without a block should not concat to output_buffer' end def test_javascript_tag_with_options @@ -96,15 +96,13 @@ class JavaScriptHelperTest < ActionView::TestCase end def test_javascript_tag_with_block - @output_buffer = '' - javascript_tag { @output_buffer.concat "alert('hello')" } - assert_dom_equal "", @output_buffer + javascript_tag { concat "alert('hello')" } + assert_dom_equal "", output_buffer end def test_javascript_tag_with_block_and_options - @output_buffer = '' - javascript_tag(:id => "the_js_tag") { @output_buffer.concat "alert('hello')" } - assert_dom_equal "", @output_buffer + javascript_tag(:id => "the_js_tag") { concat "alert('hello')" } + assert_dom_equal "", output_buffer end def test_javascript_cdata_section diff --git a/actionpack/test/template/prototype_helper_test.rb b/actionpack/test/template/prototype_helper_test.rb index 3f5ec07214..a5be0d2789 100644 --- a/actionpack/test/template/prototype_helper_test.rb +++ b/actionpack/test/template/prototype_helper_test.rb @@ -118,52 +118,46 @@ class PrototypeHelperTest < PrototypeHelperBaseTest end def test_form_remote_tag_with_block - @output_buffer = '' - form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }) { @output_buffer.concat "Hello world!" } - assert_dom_equal %(
      Hello world!
      ), @output_buffer + form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }) { concat "Hello world!" } + assert_dom_equal %(
      Hello world!
      ), output_buffer end def test_remote_form_for_with_record_identification_with_new_record - @output_buffer = '' remote_form_for(@record, {:html => { :id => 'create-author' }}) {} expected = %(
      ) - assert_dom_equal expected, @output_buffer + assert_dom_equal expected, output_buffer end def test_remote_form_for_with_record_identification_without_html_options - @output_buffer = '' remote_form_for(@record) {} expected = %(
      ) - assert_dom_equal expected, @output_buffer + assert_dom_equal expected, output_buffer end def test_remote_form_for_with_record_identification_with_existing_record @record.save - @output_buffer = '' remote_form_for(@record) {} expected = %(
      ) - assert_dom_equal expected, @output_buffer + assert_dom_equal expected, output_buffer end def test_remote_form_for_with_new_object_in_list - @output_buffer = '' remote_form_for([@author, @article]) {} expected = %(
      ) - assert_dom_equal expected, @output_buffer + assert_dom_equal expected, output_buffer end def test_remote_form_for_with_existing_object_in_list @author.save @article.save - @output_buffer = '' remote_form_for([@author, @article]) {} expected = %(
      ) - assert_dom_equal expected, @output_buffer + assert_dom_equal expected, output_buffer end def test_on_callbacks diff --git a/actionpack/test/template/record_tag_helper_test.rb b/actionpack/test/template/record_tag_helper_test.rb index c39e5c69bf..441dc6b720 100644 --- a/actionpack/test/template/record_tag_helper_test.rb +++ b/actionpack/test/template/record_tag_helper_test.rb @@ -17,37 +17,32 @@ class RecordTagHelperTest < ActionView::TestCase end def test_content_tag_for - @output_buffer = '' expected = %(
    • ) actual = content_tag_for(:li, @post, :class => 'bar') { } assert_dom_equal expected, actual end def test_content_tag_for_prefix - @output_buffer = '' expected = %(
        ) actual = content_tag_for(:ul, @post, :archived) { } assert_dom_equal expected, actual end def test_content_tag_for_with_extra_html_tags - @output_buffer = '' expected = %() actual = content_tag_for(:tr, @post, {:class => "bar", :style => "background-color: #f0f0f0"}) { } assert_dom_equal expected, actual end def test_block_works_with_content_tag_for - @output_buffer = '' expected = %(#{@post.body}) - actual = content_tag_for(:tr, @post) { @output_buffer.concat @post.body } + actual = content_tag_for(:tr, @post) { concat @post.body } assert_dom_equal expected, actual end def test_div_for - @output_buffer = '' expected = %(
        #{@post.body}
        ) - actual = div_for(@post, :class => "bar") { @output_buffer.concat @post.body } + actual = div_for(@post, :class => "bar") { concat @post.body } assert_dom_equal expected, actual end diff --git a/actionpack/test/template/tag_helper_test.rb b/actionpack/test/template/tag_helper_test.rb index 7db04d178f..bfdaf0d639 100644 --- a/actionpack/test/template/tag_helper_test.rb +++ b/actionpack/test/template/tag_helper_test.rb @@ -35,15 +35,13 @@ class TagHelperTest < ActionView::TestCase end def test_content_tag_with_block - @output_buffer = '' - content_tag(:div) { @output_buffer.concat "Hello world!" } - assert_dom_equal "
        Hello world!
        ", @output_buffer + content_tag(:div) { concat "Hello world!" } + assert_dom_equal "
        Hello world!
        ", output_buffer end def test_content_tag_with_block_and_options - @output_buffer = '' - content_tag(:div, :class => "green") { @output_buffer.concat "Hello world!" } - assert_dom_equal %(
        Hello world!
        ), @output_buffer + content_tag(:div, :class => "green") { concat "Hello world!" } + assert_dom_equal %(
        Hello world!
        ), output_buffer end def test_content_tag_with_block_and_options_outside_of_action_view diff --git a/actionpack/test/template/text_helper_test.rb b/actionpack/test/template/text_helper_test.rb index 0f5c62acad..cbb5c7ee74 100644 --- a/actionpack/test/template/text_helper_test.rb +++ b/actionpack/test/template/text_helper_test.rb @@ -12,11 +12,11 @@ class TextHelperTest < ActionView::TestCase end def test_concat - @output_buffer = 'foo' + self.output_buffer = 'foo' concat 'bar' - assert_equal 'foobar', @output_buffer + assert_equal 'foobar', output_buffer assert_nothing_raised { concat nil } - assert_equal 'foobar', @output_buffer + assert_equal 'foobar', output_buffer end def test_simple_format -- cgit v1.2.3 From 0c9281e82140f3a69e4473b3bcefd5ccebd79e2d Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Sun, 8 Jun 2008 22:11:08 -0500 Subject: Drop ActionController::Base.allow_concurrency flag --- actionpack/CHANGELOG | 2 ++ actionpack/lib/action_controller/base.rb | 7 ------- 2 files changed, 2 insertions(+), 7 deletions(-) (limited to 'actionpack') diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index 8265b5b04f..3096716dba 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -1,5 +1,7 @@ *Edge* +* Drop ActionController::Base.allow_concurrency flag [Josh Peek] + * More efficient concat and capture helpers. Remove ActionView::Base.erb_variable. [Jeremy Kemper] * Added page.reload functionality. Resolves #277. [Sean Huber] diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index a036600c2b..44269fc735 100755 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -283,13 +283,6 @@ module ActionController #:nodoc: @@debug_routes = true cattr_accessor :debug_routes - # Indicates to Mongrel or Webrick whether to allow concurrent action - # processing. Your controller actions and any other code they call must - # also behave well when called from concurrent threads. Turned off by - # default. - @@allow_concurrency = false - cattr_accessor :allow_concurrency - # Modern REST web services often need to submit complex data to the web application. # The @@param_parsers hash lets you register handlers which will process the HTTP body and add parameters to the # params hash. These handlers are invoked for POST and PUT requests. -- cgit v1.2.3 From df44df945d6315238e7d94d9bdef82e435dc9b24 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Sun, 8 Jun 2008 22:31:54 -0500 Subject: Ensure ActionView::TemplateFinder view cache is rebuilt on initialize. --- actionpack/CHANGELOG | 2 ++ actionpack/lib/action_controller/dispatcher.rb | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index 3096716dba..f9cb715400 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -1,5 +1,7 @@ *Edge* +* Ensure ActionView::TemplateFinder view cache is rebuilt on initialize [Josh Peek] + * Drop ActionController::Base.allow_concurrency flag [Josh Peek] * More efficient concat and capture helpers. Remove ActionView::Base.erb_variable. [Jeremy Kemper] diff --git a/actionpack/lib/action_controller/dispatcher.rb b/actionpack/lib/action_controller/dispatcher.rb index fe4f6b4a7e..64553fb25d 100644 --- a/actionpack/lib/action_controller/dispatcher.rb +++ b/actionpack/lib/action_controller/dispatcher.rb @@ -10,6 +10,10 @@ module ActionController # Development mode callbacks before_dispatch :reload_application after_dispatch :cleanup_application + + to_prepare :reload_view_path_cache do + ActionView::TemplateFinder.reload! unless ActionView::Base.cache_template_loading + end end # Common callbacks @@ -134,7 +138,6 @@ module ActionController run_callbacks :prepare_dispatch Routing::Routes.reload - ActionView::TemplateFinder.reload! unless ActionView::Base.cache_template_loading end # Cleanup the application by clearing out loaded classes so they can -- cgit v1.2.3 From c88f2b5e23b0cb6c1a3b3687958f45d518414041 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Sun, 8 Jun 2008 20:35:14 -0700 Subject: with_output_buffer returns the temporary buffer instead of the result of the block --- actionpack/lib/action_view/helpers/capture_helper.rb | 1 + actionpack/test/template/tag_helper_test.rb | 1 + 2 files changed, 2 insertions(+) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb index ab453fadf2..9cd9d3d06a 100644 --- a/actionpack/lib/action_view/helpers/capture_helper.rb +++ b/actionpack/lib/action_view/helpers/capture_helper.rb @@ -123,6 +123,7 @@ module ActionView def with_output_buffer(buf = '') self.output_buffer, old_buffer = buf, output_buffer yield + output_buffer ensure self.output_buffer = old_buffer end diff --git a/actionpack/test/template/tag_helper_test.rb b/actionpack/test/template/tag_helper_test.rb index bfdaf0d639..2941dfe217 100644 --- a/actionpack/test/template/tag_helper_test.rb +++ b/actionpack/test/template/tag_helper_test.rb @@ -45,6 +45,7 @@ class TagHelperTest < ActionView::TestCase end def test_content_tag_with_block_and_options_outside_of_action_view + self.output_buffer = nil assert_equal content_tag("a", "Create", :href => "create"), content_tag("a", "href" => "create") { "Create" } end -- cgit v1.2.3 From 057768cd2c8541f9c466131cb6c77f13ce12204d Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Sun, 8 Jun 2008 21:21:54 -0700 Subject: Process view paths passed to AV::Base#initialize instead of raising. --- actionpack/lib/action_view/template_finder.rb | 11 +---------- actionpack/test/template/template_finder_test.rb | 6 ------ 2 files changed, 1 insertion(+), 16 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/template_finder.rb b/actionpack/lib/action_view/template_finder.rb index 83b7e27c09..fc2a07b30c 100644 --- a/actionpack/lib/action_view/template_finder.rb +++ b/actionpack/lib/action_view/template_finder.rb @@ -1,14 +1,5 @@ module ActionView #:nodoc: class TemplateFinder #:nodoc: - - class InvalidViewPath < StandardError #:nodoc: - attr_reader :unprocessed_path - def initialize(path) - @unprocessed_path = path - super("Unprocessed view path found: #{@unprocessed_path.inspect}. Set your view paths with #append_view_path, #prepend_view_path, or #view_paths=.") - end - end - cattr_reader :processed_view_paths @@processed_view_paths = Hash.new {|hash, key| hash[key] = []} @@ -76,7 +67,7 @@ module ActionView #:nodoc: @view_paths = args.flatten @view_paths = @view_paths.respond_to?(:find) ? @view_paths.dup : [*@view_paths].compact - check_view_paths(@view_paths) + self.class.process_view_paths(@view_paths) end def prepend_view_path(path) diff --git a/actionpack/test/template/template_finder_test.rb b/actionpack/test/template/template_finder_test.rb index 3d6baff5fb..d6aac87b13 100644 --- a/actionpack/test/template/template_finder_test.rb +++ b/actionpack/test/template/template_finder_test.rb @@ -11,12 +11,6 @@ class TemplateFinderTest < Test::Unit::TestCase @finder = ActionView::TemplateFinder.new(@template, LOAD_PATH_ROOT) end - def test_should_raise_exception_for_unprocessed_view_path - assert_raises ActionView::TemplateFinder::InvalidViewPath do - ActionView::TemplateFinder.new(@template, File.dirname(__FILE__)) - end - end - def test_should_cache_file_extension_properly assert_equal ["builder", "erb", "rhtml", "rjs", "rxml", "mab"].sort, ActionView::TemplateFinder.file_extension_cache[LOAD_PATH_ROOT].values.flatten.uniq.sort -- cgit v1.2.3 From 55791c6c0012d0daea2a75b6a5927f459be25c54 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Mon, 9 Jun 2008 10:05:02 -0500 Subject: Removed used check_view_paths after 057768c --- actionpack/lib/action_view/template_finder.rb | 7 ------- 1 file changed, 7 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/template_finder.rb b/actionpack/lib/action_view/template_finder.rb index fc2a07b30c..cd5e290644 100644 --- a/actionpack/lib/action_view/template_finder.rb +++ b/actionpack/lib/action_view/template_finder.rb @@ -157,12 +157,5 @@ module ActionView #:nodoc: def find_template_extension_from_first_render File.basename(@template.first_render.to_s)[/^[^.]+\.(.+)$/, 1] end - - private - def check_view_paths(view_paths) - view_paths.each do |path| - raise InvalidViewPath.new(path) unless @@processed_view_paths.has_key?(path) - end - end end end -- cgit v1.2.3 From 233643047104131565467787d0bbc0841bbc77cb Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Mon, 9 Jun 2008 10:21:30 -0500 Subject: Removed TemplateFinder.update_extension_cache_for since view path cache will be updated on boot. --- actionpack/lib/action_view/template.rb | 1 - actionpack/lib/action_view/template_finder.rb | 16 +--------------- actionpack/test/template/template_finder_test.rb | 7 ------- 3 files changed, 1 insertion(+), 23 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/template.rb b/actionpack/lib/action_view/template.rb index 369526188f..a878ac66d9 100644 --- a/actionpack/lib/action_view/template.rb +++ b/actionpack/lib/action_view/template.rb @@ -99,7 +99,6 @@ module ActionView #:nodoc: # return the rendered template as a string. def self.register_template_handler(extension, klass) @@template_handlers[extension.to_sym] = klass - TemplateFinder.update_extension_cache_for(extension.to_s) end def self.template_handler_extensions diff --git a/actionpack/lib/action_view/template_finder.rb b/actionpack/lib/action_view/template_finder.rb index cd5e290644..7e9a310810 100644 --- a/actionpack/lib/action_view/template_finder.rb +++ b/actionpack/lib/action_view/template_finder.rb @@ -9,7 +9,6 @@ module ActionView #:nodoc: } class << self #:nodoc: - # This method is not thread safe. Mutex should be used whenever this is accessed from an instance method def process_view_paths(*view_paths) view_paths.flatten.compact.each do |dir| @@ -26,7 +25,7 @@ module ActionView #:nodoc: # Build extension cache extension = file.split(".").last - if template_handler_extensions.include?(extension) + if ActionView::Template.template_handler_extensions.include?(extension) key = file.split(dir).last.sub(/^\//, '').sub(/\.(\w+)$/, '') @@file_extension_cache[dir][key] << extension end @@ -35,19 +34,6 @@ module ActionView #:nodoc: end end - def update_extension_cache_for(extension) - @@processed_view_paths.keys.each do |dir| - Dir.glob("#{dir}/**/*.#{extension}").each do |file| - key = file.split(dir).last.sub(/^\//, '').sub(/\.(\w+)$/, '') - @@file_extension_cache[dir][key] << extension - end - end - end - - def template_handler_extensions - ActionView::Template.template_handler_extensions - end - def reload! view_paths = @@processed_view_paths.keys diff --git a/actionpack/test/template/template_finder_test.rb b/actionpack/test/template/template_finder_test.rb index d6aac87b13..07fc4b8c56 100644 --- a/actionpack/test/template/template_finder_test.rb +++ b/actionpack/test/template/template_finder_test.rb @@ -57,11 +57,4 @@ class TemplateFinderTest < Test::Unit::TestCase assert_equal false, @finder.send(:file_exists?, 'baz') assert_equal false, @finder.send(:file_exists?, 'baz.rb') end - - uses_mocha 'Template finder tests' do - def test_should_update_extension_cache_when_template_handler_is_registered - ActionView::TemplateFinder.expects(:update_extension_cache_for).with("funky") - ActionView::Template::register_template_handler :funky, Class.new(ActionView::TemplateHandler) - end - end end -- cgit v1.2.3 From 64637da284ed4685591c178202ee103e6bee71cf Mon Sep 17 00:00:00 2001 From: rick Date: Mon, 9 Jun 2008 12:06:23 -0400 Subject: add deprecation for the #concat helper's 2nd argument, which is no longer needed --- actionpack/lib/action_view/helpers/text_helper.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/text_helper.rb b/actionpack/lib/action_view/helpers/text_helper.rb index f81f7eded6..3077c8f970 100644 --- a/actionpack/lib/action_view/helpers/text_helper.rb +++ b/actionpack/lib/action_view/helpers/text_helper.rb @@ -25,7 +25,10 @@ module ActionView # end # # will either display "Logged in!" or a login link # %> - def concat(string) + def concat(string, unused_binding = nil) + if unused_binding + ActiveSupport::Deprecation.warn("The binding argument of #concat is no longer needed. Please remove it from your views and helpers.") + end if @output_buffer && string @output_buffer << string else -- cgit v1.2.3 From f545e19692c84eeaa8de38319766b5ceed1768c1 Mon Sep 17 00:00:00 2001 From: rick Date: Mon, 9 Jun 2008 12:06:23 -0400 Subject: add deprecation for the #concat helper's 2nd argument, which is no longer needed --- actionpack/lib/action_view/helpers/text_helper.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/text_helper.rb b/actionpack/lib/action_view/helpers/text_helper.rb index 85a3672678..a1a91f6b3d 100644 --- a/actionpack/lib/action_view/helpers/text_helper.rb +++ b/actionpack/lib/action_view/helpers/text_helper.rb @@ -25,7 +25,11 @@ module ActionView # end # # will either display "Logged in!" or a login link # %> - def concat(string) + def concat(string, unused_binding = nil) + if unused_binding + ActiveSupport::Deprecation.warn("The binding argument of #concat is no longer needed. Please remove it from your views and helpers.") + end + if output_buffer && string output_buffer << string else -- cgit v1.2.3 From 19895f087c338d8385dff9d272d30fb87cb10330 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Tue, 10 Jun 2008 10:29:25 +0100 Subject: Lazy load cache and session stores --- actionpack/lib/action_controller/session_management.rb | 9 ++------- actionpack/test/controller/caching_test.rb | 1 + actionpack/test/controller/session/mem_cache_store_test.rb | 2 +- 3 files changed, 4 insertions(+), 8 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/session_management.rb b/actionpack/lib/action_controller/session_management.rb index 80a3ddd2c5..ad1013b379 100644 --- a/actionpack/lib/action_controller/session_management.rb +++ b/actionpack/lib/action_controller/session_management.rb @@ -1,10 +1,3 @@ -require 'action_controller/session/cookie_store' -require 'action_controller/session/drb_store' -require 'action_controller/session/mem_cache_store' -if Object.const_defined?(:ActiveRecord) - require 'action_controller/session/active_record_store' -end - module ActionController #:nodoc: module SessionManagement #:nodoc: def self.included(base) @@ -22,6 +15,8 @@ module ActionController #:nodoc: # :p_store, :drb_store, :mem_cache_store, or # :memory_store) or your own custom class. def session_store=(store) + require "action_controller/session/#{store.to_s}" if [:active_record_store, :drb_store, :mem_cache_store].include?(store) + ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS[:database_manager] = store.is_a?(Symbol) ? CGI::Session.const_get(store == :drb_store ? "DRbStore" : store.to_s.camelize) : store end diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index aee60b1c6f..4fb2397e5b 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -1,5 +1,6 @@ require 'fileutils' require 'abstract_unit' +require "active_support/cache/memory_store" CACHE_DIR = 'test_cache' # Don't change '/../temp/' cavalierly or you might hose something you don't want hosed diff --git a/actionpack/test/controller/session/mem_cache_store_test.rb b/actionpack/test/controller/session/mem_cache_store_test.rb index a7d48431f8..079a870ece 100644 --- a/actionpack/test/controller/session/mem_cache_store_test.rb +++ b/actionpack/test/controller/session/mem_cache_store_test.rb @@ -1,7 +1,7 @@ require 'abstract_unit' require 'action_controller/cgi_process' require 'action_controller/cgi_ext' - +require 'action_controller/session/mem_cache_store' class CGI::Session def cache -- cgit v1.2.3 From 0ad0bdc01c4fe2d66dd2b405433186824e7ce136 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Tue, 10 Jun 2008 23:53:30 +0100 Subject: Delegate ActionView::Base#controller_name to controller --- actionpack/lib/action_view/base.rb | 2 +- actionpack/test/controller/new_render_test.rb | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index eeebf335dc..c417cc07ac 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -184,7 +184,7 @@ module ActionView #:nodoc: attr_internal :request delegate :request_forgery_protection_token, :template, :params, :session, :cookies, :response, :headers, - :flash, :logger, :action_name, :to => :controller + :flash, :logger, :action_name, :controller_name, :to => :controller module CompiledTemplates #:nodoc: # holds compiled template code diff --git a/actionpack/test/controller/new_render_test.rb b/actionpack/test/controller/new_render_test.rb index 6b83b8337e..b77b3ceffa 100644 --- a/actionpack/test/controller/new_render_test.rb +++ b/actionpack/test/controller/new_render_test.rb @@ -220,7 +220,7 @@ class NewRenderTestController < ActionController::Base render :action => "test/hello_world" end - def render_to_string_with_partial + 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" @@ -251,11 +251,15 @@ class NewRenderTestController < ActionController::Base def accessing_logger_in_template render :inline => "<%= logger.class %>" end - + def accessing_action_name_in_template render :inline => "<%= action_name %>" end + def accessing_controller_name_in_template + render :inline => "<%= controller_name %>" + end + def accessing_params_in_template_with_layout render :layout => nil, :inline => "Hello: <%= params[:name] %>" end @@ -559,12 +563,17 @@ class NewRenderTest < Test::Unit::TestCase get :accessing_logger_in_template assert_equal "Logger", @response.body end - + def test_access_to_action_name_in_view get :accessing_action_name_in_template assert_equal "accessing_action_name_in_template", @response.body end + def test_access_to_controller_name_in_view + get :accessing_controller_name_in_template + assert_equal "test", @response.body # name is explicitly set to 'test' inside the controller. + end + def test_render_xml get :render_xml_hello assert_equal "\n

        Hello David

        \n

        This is grand!

        \n\n", @response.body -- cgit v1.2.3 From e8a0ba4c93e2f0f811675bc6a6720725c866d1a5 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 10 Jun 2008 20:38:18 -0500 Subject: Ensure view path cache is rebuilt in production mode which was broke by df44df9. --- actionpack/lib/action_controller/dispatcher.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/dispatcher.rb b/actionpack/lib/action_controller/dispatcher.rb index 64553fb25d..f20d9cc40f 100644 --- a/actionpack/lib/action_controller/dispatcher.rb +++ b/actionpack/lib/action_controller/dispatcher.rb @@ -10,10 +10,6 @@ module ActionController # Development mode callbacks before_dispatch :reload_application after_dispatch :cleanup_application - - to_prepare :reload_view_path_cache do - ActionView::TemplateFinder.reload! unless ActionView::Base.cache_template_loading - end end # Common callbacks @@ -25,6 +21,10 @@ module ActionController end end + to_prepare :reload_view_path_cache do + ActionView::TemplateFinder.reload! + end + if defined?(ActiveRecord) before_dispatch { ActiveRecord::Base.verify_active_connections! } to_prepare(:activerecord_instantiate_observers) { ActiveRecord::Base.instantiate_observers } -- cgit v1.2.3 From 3f594299c85ef111ac479b845fa8c7e37563ff66 Mon Sep 17 00:00:00 2001 From: Ruy Asan Date: Tue, 10 Jun 2008 21:13:27 -0700 Subject: TimeZone -> ActiveSupport::TimeZone. [#387 state:resolved] --- actionpack/lib/action_view/helpers/form_options_helper.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb index e0a097e367..b3f8e63c1b 100644 --- a/actionpack/lib/action_view/helpers/form_options_helper.rb +++ b/actionpack/lib/action_view/helpers/form_options_helper.rb @@ -304,7 +304,7 @@ module ActionView # # NOTE: Only the option tags are returned, you have to wrap this call in # a regular HTML select tag. - def time_zone_options_for_select(selected = nil, priority_zones = nil, model = TimeZone) + def time_zone_options_for_select(selected = nil, priority_zones = nil, model = ::ActiveSupport::TimeZone) zone_options = "" zones = model.all @@ -417,7 +417,7 @@ module ActionView value = value(object) content_tag("select", add_options( - time_zone_options_for_select(value || options[:default], priority_zones, options[:model] || TimeZone), + time_zone_options_for_select(value || options[:default], priority_zones, options[:model] || ActiveSupport::TimeZone), options, value ), html_options ) -- cgit v1.2.3 From f728e57d2204a429f5282856ec89d4e047e72957 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Wed, 11 Jun 2008 09:11:08 +0100 Subject: Make sure cache_template_loading works and don't use to_prepare callback --- actionpack/CHANGELOG | 2 -- actionpack/lib/action_controller/dispatcher.rb | 5 +---- actionpack/lib/action_view/template.rb | 1 + 3 files changed, 2 insertions(+), 6 deletions(-) (limited to 'actionpack') diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index f9cb715400..3096716dba 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -1,7 +1,5 @@ *Edge* -* Ensure ActionView::TemplateFinder view cache is rebuilt on initialize [Josh Peek] - * Drop ActionController::Base.allow_concurrency flag [Josh Peek] * More efficient concat and capture helpers. Remove ActionView::Base.erb_variable. [Jeremy Kemper] diff --git a/actionpack/lib/action_controller/dispatcher.rb b/actionpack/lib/action_controller/dispatcher.rb index f20d9cc40f..fe4f6b4a7e 100644 --- a/actionpack/lib/action_controller/dispatcher.rb +++ b/actionpack/lib/action_controller/dispatcher.rb @@ -21,10 +21,6 @@ module ActionController end end - to_prepare :reload_view_path_cache do - ActionView::TemplateFinder.reload! - end - if defined?(ActiveRecord) before_dispatch { ActiveRecord::Base.verify_active_connections! } to_prepare(:activerecord_instantiate_observers) { ActiveRecord::Base.instantiate_observers } @@ -138,6 +134,7 @@ module ActionController run_callbacks :prepare_dispatch Routing::Routes.reload + ActionView::TemplateFinder.reload! unless ActionView::Base.cache_template_loading end # Cleanup the application by clearing out loaded classes so they can diff --git a/actionpack/lib/action_view/template.rb b/actionpack/lib/action_view/template.rb index a878ac66d9..25d5819af9 100644 --- a/actionpack/lib/action_view/template.rb +++ b/actionpack/lib/action_view/template.rb @@ -99,6 +99,7 @@ module ActionView #:nodoc: # return the rendered template as a string. def self.register_template_handler(extension, klass) @@template_handlers[extension.to_sym] = klass + ActionView::TemplateFinder.reload! end def self.template_handler_extensions -- cgit v1.2.3 From 3e07f320c10b53ec21b947d949d0063e724c5fd8 Mon Sep 17 00:00:00 2001 From: Jonathan del Strother Date: Thu, 6 Mar 2008 11:50:44 +0000 Subject: Improve ActionCaching's format-handling Make ActionCaching more aware of different mimetype formats. It will now use request.format to look up the cache type, in addition to the path extension. When expiring caches, the request format no longer affects which cache is expired. Signed-off-by: Pratik Naik --- actionpack/CHANGELOG | 2 + .../lib/action_controller/caching/actions.rb | 41 ++++++++++++----- actionpack/test/controller/caching_test.rb | 53 ++++++++++++++++++++-- 3 files changed, 79 insertions(+), 17 deletions(-) (limited to 'actionpack') diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index 3096716dba..8d1acb265f 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -1,5 +1,7 @@ *Edge* +* Make caching more aware of mime types. Ensure request format is not considered while expiring cache. [Jonathan del Strother] + * Drop ActionController::Base.allow_concurrency flag [Josh Peek] * More efficient concat and capture helpers. Remove ActionView::Base.erb_variable. [Jeremy Kemper] diff --git a/actionpack/lib/action_controller/caching/actions.rb b/actionpack/lib/action_controller/caching/actions.rb index c4b0a97a33..65a36f7f98 100644 --- a/actionpack/lib/action_controller/caching/actions.rb +++ b/actionpack/lib/action_controller/caching/actions.rb @@ -67,10 +67,10 @@ module ActionController #:nodoc: if options[:action].is_a?(Array) options[:action].dup.each do |action| - expire_fragment(ActionCachePath.path_for(self, options.merge({ :action => action }))) + expire_fragment(ActionCachePath.path_for(self, options.merge({ :action => action }), false)) end else - expire_fragment(ActionCachePath.path_for(self, options)) + expire_fragment(ActionCachePath.path_for(self, options, false)) end end @@ -125,16 +125,24 @@ module ActionController #:nodoc: attr_reader :path, :extension class << self - def path_for(controller, options) - new(controller, options).path + def path_for(controller, options, infer_extension=true) + new(controller, options, infer_extension).path end end - - def initialize(controller, options = {}) - @extension = extract_extension(controller.request.path) + + # When true, infer_extension will look up the cache path extension from the request's path & format. + # This is desirable when reading and writing the cache, but not when expiring the cache - expire_action should expire the same files regardless of the request format. + def initialize(controller, options = {}, infer_extension=true) + if infer_extension and options.is_a? Hash + request_extension = extract_extension(controller.request) + options = options.reverse_merge(:format => request_extension) + end path = controller.url_for(options).split('://').last normalize!(path) - add_extension!(path, @extension) + if infer_extension + @extension = request_extension + add_extension!(path, @extension) + end @path = URI.unescape(path) end @@ -144,13 +152,22 @@ module ActionController #:nodoc: end def add_extension!(path, extension) - path << ".#{extension}" if extension + path << ".#{extension}" if extension and !path.ends_with?(extension) end - - def extract_extension(file_path) + + def extract_extension(request) # Don't want just what comes after the last '.' to accommodate multi part extensions # such as tar.gz. - file_path[/^[^.]+\.(.+)$/, 1] + extension = request.path[/^[^.]+\.(.+)$/, 1] + + # If there's no extension in the path, check request.format + if extension.nil? + extension = request.format.to_sym.to_s + if extension=='all' + extension = nil + end + end + extension end end end diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index 4fb2397e5b..89e12ddae3 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -189,6 +189,10 @@ class ActionCachingTestController < ActionController::Base expire_action :controller => 'action_caching_test', :action => 'index' render :nothing => true end + def expire_xml + expire_action :controller => 'action_caching_test', :action => 'index', :format => 'xml' + render :nothing => true + end end class MockTime < Time @@ -214,6 +218,7 @@ class ActionCachingMockController mocked_path = @mock_path Object.new.instance_eval(<<-EVAL) def path; '#{@mock_path}' end + def format; 'all' end self EVAL end @@ -327,6 +332,20 @@ class ActionCacheTest < Test::Unit::TestCase assert_equal new_cached_time, @response.body end + def test_cache_expiration_isnt_affected_by_request_format + get :index + cached_time = content_to_cache + reset! + + @request.set_REQUEST_URI "/action_caching_test/expire.xml" + get :expire, :format => :xml + reset! + + get :index + new_cached_time = content_to_cache + assert_not_equal cached_time, @response.body + end + def test_cache_is_scoped_by_subdomain @request.host = 'jamis.hostname.com' get :index @@ -371,11 +390,35 @@ class ActionCacheTest < Test::Unit::TestCase end def test_xml_version_of_resource_is_treated_as_different_cache - @mock_controller.mock_url_for = 'http://example.org/posts/' - @mock_controller.mock_path = '/posts/index.xml' - path_object = @path_class.new(@mock_controller, {}) - assert_equal 'xml', path_object.extension - assert_equal 'example.org/posts/index.xml', path_object.path + with_routing do |set| + ActionController::Routing::Routes.draw do |map| + map.connect ':controller/:action.:format' + map.connect ':controller/:action' + end + + get :index, :format => 'xml' + cached_time = content_to_cache + assert_equal cached_time, @response.body + assert fragment_exist?('hostname.com/action_caching_test/index.xml') + reset! + + get :index, :format => 'xml' + assert_equal cached_time, @response.body + assert_equal 'application/xml', @response.content_type + reset! + + @request.env['HTTP_ACCEPT'] = "application/xml" + get :index + assert_equal cached_time, @response.body + assert_equal 'application/xml', @response.content_type + reset! + + get :expire_xml + reset! + + get :index, :format => 'xml' + assert_not_equal cached_time, @response.body + end end def test_correct_content_type_is_returned_for_cache_hit -- cgit v1.2.3 From ca9641f8a7ca1142d0ea99405a079c8699bd443c Mon Sep 17 00:00:00 2001 From: Jan De Poorter Date: Wed, 11 Jun 2008 13:17:40 +0100 Subject: Fix FormOptionsHelper tests. Signed-off-by: Pratik Naik --- actionpack/test/template/form_options_helper_test.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'actionpack') diff --git a/actionpack/test/template/form_options_helper_test.rb b/actionpack/test/template/form_options_helper_test.rb index 4fb2be9d3f..d5aeb4939e 100644 --- a/actionpack/test/template/form_options_helper_test.rb +++ b/actionpack/test/template/form_options_helper_test.rb @@ -20,7 +20,7 @@ class MockTimeZone end end -ActionView::Helpers::FormOptionsHelper::TimeZone = MockTimeZone +ActiveSupport::TimeZone = MockTimeZone class FormOptionsHelperTest < ActionView::TestCase tests ActionView::Helpers::FormOptionsHelper @@ -183,7 +183,7 @@ class FormOptionsHelperTest < ActionView::TestCase end def test_time_zone_options_with_priority_zones - zones = [ TimeZone.new( "B" ), TimeZone.new( "E" ) ] + zones = [ ActiveSupport::TimeZone.new( "B" ), ActiveSupport::TimeZone.new( "E" ) ] opts = time_zone_options_for_select( nil, zones ) assert_dom_equal "\n" + "" + @@ -195,7 +195,7 @@ class FormOptionsHelperTest < ActionView::TestCase end def test_time_zone_options_with_selected_priority_zones - zones = [ TimeZone.new( "B" ), TimeZone.new( "E" ) ] + zones = [ ActiveSupport::TimeZone.new( "B" ), ActiveSupport::TimeZone.new( "E" ) ] opts = time_zone_options_for_select( "E", zones ) assert_dom_equal "\n" + "" + @@ -207,7 +207,7 @@ class FormOptionsHelperTest < ActionView::TestCase end def test_time_zone_options_with_unselected_priority_zones - zones = [ TimeZone.new( "B" ), TimeZone.new( "E" ) ] + zones = [ ActiveSupport::TimeZone.new( "B" ), ActiveSupport::TimeZone.new( "E" ) ] opts = time_zone_options_for_select( "C", zones ) assert_dom_equal "\n" + "" + @@ -1287,7 +1287,7 @@ COUNTRIES def test_time_zone_select_with_priority_zones @firm = Firm.new("D") - zones = [ TimeZone.new("A"), TimeZone.new("D") ] + zones = [ ActiveSupport::TimeZone.new("A"), ActiveSupport::TimeZone.new("D") ] html = time_zone_select("firm", "time_zone", zones ) assert_dom_equal " @@ -146,13 +146,13 @@ module ActionView # # => # # hidden_field_tag 'collected_input', '', :onchange => "alert('Input collected!')" - # # => def hidden_field_tag(name, value = nil, options = {}) text_field_tag(name, value, options.stringify_keys.update("type" => "hidden")) end - # Creates a file upload field. If you are using file uploads then you will also need + # Creates a file upload field. If you are using file uploads then you will also need # to set the multipart option for the form tag: # # <%= form_tag { :action => "post" }, { :multipart => true } %> @@ -160,7 +160,7 @@ module ActionView # <%= submit_tag %> # <%= end_form_tag %> # - # The specified URL will then be passed a File object containing the selected file, or if the field + # The specified URL will then be passed a File object containing the selected file, or if the field # was left blank, a StringIO object. # # ==== Options @@ -181,7 +181,7 @@ module ActionView # # => # # file_field_tag 'user_pic', :accept => 'image/png,image/gif,image/jpeg' - # # => + # # => # # file_field_tag 'file', :accept => 'text/html', :class => 'upload', :value => 'index.html' # # => @@ -286,7 +286,7 @@ module ActionView tag :input, html_options end - # Creates a radio button; use groups of radio buttons named the same to allow users to + # Creates a radio button; use groups of radio buttons named the same to allow users to # select from a group of options. # # ==== Options @@ -313,14 +313,14 @@ module ActionView tag :input, html_options end - # Creates a submit button with the text value as the caption. + # Creates a submit button with the text value as the caption. # # ==== Options # * :confirm => 'question?' - This will add a JavaScript confirm # prompt with the question specified. If the user accepts, the form is # processed normally, otherwise no action is taken. # * :disabled - If true, the user will not be able to use this input. - # * :disable_with - Value of this parameter will be used as the value for a disabled version + # * :disable_with - Value of this parameter will be used as the value for a disabled version # of the submit button when the form is submitted. # * Any other key creates standard HTML options for the tag. # @@ -335,7 +335,7 @@ module ActionView # # => # # submit_tag "Complete sale", :disable_with => "Please wait..." - # # => # # submit_tag nil, :class => "form_submit" @@ -346,7 +346,7 @@ module ActionView # # name="commit" type="submit" value="Edit" /> def submit_tag(value = "Save changes", options = {}) options.stringify_keys! - + if disable_with = options.delete("disable_with") options["onclick"] = [ "this.setAttribute('originalValue', this.value)", @@ -358,15 +358,15 @@ module ActionView "return result;", ].join(";") end - + if confirm = options.delete("confirm") options["onclick"] ||= '' options["onclick"] += "return #{confirm_javascript_function(confirm)};" end - + tag :input, { "type" => "submit", "name" => "commit", "value" => value }.update(options.stringify_keys) end - + # Displays an image which when clicked will submit the form. # # source is passed to AssetTagHelper#image_path @@ -412,7 +412,7 @@ module ActionView concat(content) concat("") end - + private def html_options_for_form(url_for_options, options, *parameters_for_url) returning options.stringify_keys do |html_options| @@ -420,7 +420,7 @@ module ActionView html_options["action"] = url_for(url_for_options, *parameters_for_url) end end - + def extra_tags_for_form(html_options) case method = html_options.delete("method").to_s when /^get$/i # must be case-insentive, but can't use downcase as might be nil @@ -434,12 +434,12 @@ module ActionView content_tag(:div, tag(:input, :type => "hidden", :name => "_method", :value => method) + token_tag, :style => 'margin:0;padding:0') end end - + def form_tag_html(html_options) extra_tags = extra_tags_for_form(html_options) tag(:form, html_options, true) + extra_tags end - + def form_tag_in_block(html_options, &block) content = capture(&block) concat(form_tag_html(html_options)) diff --git a/actionpack/lib/action_view/helpers/tag_helper.rb b/actionpack/lib/action_view/helpers/tag_helper.rb index e1abec1847..649ec87a24 100644 --- a/actionpack/lib/action_view/helpers/tag_helper.rb +++ b/actionpack/lib/action_view/helpers/tag_helper.rb @@ -12,14 +12,14 @@ module ActionView BOOLEAN_ATTRIBUTES = %w(disabled readonly multiple).to_set BOOLEAN_ATTRIBUTES.merge(BOOLEAN_ATTRIBUTES.map(&:to_sym)) - # Returns an empty HTML tag of type +name+ which by default is XHTML - # compliant. Set +open+ to true to create an open tag compatible - # with HTML 4.0 and below. Add HTML attributes by passing an attributes + # Returns an empty HTML tag of type +name+ which by default is XHTML + # compliant. Set +open+ to true to create an open tag compatible + # with HTML 4.0 and below. Add HTML attributes by passing an attributes # hash to +options+. Set +escape+ to false to disable attribute value # escaping. # # ==== Options - # The +options+ hash is used with attributes with no value like (disabled and + # The +options+ hash is used with attributes with no value like (disabled and # readonly), which you can give a value of true in the +options+ hash. You can use # symbols or strings for the attribute names. # @@ -30,7 +30,7 @@ module ActionView # tag("br", nil, true) # # =>
        # - # tag("input", { :type => 'text', :disabled => true }) + # tag("input", { :type => 'text', :disabled => true }) # # => # # tag("img", { :src => "open & shut.png" }) @@ -43,13 +43,13 @@ module ActionView end # Returns an HTML block tag of type +name+ surrounding the +content+. Add - # HTML attributes by passing an attributes hash to +options+. + # HTML attributes by passing an attributes hash to +options+. # Instead of passing the content as an argument, you can also use a block # in which case, you pass your +options+ as the second parameter. # Set escape to false to disable attribute value escaping. # # ==== Options - # The +options+ hash is used with attributes with no value like (disabled and + # The +options+ hash is used with attributes with no value like (disabled and # readonly), which you can give a value of true in the +options+ hash. You can use # symbols or strings for the attribute names. # @@ -68,7 +68,13 @@ 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) - concat(content_tag_string(name, capture(&block), options, escape)) + content_tag = content_tag_string(name, capture(&block), options, escape) + + if block_called_from_erb?(block) + concat(content_tag) + else + content_tag + end else content_tag_string(name, content_or_options_with_block, options, escape) end @@ -102,6 +108,16 @@ module ActionView end private + BLOCK_CALLED_FROM_ERB = 'defined? __in_erb_template' + + # 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) + eval(BLOCK_CALLED_FROM_ERB, block) + end + def content_tag_string(name, content, options, escape = true) tag_options = tag_options(options, escape) if options "<#{name}#{tag_options}>#{content}" diff --git a/actionpack/lib/action_view/helpers/text_helper.rb b/actionpack/lib/action_view/helpers/text_helper.rb index a1a91f6b3d..d98c5bd0d5 100644 --- a/actionpack/lib/action_view/helpers/text_helper.rb +++ b/actionpack/lib/action_view/helpers/text_helper.rb @@ -30,11 +30,7 @@ module ActionView ActiveSupport::Deprecation.warn("The binding argument of #concat is no longer needed. Please remove it from your views and helpers.") end - if output_buffer && string - output_buffer << string - else - string - end + output_buffer << string end if RUBY_VERSION < '1.9' diff --git a/actionpack/lib/action_view/template_handlers/compilable.rb b/actionpack/lib/action_view/template_handlers/compilable.rb index 1aef81ba1a..783456ab53 100644 --- a/actionpack/lib/action_view/template_handlers/compilable.rb +++ b/actionpack/lib/action_view/template_handlers/compilable.rb @@ -106,7 +106,13 @@ module ActionView locals_code << "#{key} = local_assigns[:#{key}]\n" end - "def #{render_symbol}(local_assigns)\nold_output_buffer = output_buffer;#{locals_code}#{body}\nensure\nself.output_buffer = old_output_buffer\nend" + <<-end_src + def #{render_symbol}(local_assigns) + old_output_buffer = output_buffer;#{locals_code}#{body} + ensure + self.output_buffer = old_output_buffer + end + end_src end # Return true if the given template was compiled for a superset of the keys in local_assigns diff --git a/actionpack/lib/action_view/template_handlers/erb.rb b/actionpack/lib/action_view/template_handlers/erb.rb index 0733b3e3c2..458416b6cb 100644 --- a/actionpack/lib/action_view/template_handlers/erb.rb +++ b/actionpack/lib/action_view/template_handlers/erb.rb @@ -48,7 +48,8 @@ module ActionView self.erb_trim_mode = '-' def compile(template) - ::ERB.new(template.source, nil, erb_trim_mode, '@output_buffer').src + src = ::ERB.new(template.source, nil, erb_trim_mode, '@output_buffer').src + "__in_erb_template=true;#{src}" end def cache_fragment(block, name = {}, options = nil) #:nodoc: diff --git a/actionpack/test/fixtures/test/non_erb_block_content_for.builder b/actionpack/test/fixtures/test/non_erb_block_content_for.builder index 6ff6db0f95..a94643561c 100644 --- a/actionpack/test/fixtures/test/non_erb_block_content_for.builder +++ b/actionpack/test/fixtures/test/non_erb_block_content_for.builder @@ -1,4 +1,4 @@ content_for :title do 'Putting stuff in the title!' end -xml << "\nGreat stuff!" \ No newline at end of file +xml << "\nGreat stuff!" diff --git a/actionpack/test/template/form_tag_helper_test.rb b/actionpack/test/template/form_tag_helper_test.rb index 47b3605849..eabbe9c8a0 100644 --- a/actionpack/test/template/form_tag_helper_test.rb +++ b/actionpack/test/template/form_tag_helper_test.rb @@ -35,21 +35,23 @@ class FormTagHelperTest < ActionView::TestCase expected = %(
        ) assert_dom_equal expected, actual end - + def test_form_tag_with_method_delete actual = form_tag({}, { :method => :delete }) expected = %(
        ) assert_dom_equal expected, actual end - def test_form_tag_with_block + def test_form_tag_with_block_in_erb + __in_erb_template = '' 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 + def test_form_tag_with_block_and_method_in_erb + __in_erb_template = '' form_tag("http://example.com", :method => :put) { concat "Hello world!" } expected = %(
        Hello world!
        ) @@ -88,11 +90,11 @@ class FormTagHelperTest < ActionView::TestCase actual = radio_button_tag("gender", "m") + radio_button_tag("gender", "f") expected = %() assert_dom_equal expected, actual - + actual = radio_button_tag("opinion", "-1") + radio_button_tag("opinion", "1") expected = %() assert_dom_equal expected, actual - + actual = radio_button_tag("person[gender]", "m") expected = %() assert_dom_equal expected, actual @@ -103,13 +105,13 @@ class FormTagHelperTest < ActionView::TestCase expected = %() assert_dom_equal expected, actual end - + def test_select_tag_with_multiple actual = select_tag "colors", "", :multiple => :true expected = %() assert_dom_equal expected, actual end - + def test_select_tag_disabled actual = select_tag "places", "", :disabled => :true expected = %() @@ -145,37 +147,37 @@ class FormTagHelperTest < ActionView::TestCase expected = %() assert_dom_equal expected, actual end - + def test_text_field_tag_size_symbol actual = text_field_tag "title", "Hello!", :size => 75 expected = %() assert_dom_equal expected, actual end - + def test_text_field_tag_size_string actual = text_field_tag "title", "Hello!", "size" => "75" expected = %() assert_dom_equal expected, actual end - + def test_text_field_tag_maxlength_symbol actual = text_field_tag "title", "Hello!", :maxlength => 75 expected = %() assert_dom_equal expected, actual end - + def test_text_field_tag_maxlength_string actual = text_field_tag "title", "Hello!", "maxlength" => "75" expected = %() assert_dom_equal expected, actual end - + def test_text_field_disabled actual = text_field_tag "title", "Hello!", :disabled => :true expected = %() assert_dom_equal expected, actual end - + def test_text_field_tag_with_multiple_options actual = text_field_tag "title", "Hello!", :size => 70, :maxlength => 80 expected = %() @@ -226,12 +228,13 @@ class FormTagHelperTest < ActionView::TestCase submit_tag("Save", :confirm => "Are you sure?") ) end - + def test_pass assert_equal 1, 1 end - def test_field_set_tag + def test_field_set_tag_in_erb + __in_erb_template = '' field_set_tag("Your details") { concat "Hello world!" } expected = %(
        Your detailsHello world!
        ) diff --git a/actionpack/test/template/javascript_helper_test.rb b/actionpack/test/template/javascript_helper_test.rb index 8c649ea544..d6d398d224 100644 --- a/actionpack/test/template/javascript_helper_test.rb +++ b/actionpack/test/template/javascript_helper_test.rb @@ -48,7 +48,7 @@ class JavaScriptHelperTest < ActionView::TestCase end def test_link_to_function_with_href - assert_dom_equal %(Greeting), + assert_dom_equal %(Greeting), link_to_function("Greeting", "alert('Hello world!')", :href => 'http://example.com/') end @@ -95,12 +95,14 @@ class JavaScriptHelperTest < ActionView::TestCase javascript_tag("alert('hello')", :id => "the_js_tag") end - def test_javascript_tag_with_block + 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 + 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 diff --git a/actionpack/test/template/prototype_helper_test.rb b/actionpack/test/template/prototype_helper_test.rb index a5be0d2789..60b83b476d 100644 --- a/actionpack/test/template/prototype_helper_test.rb +++ b/actionpack/test/template/prototype_helper_test.rb @@ -54,7 +54,7 @@ class PrototypeHelperBaseTest < ActionView::TestCase end def create_generator - block = Proc.new { |*args| yield *args if block_given? } + block = Proc.new { |*args| yield *args if block_given? } JavaScriptGenerator.new self, &block end end @@ -70,7 +70,7 @@ class PrototypeHelperTest < PrototypeHelperBaseTest assert_dom_equal %(Remote outauthor), link_to_remote("Remote outauthor", { :url => { :action => "whatnot" }}, { :class => "fine" }) assert_dom_equal %(Remote outauthor), - link_to_remote("Remote outauthor", :complete => "alert(request.responseText)", :url => { :action => "whatnot" }) + link_to_remote("Remote outauthor", :complete => "alert(request.responseText)", :url => { :action => "whatnot" }) assert_dom_equal %(Remote outauthor), link_to_remote("Remote outauthor", :success => "alert(request.responseText)", :url => { :action => "whatnot" }) assert_dom_equal %(Remote outauthor), @@ -78,12 +78,12 @@ class PrototypeHelperTest < PrototypeHelperBaseTest assert_dom_equal %(Remote outauthor), link_to_remote("Remote outauthor", :failure => "alert(request.responseText)", :url => { :action => "whatnot", :a => '10', :b => '20' }) end - + def test_link_to_remote_html_options assert_dom_equal %(Remote outauthor), link_to_remote("Remote outauthor", { :url => { :action => "whatnot" }, :html => { :class => "fine" } }) end - + def test_link_to_remote_url_quote_escaping assert_dom_equal %(Remote), link_to_remote("Remote", { :url => { :action => "whatnot's" } }) @@ -93,14 +93,14 @@ class PrototypeHelperTest < PrototypeHelperBaseTest assert_dom_equal %(), periodically_call_remote(:update => "schremser_bier", :url => { :action => "mehr_bier" }) end - + def test_periodically_call_remote_with_frequency assert_dom_equal( "", periodically_call_remote(:frequency => 2) ) end - + def test_form_remote_tag assert_dom_equal %(
        ), form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }) @@ -117,21 +117,22 @@ class PrototypeHelperTest < PrototypeHelperBaseTest form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }, :html => { :method => :put }) end - def test_form_remote_tag_with_block + def test_form_remote_tag_with_block_in_erb + __in_erb_template = '' form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }) { concat "Hello world!" } assert_dom_equal %(Hello world!
        ), output_buffer end def test_remote_form_for_with_record_identification_with_new_record remote_form_for(@record, {:html => { :id => 'create-author' }}) {} - + expected = %(
        ) assert_dom_equal expected, output_buffer end def test_remote_form_for_with_record_identification_without_html_options remote_form_for(@record) {} - + expected = %(
        ) assert_dom_equal expected, output_buffer end @@ -139,23 +140,23 @@ class PrototypeHelperTest < PrototypeHelperBaseTest def test_remote_form_for_with_record_identification_with_existing_record @record.save remote_form_for(@record) {} - + expected = %(
        ) assert_dom_equal expected, output_buffer end def test_remote_form_for_with_new_object_in_list remote_form_for([@author, @article]) {} - + expected = %(
        ) assert_dom_equal expected, output_buffer end - + def test_remote_form_for_with_existing_object_in_list @author.save @article.save remote_form_for([@author, @article]) {} - + expected = %(
        ) assert_dom_equal expected, output_buffer end @@ -172,18 +173,18 @@ class PrototypeHelperTest < PrototypeHelperBaseTest assert_dom_equal %(
        ), form_remote_tag(:update => { :success => "glass_of_beer", :failure => "glass_of_water" }, :url => { :action => :fast }, callback=>"monkeys();") end - + #HTTP status codes 200 up to 599 have callbacks #these should work 100.upto(599) do |callback| assert_dom_equal %(), form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }, callback=>"monkeys();") end - + #test 200 and 404 assert_dom_equal %(), form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }, 200=>"monkeys();", 404=>"bananas();") - + #these shouldn't 1.upto(99) do |callback| assert_dom_equal %(), @@ -193,44 +194,44 @@ class PrototypeHelperTest < PrototypeHelperBaseTest assert_dom_equal %(), form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }, callback=>"monkeys();") end - + #test ultimate combo assert_dom_equal %(), form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }, :loading => "c1()", :success => "s()", :failure => "f();", :complete => "c();", 200=>"monkeys();", 404=>"bananas();") - + end - + def test_submit_to_remote assert_dom_equal %(), submit_to_remote("More beer!", 1_000_000, :update => "empty_bottle") end - + def test_observe_field assert_dom_equal %(), observe_field("glass", :frequency => 5.minutes, :url => { :action => "reorder_if_empty" }) end - + def test_observe_field_using_with_option expected = %() assert_dom_equal expected, observe_field("glass", :frequency => 5.minutes, :url => { :action => "check_value" }, :with => 'id') assert_dom_equal expected, observe_field("glass", :frequency => 5.minutes, :url => { :action => "check_value" }, :with => "'id=' + encodeURIComponent(value)") end - + def test_observe_field_using_json_in_with_option expected = %() - assert_dom_equal expected, observe_field("glass", :frequency => 5.minutes, :url => { :action => "check_value" }, :with => "{'id':value}") + assert_dom_equal expected, observe_field("glass", :frequency => 5.minutes, :url => { :action => "check_value" }, :with => "{'id':value}") end - + def test_observe_field_using_function_for_callback assert_dom_equal %(), observe_field("glass", :frequency => 5.minutes, :function => "alert('Element changed')") end - + def test_observe_form assert_dom_equal %(), observe_form("cart", :frequency => 2, :url => { :action => "cart_changed" }) end - + def test_observe_form_using_function_for_callback assert_dom_equal %(), observe_form("cart", :frequency => 2, :function => "alert('Form changed')") @@ -245,7 +246,7 @@ class PrototypeHelperTest < PrototypeHelperBaseTest block = Proc.new { |page| page.replace_html('foo', 'bar') } assert_equal create_generator(&block).to_s, update_page(&block) end - + def test_update_page_tag block = Proc.new { |page| page.replace_html('foo', 'bar') } assert_equal javascript_tag(create_generator(&block).to_s), update_page_tag(&block) @@ -261,15 +262,15 @@ class PrototypeHelperTest < PrototypeHelperBaseTest def author_path(record) "/authors/#{record.id}" end - + def authors_path "/authors" end - + def author_articles_path(author) "/authors/#{author.id}/articles" end - + def author_article_path(author, article) "/authors/#{author.id}/articles/#{article.id}" end @@ -280,7 +281,7 @@ class JavaScriptGeneratorTest < PrototypeHelperBaseTest super @generator = create_generator end - + def test_insert_html_with_string assert_equal 'new Insertion.Top("element", "\\u003Cp\\u003EThis is a test\\u003C/p\\u003E");', @generator.insert_html(:top, 'element', '

        This is a test

        ') @@ -291,56 +292,56 @@ class JavaScriptGeneratorTest < PrototypeHelperBaseTest assert_equal 'new Insertion.After("element", "\\u003Cp\u003EThis is a test\\u003C/p\u003E");', @generator.insert_html(:after, 'element', '

        This is a test

        ') end - + def test_replace_html_with_string assert_equal 'Element.update("element", "\\u003Cp\\u003EThis is a test\\u003C/p\\u003E");', @generator.replace_html('element', '

        This is a test

        ') end - + def test_replace_element_with_string assert_equal 'Element.replace("element", "\\u003Cdiv id=\"element\"\\u003E\\u003Cp\\u003EThis is a test\\u003C/p\\u003E\\u003C/div\\u003E");', @generator.replace('element', '

        This is a test

        ') end - + def test_remove assert_equal 'Element.remove("foo");', @generator.remove('foo') assert_equal '["foo", "bar", "baz"].each(Element.remove);', @generator.remove('foo', 'bar', 'baz') end - + def test_show assert_equal 'Element.show("foo");', @generator.show('foo') assert_equal '["foo", "bar", "baz"].each(Element.show);', - @generator.show('foo', 'bar', 'baz') + @generator.show('foo', 'bar', 'baz') end - + def test_hide assert_equal 'Element.hide("foo");', @generator.hide('foo') assert_equal '["foo", "bar", "baz"].each(Element.hide);', - @generator.hide('foo', 'bar', 'baz') + @generator.hide('foo', 'bar', 'baz') end - + def test_toggle assert_equal 'Element.toggle("foo");', @generator.toggle('foo') assert_equal '["foo", "bar", "baz"].each(Element.toggle);', - @generator.toggle('foo', 'bar', 'baz') + @generator.toggle('foo', 'bar', 'baz') end - + def test_alert assert_equal 'alert("hello");', @generator.alert('hello') end - + def test_redirect_to assert_equal 'window.location.href = "http://www.example.com/welcome";', @generator.redirect_to(:action => 'welcome') assert_equal 'window.location.href = "http://www.example.com/welcome?a=b&c=d";', @generator.redirect_to("http://www.example.com/welcome?a=b&c=d") end - + def test_reload assert_equal 'window.location.reload();', @generator.reload @@ -350,16 +351,16 @@ class JavaScriptGeneratorTest < PrototypeHelperBaseTest @generator.delay(20) do @generator.hide('foo') end - + assert_equal "setTimeout(function() {\n;\nElement.hide(\"foo\");\n}, 20000);", @generator.to_s end - + def test_to_s @generator.insert_html(:top, 'element', '

        This is a test

        ') @generator.insert_html(:bottom, 'element', '

        This is a test

        ') @generator.remove('foo', 'bar') @generator.replace_html('baz', '

        This is a test

        ') - + assert_equal <<-EOS.chomp, @generator.to_s new Insertion.Top("element", "\\u003Cp\\u003EThis is a test\\u003C/p\\u003E"); new Insertion.Bottom("element", "\\u003Cp\\u003EThis is a test\\u003C/p\\u003E"); @@ -381,12 +382,12 @@ Element.update("baz", "\\u003Cp\\u003EThis is a test\\u003C/p\\u003E"); @generator['hello'].hide assert_equal %($("hello").hide();), @generator.to_s end - + def test_element_proxy_variable_access @generator['hello']['style'] assert_equal %($("hello").style;), @generator.to_s end - + def test_element_proxy_variable_access_with_assignment @generator['hello']['style']['color'] = 'red' assert_equal %($("hello").style.color = "red";), @generator.to_s @@ -401,7 +402,7 @@ Element.update("baz", "\\u003Cp\\u003EThis is a test\\u003C/p\\u003E"); @generator['hello'].hide("first").clean_whitespace assert_equal %($("hello").hide("first").cleanWhitespace();), @generator.to_s end - + def test_select_access assert_equal %($$("div.hello");), @generator.select('div.hello') end @@ -410,29 +411,29 @@ Element.update("baz", "\\u003Cp\\u003EThis is a test\\u003C/p\\u003E"); @generator.select('p.welcome b').first.hide assert_equal %($$("p.welcome b").first().hide();), @generator.to_s end - + def test_visual_effect - assert_equal %(new Effect.Puff("blah",{});), + assert_equal %(new Effect.Puff("blah",{});), @generator.visual_effect(:puff,'blah') - end - + end + def test_visual_effect_toggle - assert_equal %(Effect.toggle("blah",'appear',{});), + assert_equal %(Effect.toggle("blah",'appear',{});), @generator.visual_effect(:toggle_appear,'blah') end - + def test_sortable - assert_equal %(Sortable.create("blah", {onUpdate:function(){new Ajax.Request('http://www.example.com/order', {asynchronous:true, evalScripts:true, parameters:Sortable.serialize("blah")})}});), + assert_equal %(Sortable.create("blah", {onUpdate:function(){new Ajax.Request('http://www.example.com/order', {asynchronous:true, evalScripts:true, parameters:Sortable.serialize("blah")})}});), @generator.sortable('blah', :url => { :action => "order" }) end - + def test_draggable - assert_equal %(new Draggable("blah", {});), + assert_equal %(new Draggable("blah", {});), @generator.draggable('blah') end - + def test_drop_receiving - assert_equal %(Droppables.add("blah", {onDrop:function(element){new Ajax.Request('http://www.example.com/order', {asynchronous:true, evalScripts:true, parameters:'id=' + encodeURIComponent(element.id)})}});), + assert_equal %(Droppables.add("blah", {onDrop:function(element){new Ajax.Request('http://www.example.com/order', {asynchronous:true, evalScripts:true, parameters:'id=' + encodeURIComponent(element.id)})}});), @generator.drop_receiving('blah', :url => { :action => "order" }) end @@ -534,7 +535,7 @@ return array.reverse(); }); EOS end - + def test_collection_proxy_with_find_all @generator.select('p').find_all 'a' do |value, index| @generator << '(value.className == "welcome")' @@ -546,7 +547,7 @@ return (value.className == "welcome"); }); EOS end - + def test_collection_proxy_with_in_groups_of @generator.select('p').in_groups_of('a', 3) @generator.select('p').in_groups_of('a', 3, 'x') @@ -555,13 +556,13 @@ var a = $$("p").inGroupsOf(3); var a = $$("p").inGroupsOf(3, "x"); EOS end - + def test_collection_proxy_with_each_slice @generator.select('p').each_slice('a', 3) @generator.select('p').each_slice('a', 3) do |group, index| group.reverse end - + assert_equal <<-EOS.strip, @generator.to_s var a = $$("p").eachSlice(3); var a = $$("p").eachSlice(3, function(value, index) { @@ -569,7 +570,7 @@ return value.reverse(); }); EOS end - + def test_debug_rjs ActionView::Base.debug_rjs = true @generator['welcome'].replace_html 'Welcome' @@ -577,7 +578,7 @@ return value.reverse(); ensure ActionView::Base.debug_rjs = false end - + def test_literal literal = @generator.literal("function() {}") assert_equal "function() {}", literal.to_json @@ -588,7 +589,7 @@ return value.reverse(); @generator.form.focus('my_field') assert_equal "Form.focus(\"my_field\");", @generator.to_s end - + def test_call_with_block @generator.call(:before) @generator.call(:my_method) do |p| @@ -601,7 +602,7 @@ return value.reverse(); end assert_equal "before();\nmy_method(function() { $(\"one\").show();\n$(\"two\").hide(); });\nin_between();\nmy_method_with_arguments(true, \"hello\", function() { $(\"three\").visualEffect(\"highlight\"); });", @generator.to_s end - + def test_class_proxy_call_with_block @generator.my_object.my_method do |p| p[:one].show diff --git a/actionpack/test/template/record_tag_helper_test.rb b/actionpack/test/template/record_tag_helper_test.rb index 441dc6b720..34a200b933 100644 --- a/actionpack/test/template/record_tag_helper_test.rb +++ b/actionpack/test/template/record_tag_helper_test.rb @@ -2,7 +2,7 @@ require 'abstract_unit' class Post def id - 45 + 45 end def body "What a wonderful world!" @@ -15,35 +15,36 @@ class RecordTagHelperTest < ActionView::TestCase def setup @post = Post.new end - + def test_content_tag_for expected = %(
      • ) actual = content_tag_for(:li, @post, :class => 'bar') { } assert_dom_equal expected, actual end - + def test_content_tag_for_prefix expected = %(
          ) actual = content_tag_for(:ul, @post, :archived) { } - assert_dom_equal expected, actual + assert_dom_equal expected, actual end - + def test_content_tag_for_with_extra_html_tags expected = %() actual = content_tag_for(:tr, @post, {:class => "bar", :style => "background-color: #f0f0f0"}) { } - assert_dom_equal expected, actual + assert_dom_equal expected, actual end - - def test_block_works_with_content_tag_for + + def test_block_works_with_content_tag_for_in_erb + __in_erb_template = '' expected = %(#{@post.body}) actual = content_tag_for(:tr, @post) { concat @post.body } - assert_dom_equal expected, actual + assert_dom_equal expected, actual end - - def test_div_for + + def test_div_for_in_erb + __in_erb_template = '' expected = %(
          #{@post.body}
          ) actual = div_for(@post, :class => "bar") { concat @post.body } assert_dom_equal expected, actual - end - + end end diff --git a/actionpack/test/template/tag_helper_test.rb b/actionpack/test/template/tag_helper_test.rb index 2941dfe217..fc49d340ef 100644 --- a/actionpack/test/template/tag_helper_test.rb +++ b/actionpack/test/template/tag_helper_test.rb @@ -33,23 +33,40 @@ class TagHelperTest < ActionView::TestCase assert_equal content_tag("a", "Create", "href" => "create"), content_tag("a", "Create", :href => "create") end - - def test_content_tag_with_block + + def test_content_tag_with_block_in_erb + __in_erb_template = '' content_tag(:div) { concat "Hello world!" } assert_dom_equal "
          Hello world!
          ", output_buffer end - - def test_content_tag_with_block_and_options + + 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 end - - def test_content_tag_with_block_and_options_outside_of_action_view - self.output_buffer = nil + + def test_content_tag_with_block_and_options_out_of_erb + assert_dom_equal %(
          Hello world!
          ), content_tag(:div, :class => "green") { "Hello world!" } + end + + def test_content_tag_with_block_and_options_outside_out_of_erb assert_equal content_tag("a", "Create", :href => "create"), - content_tag("a", "href" => "create") { "Create" } + content_tag("a", "href" => "create") { "Create" } end - + + def test_content_tag_nested_in_content_tag_out_of_erb + assert_equal content_tag("p", content_tag("b", "Hello")), + content_tag("p") { content_tag("b", "Hello") }, + output_buffer + end + + 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 + end + def test_cdata_section assert_equal "]]>", cdata_section("") end diff --git a/actionpack/test/template/text_helper_test.rb b/actionpack/test/template/text_helper_test.rb index cbb5c7ee74..df6be3bb13 100644 --- a/actionpack/test/template/text_helper_test.rb +++ b/actionpack/test/template/text_helper_test.rb @@ -13,9 +13,7 @@ class TextHelperTest < ActionView::TestCase def test_concat self.output_buffer = 'foo' - concat 'bar' - assert_equal 'foobar', output_buffer - assert_nothing_raised { concat nil } + assert_equal 'foobar', concat('bar') assert_equal 'foobar', output_buffer end diff --git a/actionpack/test/template/url_helper_test.rb b/actionpack/test/template/url_helper_test.rb index 0713cea8ac..44ceed6661 100644 --- a/actionpack/test/template/url_helper_test.rb +++ b/actionpack/test/template/url_helper_test.rb @@ -80,7 +80,7 @@ class UrlHelperTest < ActionView::TestCase def test_link_tag_with_straight_url assert_dom_equal "Hello", link_to("Hello", "http://www.example.com") end - + def test_link_tag_without_host_option ActionController::Base.class_eval { attr_accessor :url } url = {:controller => 'weblog', :action => 'show'} @@ -121,7 +121,7 @@ class UrlHelperTest < ActionView::TestCase @controller.request = RequestMock.new("http://www.example.com/weblog/show", nil, nil, {'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, {}) assert_dom_equal "go back", link_to('go back', :back) @@ -212,14 +212,14 @@ class UrlHelperTest < ActionView::TestCase assert_raises(ActionView::ActionViewError) { link_to("Hello", "http://www.example.com", :popup => true, :method => :post, :confirm => "Are you serious?") } end - def test_link_tag_using_block - self.output_buffer = '' + def test_link_tag_using_block_in_erb + __in_erb_template = '' link_to("http://example.com") { concat("Example site") } assert_equal 'Example site', output_buffer end - + def test_link_to_unless assert_equal "Showing", link_to_unless(true, "Showing", :action => "show", :controller => "weblog") assert_dom_equal "Listing", link_to_unless(false, "Listing", :action => "list", :controller => "weblog") @@ -293,7 +293,7 @@ class UrlHelperTest < ActionView::TestCase assert_dom_equal "me(at)domain(dot)com", mail_to("me@domain.com", nil, :encode => "hex", :replace_at => "(at)", :replace_dot => "(dot)") assert_dom_equal "", mail_to("me@domain.com", "My email", :encode => "javascript", :replace_at => "(at)", :replace_dot => "(dot)") end - + def protect_against_forgery? false end @@ -420,11 +420,11 @@ class Workshop def initialize(id, new_record) @id, @new_record = id, new_record end - + def new_record? @new_record end - + def to_s id.to_s end -- cgit v1.2.3 From f4ccc179530d5b9436da87d3c221dfa8fa89119a Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Sat, 21 Jun 2008 14:54:10 -0700 Subject: Performance: javascript helper tweaks to speed up escaping and reduce object allocations when building options strings --- .../lib/action_view/helpers/javascript_helper.rb | 129 ++++++++++++--------- actionpack/lib/action_view/helpers/tag_helper.rb | 2 +- actionpack/lib/action_view/helpers/url_helper.rb | 2 +- 3 files changed, 73 insertions(+), 60 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/javascript_helper.rb b/actionpack/lib/action_view/helpers/javascript_helper.rb index 7404a251e4..31571de6c4 100644 --- a/actionpack/lib/action_view/helpers/javascript_helper.rb +++ b/actionpack/lib/action_view/helpers/javascript_helper.rb @@ -4,10 +4,10 @@ require 'action_view/helpers/prototype_helper' module ActionView module Helpers # Provides functionality for working with JavaScript in your views. - # + # # == Ajax, controls and visual effects - # - # * For information on using Ajax, see + # + # * For information on using Ajax, see # ActionView::Helpers::PrototypeHelper. # * For information on using controls and visual effects, see # ActionView::Helpers::ScriptaculousHelper. @@ -20,22 +20,22 @@ module ActionView # and ActionView::Helpers::ScriptaculousHelper), you must do one of the # following: # - # * Use <%= javascript_include_tag :defaults %> in the HEAD - # section of your page (recommended): This function will return + # * Use <%= javascript_include_tag :defaults %> in the HEAD + # section of your page (recommended): This function will return # references to the JavaScript files created by the +rails+ command in # your public/javascripts directory. Using it is recommended as - # the browser can then cache the libraries instead of fetching all the + # the browser can then cache the libraries instead of fetching all the # functions anew on every request. - # * Use <%= javascript_include_tag 'prototype' %>: As above, but + # * Use <%= javascript_include_tag 'prototype' %>: As above, but # will only include the Prototype core library, which means you are able - # to use all basic AJAX functionality. For the Scriptaculous-based - # JavaScript helpers, like visual effects, autocompletion, drag and drop + # to use all basic AJAX functionality. For the Scriptaculous-based + # JavaScript helpers, like visual effects, autocompletion, drag and drop # and so on, you should use the method described above. # * Use <%= define_javascript_functions %>: this will copy all the # JavaScript support functions within a single script block. Not # recommended. # - # For documentation on +javascript_include_tag+ see + # For documentation on +javascript_include_tag+ see # ActionView::Helpers::AssetTagHelper. module JavaScriptHelper unless const_defined? :JAVASCRIPT_PATH @@ -43,13 +43,13 @@ module ActionView end include PrototypeHelper - - # Returns a link that will trigger a JavaScript +function+ using the + + # Returns a link that will trigger a JavaScript +function+ using the # onclick handler and return false after the fact. # # The +function+ argument can be omitted in favor of an +update_page+ # block, which evaluates to a string when the template is rendered - # (instead of making an Ajax request first). + # (instead of making an Ajax request first). # # Examples: # link_to_function "Greeting", "alert('Hello world!')" @@ -70,36 +70,31 @@ module ActionView # Show me more # def link_to_function(name, *args, &block) - html_options = args.extract_options! - function = args[0] || '' - - html_options.symbolize_keys! - function = update_page(&block) if block_given? - content_tag( - "a", name, - html_options.merge({ - :href => html_options[:href] || "#", - :onclick => (html_options[:onclick] ? "#{html_options[:onclick]}; " : "") + "#{function}; return false;" - }) - ) + html_options = args.extract_options!.symbolize_keys! + + function = block_given? ? update_page(&block) : args[0] || '' + onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function}; return false;" + href = html_options[:href] || '#' + + content_tag(:a, name, html_options.merge(:href => href, :onclick => onclick)) end - - # Returns a button that'll trigger a JavaScript +function+ using the + + # Returns a button that'll trigger a JavaScript +function+ using the # onclick handler. # # The +function+ argument can be omitted in favor of an +update_page+ # block, which evaluates to a string when the template is rendered - # (instead of making an Ajax request first). + # (instead of making an Ajax request first). # # Examples: # button_to_function "Greeting", "alert('Hello world!')" @@ -111,45 +106,56 @@ module ActionView # page[:details].visual_effect :toggle_slide # end def button_to_function(name, *args, &block) - html_options = args.extract_options! - function = args[0] || '' - - html_options.symbolize_keys! - function = update_page(&block) if block_given? - tag(:input, html_options.merge({ - :type => "button", :value => name, - :onclick => (html_options[:onclick] ? "#{html_options[:onclick]}; " : "") + "#{function};" - })) + html_options = args.extract_options!.symbolize_keys! + + function = block_given? ? update_page(&block) : args[0] || '' + onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function};" + + tag(:input, html_options.merge(:type => 'button', :value => name, :onclick => onclick)) end - # Includes the Action Pack JavaScript libraries inside a single ' end + + JS_ESCAPE_MAP = { + '\\' => '\\\\', + ' '<\/', + "\r\n" => '\n', + "\n" => '\n', + "\r" => '\n', + '"' => '\\"', + "'" => "\\'" } + # Escape carrier returns and single and double quotes for JavaScript segments. def escape_javascript(javascript) - (javascript || '').gsub('\\','\0\0').gsub(' # # +html_options+ may be a hash of attributes for the # # Instead of passing the content as an argument, you can also use a block @@ -180,30 +186,37 @@ module ActionView content_or_options_with_block end - tag = content_tag("script", javascript_cdata_section(content), html_options.merge(:type => Mime::JS)) + tag = content_tag(:script, javascript_cdata_section(content), html_options.merge(:type => Mime::JS)) - block_given? ? concat(tag) : tag + if block_called_from_erb?(block) + concat(tag) + else + tag + end end def javascript_cdata_section(content) #:nodoc: "\n//#{cdata_section("\n#{content}\n//")}\n" end - + protected def options_for_javascript(options) - '{' + options.map {|k, v| "#{k}:#{v}"}.sort.join(', ') + '}' + if options.empty? + '{}' + else + "{#{options.keys.map { |k| "#{k}:#{options[k]}" }.sort.join(', ')}}" + end end - + def array_or_string_for_javascript(option) - js_option = if option.kind_of?(Array) + if option.kind_of?(Array) "['#{option.join('\',\'')}']" elsif !option.nil? "'#{option}'" end - js_option end end - + JavascriptHelper = JavaScriptHelper unless const_defined? :JavascriptHelper end end diff --git a/actionpack/lib/action_view/helpers/tag_helper.rb b/actionpack/lib/action_view/helpers/tag_helper.rb index 649ec87a24..aeafd3906d 100644 --- a/actionpack/lib/action_view/helpers/tag_helper.rb +++ b/actionpack/lib/action_view/helpers/tag_helper.rb @@ -115,7 +115,7 @@ module ActionView # can't take an <% end %> later on, so we have to use <% ... %> # and implicitly concat. def block_called_from_erb?(block) - eval(BLOCK_CALLED_FROM_ERB, block) + block && eval(BLOCK_CALLED_FROM_ERB, block) end def content_tag_string(name, content, options, escape = true) diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb index baecd304cd..d5b7255642 100644 --- a/actionpack/lib/action_view/helpers/url_helper.rb +++ b/actionpack/lib/action_view/helpers/url_helper.rb @@ -535,7 +535,7 @@ module ActionView when method "#{method_javascript_function(method, url, href)}return false;" when popup - popup_javascript_function(popup) + 'return false;' + "#{popup_javascript_function(popup)}return false;" else html_options["onclick"] end -- cgit v1.2.3 From a02d672cd7aead8a24e3b10a6b8e12dd91ee0a49 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Sun, 22 Jun 2008 10:38:25 -0700 Subject: Horo rdoc template --- actionpack/Rakefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/Rakefile b/actionpack/Rakefile index 86a2f3af14..1880f21f67 100644 --- a/actionpack/Rakefile +++ b/actionpack/Rakefile @@ -49,7 +49,7 @@ Rake::RDocTask.new { |rdoc| rdoc.title = "Action Pack -- On rails from request to response" rdoc.options << '--line-numbers' << '--inline-source' rdoc.options << '--charset' << 'utf-8' - rdoc.template = "#{ENV['template']}.rb" if ENV['template'] + rdoc.template = ENV['template'] ? "#{ENV['template']}.rb" : '../doc/template/horo' if ENV['DOC_FILES'] rdoc.rdoc_files.include(ENV['DOC_FILES'].split(/,\s*/)) else -- cgit v1.2.3 From bb6e8eea5a8190aaab67da0a7efedb3bb3d9fccb Mon Sep 17 00:00:00 2001 From: Tammer Saleh Date: Fri, 20 Jun 2008 15:21:04 -0400 Subject: Fixed polymorphic_url to be able to handle singleton resources. Example usage: polymorphic_url([:admin, @user, :blog, @post]) # => admin_user_blog_post_url(@user, @post) [#461 state:resolved] --- actionpack/CHANGELOG | 2 ++ .../lib/action_controller/polymorphic_routes.rb | 37 +++++++++++++++------- .../test/controller/polymorphic_routes_test.rb | 33 +++++++++++++++++++ 3 files changed, 60 insertions(+), 12 deletions(-) (limited to 'actionpack') diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index 4a6e70a153..a28bf66b88 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -1,5 +1,7 @@ *Edge* +* Fix polymorphic_url with singleton resources. #461 [Tammer Saleh] + * Replaced TemplateFinder abstraction with ViewLoadPaths [Josh Peek] * Added block-call style to link_to [Sam Stephenson/DHH]. Example: diff --git a/actionpack/lib/action_controller/polymorphic_routes.rb b/actionpack/lib/action_controller/polymorphic_routes.rb index 509fa6a08e..7c30bf0778 100644 --- a/actionpack/lib/action_controller/polymorphic_routes.rb +++ b/actionpack/lib/action_controller/polymorphic_routes.rb @@ -48,6 +48,9 @@ module ActionController # # # calls post_url(post) # polymorphic_url(post) # => "http://example.com/posts/1" + # polymorphic_url([blog, post]) # => "http://example.com/blogs/1/posts/1" + # polymorphic_url([:admin, blog, post]) # => "http://example.com/admin/blogs/1/posts/1" + # polymorphic_url([user, :blog, post]) # => "http://example.com/users/1/blog/posts/1" # # ==== Options # @@ -83,8 +86,6 @@ module ActionController else [ record_or_hash_or_array ] end - args << format if format - inflection = case when options[:action].to_s == "new" @@ -96,6 +97,9 @@ module ActionController else :singular end + + args.delete_if {|arg| arg.is_a?(Symbol) || arg.is_a?(String)} + args << format if format named_route = build_named_route_call(record_or_hash_or_array, namespace, inflection, options) send!(named_route, *args) @@ -136,11 +140,19 @@ module ActionController else record = records.pop route = records.inject("") do |string, parent| - string << "#{RecordIdentifier.send!("singular_class_name", parent)}_" + if parent.is_a?(Symbol) || parent.is_a?(String) + string << "#{parent}_" + else + string << "#{RecordIdentifier.send!("singular_class_name", parent)}_" + end end end - route << "#{RecordIdentifier.send!("#{inflection}_class_name", record)}_" + if record.is_a?(Symbol) || record.is_a?(String) + route << "#{record}_" + else + route << "#{RecordIdentifier.send!("#{inflection}_class_name", record)}_" + end action_prefix(options) + namespace + route + routing_type(options).to_s end @@ -163,16 +175,17 @@ module ActionController end end + # Remove the first symbols from the array and return the url prefix + # implied by those symbols. def extract_namespace(record_or_hash_or_array) - returning "" do |namespace| - if record_or_hash_or_array.is_a?(Array) - record_or_hash_or_array.delete_if do |record_or_namespace| - if record_or_namespace.is_a?(String) || record_or_namespace.is_a?(Symbol) - namespace << "#{record_or_namespace}_" - end - end - end + return "" unless record_or_hash_or_array.is_a?(Array) + + namespace_keys = [] + while (key = record_or_hash_or_array.first) && key.is_a?(String) || key.is_a?(Symbol) + namespace_keys << record_or_hash_or_array.shift end + + namespace_keys.map {|k| "#{k}_"}.join end end end diff --git a/actionpack/test/controller/polymorphic_routes_test.rb b/actionpack/test/controller/polymorphic_routes_test.rb index 4ec0d3cd4e..3f52526f08 100644 --- a/actionpack/test/controller/polymorphic_routes_test.rb +++ b/actionpack/test/controller/polymorphic_routes_test.rb @@ -118,6 +118,39 @@ uses_mocha 'polymorphic URL helpers' do polymorphic_url([:site, :admin, @article, @response, @tag]) end + def test_nesting_with_array_ending_in_singleton_resource + expects(:article_response_url).with(@article) + polymorphic_url([@article, :response]) + end + + def test_nesting_with_array_containing_singleton_resource + @tag = Tag.new + @tag.save + expects(:article_response_tag_url).with(@article, @tag) + polymorphic_url([@article, :response, @tag]) + end + + def test_nesting_with_array_containing_namespace_and_singleton_resource + @tag = Tag.new + @tag.save + expects(:admin_article_response_tag_url).with(@article, @tag) + polymorphic_url([:admin, @article, :response, @tag]) + end + + def test_nesting_with_array_containing_singleton_resource_and_format + @tag = Tag.new + @tag.save + expects(:formatted_article_response_tag_url).with(@article, @tag, :pdf) + formatted_polymorphic_url([@article, :response, @tag, :pdf]) + end + + def test_nesting_with_array_containing_singleton_resource_and_format_option + @tag = Tag.new + @tag.save + expects(:article_response_tag_url).with(@article, @tag, :pdf) + polymorphic_url([@article, :response, @tag], :format => :pdf) + end + # TODO: Needs to be updated to correctly know about whether the object is in a hash or not def xtest_with_hash expects(:article_url).with(@article) -- cgit v1.2.3 From b40947432540ad29abacaad9d9254bf70048190d Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Mon, 23 Jun 2008 23:41:21 -0700 Subject: link_to_function and button_to_function shouldn't modify their options hashes --- actionpack/lib/action_view/helpers/javascript_helper.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/javascript_helper.rb b/actionpack/lib/action_view/helpers/javascript_helper.rb index 31571de6c4..f89b6c2f70 100644 --- a/actionpack/lib/action_view/helpers/javascript_helper.rb +++ b/actionpack/lib/action_view/helpers/javascript_helper.rb @@ -80,7 +80,7 @@ module ActionView # return false;">Show me more # def link_to_function(name, *args, &block) - html_options = args.extract_options!.symbolize_keys! + html_options = args.extract_options!.symbolize_keys function = block_given? ? update_page(&block) : args[0] || '' onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function}; return false;" @@ -106,7 +106,7 @@ module ActionView # page[:details].visual_effect :toggle_slide # end def button_to_function(name, *args, &block) - html_options = args.extract_options!.symbolize_keys! + html_options = args.extract_options!.symbolize_keys function = block_given? ? update_page(&block) : args[0] || '' onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function};" -- cgit v1.2.3 From 69e72af62261dd8971890711b51c6eef2c68bc71 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Tue, 24 Jun 2008 11:53:49 -0700 Subject: Improve readability --- actionpack/lib/action_controller/caching/fragments.rb | 18 ++++++++++-------- actionpack/lib/action_view/template_handlers/erb.rb | 4 +++- 2 files changed, 13 insertions(+), 9 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/caching/fragments.rb b/actionpack/lib/action_controller/caching/fragments.rb index e4f5de44ab..57b31ec9d1 100644 --- a/actionpack/lib/action_controller/caching/fragments.rb +++ b/actionpack/lib/action_controller/caching/fragments.rb @@ -61,16 +61,18 @@ module ActionController #:nodoc: end def fragment_for(block, name = {}, options = nil) #:nodoc: - unless perform_caching then block.call; return end - - buffer = yield - - if cache = read_fragment(name, options) - buffer.concat(cache) + if perform_caching + buffer = yield + + if cache = read_fragment(name, options) + buffer.concat(cache) + else + pos = buffer.length + block.call + write_fragment(name, buffer[pos..-1], options) + end else - pos = buffer.length block.call - write_fragment(name, buffer[pos..-1], options) end end diff --git a/actionpack/lib/action_view/template_handlers/erb.rb b/actionpack/lib/action_view/template_handlers/erb.rb index 458416b6cb..ac715e30c2 100644 --- a/actionpack/lib/action_view/template_handlers/erb.rb +++ b/actionpack/lib/action_view/template_handlers/erb.rb @@ -53,7 +53,9 @@ module ActionView end def cache_fragment(block, name = {}, options = nil) #:nodoc: - @view.fragment_for(block, name, options) { @view.response.template.output_buffer ||= '' } + @view.fragment_for(block, name, options) do + @view.response.template.output_buffer + end end end end -- cgit v1.2.3 From 670e22e3724791f51d639f409930fba5af920081 Mon Sep 17 00:00:00 2001 From: Jimmy Baker Date: Tue, 24 Jun 2008 22:21:58 -0700 Subject: Patched HTML::Document#initialize call to Node.parse so that it includes the strict argument. [#330] --- .../vendor/html-scanner/html/document.rb | 2 +- .../test/controller/html-scanner/document_test.rb | 25 ++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/vendor/html-scanner/html/document.rb b/actionpack/lib/action_controller/vendor/html-scanner/html/document.rb index 607fd186b9..b8d73c350d 100644 --- a/actionpack/lib/action_controller/vendor/html-scanner/html/document.rb +++ b/actionpack/lib/action_controller/vendor/html-scanner/html/document.rb @@ -17,7 +17,7 @@ module HTML #:nodoc: @root = Node.new(nil) node_stack = [ @root ] while token = tokenizer.next - node = Node.parse(node_stack.last, tokenizer.line, tokenizer.position, token) + node = Node.parse(node_stack.last, tokenizer.line, tokenizer.position, token, strict) node_stack.last.children << node unless node.tag? && node.closing == :close if node.tag? diff --git a/actionpack/test/controller/html-scanner/document_test.rb b/actionpack/test/controller/html-scanner/document_test.rb index 0519533dbd..1c3facb9e3 100644 --- a/actionpack/test/controller/html-scanner/document_test.rb +++ b/actionpack/test/controller/html-scanner/document_test.rb @@ -120,4 +120,29 @@ HTML assert doc.find(:tag => "div", :attributes => { :id => "map" }, :content => "") assert doc.find(:tag => "div", :attributes => { :id => "map" }, :content => nil) end + + def test_parse_invalid_document + assert_nothing_raised do + doc = HTML::Document.new(" + + + + +
          About Us
          + ") + end + end + + def test_invalid_document_raises_exception_when_strict + assert_raises RuntimeError do + doc = HTML::Document.new(" + + + + +
          About Us
          + ", true) + end + end + end -- cgit v1.2.3