diff options
Diffstat (limited to 'actionpack')
30 files changed, 362 insertions, 56 deletions
diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index c52241a9c0..10bba63390 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -1,4 +1,139 @@ -## Rails 3.2.9 (unreleased) ## +## Rails 3.2.10 (unreleased) ## + +* Accept symbols as #send_data :disposition value. [Backport #8329] *Elia Schito* + +* Add i18n scope to distance_of_time_in_words. [Backport #7997] *Steve Klabnik* + +* Fix side effect of `url_for` changing the `:controller` string option. [Backport #6003] + Before: + + controller = '/projects' + url_for :controller => controller, :action => 'status' + + puts controller #=> 'projects' + + After + + puts controller #=> '/projects' + + [Nikita Beloglazov + Andrew White] + +* Introduce `ActionView::Template::Handlers::ERB.escape_whitelist`. This is a list + of mime types where template text is not html escaped by default. It prevents `Jack & Joe` + from rendering as `Jack & Joe` for the whitelisted mime types. The default whitelist + contains text/plain. Fix #7976 [Backport #8235] + + *Joost Baaij* + +* `BestStandardsSupport` middleware now appends it's `X-UA-Compatible` value to app's + returned value if any. Fix #8086 [Backport #8093] + + *Nikita Afanasenko* + +* prevent double slashes in engine urls when `Rails.application.default_url_options[:trailing_slash] = true` is set + Fix #7842 + + *Yves Senn* + +* Fix input name when `:multiple => true` and `:index` are set. + + Before: + + check_box("post", "comment_ids", { :multiple => true, :index => "foo" }, 1) + #=> <input name=\"post[foo][comment_ids]\" type=\"hidden\" value=\"0\" /><input id=\"post_foo_comment_ids_1\" name=\"post[foo][comment_ids]\" type=\"checkbox\" value=\"1\" /> + + After: + + check_box("post", "comment_ids", { :multiple => true, :index => "foo" }, 1) + #=> <input name=\"post[foo][comment_ids][]\" type=\"hidden\" value=\"0\" /><input id=\"post_foo_comment_ids_1\" name=\"post[foo][comment_ids][]\" type=\"checkbox\" value=\"1\" /> + + Fix #8108 + + *Daniel Fox, Grant Hutchins & Trace Wax* + +## Rails 3.2.9 (Nov 12, 2012) ## + +* Clear url helpers when reloading routes. + + *Santiago Pastorino* + +* Revert the shorthand routes scoped with `:module` option fix + This added a regression since it is changing the URL mapping. + This makes the stable release backward compatible. + + *Rafael Mendonça França* + +* Revert the `assert_template` fix to not pass with ever string that matches the template name. + This added a regression since people were relying on this buggy behavior. + This will introduce back #3849 but this stable release will be backward compatible. + Fixes #8068. + + *Rafael Mendonça França* + +* Revert the rename of internal variable on ActionController::TemplateAssertions to prevent + naming collisions. This added a regression related with shoulda-matchers, since it is + expecting the [instance variable @layouts](https://github.com/thoughtbot/shoulda-matchers/blob/9e1188eea68c47d9a56ce6280e45027da6187ab1/lib/shoulda/matchers/action_controller/render_with_layout_matcher.rb#L74). + This will introduce back #7459 but this stable release will be backward compatible. + Fixes #8068. + + *Rafael Mendonça França* + +* Accept :remote as symbolic option for `link_to` helper. *Riley Lynch* + +* Warn when the `:locals` option is passed to `assert_template` outside of a view test case + Fix #3415 + + *Yves Senn* + +* Rename internal variables on ActionController::TemplateAssertions to prevent + naming collisions. @partials, @templates and @layouts are now prefixed with an underscore. + Fix #7459 + + *Yves Senn* + +* `resource` and `resources` don't modify the passed options hash + Fix #7777 + + *Yves Senn* + +* Precompiled assets include aliases from foo.js to foo/index.js and vice versa. + + # Precompiles phone-<digest>.css and aliases phone/index.css to phone.css. + config.assets.precompile = [ 'phone.css' ] + + # Precompiles phone/index-<digest>.css and aliases phone.css to phone/index.css. + config.assets.precompile = [ 'phone/index.css' ] + + # Both of these work with either precompile thanks to their aliases. + <%= stylesheet_link_tag 'phone', media: 'all' %> + <%= stylesheet_link_tag 'phone/index', media: 'all' %> + + *Jeremy Kemper* + +* `assert_template` is no more passing with what ever string that matches + with the template name. + + Before when we have a template `/layout/hello.html.erb`, `assert_template` + was passing with any string that matches. This behavior allowed false + positive like: + + assert_template "layout" + assert_template "out/hello" + + Now it only passes with: + + assert_template "layout/hello" + assert_template "hello" + + Fixes #3849. + + *Hugolnx* + +* Handle `ActionDispatch::Http::UploadedFile` like `Rack::Test::UploadedFile`, don't call to_param on it. Since + `Rack::Test::UploadedFile` isn't API compatible this is needed to test file uploads that rely on `tempfile` + being available. + + *Tim Vandecasteele* * Respect `config.digest = false` for `asset_path` diff --git a/actionpack/actionpack.gemspec b/actionpack/actionpack.gemspec index 3d67541557..ebd3c926eb 100644 --- a/actionpack/actionpack.gemspec +++ b/actionpack/actionpack.gemspec @@ -23,7 +23,7 @@ Gem::Specification.new do |s| s.add_dependency('rack', '~> 1.4.0') s.add_dependency('rack-test', '~> 0.6.1') s.add_dependency('journey', '~> 1.0.4') - s.add_dependency('sprockets', '~> 2.1') + s.add_dependency('sprockets', '~> 2.2.1') s.add_dependency('erubis', '~> 2.7.0') s.add_development_dependency('tzinfo', '~> 0.3.29') diff --git a/actionpack/lib/abstract_controller/layouts.rb b/actionpack/lib/abstract_controller/layouts.rb index c482062592..3b07e4cdba 100644 --- a/actionpack/lib/abstract_controller/layouts.rb +++ b/actionpack/lib/abstract_controller/layouts.rb @@ -309,7 +309,7 @@ module AbstractController # still does a dynamic lookup. In next Rails release, we should @_layout # to be inheritable so we can skip the child lookup if the parent explicitly # set the layout. - parent = self.superclass.instance_variable_get(:@_layout) + parent = self.superclass.instance_eval { @_layout if defined?(@_layout) } @_layout = nil inspect = parent.is_a?(Proc) ? parent.inspect : parent diff --git a/actionpack/lib/action_controller/metal/data_streaming.rb b/actionpack/lib/action_controller/metal/data_streaming.rb index 62e16ea047..95c058fc86 100644 --- a/actionpack/lib/action_controller/metal/data_streaming.rb +++ b/actionpack/lib/action_controller/metal/data_streaming.rb @@ -141,7 +141,7 @@ module ActionController #:nodoc: raise ArgumentError, ":#{arg} option required" if options[arg].nil? end - disposition = options[:disposition] + disposition = options[:disposition].to_s disposition += %(; filename="#{options[:filename]}") if options[:filename] content_type = options[:type] diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb index 05e3cd40b5..b574a36430 100644 --- a/actionpack/lib/action_controller/test_case.rb +++ b/actionpack/lib/action_controller/test_case.rb @@ -103,9 +103,13 @@ module ActionController if expected_partial = options[:partial] if expected_locals = options[:locals] - actual_locals = @locals[expected_partial.to_s.sub(/^_/,'')] - expected_locals.each_pair do |k,v| - assert_equal(v, actual_locals[k]) + if defined?(@locals) + actual_locals = @locals[expected_partial.to_s.sub(/^_/,'')] + expected_locals.each_pair do |k,v| + assert_equal(v, actual_locals[k]) + end + else + warn "the :locals option to #assert_template is only supported in a ActionView::TestCase" end elsif expected_count = options[:count] actual_count = @partials[expected_partial] @@ -422,7 +426,7 @@ module ActionController Hash[hash_or_array_or_value.map{|key, value| [key, paramify_values(value)] }] when Array hash_or_array_or_value.map {|i| paramify_values(i)} - when Rack::Test::UploadedFile + when Rack::Test::UploadedFile, ActionDispatch::Http::UploadedFile hash_or_array_or_value else hash_or_array_or_value.to_param diff --git a/actionpack/lib/action_dispatch/http/upload.rb b/actionpack/lib/action_dispatch/http/upload.rb index 94fa747a79..eb95f79e0b 100644 --- a/actionpack/lib/action_dispatch/http/upload.rb +++ b/actionpack/lib/action_dispatch/http/upload.rb @@ -19,7 +19,7 @@ module ActionDispatch [:open, :path, :rewind, :size].each do |method| class_eval "def #{method}; @tempfile.#{method}; end" end - + private def encode_filename(filename) # Encode the filename in the utf8 encoding, unless it is nil or we're in 1.8 diff --git a/actionpack/lib/action_dispatch/middleware/best_standards_support.rb b/actionpack/lib/action_dispatch/middleware/best_standards_support.rb index 69adcc419f..d338996240 100644 --- a/actionpack/lib/action_dispatch/middleware/best_standards_support.rb +++ b/actionpack/lib/action_dispatch/middleware/best_standards_support.rb @@ -15,7 +15,13 @@ module ActionDispatch def call(env) status, headers, body = @app.call(env) - headers["X-UA-Compatible"] = @header + + if headers["X-UA-Compatible"] && @header + headers["X-UA-Compatible"] << "," << @header.to_s + else + headers["X-UA-Compatible"] = @header + end + [status, headers, body] end end diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 40ff69693b..9a474d2e3a 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -451,7 +451,7 @@ module ActionDispatch # we must actually delete prefix segment keys to avoid passing them to next url_for _route.segment_keys.each { |k| options.delete(k) } prefix = _routes.url_helpers.send("#{name}_path", prefix_options) - prefix = '' if prefix == '/' + prefix = prefix.gsub(%r{/\z}, '') prefix end end @@ -982,7 +982,7 @@ module ActionDispatch # === Options # Takes same options as +resources+. def resource(*resources, &block) - options = resources.extract_options! + options = resources.extract_options!.dup if apply_common_behavior_for(:resource, resources, options, &block) return self @@ -1120,7 +1120,7 @@ module ActionDispatch # # resource actions are at /admin/posts. # resources :posts, :path => "admin/posts" def resources(*resources, &block) - options = resources.extract_options! + options = resources.extract_options!.dup if apply_common_behavior_for(:resources, resources, options, &block) return self diff --git a/actionpack/lib/action_dispatch/routing/redirection.rb b/actionpack/lib/action_dispatch/routing/redirection.rb index dc28389360..50b20a2a25 100644 --- a/actionpack/lib/action_dispatch/routing/redirection.rb +++ b/actionpack/lib/action_dispatch/routing/redirection.rb @@ -78,10 +78,10 @@ module ActionDispatch # params, depending of how many arguments your block accepts. A string is required as a # return value. # - # match 'jokes/:number', :to => redirect do |params, request| - # path = (params[:number].to_i.even? ? "/wheres-the-beef" : "/i-love-lamp") + # match 'jokes/:number', :to => redirect { |params, request| + # path = (params[:number].to_i.even? ? "wheres-the-beef" : "i-love-lamp") # "http://#{request.host_with_port}/#{path}" - # end + # } # # The options version of redirect allows you to supply only the parts of the url which need # to change, it also supports interpolation of the path similar to the first example. diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index cde6cb20cc..8168bd4fcc 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -291,6 +291,7 @@ module ActionDispatch def clear! @finalized = false + @url_helpers = nil named_routes.clear set.clear formatter.clear @@ -441,12 +442,12 @@ module ActionDispatch normalize_options! normalize_controller_action_id! use_relative_controller! - controller.sub!(%r{^/}, '') if controller + normalize_controller! handle_nil_action! end def controller - @controller ||= @options[:controller] + @options[:controller] end def current_controller @@ -503,10 +504,15 @@ module ActionDispatch old_parts = current_controller.split('/') size = controller.count("/") + 1 parts = old_parts[0...-size] << controller - @controller = @options[:controller] = parts.join("/") + @options[:controller] = parts.join("/") end end + # Remove leading slashes from controllers + def normalize_controller! + @options[:controller] = controller.sub(%r{^/}, '') if controller + end + # This handles the case of :action => nil being explicitly passed. # It is identical to :action => "index" def handle_nil_action! diff --git a/actionpack/lib/action_pack/version.rb b/actionpack/lib/action_pack/version.rb index 7296b19cf7..ab0dd1d618 100644 --- a/actionpack/lib/action_pack/version.rb +++ b/actionpack/lib/action_pack/version.rb @@ -2,7 +2,7 @@ module ActionPack module VERSION #:nodoc: MAJOR = 3 MINOR = 2 - TINY = 8 + TINY = 9 PRE = nil STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.') diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb index 87e2332c42..cb3e8b9d7f 100644 --- a/actionpack/lib/action_view/helpers/date_helper.rb +++ b/actionpack/lib/action_view/helpers/date_helper.rb @@ -65,12 +65,16 @@ module ActionView # distance_of_time_in_words(Time.now, Time.now) # => less than a minute # def distance_of_time_in_words(from_time, to_time = 0, include_seconds = false, options = {}) + options = { + :scope => :'datetime.distance_in_words', + }.merge!(options) + from_time = from_time.to_time if from_time.respond_to?(:to_time) to_time = to_time.to_time if to_time.respond_to?(:to_time) distance_in_minutes = (((to_time - from_time).abs)/60).round distance_in_seconds = ((to_time - from_time).abs).round - I18n.with_options :locale => options[:locale], :scope => :'datetime.distance_in_words' do |locale| + I18n.with_options :locale => options[:locale], :scope => options[:scope] do |locale| case distance_in_minutes when 0..1 return distance_in_minutes == 0 ? @@ -129,8 +133,8 @@ module ActionView # from_time = Time.now - 3.days - 14.minutes - 25.seconds # time_ago_in_words(from_time) # => 3 days # - def time_ago_in_words(from_time, include_seconds = false) - distance_of_time_in_words(from_time, Time.now, include_seconds) + def time_ago_in_words(from_time, include_seconds = false, options = {}) + distance_of_time_in_words(from_time, Time.now, include_seconds, options) end alias_method :distance_of_time_in_words_to_now, :time_ago_in_words diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index a3409ee3c7..d00bad7608 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -1205,9 +1205,11 @@ module ActionView options["name"] ||= tag_name_with_index(@auto_index) options["id"] = options.fetch("id"){ tag_id_with_index(@auto_index) } else - options["name"] ||= tag_name + (options['multiple'] ? '[]' : '') + options["name"] ||= tag_name options["id"] = options.fetch("id"){ tag_id } end + + options["name"] += "[]" if options["multiple"] options["id"] = [options.delete('namespace'), options["id"]].compact.join("_").presence end diff --git a/actionpack/lib/action_view/helpers/form_tag_helper.rb b/actionpack/lib/action_view/helpers/form_tag_helper.rb index 670ff18a66..f0573437ca 100644 --- a/actionpack/lib/action_view/helpers/form_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/form_tag_helper.rb @@ -45,7 +45,7 @@ module ActionView # # => <form action="/posts" method="post"> # # form_tag('/posts/1', :method => :put) - # # => <form action="/posts/1" method="put"> + # # => <form action="/posts/1" method="post"> ... <input name="_method" type="hidden" value="put" /> ... # # form_tag('/upload', :multipart => true) # # => <form action="/upload" method="post" enctype="multipart/form-data"> @@ -53,7 +53,7 @@ module ActionView # <%= form_tag('/posts') do -%> # <div><%= submit_tag 'Save' %></div> # <% end -%> - # # => <form action="/posts" method="post"><div><input type="submit" name="submit" value="Save" /></div></form> + # # => <form action="/posts" method="post"><div><input type="submit" name="commit" value="Save" /></div></form> # # <%= form_tag('/posts', :remote => true) %> # # => <form action="/posts" method="post" data-remote="true"> diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb index 1f1cd3cee3..812bb4de9e 100644 --- a/actionpack/lib/action_view/helpers/url_helper.rb +++ b/actionpack/lib/action_view/helpers/url_helper.rb @@ -633,7 +633,9 @@ module ActionView end def link_to_remote_options?(options) - options.is_a?(Hash) && options.key?('remote') && options.delete('remote') + if options.is_a?(Hash) + options.delete('remote') || options.delete(:remote) + end end def add_method_to_attributes!(html_options, method) diff --git a/actionpack/lib/action_view/template/handlers/erb.rb b/actionpack/lib/action_view/template/handlers/erb.rb index ea495ea9ca..6cc6a8f8ed 100644 --- a/actionpack/lib/action_view/template/handlers/erb.rb +++ b/actionpack/lib/action_view/template/handlers/erb.rb @@ -48,6 +48,10 @@ module ActionView class_attribute :erb_implementation self.erb_implementation = Erubis + # Do not escape templates of these mime types. + class_attribute :escape_whitelist + self.escape_whitelist = ["text/plain"] + ENCODING_TAG = Regexp.new("\\A(<%#{ENCODING_FLAG}-?%>)[ \\t]*") def self.call(template) @@ -83,6 +87,7 @@ module ActionView self.class.erb_implementation.new( erb, + :escape => (self.class.escape_whitelist.include? template.mime_type), :trim => (self.class.erb_trim_mode == "-") ).src end diff --git a/actionpack/lib/sprockets/static_compiler.rb b/actionpack/lib/sprockets/static_compiler.rb index 2e2db4b760..4341a27d5d 100644 --- a/actionpack/lib/sprockets/static_compiler.rb +++ b/actionpack/lib/sprockets/static_compiler.rb @@ -15,13 +15,11 @@ module Sprockets def compile manifest = {} - env.each_logical_path do |logical_path| - if File.basename(logical_path)[/[^\.]+/, 0] == 'index' - logical_path.sub!(/\/index\./, '.') - end - next unless compile_path?(logical_path) + env.each_logical_path(paths) do |logical_path| if asset = env.find_asset(logical_path) - manifest[logical_path] = write_asset(asset) + digest_path = write_asset(asset) + manifest[asset.logical_path] = digest_path + manifest[aliased_path_for(asset.logical_path)] = digest_path end end write_manifest(manifest) if @manifest @@ -43,22 +41,16 @@ module Sprockets end end - def compile_path?(logical_path) - paths.each do |path| - case path - when Regexp - return true if path.match(logical_path) - when Proc - return true if path.call(logical_path) - else - return true if File.fnmatch(path.to_s, logical_path) - end - end - false - end - def path_for(asset) @digest ? asset.digest_path : asset.logical_path end + + def aliased_path_for(logical_path) + if File.basename(logical_path).start_with?('index') + logical_path.sub(/\/index([^\/]+)$/, '\1') + else + logical_path.sub(/\.([^\/]+)$/, '/index.\1') + end + end end end diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb index afaf9e5ea9..8c631e218f 100644 --- a/actionpack/test/controller/render_test.rb +++ b/actionpack/test/controller/render_test.rb @@ -1405,6 +1405,17 @@ class RenderTest < ActionController::TestCase assert_equal "Bonjour: davidBonjour: mary", @response.body end + def test_locals_option_to_assert_template_is_not_supported + warning_buffer = StringIO.new + $stderr = warning_buffer + + get :partial_collection_with_locals + assert_template :partial => 'customer_greeting', :locals => { :greeting => 'Bonjour' } + assert_equal "the :locals option to #assert_template is only supported in a ActionView::TestCase\n", warning_buffer.string + ensure + $stderr = STDERR + end + def test_partial_collection_with_spacer get :partial_collection_with_spacer assert_equal "Hello: davidonly partialHello: mary", @response.body diff --git a/actionpack/test/controller/send_file_test.rb b/actionpack/test/controller/send_file_test.rb index 8f885ff28e..4e4dd8d005 100644 --- a/actionpack/test/controller/send_file_test.rb +++ b/actionpack/test/controller/send_file_test.rb @@ -118,6 +118,18 @@ class SendFileTest < ActionController::TestCase assert_equal 'private', h['Cache-Control'] end + def test_send_file_headers_with_disposition_as_a_symbol + options = { + :type => Mime::PNG, + :disposition => :disposition, + :filename => 'filename' + } + + @controller.headers = {} + @controller.send(:send_file_headers!, options) + assert_equal 'disposition; filename="filename"', @controller.headers['Content-Disposition'] + end + def test_send_file_headers_with_mime_lookup_with_symbol options = { :type => :png @@ -138,7 +150,7 @@ class SendFileTest < ActionController::TestCase @controller.headers = {} assert_raise(ArgumentError){ @controller.send(:send_file_headers!, options) } end - + def test_send_file_headers_guess_type_from_extension { 'image.png' => 'image/png', diff --git a/actionpack/test/controller/test_test.rb b/actionpack/test/controller/test_test.rb index 6a5843f9d7..1da5298900 100644 --- a/actionpack/test/controller/test_test.rb +++ b/actionpack/test/controller/test_test.rb @@ -766,6 +766,12 @@ XML assert_equal '159528', @response.body end + def test_action_dispatch_uploaded_file_upload + tf = Class.new { def size; 159528 end } + post :test_file_upload, :file => ActionDispatch::Http::UploadedFile.new(:tempfile => tf.new) + assert_equal '159528', @response.body + end + def test_test_uploaded_file_exception_when_file_doesnt_exist assert_raise(RuntimeError) { Rack::Test::UploadedFile.new('non_existent_file') } end diff --git a/actionpack/test/dispatch/best_standards_support_test.rb b/actionpack/test/dispatch/best_standards_support_test.rb new file mode 100644 index 0000000000..0737c40a39 --- /dev/null +++ b/actionpack/test/dispatch/best_standards_support_test.rb @@ -0,0 +1,34 @@ +require 'abstract_unit' + +class BestStandardsSupportTest < ActiveSupport::TestCase + def test_with_best_standards_support + _, headers, _ = app(true, {}).call({}) + assert_equal "IE=Edge,chrome=1", headers["X-UA-Compatible"] + end + + def test_with_builtin_best_standards_support + _, headers, _ = app(:builtin, {}).call({}) + assert_equal "IE=Edge", headers["X-UA-Compatible"] + end + + def test_without_best_standards_support + _, headers, _ = app(false, {}).call({}) + assert_equal nil, headers["X-UA-Compatible"] + end + + def test_appends_to_app_headers + app_headers = { "X-UA-Compatible" => "requiresActiveX=true" } + _, headers, _ = app(true, app_headers).call({}) + + expects = "requiresActiveX=true,IE=Edge,chrome=1" + assert_equal expects, headers["X-UA-Compatible"] + end + + private + + def app(type, headers) + app = proc { [200, headers, "response"] } + ActionDispatch::BestStandardsSupport.new(app, type) + end + +end diff --git a/actionpack/test/dispatch/prefix_generation_test.rb b/actionpack/test/dispatch/prefix_generation_test.rb index bd5b5edab0..88dc2c093b 100644 --- a/actionpack/test/dispatch/prefix_generation_test.rb +++ b/actionpack/test/dispatch/prefix_generation_test.rb @@ -248,6 +248,11 @@ module TestGenerationPrefix assert_equal "/something/", app_object.root_path end + test "[OBJECT] generating application's route includes default_url_options[:trailing_slash]" do + RailsApplication.routes.default_url_options[:trailing_slash] = true + assert_equal "/awesome/blog/posts", engine_object.posts_path + end + test "[OBJECT] generating engine's route with url_for" do path = engine_object.url_for(:controller => "inside_engine_generating", :action => "show", diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb index 00c71dc8be..46d16598f7 100644 --- a/actionpack/test/dispatch/routing_test.rb +++ b/actionpack/test/dispatch/routing_test.rb @@ -280,6 +280,8 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest scope(':version', :version => /.+/) do resources :users, :id => /.+?/, :format => /json|xml/ end + + get "products/list" end match 'sprockets.js' => ::TestRoutingMapper::SprocketsApp @@ -885,6 +887,15 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest assert_equal original_options, options end + def test_url_for_does_not_modify_controller + controller = '/projects' + options = {:controller => controller, :action => 'status', :only_path => true} + url = url_for(options) + + assert_equal '/projects/status', url + assert_equal '/projects', controller + end + # tests the arguments modification free version of define_hash_access def test_named_route_with_no_side_effects original_options = { :host => 'test.host' } @@ -1185,6 +1196,26 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest end end + def test_resource_does_not_modify_passed_options + options = {:id => /.+?/, :format => /json|xml/} + self.class.stub_controllers do |routes| + routes.draw do + resource :user, options + end + end + assert_equal({:id => /.+?/, :format => /json|xml/}, options) + end + + def test_resources_does_not_modify_passed_options + options = {:id => /.+?/, :format => /json|xml/} + self.class.stub_controllers do |routes| + routes.draw do + resources :users, options + end + end + assert_equal({:id => /.+?/, :format => /json|xml/}, options) + end + def test_path_names with_test_routes do get '/pt/projetos' @@ -1376,6 +1407,14 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest end end + def test_match_shorthand_inside_namespace_with_controller + with_test_routes do + assert_equal '/api/products/list', api_products_list_path + get '/api/products/list' + assert_equal 'api/products#list', @response.body + end + end + def test_dynamically_generated_helpers_on_collection_do_not_clobber_resources_url_helper with_test_routes do assert_equal '/replies', replies_path diff --git a/actionpack/test/dispatch/uploaded_file_test.rb b/actionpack/test/dispatch/uploaded_file_test.rb index 7e4a1519fb..fae39a403e 100644 --- a/actionpack/test/dispatch/uploaded_file_test.rb +++ b/actionpack/test/dispatch/uploaded_file_test.rb @@ -12,7 +12,7 @@ module ActionDispatch uf = Http::UploadedFile.new(:filename => 'foo', :tempfile => Object.new) assert_equal 'foo', uf.original_filename end - + if "ruby".encoding_aware? def test_filename_should_be_in_utf_8 uf = Http::UploadedFile.new(:filename => 'foo', :tempfile => Object.new) diff --git a/actionpack/test/template/date_helper_i18n_test.rb b/actionpack/test/template/date_helper_i18n_test.rb index d45215acfd..b0b407b473 100644 --- a/actionpack/test/template/date_helper_i18n_test.rb +++ b/actionpack/test/template/date_helper_i18n_test.rb @@ -36,16 +36,25 @@ class DateHelperDistanceOfTimeInWordsI18nTests < Test::Unit::TestCase end end - def assert_distance_of_time_in_words_translates_key(passed, expected) + def test_distance_of_time_in_words_calls_i18n_with_custom_scope + { + [30.days, false] => [:'about_x_months', 1], + [60.days, false] => [:'x_months', 2], + }.each do |passed, expected| + assert_distance_of_time_in_words_translates_key(passed, expected, {:scope => :'datetime.distance_in_words_ago'}) + end + end + + def assert_distance_of_time_in_words_translates_key(passed, expected, options = {}) diff, include_seconds = *passed key, count = *expected to = @from + diff - options = {:locale => 'en', :scope => :'datetime.distance_in_words'} + options = {:locale => 'en', :scope => :'datetime.distance_in_words'}.merge(options) options[:count] = count if count I18n.expects(:t).with(key, options) - distance_of_time_in_words(@from, to, include_seconds, :locale => 'en') + distance_of_time_in_words(@from, to, include_seconds, options) end def test_distance_of_time_pluralizations diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb index 19af01e2c8..49a325af79 100644 --- a/actionpack/test/template/form_helper_test.rb +++ b/actionpack/test/template/form_helper_test.rb @@ -393,6 +393,19 @@ class FormHelperTest < ActionView::TestCase ) end + def test_check_box_with_multiple_behavior_and_index + @post.comment_ids = [2,3] + assert_dom_equal( + '<input name="post[foo][comment_ids][]" type="hidden" value="0" /><input id="post_foo_comment_ids_1" name="post[foo][comment_ids][]" type="checkbox" value="1" />', + check_box("post", "comment_ids", { :multiple => true, :index => "foo" }, 1) + ) + assert_dom_equal( + '<input name="post[bar][comment_ids][]" type="hidden" value="0" /><input checked="checked" id="post_bar_comment_ids_3" name="post[bar][comment_ids][]" type="checkbox" value="3" />', + check_box("post", "comment_ids", { :multiple => true, :index => "bar" }, 3) + ) + + end + def test_checkbox_disabled_disables_hidden_field assert_dom_equal( '<input name="post[secret]" type="hidden" value="0" disabled="disabled"/><input checked="checked" disabled="disabled" id="post_secret" name="post[secret]" type="checkbox" value="1" />', diff --git a/actionpack/test/template/sprockets_helper_test.rb b/actionpack/test/template/sprockets_helper_test.rb index 72d03e43e9..e944cfaee3 100644 --- a/actionpack/test/template/sprockets_helper_test.rb +++ b/actionpack/test/template/sprockets_helper_test.rb @@ -1,7 +1,7 @@ require 'abstract_unit' require 'sprockets' require 'sprockets/helpers/rails_helper' -require 'mocha' +require 'mocha/setup' class SprocketsHelperTest < ActionView::TestCase include Sprockets::Helpers::RailsHelper diff --git a/actionpack/test/template/sprockets_helper_with_routes_test.rb b/actionpack/test/template/sprockets_helper_with_routes_test.rb index bcbd81a7dd..bc253ea0fd 100644 --- a/actionpack/test/template/sprockets_helper_with_routes_test.rb +++ b/actionpack/test/template/sprockets_helper_with_routes_test.rb @@ -1,7 +1,7 @@ require 'abstract_unit' require 'sprockets' require 'sprockets/helpers/rails_helper' -require 'mocha' +require 'mocha/setup' class SprocketsHelperWithRoutesTest < ActionView::TestCase include Sprockets::Helpers::RailsHelper @@ -54,4 +54,4 @@ class SprocketsHelperWithRoutesTest < ActionView::TestCase stylesheet_link_tag(:application) end -end
\ No newline at end of file +end diff --git a/actionpack/test/template/template_test.rb b/actionpack/test/template/template_test.rb index 5880eb2bd4..aa7f5b31fc 100644 --- a/actionpack/test/template/template_test.rb +++ b/actionpack/test/template/template_test.rb @@ -25,6 +25,10 @@ class TestERBTemplate < ActiveSupport::TestCase "Hello" end + def apostrophe + "l'apostrophe" + end + def partial ActionView::Template.new( "<%= @virtual_path %>", @@ -47,7 +51,7 @@ class TestERBTemplate < ActiveSupport::TestCase end end - def new_template(body = "<%= hello %>", details = {}) + def new_template(body = "<%= hello %>", details = { :format => :html }) ActionView::Template.new(body, "hello template", ERBHandler, {:virtual_path => "hello"}.merge!(details)) end @@ -64,6 +68,16 @@ class TestERBTemplate < ActiveSupport::TestCase assert_equal "Hello", render end + def test_basic_template_does_html_escape + @template = new_template("<%= apostrophe %>") + assert_equal "l'apostrophe", render + end + + def test_text_template_does_not_html_escape + @template = new_template("<%= apostrophe %>", :format => :text) + assert_equal "l'apostrophe", render + end + def test_template_loses_its_source_after_rendering @template = new_template render diff --git a/actionpack/test/template/url_helper_test.rb b/actionpack/test/template/url_helper_test.rb index d55b1fd2bd..38f77203e0 100644 --- a/actionpack/test/template/url_helper_test.rb +++ b/actionpack/test/template/url_helper_test.rb @@ -227,6 +227,13 @@ class UrlHelperTest < ActiveSupport::TestCase ) end + def test_link_to_with_symbolic_remote_in_non_html_options + assert_dom_equal( + "<a href=\"/\" data-remote=\"true\">Hello</a>", + link_to("Hello", hash_for([:remote, true]), {}) + ) + end + def test_link_tag_using_post_javascript assert_dom_equal( "<a href='http://www.example.com' data-method=\"post\" rel=\"nofollow\">Hello</a>", |