diff options
Diffstat (limited to 'actionpack')
21 files changed, 252 insertions, 121 deletions
diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index 0ec42cc6de..6f8314109b 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -1,5 +1,7 @@ *Rails 3.1.0 (unreleased)* +* file_field automatically adds :multipart => true to the enclosing form. [Santiago Pastorino] + * Renames csrf_meta_tag -> csrf_meta_tags, and aliases csrf_meta_tag for backwards compatibility. [fxn] * Add Rack::Cache to the default stack. Create a Rails store that delegates to the Rails cache, so by default, whatever caching layer you are using will be used diff --git a/actionpack/Rakefile b/actionpack/Rakefile index d67c6f2410..521ee6913a 100644 --- a/actionpack/Rakefile +++ b/actionpack/Rakefile @@ -18,7 +18,8 @@ Rake::TestTask.new(:test_action_pack) do |t| # this will not happen automatically and the tests (as a whole) will error t.test_files = Dir.glob('test/{abstract,controller,dispatch,template}/**/*_test.rb').sort - # t.warning = true + #t.warning = true + t.verbose = true end namespace :test do diff --git a/actionpack/actionpack.gemspec b/actionpack/actionpack.gemspec index 75ac47105d..0e91b44914 100644 --- a/actionpack/actionpack.gemspec +++ b/actionpack/actionpack.gemspec @@ -26,7 +26,7 @@ Gem::Specification.new do |s| s.add_dependency('builder', '~> 2.1.2') s.add_dependency('i18n', '~> 0.4.1') s.add_dependency('rack', '~> 1.2.1') - s.add_dependency('rack-test', '~> 0.5.4') + s.add_dependency('rack-test', '~> 0.5.5') s.add_dependency('rack-mount', '~> 0.6.13') s.add_dependency('tzinfo', '~> 0.3.23') s.add_dependency('erubis', '~> 2.6.6') diff --git a/actionpack/lib/action_controller/metal/conditional_get.rb b/actionpack/lib/action_controller/metal/conditional_get.rb index 797ad846f6..8930c13a68 100644 --- a/actionpack/lib/action_controller/metal/conditional_get.rb +++ b/actionpack/lib/action_controller/metal/conditional_get.rb @@ -17,7 +17,7 @@ module ActionController # # def show # @article = Article.find(params[:id]) - # fresh_when(:etag => @article, :last_modified => @article.created_at.utc, :public => true) + # fresh_when(:etag => @article, :last_modified => @article.created_at, :public => true) # end # # This will render the show template if the request isn't sending a matching etag or @@ -48,7 +48,7 @@ module ActionController # def show # @article = Article.find(params[:id]) # - # if stale?(:etag => @article, :last_modified => @article.created_at.utc) + # if stale?(:etag => @article, :last_modified => @article.created_at) # @statistics = @article.really_expensive_call # respond_to do |format| # # all the supported formats diff --git a/actionpack/lib/action_controller/metal/head.rb b/actionpack/lib/action_controller/metal/head.rb index a5c9910d68..2b4a3b9392 100644 --- a/actionpack/lib/action_controller/metal/head.rb +++ b/actionpack/lib/action_controller/metal/head.rb @@ -22,7 +22,7 @@ module ActionController location = options.delete(:location) options.each do |key, value| - headers[key.to_s.dasherize.split(/-/).map { |v| v.capitalize }.join("-")] = value.to_s + headers[key.to_s.dasherize.split('-').each { |v| v[0] = v[0].chr.upcase }.join('-')] = value.to_s end self.status = status diff --git a/actionpack/lib/action_controller/metal/http_authentication.rb b/actionpack/lib/action_controller/metal/http_authentication.rb index 1d74521e4f..251b1a8a8b 100644 --- a/actionpack/lib/action_controller/metal/http_authentication.rb +++ b/actionpack/lib/action_controller/metal/http_authentication.rb @@ -30,7 +30,7 @@ module ActionController # # # === Advanced \Basic example - # + # # Here is a more advanced \Basic example where only Atom feeds and the XML API is protected by HTTP authentication, # the regular HTML interface is protected by a session approach: # @@ -98,7 +98,7 @@ module ActionController # end # # === Notes - # + # # The +authenticate_or_request_with_http_digest+ block must return the user's password # or the ha1 digest hash so the framework can appropriately hash to check the user's # credentials. Returning +nil+ will cause authentication to fail. @@ -222,11 +222,10 @@ module ActionController end def decode_credentials(header) - header.to_s.gsub(/^Digest\s+/,'').split(',').inject({}) do |hash, pair| + Hash[header.to_s.gsub(/^Digest\s+/,'').split(',').map do |pair| key, value = pair.split('=', 2) - hash[key.strip.to_sym] = value.to_s.gsub(/^"|"$/,'').gsub(/'/, '') - hash - end + [key.strip.to_sym, value.to_s.gsub(/^"|"$/,'').gsub(/'/, '')] + end] end def authentication_header(controller, realm) diff --git a/actionpack/lib/action_controller/vendor/html-scanner/html/node.rb b/actionpack/lib/action_controller/vendor/html-scanner/html/node.rb index 0eaad2b911..85250721e7 100644 --- a/actionpack/lib/action_controller/vendor/html-scanner/html/node.rb +++ b/actionpack/lib/action_controller/vendor/html-scanner/html/node.rb @@ -38,18 +38,14 @@ module HTML #:nodoc: private def keys_to_strings(hash) - hash.keys.inject({}) do |h,k| - h[k.to_s] = hash[k] - h - end + Hash[hash.keys.map {|k| [k.to_s, hash[k]]}] end def keys_to_symbols(hash) - hash.keys.inject({}) do |h,k| + Hash[hash.keys.map do |k| raise "illegal key #{k.inspect}" unless k.respond_to?(:to_sym) - h[k.to_sym] = hash[k] - h - end + [k.to_sym, hash[k]] + end] end end diff --git a/actionpack/lib/action_dispatch/http/upload.rb b/actionpack/lib/action_dispatch/http/upload.rb index 8ee4b81cdd..49465d820e 100644 --- a/actionpack/lib/action_dispatch/http/upload.rb +++ b/actionpack/lib/action_dispatch/http/upload.rb @@ -2,32 +2,27 @@ require 'active_support/core_ext/object/blank' module ActionDispatch module Http - module UploadedFile - def self.extended(object) - object.class_eval do - attr_accessor :original_path, :content_type - alias_method :local_path, :path if method_defined?(:path) - end - end + class UploadedFile < Tempfile + attr_accessor :original_filename, :content_type, :tempfile, :headers - # Take the basename of the upload's original filename. - # This handles the full Windows paths given by Internet Explorer - # (and perhaps other broken user agents) without affecting - # those which give the lone filename. - # The Windows regexp is adapted from Perl's File::Basename. - def original_filename - unless defined? @original_filename - @original_filename = - unless original_path.blank? - if original_path =~ /^(?:.*[:\\\/])?(.*)/m - $1 - else - File.basename original_path - end - end + def initialize(hash) + @original_filename = hash[:filename] + @content_type = hash[:type] + @headers = hash[:head] + + # To the untrained eye, this may appear as insanity. Given the alternatives, + # such as busting the method cache on every request or breaking backwards + # compatibility with is_a?(Tempfile), this solution is the best available + # option. + # + # TODO: Deprecate is_a?(Tempfile) and define a real API for this parameter + tempfile = hash[:tempfile] + tempfile.instance_variables.each do |ivar| + instance_variable_set(ivar, tempfile.instance_variable_get(ivar)) end - @original_filename end + + alias local_path path end module Upload @@ -35,11 +30,7 @@ module ActionDispatch # file upload hash with UploadedFile objects def normalize_parameters(value) if Hash === value && value.has_key?(:tempfile) - upload = value[:tempfile] - upload.extend(UploadedFile) - upload.original_path = value[:filename] - upload.content_type = value[:type] - upload + UploadedFile.new(value) else super end @@ -47,4 +38,4 @@ module ActionDispatch private :normalize_parameters end end -end
\ No newline at end of file +end diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 8a161b0837..fe85acb94e 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -149,6 +149,10 @@ module ActionDispatch controller = [@scope[:module], controller].compact.join("/").presence end + if controller.is_a?(String) && controller =~ %r{\A/} + raise ArgumentError, "controller name should not start with a slash" + end + controller = controller.to_s unless controller.is_a?(Regexp) action = action.to_s unless action.is_a?(Regexp) diff --git a/actionpack/lib/action_dispatch/routing/route.rb b/actionpack/lib/action_dispatch/routing/route.rb index aefebf8f80..f91a48e16c 100644 --- a/actionpack/lib/action_dispatch/routing/route.rb +++ b/actionpack/lib/action_dispatch/routing/route.rb @@ -21,11 +21,7 @@ module ActionDispatch conditions[:path_info] = ::Rack::Mount::Strexp.compile(path, requirements, SEPARATORS, anchor) end - @conditions = conditions.inject({}) { |h, (k, v)| - h[k] = Rack::Mount::RegexpWithNamedGroups.new(v) - h - } - + @conditions = Hash[conditions.map { |k,v| [k, Rack::Mount::RegexpWithNamedGroups.new(v)] }] @conditions.delete_if{ |k,v| k != :path_info && !valid_condition?(k) } @requirements.delete_if{ |k,v| !valid_condition?(k) } end diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 835ba03784..1a5f21bd09 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -217,27 +217,35 @@ module ActionDispatch self.valid_conditions.delete(:id) self.valid_conditions.push(:controller, :action) + @append = [] @disable_clear_and_finalize = false clear! end def draw(&block) clear! unless @disable_clear_and_finalize + eval_block(block) + finalize! unless @disable_clear_and_finalize + + nil + end + + def append(&block) + @append << block + end + def eval_block(block) mapper = Mapper.new(self) if default_scope mapper.with_default_scope(default_scope, &block) else mapper.instance_exec(&block) end - - finalize! unless @disable_clear_and_finalize - - nil end def finalize! return if @finalized + @append.each { |blk| eval_block(blk) } @finalized = true @set.freeze end @@ -558,13 +566,8 @@ module ActionDispatch keys = options.delete(:_positional_keys) keys -= options.keys if args.size < keys.size - 1 # take format into account - args = args.zip(keys).inject({}) do |h, (v, k)| - h[k] = v - h - end - # Tell url_for to skip default_url_options - options.merge!(args) + options.merge!(Hash[args.zip(keys).map { |v, k| [k, v] }]) end def rewrite_authentication(options) diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb index 590ebbf364..a681c9a5b6 100644 --- a/actionpack/lib/action_dispatch/testing/integration.rb +++ b/actionpack/lib/action_dispatch/testing/integration.rb @@ -257,17 +257,19 @@ module ActionDispatch end end + port = host.split(':')[1] + env = { :method => method, :params => parameters, "SERVER_NAME" => host.split(':')[0], - "SERVER_PORT" => (https? ? "443" : "80"), + "SERVER_PORT" => (port ? port : (https? ? "443" : "80")), "HTTPS" => https? ? "on" : "off", "rack.url_scheme" => https? ? "https" : "http", "REQUEST_URI" => path, - "HTTP_HOST" => host, + "HTTP_HOST" => [host, port].compact.join(':'), "REMOTE_ADDR" => remote_addr, "CONTENT_TYPE" => "application/x-www-form-urlencoded", "HTTP_ACCEPT" => accept diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb index fdc40c8f2e..687cb83d75 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb @@ -827,7 +827,7 @@ module ActionView def expand_javascript_sources(sources, recursive = false) if sources.include?(:all) - all_javascript_files = collect_asset_files(config.javascripts_dir, ('**' if recursive), '*.js') + all_javascript_files = (collect_asset_files(config.javascripts_dir, ('**' if recursive), '*.js') - ['application']) << 'application' ((determine_source(:defaults, @@javascript_expansions).dup & all_javascript_files) + all_javascript_files).uniq else expanded_sources = sources.collect do |source| diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index 3cc412de63..0937075edf 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -317,8 +317,11 @@ module ActionView options[:html] ||= {} options[:html][:remote] = options.delete(:remote) - output = form_tag(options.delete(:url) || {}, options.delete(:html) || {}) - output << fields_for(object_name, object, options, &proc) + builder = options[:parent_builder] = instantiate_builder(object_name, object, options, &proc) + fields_for = fields_for(object_name, object, options, &proc) + default_options = builder.multipart? ? { :multipart => true } : {} + output = form_tag(options.delete(:url) || {}, default_options.merge!(options.delete(:html) || {})) + output << fields_for output.safe_concat('</form>') end @@ -339,8 +342,8 @@ module ActionView options[:html] ||= {} options[:html].reverse_merge!(html_options) - options[:url] ||= options[:format] ? \ - polymorphic_path(object_or_array, :format => options.delete(:format)) : \ + options[:url] ||= options[:format] ? + polymorphic_path(object_or_array, :format => options.delete(:format)) : polymorphic_path(object_or_array) end @@ -529,22 +532,7 @@ module ActionView # <% end %> # <% end %> def fields_for(record, record_object = nil, options = nil, &block) - raise ArgumentError, "Missing block" unless block_given? - - options, record_object = record_object, nil if record_object.is_a?(Hash) - options ||= {} - - case record - when String, Symbol - object = record_object - object_name = record - else - object = record - object_name = ActiveModel::Naming.param_key(object) - end - - builder = options[:builder] || ActionView::Base.default_form_builder - capture(builder.new(object_name, object, self, options, block), &block) + capture(instantiate_builder(record, record_object, options, &block), &block) end # Returns a label tag tailored for labelling an input field for a specified attribute (identified by +method+) on an object @@ -850,6 +838,25 @@ module ActionView def range_field(object_name, method, options = {}) InstanceTag.new(object_name, method, self, options.delete(:object)).to_number_field_tag("range", options) end + + private + + def instantiate_builder(record, record_object = nil, options = nil, &block) + options, record_object = record_object, nil if record_object.is_a?(Hash) + options ||= {} + + case record + when String, Symbol + object = record_object + object_name = record + else + object = record + object_name = ActiveModel::Naming.param_key(object) + end + + builder = options[:builder] || ActionView::Base.default_form_builder + builder.new(object_name, object, self, options, block) + end end module InstanceTagMethods #:nodoc: @@ -858,9 +865,9 @@ module ActionView attr_reader :method_name, :object_name - DEFAULT_FIELD_OPTIONS = { "size" => 30 }.freeze - DEFAULT_RADIO_OPTIONS = { }.freeze - DEFAULT_TEXT_AREA_OPTIONS = { "cols" => 40, "rows" => 20 }.freeze + DEFAULT_FIELD_OPTIONS = { "size" => 30 } + DEFAULT_RADIO_OPTIONS = { } + DEFAULT_TEXT_AREA_OPTIONS = { "cols" => 40, "rows" => 20 } def initialize(object_name, method_name, template_object, object = nil) @object_name, @method_name = object_name.to_s.dup, method_name.to_s.dup @@ -1114,6 +1121,14 @@ module ActionView attr_accessor :object_name, :object, :options + attr_reader :multipart, :parent_builder + alias :multipart? :multipart + + def multipart=(multipart) + @multipart = multipart + parent_builder.multipart = multipart if parent_builder + end + def self.model_name @model_name ||= Struct.new(:partial_path).new(name.demodulize.underscore.sub!(/_builder$/, '')) end @@ -1125,6 +1140,7 @@ module ActionView def initialize(object_name, object, template, options, proc) @nested_child_index = {} @object_name, @object, @template, @options, @proc = object_name, object, template, options, proc + @parent_builder = options[:parent_builder] @default_options = @options ? @options.slice(:index) : {} if @object_name.to_s.match(/\[\]$/) if object ||= @template.instance_variable_get("@#{Regexp.last_match.pre_match}") and object.respond_to?(:to_param) @@ -1133,9 +1149,10 @@ module ActionView raise ArgumentError, "object[] naming but object param and @object var don't exist or don't respond to to_param: #{object.inspect}" end end + @multipart = nil end - (field_helpers - %w(label check_box radio_button fields_for hidden_field)).each do |selector| + (field_helpers - %w(label check_box radio_button fields_for hidden_field file_field)).each do |selector| class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 def #{selector}(method, options = {}) # def text_field(method, options = {}) @template.send( # @template.send( @@ -1157,10 +1174,9 @@ module ActionView index = "" end - if options[:builder] - args << {} unless args.last.is_a?(Hash) - args.last[:builder] ||= options[:builder] - end + args << {} unless args.last.is_a?(Hash) + args.last[:builder] ||= options[:builder] + args.last[:parent_builder] = self case record_or_name_or_array when String, Symbol @@ -1199,6 +1215,10 @@ module ActionView @template.hidden_field(@object_name, method, objectify_options(options)) end + def file_field(method, options = {}) + self.multipart = true + @template.file_field(@object_name, method, objectify_options(options)) + end # Add the submit button for the given form. When no value is given, it checks # if the object is a new resource or not to create the proper label: # diff --git a/actionpack/lib/action_view/test_case.rb b/actionpack/lib/action_view/test_case.rb index 2c2661df26..ff35fb7df4 100644 --- a/actionpack/lib/action_view/test_case.rb +++ b/actionpack/lib/action_view/test_case.rb @@ -189,11 +189,7 @@ module ActionView end def _assigns - _instance_variables.inject({}) do |hash, var| - name = var[1..-1].to_sym - hash[name] = instance_variable_get(var) - hash - end + _instance_variables.map { |var| [var[1..-1].to_sym, instance_variable_get(var)] } end def _routes diff --git a/actionpack/test/controller/assert_select_test.rb b/actionpack/test/controller/assert_select_test.rb index 2600dae3c5..f63321c78b 100644 --- a/actionpack/test/controller/assert_select_test.rb +++ b/actionpack/test/controller/assert_select_test.rb @@ -459,8 +459,8 @@ class AssertSelectTest < ActionController::TestCase assert_select_rjs :remove, "test1" - rescue Assertion - assert_equal "No RJS statement that removes 'test1' was rendered.", $!.message + rescue Assertion => e + assert_equal "No RJS statement that removes 'test1' was rendered.", e.message end def test_assert_select_rjs_for_remove_ignores_block @@ -491,8 +491,8 @@ class AssertSelectTest < ActionController::TestCase assert_select_rjs :show, "test1" - rescue Assertion - assert_equal "No RJS statement that shows 'test1' was rendered.", $!.message + rescue Assertion => e + assert_equal "No RJS statement that shows 'test1' was rendered.", e.message end def test_assert_select_rjs_for_show_ignores_block @@ -523,8 +523,8 @@ class AssertSelectTest < ActionController::TestCase assert_select_rjs :hide, "test1" - rescue Assertion - assert_equal "No RJS statement that hides 'test1' was rendered.", $!.message + rescue Assertion => e + assert_equal "No RJS statement that hides 'test1' was rendered.", e.message end def test_assert_select_rjs_for_hide_ignores_block @@ -555,8 +555,8 @@ class AssertSelectTest < ActionController::TestCase assert_select_rjs :toggle, "test1" - rescue Assertion - assert_equal "No RJS statement that toggles 'test1' was rendered.", $!.message + rescue Assertion => e + assert_equal "No RJS statement that toggles 'test1' was rendered.", e.message end def test_assert_select_rjs_for_toggle_ignores_block @@ -729,7 +729,7 @@ EOF end def render_rjs(&block) - @controller.response_with &block + @controller.response_with(&block) get :rjs end diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index 84b796ba72..a83f5155f8 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -637,7 +637,7 @@ class FragmentCachingTest < ActionController::TestCase @store.write('views/another_name', 'another_value') @store.write('views/primalgrasp', 'will not expire ;-)') - @controller.expire_fragment /name/ + @controller.expire_fragment(/name/) assert_nil @store.read('views/name') assert_nil @store.read('views/another_name') @@ -727,22 +727,22 @@ CACHED def test_fragment_caching_in_partials get :html_fragment_cached_with_partial assert_response :success - assert_match /Old fragment caching in a partial/, @response.body + assert_match(/Old fragment caching in a partial/, @response.body) assert_match "Old fragment caching in a partial", @store.read('views/test.host/functional_caching/html_fragment_cached_with_partial') end def test_render_inline_before_fragment_caching get :inline_fragment_cached assert_response :success - assert_match /Some inline content/, @response.body - assert_match /Some cached content/, @response.body + assert_match(/Some inline content/, @response.body) + assert_match(/Some cached content/, @response.body) assert_match "Some cached content", @store.read('views/test.host/functional_caching/inline_fragment_cached') end def test_fragment_caching_in_rjs_partials xhr :get, :js_fragment_cached_with_partial assert_response :success - assert_match /Old fragment caching in a partial/, @response.body + assert_match(/Old fragment caching in a partial/, @response.body) assert_match "Old fragment caching in a partial", @store.read('views/test.host/functional_caching/js_fragment_cached_with_partial') end diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb index ab12c0bf17..42723c834e 100644 --- a/actionpack/test/controller/render_test.rb +++ b/actionpack/test/controller/render_test.rb @@ -488,6 +488,10 @@ class TestController < ActionController::Base head :x_custom_header => "something" end + def head_with_www_authenticate_header + head 'WWW-Authenticate' => 'something' + end + def head_with_status_code_first head :forbidden, :x_custom_header => "something" end @@ -1139,6 +1143,13 @@ class RenderTest < ActionController::TestCase assert_response :ok end + def test_head_with_www_authenticate_header + get :head_with_www_authenticate_header + assert_blank @response.body + assert_equal "something", @response.headers["WWW-Authenticate"] + assert_response :ok + end + def test_head_with_symbolic_status get :head_with_symbolic_status, :status => "ok" assert_equal 200, @response.status diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb index b642adc06b..3daabf7a64 100644 --- a/actionpack/test/dispatch/routing_test.rb +++ b/actionpack/test/dispatch/routing_test.rb @@ -2128,6 +2128,38 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest assert_raises(ActionController::RoutingError){ list_todo_path(:list_id => '2', :id => '1') } end + def test_controller_name_with_leading_slash_raise_error + assert_raise(ArgumentError) do + self.class.stub_controllers do |routes| + routes.draw { get '/feeds/:service', :to => '/feeds#show' } + end + end + + assert_raise(ArgumentError) do + self.class.stub_controllers do |routes| + routes.draw { get '/feeds/:service', :controller => '/feeds', :action => 'show' } + end + end + + assert_raise(ArgumentError) do + self.class.stub_controllers do |routes| + routes.draw { get '/api/feeds/:service', :to => '/api/feeds#show' } + end + end + + assert_raise(ArgumentError) do + self.class.stub_controllers do |routes| + routes.draw { controller("/feeds") { get '/feeds/:service', :to => :show } } + end + end + + assert_raise(ArgumentError) do + self.class.stub_controllers do |routes| + routes.draw { resources :feeds, :controller => '/feeds' } + end + end + end + private def with_test_routes yield @@ -2152,6 +2184,39 @@ private end end +class TestAppendingRoutes < ActionController::IntegrationTest + def simple_app(resp) + lambda { |e| [ 200, { 'Content-Type' => 'text/plain' }, [resp] ] } + end + + setup do + s = self + @app = ActionDispatch::Routing::RouteSet.new + @app.append do + match '/hello' => s.simple_app('fail') + match '/goodbye' => s.simple_app('goodbye') + end + + @app.draw do + match '/hello' => s.simple_app('hello') + end + end + + def test_goodbye_should_be_available + get '/goodbye' + assert_equal 'goodbye', @response.body + end + + def test_hello_should_not_be_overwritten + get '/hello' + assert_equal 'hello', @response.body + end + + def test_missing_routes_are_still_missing + get '/random' + assert_equal 404, @response.status + end +end class TestDefaultScope < ActionController::IntegrationTest module ::Blog diff --git a/actionpack/test/template/asset_tag_helper_test.rb b/actionpack/test/template/asset_tag_helper_test.rb index 2b83cfe1a9..ec28d4442c 100644 --- a/actionpack/test/template/asset_tag_helper_test.rb +++ b/actionpack/test/template/asset_tag_helper_test.rb @@ -89,8 +89,8 @@ class AssetTagHelperTest < ActionView::TestCase %(javascript_include_tag("bank", :lang => "vbscript")) => %(<script lang="vbscript" src="/javascripts/bank.js" type="text/javascript"></script>), %(javascript_include_tag("common.javascript", "/elsewhere/cools")) => %(<script src="/javascripts/common.javascript" type="text/javascript"></script>\n<script src="/elsewhere/cools.js" type="text/javascript"></script>), %(javascript_include_tag(:defaults)) => %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/rails.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>), - %(javascript_include_tag(:all)) => %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/robber.js" type="text/javascript"></script>\n<script src="/javascripts/version.1.0.js" type="text/javascript"></script>), - %(javascript_include_tag(:all, :recursive => true)) => %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/robber.js" type="text/javascript"></script>\n<script src="/javascripts/subdir/subdir.js" type="text/javascript"></script>\n<script src="/javascripts/version.1.0.js" type="text/javascript"></script>), + %(javascript_include_tag(:all)) => %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/robber.js" type="text/javascript"></script>\n<script src="/javascripts/version.1.0.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>), + %(javascript_include_tag(:all, :recursive => true)) => %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/robber.js" type="text/javascript"></script>\n<script src="/javascripts/subdir/subdir.js" type="text/javascript"></script>\n<script src="/javascripts/version.1.0.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>), %(javascript_include_tag(:defaults, "bank")) => %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/rails.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>), %(javascript_include_tag("bank", :defaults)) => %(<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/rails.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>), @@ -628,7 +628,7 @@ class AssetTagHelperTest < ActionView::TestCase assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'combined.js')) assert_equal( - %(// prototype js\n\n// effects js\n\n// dragdrop js\n\n// controls js\n\n// application js\n\n// bank js\n\n// robber js\n\n// subdir js\n\n\n// version.1.0 js), + %(// prototype js\n\n// effects js\n\n// dragdrop js\n\n// controls js\n\n// bank js\n\n// robber js\n\n// subdir js\n\n\n// version.1.0 js\n\n// application js), IO.read(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'combined.js')) ) @@ -649,7 +649,7 @@ class AssetTagHelperTest < ActionView::TestCase assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'combined.js')) assert_equal( - %(// prototype js\n\n// effects js\n\n// dragdrop js\n\n// controls js\n\n// application js\n\n// bank js\n\n// robber js\n\n// version.1.0 js), + %(// prototype js\n\n// effects js\n\n// dragdrop js\n\n// controls js\n\n// bank js\n\n// robber js\n\n// version.1.0 js\n\n// application js), IO.read(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'combined.js')) ) @@ -686,24 +686,24 @@ class AssetTagHelperTest < ActionView::TestCase config.perform_caching = false assert_dom_equal( - %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/robber.js" type="text/javascript"></script>\n<script src="/javascripts/version.1.0.js" type="text/javascript"></script>), + %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/robber.js" type="text/javascript"></script>\n<script src="/javascripts/version.1.0.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>), javascript_include_tag(:all, :cache => true) ) assert_dom_equal( - %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/robber.js" type="text/javascript"></script>\n<script src="/javascripts/subdir/subdir.js" type="text/javascript"></script>\n<script src="/javascripts/version.1.0.js" type="text/javascript"></script>), + %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/robber.js" type="text/javascript"></script>\n<script src="/javascripts/subdir/subdir.js" type="text/javascript"></script>\n<script src="/javascripts/version.1.0.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>), javascript_include_tag(:all, :cache => true, :recursive => true) ) assert !File.exist?(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'all.js')) assert_dom_equal( - %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/robber.js" type="text/javascript"></script>\n<script src="/javascripts/version.1.0.js" type="text/javascript"></script>), + %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/robber.js" type="text/javascript"></script>\n<script src="/javascripts/version.1.0.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>), javascript_include_tag(:all, :cache => "money") ) assert_dom_equal( - %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/robber.js" type="text/javascript"></script>\n<script src="/javascripts/subdir/subdir.js" type="text/javascript"></script>\n<script src="/javascripts/version.1.0.js" type="text/javascript"></script>), + %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/robber.js" type="text/javascript"></script>\n<script src="/javascripts/subdir/subdir.js" type="text/javascript"></script>\n<script src="/javascripts/version.1.0.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>), javascript_include_tag(:all, :cache => "money", :recursive => true) ) diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb index 97a08d45ba..d40dd409b8 100644 --- a/actionpack/test/template/form_helper_test.rb +++ b/actionpack/test/template/form_helper_test.rb @@ -640,6 +640,12 @@ class FormHelperTest < ActionView::TestCase ) end + def test_form_for_requires_block + assert_raises(ArgumentError) do + form_for(:post, @post, :html => { :id => 'create-post' }) + end + end + def test_form_for assert_deprecated do form_for(:post, @post, :html => { :id => 'create-post' }) do |f| @@ -665,6 +671,45 @@ class FormHelperTest < ActionView::TestCase assert_dom_equal expected, output_buffer end + def test_form_for_with_file_field_generate_multipart + Post.send :attr_accessor, :file + + assert_deprecated do + form_for(:post, @post, :html => { :id => 'create-post' }) do |f| + concat f.file_field(:file) + end + end + + expected = + "<form accept-charset='UTF-8' action='/' id='create-post' method='post' enctype='multipart/form-data'>" + + snowman + + "<input name='post[file]' type='file' id='post_file' />" + + "</form>" + + assert_dom_equal expected, output_buffer + end + + def test_fields_for_with_file_field_generate_multipart + Comment.send :attr_accessor, :file + + assert_deprecated do + form_for(:post, @post) do |f| + concat f.fields_for(:comment, @post) { |c| + concat c.file_field(:file) + } + end + end + + expected = + "<form accept-charset='UTF-8' action='/' method='post' enctype='multipart/form-data'>" + + snowman + + "<input name='post[comment][file]' type='file' id='post_comment_file' />" + + "</form>" + + assert_dom_equal expected, output_buffer + end + + def test_form_for_with_format form_for(@post, :format => :json, :html => { :id => "edit_post_123", :class => "edit_post" }) do |f| concat f.label(:title) |