diff options
author | Emilio Tagua <miloops@gmail.com> | 2009-06-09 10:29:55 -0300 |
---|---|---|
committer | Emilio Tagua <miloops@gmail.com> | 2009-06-09 10:29:55 -0300 |
commit | 103b282130dd340143654801430aed787da4c9c6 (patch) | |
tree | eddbe800d02f1a3c23f6266b808e74656af31f82 /actionpack | |
parent | fd3c55f09fdfb45c33a5383af2c0b9ddf8f63e90 (diff) | |
parent | a94e7d7897a300a95d5d5a00c5efc573b42bcb58 (diff) | |
download | rails-103b282130dd340143654801430aed787da4c9c6.tar.gz rails-103b282130dd340143654801430aed787da4c9c6.tar.bz2 rails-103b282130dd340143654801430aed787da4c9c6.zip |
Merge commit 'rails/master'
Diffstat (limited to 'actionpack')
36 files changed, 421 insertions, 163 deletions
diff --git a/actionpack/Rakefile b/actionpack/Rakefile index 5f5614e58f..074bc90ca9 100644 --- a/actionpack/Rakefile +++ b/actionpack/Rakefile @@ -35,6 +35,7 @@ Rake::TestTask.new(:test_action_pack) do |t| t.verbose = true #t.warning = true end + task :isolated_test do ruby = File.join(*RbConfig::CONFIG.values_at('bindir', 'RUBY_INSTALL_NAME')) Dir.glob("test/{controller,dispatch,template}/**/*_test.rb").all? do |file| diff --git a/actionpack/lib/action_controller/abstract.rb b/actionpack/lib/action_controller/abstract.rb index f46b91627f..d0eba253b8 100644 --- a/actionpack/lib/action_controller/abstract.rb +++ b/actionpack/lib/action_controller/abstract.rb @@ -2,13 +2,15 @@ require "active_support/core_ext/module/attr_internal" require "active_support/core_ext/module/delegation" module AbstractController - autoload :Base, "action_controller/abstract/base" - autoload :Benchmarker, "action_controller/abstract/benchmarker" - autoload :Callbacks, "action_controller/abstract/callbacks" - autoload :Helpers, "action_controller/abstract/helpers" - autoload :Layouts, "action_controller/abstract/layouts" - autoload :Logger, "action_controller/abstract/logger" - autoload :Renderer, "action_controller/abstract/renderer" + autoload :Base, "action_controller/abstract/base" + autoload :Benchmarker, "action_controller/abstract/benchmarker" + autoload :Callbacks, "action_controller/abstract/callbacks" + autoload :Helpers, "action_controller/abstract/helpers" + autoload :Layouts, "action_controller/abstract/layouts" + autoload :Logger, "action_controller/abstract/logger" + autoload :Renderer, "action_controller/abstract/renderer" # === Exceptions - autoload :ActionNotFound, "action_controller/abstract/exceptions" + autoload :ActionNotFound, "action_controller/abstract/exceptions" + autoload :DoubleRenderError, "action_controller/abstract/exceptions" + autoload :Error, "action_controller/abstract/exceptions" end diff --git a/actionpack/lib/action_controller/abstract/base.rb b/actionpack/lib/action_controller/abstract/base.rb index 87083a4d79..c3daef8759 100644 --- a/actionpack/lib/action_controller/abstract/base.rb +++ b/actionpack/lib/action_controller/abstract/base.rb @@ -1,53 +1,65 @@ require 'active_support/core_ext/module/attr_internal' module AbstractController - class Error < StandardError; end - - class DoubleRenderError < Error - DEFAULT_MESSAGE = "Render and/or redirect were called multiple times in this action. Please note that you may only call render OR redirect, and at most once per action. Also note that neither redirect nor render terminate execution of the action, so if you want to exit an action after redirecting, you need to do something like \"redirect_to(...) and return\"." - - def initialize(message = nil) - super(message || DEFAULT_MESSAGE) - end - end class Base attr_internal :response_body - attr_internal :response_obj attr_internal :action_name class << self attr_reader :abstract + alias_method :abstract?, :abstract + # Define a controller as abstract. See internal_methods for more + # details. def abstract! @abstract = true end - alias_method :abstract?, :abstract - def inherited(klass) - ::AbstractController::Base.subclasses << klass.to_s + ::AbstractController::Base.descendants << klass.to_s super end - def subclasses - @subclasses ||= [] + # A list of all descendents of AbstractController::Base. This is + # useful for initializers which need to add behavior to all controllers. + def descendants + @descendants ||= [] end + # A list of all internal methods for a controller. This finds the first + # abstract superclass of a controller, and gets a list of all public + # instance methods on that abstract class. Public instance methods of + # a controller would normally be considered action methods, so we + # are removing those methods on classes declared as abstract + # (ActionController::Http and ActionController::Base are defined + # as abstract) def internal_methods controller = self controller = controller.superclass until controller.abstract? controller.public_instance_methods(true) end - def process(action) - new.process(action.to_s) - end - + # The list of hidden actions to an empty Array. Defaults to an + # empty Array. This can be modified by other modules or subclasses + # to specify particular actions as hidden. + # + # ==== Returns + # Array[String]:: An array of method names that should not be + # considered actions. def hidden_actions [] end + # A list of method names that should be considered actions. This + # includes all public instance methods on a controller, less + # any internal methods (see #internal_methods), adding back in + # any methods that are internal, but still exist on the class + # itself. Finally, #hidden_actions are removed. + # + # ==== Returns + # Array[String]:: A list of all methods that should be considered + # actions. def action_methods @action_methods ||= # All public instance methods of this class, including ancestors @@ -63,10 +75,14 @@ module AbstractController abstract! - def initialize - self.response_obj = {} - end - + # Calls the action going through the entire action dispatch stack. + # + # The actual method that is called is determined by calling + # #method_for_action. If no method can handle the action, then an + # ActionNotFound error is raised. + # + # ==== Returns + # self def process(action) @_action_name = action_name = action.to_s @@ -79,33 +95,68 @@ module AbstractController end private + # See AbstractController::Base.action_methods def action_methods self.class.action_methods end - def action_method?(action) - action_methods.include?(action) + # Returns true if the name can be considered an action. This can + # be overridden in subclasses to modify the semantics of what + # can be considered an action. + # + # ==== Parameters + # name<String>:: The name of an action to be tested + # + # ==== Returns + # TrueClass, FalseClass + def action_method?(name) + action_methods.include?(name) end - # It is possible for respond_to?(action_name) to be false and - # respond_to?(:action_missing) to be false if respond_to_action? - # is overridden in a subclass. For instance, ActionController::Base - # overrides it to include the case where a template matching the - # action_name is found. + # Call the action. Override this in a subclass to modify the + # behavior around processing an action. This, and not #process, + # is the intended way to override action dispatching. def process_action(method_name) send_action(method_name) end + # Actually call the method associated with the action. Override + # this method if you wish to change how action methods are called, + # not to add additional behavior around it. For example, you would + # override #send_action if you want to inject arguments into the + # method. alias send_action send + # If the action name was not found, but a method called "action_missing" + # was found, #method_for_action will return "_handle_action_missing". + # This method calls #action_missing with the current action name. def _handle_action_missing action_missing(@_action_name) end - # Override this to change the conditions that will raise an - # ActionNotFound error. If you accept a difference case, - # you must handle it by also overriding process_action and - # handling the case. + # Takes an action name and returns the name of the method that will + # handle the action. In normal cases, this method returns the same + # name as it receives. By default, if #method_for_action receives + # a name that is not an action, it will look for an #action_missing + # method and return "_handle_action_missing" if one is found. + # + # Subclasses may override this method to add additional conditions + # that should be considered an action. For instance, an HTTP controller + # with a template matching the action name is considered to exist. + # + # If you override this method to handle additional cases, you may + # also provide a method (like _handle_method_missing) to handle + # the case. + # + # If none of these conditions are true, and method_for_action + # returns nil, an ActionNotFound exception will be raised. + # + # ==== Parameters + # action_name<String>:: An action name to find a method name for + # + # ==== Returns + # String:: The name of the method that handles the action + # nil:: No method name could be found. Raise ActionNotFound. def method_for_action(action_name) if action_method?(action_name) then action_name elsif respond_to?(:action_missing, true) then "_handle_action_missing" diff --git a/actionpack/lib/action_controller/abstract/benchmarker.rb b/actionpack/lib/action_controller/abstract/benchmarker.rb index 07294cede3..58e9564c2f 100644 --- a/actionpack/lib/action_controller/abstract/benchmarker.rb +++ b/actionpack/lib/action_controller/abstract/benchmarker.rb @@ -5,6 +5,16 @@ module AbstractController include Logger module ClassMethods + # Execute the passed in block, timing the duration of the block in ms. + # + # ==== Parameters + # title<#to_s>:: The title of block to benchmark + # log_level<Integer>:: A valid log level. Defaults to Logger::DEBUG + # use_silence<TrueClass, FalseClass>:: Whether or not to silence the + # logger for the duration of the block. + # + # ==== Returns + # Object:: The result of the block def benchmark(title, log_level = ::Logger::DEBUG, use_silence = true) if logger && logger.level >= log_level result = nil diff --git a/actionpack/lib/action_controller/abstract/callbacks.rb b/actionpack/lib/action_controller/abstract/callbacks.rb index affe053bac..0d5161c80e 100644 --- a/actionpack/lib/action_controller/abstract/callbacks.rb +++ b/actionpack/lib/action_controller/abstract/callbacks.rb @@ -2,12 +2,17 @@ module AbstractController module Callbacks extend ActiveSupport::Concern + # Uses ActiveSupport::NewCallbacks as the base functionality. For + # more details on the whole callback system, read the documentation + # for ActiveSupport::NewCallbacks. include ActiveSupport::NewCallbacks included do define_callbacks :process_action, "response_body" end + # Override AbstractController::Base's process_action to run the + # process_action callbacks around the normal behavior. def process_action(method_name) _run_process_action_callbacks(method_name) do super @@ -15,6 +20,17 @@ module AbstractController end module ClassMethods + # If :only or :accept are used, convert the options into the + # primitive form (:per_key) used by ActiveSupport::Callbacks. + # The basic idea is that :only => :index gets converted to + # :if => proc {|c| c.action_name == "index" }, but that the + # proc is only evaluated once per action for the lifetime of + # a Rails process. + # + # ==== Options + # :only<#to_s>:: The callback should be run only for this action + # :except<#to_s>:: The callback should be run for all actions + # except this action def _normalize_callback_options(options) if only = options[:only] only = Array(only).map {|o| "action_name == '#{o}'"}.join(" || ") @@ -26,41 +42,69 @@ module AbstractController end end + # Skip before, after, and around filters matching any of the names + # + # ==== Parameters + # *names<Object>:: A list of valid names that could be used for + # callbacks. Note that skipping uses Ruby equality, so it's + # impossible to skip a callback defined using an anonymous proc + # using #skip_filter def skip_filter(*names, &blk) - skip_before_filter(*names, &blk) - skip_after_filter(*names, &blk) - skip_around_filter(*names, &blk) + skip_before_filter(*names) + skip_after_filter(*names) + skip_around_filter(*names) end + # Take callback names and an optional callback proc, normalize them, + # then call the block with each callback. This allows us to abstract + # the normalization across several methods that use it. + # + # ==== Parameters + # callbacks<Array[*Object, Hash]>:: A list of callbacks, with an optional + # options hash as the last parameter. + # block<Proc>:: A proc that should be added to the callbacks. + # + # ==== Block Parameters + # name<Symbol>:: The callback to be added + # options<Hash>:: A list of options to be used when adding the callback + def _insert_callbacks(callbacks, block) + options = callbacks.last.is_a?(Hash) ? callbacks.pop : {} + _normalize_callback_options(options) + callbacks.push(block) if block + callbacks.each do |callback| + yield callback, options + end + end + + # set up before_filter, prepend_before_filter, skip_before_filter, etc. + # for each of before, after, and around. [:before, :after, :around].each do |filter| class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 + # Append a before, after or around filter. See _insert_callbacks + # for details on the allowed parameters. def #{filter}_filter(*names, &blk) - options = names.last.is_a?(Hash) ? names.pop : {} - _normalize_callback_options(options) - names.push(blk) if block_given? - names.each do |name| - process_action_callback(:#{filter}, name, options) + _insert_callbacks(names, blk) do |name, options| + set_callback(:process_action, :#{filter}, name, options) end end + # Prepend a before, after or around filter. See _insert_callbacks + # for details on the allowed parameters. def prepend_#{filter}_filter(*names, &blk) - options = names.last.is_a?(Hash) ? names.pop : {} - _normalize_callback_options(options) - names.push(blk) if block_given? - names.each do |name| - process_action_callback(:#{filter}, name, options.merge(:prepend => true)) + _insert_callbacks(names, blk) do |name, options| + set_callback(:process_action, :#{filter}, name, options.merge(:prepend => true)) end end + # Skip a before, after or around filter. See _insert_callbacks + # for details on the allowed parameters. def skip_#{filter}_filter(*names, &blk) - options = names.last.is_a?(Hash) ? names.pop : {} - _normalize_callback_options(options) - names.push(blk) if block_given? - names.each do |name| - skip_process_action_callback(:#{filter}, name, options) + _insert_callbacks(names, blk) do |name, options| + skip_callback(:process_action, :#{filter}, name, options) end end + # *_filter is the same as append_*_filter alias_method :append_#{filter}_filter, :#{filter}_filter RUBY_EVAL end diff --git a/actionpack/lib/action_controller/abstract/exceptions.rb b/actionpack/lib/action_controller/abstract/exceptions.rb index 2f6c55f068..b671516de1 100644 --- a/actionpack/lib/action_controller/abstract/exceptions.rb +++ b/actionpack/lib/action_controller/abstract/exceptions.rb @@ -1,3 +1,12 @@ module AbstractController + class Error < StandardError; end class ActionNotFound < StandardError; end + + class DoubleRenderError < Error + DEFAULT_MESSAGE = "Render and/or redirect were called multiple times in this action. Please note that you may only call render OR redirect, and at most once per action. Also note that neither redirect nor render terminate execution of the action, so if you want to exit an action after redirecting, you need to do something like \"redirect_to(...) and return\"." + + def initialize(message = nil) + super(message || DEFAULT_MESSAGE) + end + end end diff --git a/actionpack/lib/action_controller/abstract/renderer.rb b/actionpack/lib/action_controller/abstract/renderer.rb index dd58c7cb64..28bdda4a75 100644 --- a/actionpack/lib/action_controller/abstract/renderer.rb +++ b/actionpack/lib/action_controller/abstract/renderer.rb @@ -14,10 +14,29 @@ module AbstractController self._view_paths ||= ActionView::PathSet.new end + # An instance of a view class. The default view class is ActionView::Base + # + # The view class must have the following methods: + # initialize[paths, assigns_for_first_render, controller] + # paths<Array[ViewPath]>:: A list of resolvers to look for templates in + # controller<AbstractController::Base> A controller + # _render_partial_from_controller[options] + # options<Hash>:: see _render_partial in ActionView::Base + # _render_template_from_controller[template, layout, options, partial] + # template<ActionView::Template>:: The template to render + # layout<ActionView::Template>:: The layout to render around the template + # options<Hash>:: See _render_template_with_layout in ActionView::Base + # partial<Boolean>:: Whether or not the template to render is a partial + # _partial:: If a partial, rather than a template, was rendered, return + # the partial. + # + # Override this method in a to change the default behavior. def _action_view @_action_view ||= ActionView::Base.new(self.class.view_paths, {}, self) end + # Mostly abstracts the fact that calling render twice is a DoubleRenderError. + # Delegates render_to_body and sticks the result in self.response_body. def render(*args) if response_body raise AbstractController::DoubleRenderError, "OMG" @@ -27,9 +46,10 @@ module AbstractController end # Raw rendering of a template to a Rack-compatible body. - # ==== - # @option _prefix<String> The template's path prefix - # @option _layout<String> The relative path to the layout template to use + # + # ==== Options + # _partial_object<Object>:: The object that is being rendered. If this + # exists, we are in the special case of rendering an object as a partial. # # :api: plugin def render_to_body(options = {}) @@ -42,21 +62,27 @@ module AbstractController end end - # Raw rendering of a template to a string. - # ==== - # @option _prefix<String> The template's path prefix - # @option _layout<String> The relative path to the layout template to use + # Raw rendering of a template to a string. Just convert the results of + # render_to_body into a String. # # :api: plugin def render_to_string(options = {}) AbstractController::Renderer.body_to_s(render_to_body(options)) end + # Renders the template from an object. + # + # ==== Options + # _template<ActionView::Template>:: The template to render + # _layout<ActionView::Template>:: The layout to wrap the template in (optional) + # _partial<TrueClass, FalseClass>:: Whether or not the template to be rendered is a partial def _render_template(options) _action_view._render_template_from_controller(options[:_template], options[:_layout], options, options[:_partial]) end - def view_paths() + # The list of view paths for this controller. See ActionView::ViewPathSet for + # more details about writing custom view paths. + def view_paths _view_paths end @@ -73,6 +99,15 @@ module AbstractController end private + # Take in a set of options and determine the template to render + # + # ==== Options + # _template<ActionView::Template>:: If this is provided, the search is over + # _template_name<#to_s>:: The name of the template to look up. Otherwise, + # use the current action name. + # _prefix<String>:: The prefix to look inside of. In a file system, this corresponds + # to a directory. + # _partial<TrueClass, FalseClass>:: Whether or not the file to look up is a partial def _determine_template(options) name = (options[:_template_name] || action_name).to_s @@ -82,18 +117,36 @@ module AbstractController end module ClassMethods + # Append a path to the list of view paths for this controller. + # + # ==== Parameters + # path<String, ViewPath>:: If a String is provided, it gets converted into + # the default view path. You may also provide a custom view path + # (see ActionView::ViewPathSet for more information) def append_view_path(path) self.view_paths << path end + # Prepend a path to the list of view paths for this controller. + # + # ==== Parameters + # path<String, ViewPath>:: If a String is provided, it gets converted into + # the default view path. You may also provide a custom view path + # (see ActionView::ViewPathSet for more information) def prepend_view_path(path) self.view_paths.unshift(path) end + # A list of all of the default view paths for this controller. def view_paths self._view_paths end + # Set the view paths. + # + # ==== Parameters + # paths<ViewPathSet, Object>:: If a ViewPathSet is provided, use that; + # otherwise, process the parameter into a ViewPathSet. def view_paths=(paths) self._view_paths = paths.is_a?(ActionView::PathSet) ? paths : ActionView::Base.process_view_paths(paths) diff --git a/actionpack/lib/action_controller/base/http_authentication.rb b/actionpack/lib/action_controller/base/http_authentication.rb index 2893290efb..2519f55269 100644 --- a/actionpack/lib/action_controller/base/http_authentication.rb +++ b/actionpack/lib/action_controller/base/http_authentication.rb @@ -185,7 +185,7 @@ module ActionController request.env['REDIRECT_X_HTTP_AUTHORIZATION'] end - # Raises error unless the request credentials response value matches the expected value. + # Returns false unless the request credentials response value matches the expected value. # First try the password as a ha1 digest password. If this fails, then try it as a plain # text password. def validate_digest_response(request, realm, &password_procedure) @@ -194,6 +194,8 @@ module ActionController if valid_nonce && realm == credentials[:realm] && opaque == credentials[:opaque] password = password_procedure.call(credentials[:username]) + return false unless password + method = request.env['rack.methodoverride.original_method'] || request.env['REQUEST_METHOD'] [true, false].any? do |password_is_ha1| diff --git a/actionpack/lib/action_controller/new_base/base.rb b/actionpack/lib/action_controller/new_base/base.rb index d7b65d37fa..e8fc153578 100644 --- a/actionpack/lib/action_controller/new_base/base.rb +++ b/actionpack/lib/action_controller/new_base/base.rb @@ -39,7 +39,7 @@ module ActionController # TODO: Extract into its own module # This should be moved together with other normalizing behavior module ImplicitRender - def send_action(method_name) + def send_action(*) ret = super default_render unless performed? ret diff --git a/actionpack/lib/action_controller/routing/resources.rb b/actionpack/lib/action_controller/routing/resources.rb index 05c782d226..2dee0a3d87 100644 --- a/actionpack/lib/action_controller/routing/resources.rb +++ b/actionpack/lib/action_controller/routing/resources.rb @@ -150,9 +150,9 @@ module ActionController end if only - @allowed_actions[:only] = Array(only).map(&:to_sym) + @allowed_actions[:only] = Array(only).map {|a| a.to_sym } elsif except - @allowed_actions[:except] = Array(except).map(&:to_sym) + @allowed_actions[:except] = Array(except).map {|a| a.to_sym } end end diff --git a/actionpack/lib/action_dispatch/middleware/session/mem_cache_store.rb b/actionpack/lib/action_dispatch/middleware/session/mem_cache_store.rb index 8f448970d9..1d9efc2b36 100644 --- a/actionpack/lib/action_dispatch/middleware/session/mem_cache_store.rb +++ b/actionpack/lib/action_dispatch/middleware/session/mem_cache_store.rb @@ -1,3 +1,4 @@ +require "active_support/core_ext/kernel/requires" begin require_library_or_gem 'memcache' diff --git a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb index bfff307669..036deec6d2 100644 --- a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb +++ b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb @@ -1,3 +1,5 @@ +require "active_support/core_ext/exception" + module ActionDispatch class ShowExceptions include StatusCodes diff --git a/actionpack/lib/action_view/helpers.rb b/actionpack/lib/action_view/helpers.rb index 693ab7c2e0..97fa2d80e9 100644 --- a/actionpack/lib/action_view/helpers.rb +++ b/actionpack/lib/action_view/helpers.rb @@ -11,7 +11,7 @@ module ActionView #:nodoc: autoload :FormHelper, 'action_view/helpers/form_helper' autoload :FormOptionsHelper, 'action_view/helpers/form_options_helper' autoload :FormTagHelper, 'action_view/helpers/form_tag_helper' - autoload :JavascriptHelper, 'action_view/helpers/javascript_helper' + autoload :JavaScriptHelper, 'action_view/helpers/javascript_helper' autoload :NumberHelper, 'action_view/helpers/number_helper' autoload :PrototypeHelper, 'action_view/helpers/prototype_helper' autoload :RecordIdentificationHelper, 'action_view/helpers/record_identification_helper' diff --git a/actionpack/lib/action_view/helpers/active_record_helper.rb b/actionpack/lib/action_view/helpers/active_record_helper.rb index b4b9f6e34b..8b70200654 100644 --- a/actionpack/lib/action_view/helpers/active_record_helper.rb +++ b/actionpack/lib/action_view/helpers/active_record_helper.rb @@ -1,6 +1,8 @@ require 'cgi' require 'action_view/helpers/form_helper' require 'active_support/core_ext/class/attribute_accessors' +require 'active_support/core_ext/enumerable' +require 'active_support/core_ext/kernel/reporting' module ActionView class Base diff --git a/actionpack/lib/action_view/helpers/benchmark_helper.rb b/actionpack/lib/action_view/helpers/benchmark_helper.rb index 61c2cecb04..c13a069a35 100644 --- a/actionpack/lib/action_view/helpers/benchmark_helper.rb +++ b/actionpack/lib/action_view/helpers/benchmark_helper.rb @@ -1,4 +1,4 @@ -require 'benchmark' +require 'active_support/core_ext/benchmark' module ActionView module Helpers diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index beef661a37..8ecec87b10 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -3,6 +3,7 @@ require 'action_view/helpers/date_helper' require 'action_view/helpers/tag_helper' require 'action_view/helpers/form_tag_helper' require 'active_support/core_ext/class/inheritable_attributes' +require 'active_support/core_ext/hash/slice' module ActionView module Helpers @@ -494,7 +495,8 @@ module ActionView # Returns a label tag tailored for labelling an input field for a specified attribute (identified by +method+) on an object # assigned to the template (identified by +object+). The text of label will default to the attribute name unless you specify # it explicitly. Additional options on the label tag can be passed as a hash with +options+. These options will be tagged - # onto the HTML as an HTML element attribute as in the example shown. + # onto the HTML as an HTML element attribute as in the example shown, except for the <tt>:value</tt> option, which is designed to + # target labels for radio_button tags (where the value is used in the ID of the input tag). # # ==== Examples # label(:post, :title) @@ -506,6 +508,9 @@ module ActionView # label(:post, :title, "A short title", :class => "title_label") # # => <label for="post_title" class="title_label">A short title</label> # + # label(:post, :privacy, "Public Post", :value => "public") + # # => <label for="post_privacy_public">Public Post</label> + # def label(object_name, method, text = nil, options = {}) InstanceTag.new(object_name, method, self, options.delete(:object)).to_label_tag(text, options) end @@ -728,8 +733,9 @@ module ActionView def to_label_tag(text = nil, options = {}) options = options.stringify_keys + tag_value = options.delete("value") name_and_id = options.dup - add_default_name_and_id(name_and_id) + add_default_name_and_id_for_value(tag_value, name_and_id) options.delete("index") options["for"] ||= name_and_id["id"] content = (text.blank? ? nil : text.to_s) || method_name.humanize @@ -761,11 +767,7 @@ module ActionView checked = self.class.radio_button_checked?(value(object), tag_value) end options["checked"] = "checked" if checked - pretty_tag_value = tag_value.to_s.gsub(/\s/, "_").gsub(/\W/, "").downcase - options["id"] ||= defined?(@auto_index) ? - "#{tag_id_with_index(@auto_index)}_#{pretty_tag_value}" : - "#{tag_id}_#{pretty_tag_value}" - add_default_name_and_id(options) + add_default_name_and_id_for_value(tag_value, options) tag("input", options) end @@ -866,6 +868,17 @@ module ActionView end private + def add_default_name_and_id_for_value(tag_value, options) + if tag_value + pretty_tag_value = tag_value.to_s.gsub(/\s/, "_").gsub(/\W/, "").downcase + specified_id = options["id"] + add_default_name_and_id(options) + options["id"] += "_#{pretty_tag_value}" unless specified_id + else + add_default_name_and_id(options) + end + end + def add_default_name_and_id(options) if options.has_key?("index") options["name"] ||= tag_name_with_index(options["index"]) diff --git a/actionpack/lib/action_view/helpers/form_tag_helper.rb b/actionpack/lib/action_view/helpers/form_tag_helper.rb index c96b1fc8d2..8ab78e7bc6 100644 --- a/actionpack/lib/action_view/helpers/form_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/form_tag_helper.rb @@ -1,5 +1,6 @@ require 'cgi' require 'action_view/helpers/tag_helper' +require 'active_support/core_ext/object/returning' module ActionView module Helpers @@ -257,7 +258,7 @@ module ActionView options["cols"], options["rows"] = size.split("x") if size.respond_to?(:split) end - content_tag :textarea, content, { "name" => name, "id" => name }.update(options.stringify_keys) + content_tag :textarea, content, { "name" => name, "id" => sanitize_to_id(name) }.update(options.stringify_keys) end # Creates a check box form input tag. diff --git a/actionpack/lib/action_view/helpers/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb index c0f5df3468..624b537ad2 100644 --- a/actionpack/lib/action_view/helpers/prototype_helper.rb +++ b/actionpack/lib/action_view/helpers/prototype_helper.rb @@ -1,6 +1,7 @@ require 'set' require 'active_support/json' require 'active_support/core_ext/object/extending' +require 'active_support/core_ext/object/returning' module ActionView module Helpers @@ -1175,7 +1176,7 @@ module ActionView class JavaScriptVariableProxy < JavaScriptProxy #:nodoc: def initialize(generator, variable) - @variable = variable + @variable = ::ActiveSupport::JSON::Variable.new(variable) @empty = true # only record lines if we have to. gets rid of unnecessary linebreaks super(generator) end @@ -1186,7 +1187,7 @@ module ActionView true end - def rails_to_json(*) + def as_json(options = nil) @variable end diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb index 36e0a78e93..de864f453c 100644 --- a/actionpack/lib/action_view/helpers/url_helper.rb +++ b/actionpack/lib/action_view/helpers/url_helper.rb @@ -1,4 +1,5 @@ require 'action_view/helpers/javascript_helper' +require 'active_support/core_ext/hash/keys' module ActionView module Helpers #:nodoc: @@ -221,9 +222,9 @@ module ActionView html_options = args.second concat(link_to(capture(&block), options, html_options)) else - name = args.first - options = args.second || {} - html_options = args.third + name = args[0] + options = args[1] || {} + html_options = args[2] url = url_for(options) diff --git a/actionpack/lib/action_view/template/error.rb b/actionpack/lib/action_view/template/error.rb index a06e80b294..6e5093c5bd 100644 --- a/actionpack/lib/action_view/template/error.rb +++ b/actionpack/lib/action_view/template/error.rb @@ -1,3 +1,5 @@ +require "active_support/core_ext/enumerable" + module ActionView # The TemplateError exception is raised when the compilation of the template fails. This exception then gathers a # bunch of intimate details and uses it to report a very precise exception message. diff --git a/actionpack/test/abstract_controller/abstract_controller_test.rb b/actionpack/test/abstract_controller/abstract_controller_test.rb index 9c028e7d1e..c7eaaeb4ba 100644 --- a/actionpack/test/abstract_controller/abstract_controller_test.rb +++ b/actionpack/test/abstract_controller/abstract_controller_test.rb @@ -19,7 +19,7 @@ module AbstractController class TestBasic < ActiveSupport::TestCase test "dispatching works" do - result = Me.process(:index) + result = Me.new.process(:index) assert_equal "Hello world", result.response_body end end @@ -68,27 +68,27 @@ module AbstractController class TestRenderer < ActiveSupport::TestCase test "rendering templates works" do - result = Me2.process(:index) + result = Me2.new.process(:index) assert_equal "Hello from index.erb", result.response_body end test "rendering passes ivars to the view" do - result = Me2.process(:action_with_ivars) + result = Me2.new.process(:action_with_ivars) assert_equal "Hello from index_with_ivars.erb", result.response_body end test "rendering with no template name" do - result = Me2.process(:naked_render) + result = Me2.new.process(:naked_render) assert_equal "Hello from naked_render.erb", result.response_body end test "rendering to a rack body" do - result = Me2.process(:rendering_to_body) + result = Me2.new.process(:rendering_to_body) assert_equal "Hello from naked_render.erb", result.response_body end test "rendering to a string" do - result = Me2.process(:rendering_to_string) + result = Me2.new.process(:rendering_to_string) assert_equal "Hello from naked_render.erb", result.response_body end end @@ -120,12 +120,12 @@ module AbstractController class TestPrefixedViews < ActiveSupport::TestCase test "templates are located inside their 'prefix' folder" do - result = Me3.process(:index) + result = Me3.new.process(:index) assert_equal "Hello from me3/index.erb", result.response_body end test "templates included their format" do - result = Me3.process(:formatted) + result = Me3.new.process(:formatted) assert_equal "Hello from me3/formatted.html.erb", result.response_body end end @@ -173,7 +173,7 @@ module AbstractController class TestLayouts < ActiveSupport::TestCase test "layouts are included" do - result = Me4.process(:index) + result = Me4.new.process(:index) assert_equal "Me4 Enter : Hello from me4/index.erb : Exit", result.response_body end end @@ -210,7 +210,7 @@ module AbstractController class TestRespondToAction < ActiveSupport::TestCase def assert_dispatch(klass, body = "success", action = :index) - response = klass.process(action).response_body + response = klass.new.process(action).response_body assert_equal body, response end @@ -219,7 +219,7 @@ module AbstractController end test "raises ActionNotFound when method does not exist and action_missing is not defined" do - assert_raise(ActionNotFound) { DefaultRespondToActionController.process(:fail) } + assert_raise(ActionNotFound) { DefaultRespondToActionController.new.process(:fail) } end test "dispatches to action_missing when method does not exist and action_missing is defined" do @@ -231,7 +231,7 @@ module AbstractController end test "raises ActionNotFound if method is defined but respond_to_action? returns false" do - assert_raise(ActionNotFound) { RespondToActionController.process(:fail) } + assert_raise(ActionNotFound) { RespondToActionController.new.process(:fail) } end end diff --git a/actionpack/test/abstract_controller/callbacks_test.rb b/actionpack/test/abstract_controller/callbacks_test.rb index 1de60868c3..817f60f7d1 100644 --- a/actionpack/test/abstract_controller/callbacks_test.rb +++ b/actionpack/test/abstract_controller/callbacks_test.rb @@ -8,7 +8,7 @@ module AbstractController end class Callback1 < ControllerWithCallbacks - process_action_callback :before, :first + set_callback :process_action, :before, :first def first @text = "Hello world" @@ -21,7 +21,7 @@ module AbstractController class TestCallbacks < ActiveSupport::TestCase test "basic callbacks work" do - result = Callback1.process(:index) + result = Callback1.new.process(:index) assert_equal "Hello world", result.response_body end end @@ -52,17 +52,17 @@ module AbstractController class TestCallbacks < ActiveSupport::TestCase test "before_filter works" do - result = Callback2.process(:index) + result = Callback2.new.process(:index) assert_equal "Hello world", result.response_body end test "after_filter works" do - result = Callback2.process(:index) + result = Callback2.new.process(:index) assert_equal "Goodbye", result.instance_variable_get("@second") end test "around_filter works" do - result = Callback2.process(:index) + result = Callback2.new.process(:index) assert_equal "FIRSTSECOND", result.instance_variable_get("@aroundz") end end @@ -83,12 +83,12 @@ module AbstractController class TestCallbacks < ActiveSupport::TestCase test "before_filter works with procs" do - result = Callback3.process(:index) + result = Callback3.new.process(:index) assert_equal "Hello world", result.response_body end test "after_filter works with procs" do - result = Callback3.process(:index) + result = Callback3.new.process(:index) assert_equal "Goodbye", result.instance_variable_get("@second") end end @@ -118,17 +118,17 @@ module AbstractController class TestCallbacks < ActiveSupport::TestCase test "when :only is specified, a before filter is triggered on that action" do - result = CallbacksWithConditions.process(:index) + result = CallbacksWithConditions.new.process(:index) assert_equal "Hello, World", result.response_body end test "when :only is specified, a before filter is not triggered on other actions" do - result = CallbacksWithConditions.process(:sekrit_data) + result = CallbacksWithConditions.new.process(:sekrit_data) assert_equal "true", result.response_body end test "when :except is specified, an after filter is not triggered on that action" do - result = CallbacksWithConditions.process(:index) + result = CallbacksWithConditions.new.process(:index) assert_nil result.instance_variable_get("@authenticated") end end @@ -158,17 +158,17 @@ module AbstractController class TestCallbacks < ActiveSupport::TestCase test "when :only is specified with an array, a before filter is triggered on that action" do - result = CallbacksWithArrayConditions.process(:index) + result = CallbacksWithArrayConditions.new.process(:index) assert_equal "Hello, World", result.response_body end test "when :only is specified with an array, a before filter is not triggered on other actions" do - result = CallbacksWithArrayConditions.process(:sekrit_data) + result = CallbacksWithArrayConditions.new.process(:sekrit_data) assert_equal "true", result.response_body end test "when :except is specified with an array, an after filter is not triggered on that action" do - result = CallbacksWithArrayConditions.process(:index) + result = CallbacksWithArrayConditions.new.process(:index) assert_nil result.instance_variable_get("@authenticated") end end @@ -183,12 +183,12 @@ module AbstractController class TestCallbacks < ActiveSupport::TestCase test "when a callback is modified in a child with :only, it works for the :only action" do - result = ChangedConditions.process(:index) + result = ChangedConditions.new.process(:index) assert_equal "Hello world", result.response_body end test "when a callback is modified in a child with :only, it does not work for other actions" do - result = ChangedConditions.process(:not_index) + result = ChangedConditions.new.process(:not_index) assert_equal "", result.response_body end end @@ -207,7 +207,7 @@ module AbstractController class TestHalting < ActiveSupport::TestCase test "when a callback sets the response body, the action should not be invoked" do - result = SetsResponseBody.process(:index) + result = SetsResponseBody.new.process(:index) assert_equal "Success", result.response_body end end diff --git a/actionpack/test/abstract_controller/helper_test.rb b/actionpack/test/abstract_controller/helper_test.rb index f91aefe606..0a2535f834 100644 --- a/actionpack/test/abstract_controller/helper_test.rb +++ b/actionpack/test/abstract_controller/helper_test.rb @@ -34,7 +34,7 @@ module AbstractController class TestHelpers < ActiveSupport::TestCase def test_helpers - result = MyHelpers1.process(:index) + result = MyHelpers1.new.process(:index) assert_equal "Hello World : Included", result.response_body end end diff --git a/actionpack/test/abstract_controller/layouts_test.rb b/actionpack/test/abstract_controller/layouts_test.rb index d3440c3de0..4b66f063f3 100644 --- a/actionpack/test/abstract_controller/layouts_test.rb +++ b/actionpack/test/abstract_controller/layouts_test.rb @@ -142,7 +142,7 @@ module AbstractControllerTests end # TODO Move to bootloader - AbstractController::Base.subclasses.each do |klass| + AbstractController::Base.descendants.each do |klass| klass = klass.constantize next unless klass < AbstractController::Layouts klass.class_eval do @@ -152,70 +152,70 @@ module AbstractControllerTests class TestBase < ActiveSupport::TestCase test "when no layout is specified, and no default is available, render without a layout" do - result = Blank.process(:index) + result = Blank.new.process(:index) assert_equal "Hello blank!", result.response_body end test "when layout is specified as a string, render with that layout" do - result = WithString.process(:index) + result = WithString.new.process(:index) assert_equal "With String Hello string!", result.response_body end test "when layout is specified as a string, but the layout is missing, raise an exception" do - assert_raises(ActionView::MissingTemplate) { WithMissingLayout.process(:index) } + assert_raises(ActionView::MissingTemplate) { WithMissingLayout.new.process(:index) } end test "when layout is specified as false, do not use a layout" do - result = WithFalseLayout.process(:index) + result = WithFalseLayout.new.process(:index) assert_equal "Hello false!", result.response_body end test "when layout is specified as nil, do not use a layout" do - result = WithNilLayout.process(:index) + result = WithNilLayout.new.process(:index) assert_equal "Hello nil!", result.response_body end test "when layout is specified as a symbol, call the requested method and use the layout returned" do - result = WithSymbol.process(:index) + result = WithSymbol.new.process(:index) assert_equal "OMGHI2U Hello symbol!", result.response_body end test "when layout is specified as a symbol and the method returns nil, don't use a layout" do - result = WithSymbolReturningNil.process(:index) + result = WithSymbolReturningNil.new.process(:index) assert_equal "Hello nilz!", result.response_body end test "when the layout is specified as a symbol and the method doesn't exist, raise an exception" do - assert_raises(NoMethodError, /:nilz/) { WithSymbolAndNoMethod.process(:index) } + assert_raises(NoMethodError, /:nilz/) { WithSymbolAndNoMethod.new.process(:index) } end test "when the layout is specified as a symbol and the method returns something besides a string/false/nil, raise an exception" do - assert_raises(ArgumentError) { WithSymbolReturningObj.process(:index) } + assert_raises(ArgumentError) { WithSymbolReturningObj.new.process(:index) } end test "when a child controller does not have a layout, use the parent controller layout" do - result = WithStringChild.process(:index) + result = WithStringChild.new.process(:index) assert_equal "With String Hello string!", result.response_body end test "when a child controller has specified a layout, use that layout and not the parent controller layout" do - result = WithStringOverriddenChild.process(:index) + result = WithStringOverriddenChild.new.process(:index) assert_equal "With Override Hello string!", result.response_body end test "when a child controller has an implied layout, use that layout and not the parent controller layout" do - result = WithStringImpliedChild.process(:index) + result = WithStringImpliedChild.new.process(:index) assert_equal "With Implied Hello string!", result.response_body end test "when a child controller specifies layout nil, do not use the parent layout" do - result = WithNilChild.process(:index) + result = WithNilChild.new.process(:index) assert_equal "Hello string!", result.response_body end test "when a grandchild has no layout specified, the child has an implied layout, and the " \ "parent has specified a layout, use the child controller layout" do - result = WithChildOfImplied.process(:index) + result = WithChildOfImplied.new.process(:index) assert_equal "With Implied Hello string!", result.response_body end diff --git a/actionpack/test/controller/filters_test.rb b/actionpack/test/controller/filters_test.rb index df0a9dbfb0..b930ff4997 100644 --- a/actionpack/test/controller/filters_test.rb +++ b/actionpack/test/controller/filters_test.rb @@ -876,10 +876,12 @@ class YieldingAroundFiltersTest < ActionController::TestCase assert_raise(After) { test_process(controller,'raises_after') } end - def test_with_method - controller = ControllerWithFilterMethod - assert_nothing_raised { test_process(controller,'no_raise') } - assert_raise(After) { test_process(controller,'raises_after') } + for_tag(:old_base) do + def test_with_method + controller = ControllerWithFilterMethod + assert_nothing_raised { test_process(controller,'no_raise') } + assert_raise(After) { test_process(controller,'raises_after') } + end end def test_with_proc diff --git a/actionpack/test/controller/helper_test.rb b/actionpack/test/controller/helper_test.rb index 5b9feb3630..342cbfbcd3 100644 --- a/actionpack/test/controller/helper_test.rb +++ b/actionpack/test/controller/helper_test.rb @@ -127,7 +127,7 @@ class HelperTest < Test::Unit::TestCase end def test_all_helpers - methods = AllHelpersController.master_helper_module.instance_methods.map(&:to_s) + methods = AllHelpersController.master_helper_module.instance_methods.map {|m| m.to_s} # abc_helper.rb assert methods.include?('bare_a') @@ -171,11 +171,11 @@ class HelperTest < Test::Unit::TestCase private def expected_helper_methods - TestHelper.instance_methods.map(&:to_s) + TestHelper.instance_methods.map {|m| m.to_s } end def master_helper_methods - @controller_class.master_helper_module.instance_methods.map(&:to_s) + @controller_class.master_helper_module.instance_methods.map {|m| m.to_s } end def missing_methods diff --git a/actionpack/test/controller/http_digest_authentication_test.rb b/actionpack/test/controller/http_digest_authentication_test.rb index 15a11395bb..58f3b88075 100644 --- a/actionpack/test/controller/http_digest_authentication_test.rb +++ b/actionpack/test/controller/http_digest_authentication_test.rb @@ -76,6 +76,15 @@ class HttpDigestAuthenticationTest < ActionController::TestCase assert_equal 'SuperSecret', credentials[:realm] end + test "authentication request with nil credentials" do + @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => nil, :password => nil) + get :index + + assert_response :unauthorized + assert_equal "HTTP Digest: Access denied.\n", @response.body, "Authentication didn't fail for request" + assert_not_equal 'Hello Secret', @response.body, "Authentication didn't fail for request" + end + test "authentication request with invalid password" do @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'foo') get :display @@ -168,6 +177,11 @@ class HttpDigestAuthenticationTest < ActionController::TestCase assert_equal 'Definitely Maybe', @response.body end + test "validate_digest_response should fail with nil returning password_procedure" do + @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => nil, :password => nil) + assert !ActionController::HttpAuthentication::Digest.validate_digest_response(@request, "SuperSecret"){nil} + end + private def encode_credentials(options) diff --git a/actionpack/test/controller/routing_test.rb b/actionpack/test/controller/routing_test.rb index 6b08a04b10..c2acc03a1b 100644 --- a/actionpack/test/controller/routing_test.rb +++ b/actionpack/test/controller/routing_test.rb @@ -1623,13 +1623,13 @@ class RouteSetTest < Test::Unit::TestCase 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 + assert_equal %w(that this), extras.map { |e| e.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 + assert_equal %w(that this), extras.map { |e| e.to_s }.sort end def test_generate_extras_not_first @@ -1639,7 +1639,7 @@ class RouteSetTest < Test::Unit::TestCase 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 + assert_equal %w(that this), extras.map { |e| e.to_s }.sort end def test_generate_not_first @@ -1656,7 +1656,7 @@ class RouteSetTest < Test::Unit::TestCase 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 + assert_equal %w(that this), extras.map { |e| e.to_s }.sort end def test_draw diff --git a/actionpack/test/dispatch/mime_type_test.rb b/actionpack/test/dispatch/mime_type_test.rb index 2fdf4819bb..27bdd10ee5 100644 --- a/actionpack/test/dispatch/mime_type_test.rb +++ b/actionpack/test/dispatch/mime_type_test.rb @@ -56,7 +56,7 @@ class MimeTypeTest < ActiveSupport::TestCase test "type convenience methods" do # Don't test Mime::ALL, since it Mime::ALL#html? == true - types = Mime::SET.to_a.map(&:to_sym).uniq - [:all] + types = Mime::SET.to_a.map{|m| m.to_sym }.uniq - [:all] # Remove custom Mime::Type instances set in other tests, like Mime::GIF and Mime::IPHONE types.delete_if { |type| !Mime.const_defined?(type.to_s.upcase) } @@ -76,7 +76,7 @@ class MimeTypeTest < ActiveSupport::TestCase end test "verifiable mime types" do - all_types = Mime::SET.to_a.map(&:to_sym) + all_types = Mime::SET.to_a.map{|m| m.to_sym} all_types.uniq! # Remove custom Mime::Type instances set in other tests, like Mime::GIF and Mime::IPHONE all_types.delete_if { |type| !Mime.const_defined?(type.to_s.upcase) } diff --git a/actionpack/test/fixtures/test/_local_inspector.html.erb b/actionpack/test/fixtures/test/_local_inspector.html.erb index c5a6e3e5bc..e6765c0882 100644 --- a/actionpack/test/fixtures/test/_local_inspector.html.erb +++ b/actionpack/test/fixtures/test/_local_inspector.html.erb @@ -1 +1 @@ -<%= local_assigns.keys.map(&:to_s).sort.join(",") -%>
\ No newline at end of file +<%= local_assigns.keys.map {|k| k.to_s }.sort.join(",") -%>
\ No newline at end of file diff --git a/actionpack/test/new_base/abstract_unit.rb b/actionpack/test/new_base/abstract_unit.rb index e6690d41d9..7d72f8393b 100644 --- a/actionpack/test/new_base/abstract_unit.rb +++ b/actionpack/test/new_base/abstract_unit.rb @@ -11,9 +11,6 @@ $stderr.puts "Running old tests on new_base" require 'test/unit' require 'active_support' -# TODO : Revisit requiring all the core extensions here -require 'active_support/core_ext' - require 'active_support/test_case' require 'action_controller/abstract' require 'action_controller/new_base' @@ -45,6 +42,16 @@ ORIGINAL_LOCALES = I18n.available_locales.map {|locale| locale.to_s }.sort FIXTURE_LOAD_PATH = File.join(File.dirname(__FILE__), '../fixtures') +module ActionView + class TestCase + setup do + ActionController::Routing::Routes.draw do |map| + map.connect ':controller/:action/:id' + end + end + end +end + module ActionController Base.session = { :key => '_testing_session', diff --git a/actionpack/test/template/erb_util_test.rb b/actionpack/test/template/erb_util_test.rb index c8c986f218..49f51c50c5 100644 --- a/actionpack/test/template/erb_util_test.rb +++ b/actionpack/test/template/erb_util_test.rb @@ -16,7 +16,7 @@ class ErbUtilTest < Test::Unit::TestCase end def test_rest_in_ascii - (0..127).to_a.map(&:chr).each do |chr| + (0..127).to_a.map {|int| int.chr }.each do |chr| next if %w(& " < >).include?(chr) assert_equal chr, html_escape(chr) end diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb index 104649deac..947668ccc6 100644 --- a/actionpack/test/template/form_helper_test.rb +++ b/actionpack/test/template/form_helper_test.rb @@ -99,6 +99,11 @@ class FormHelperTest < ActionView::TestCase assert_dom_equal('<label for="my_for">Title</label>', label(:post, :title, nil, "for" => "my_for")) end + def test_label_for_radio_buttons_with_value + assert_dom_equal('<label for="post_title_great_title">The title goes here</label>', label("post", "title", "The title goes here", :value => "great_title")) + assert_dom_equal('<label for="post_title_great_title">The title goes here</label>', label("post", "title", "The title goes here", :value => "great title")) + end + def test_text_field assert_dom_equal( '<input id="post_title" name="post[title]" size="30" type="text" value="Hello World" />', text_field("post", "title") @@ -532,6 +537,20 @@ class FormHelperTest < ActionView::TestCase assert_dom_equal expected, output_buffer end + def test_nested_fields_for_with_index_radio_button + form_for(:post, @post) do |f| + f.fields_for(:comment, @post, :index => 5) do |c| + concat c.radio_button(:title, "hello") + end + end + + expected = "<form action='http://www.example.com' method='post'>" + + "<input name='post[comment][5][title]' type='radio' id='post_comment_5_title_hello' value='hello' />" + + "</form>" + + assert_dom_equal expected, output_buffer + end + def test_nested_fields_for_with_auto_index_on_both form_for("post[]", @post) do |f| f.fields_for("comment[]", @post) do |c| diff --git a/actionpack/test/template/form_tag_helper_test.rb b/actionpack/test/template/form_tag_helper_test.rb index 5ca4d4d6ea..09d199b75d 100644 --- a/actionpack/test/template/form_tag_helper_test.rb +++ b/actionpack/test/template/form_tag_helper_test.rb @@ -154,6 +154,11 @@ class FormTagHelperTest < ActionView::TestCase assert_dom_equal expected, actual end + def test_text_area_tag_id_sanitized + input_elem = root_elem(text_area_tag("item[][description]")) + assert_match VALID_HTML_ID, input_elem['id'] + end + def test_text_field_tag actual = text_field_tag "title", "Hello!" expected = %(<input id="title" name="title" type="text" value="Hello!" />) diff --git a/actionpack/test/template/number_helper_test.rb b/actionpack/test/template/number_helper_test.rb index b6542ef29d..57b740032e 100644 --- a/actionpack/test/template/number_helper_test.rb +++ b/actionpack/test/template/number_helper_test.rb @@ -3,6 +3,22 @@ require 'abstract_unit' class NumberHelperTest < ActionView::TestCase tests ActionView::Helpers::NumberHelper + def kilobytes(number) + number * 1024 + end + + def megabytes(number) + kilobytes(number) * 1024 + end + + def gigabytes(number) + megabytes(number) * 1024 + end + + def terabytes(number) + gigabytes(number) * 1024 + end + def test_number_to_phone assert_equal("555-1234", number_to_phone(5551234)) assert_equal("800-555-1212", number_to_phone(8005551212)) @@ -96,16 +112,16 @@ class NumberHelperTest < ActionView::TestCase assert_equal '1.2 MB', number_to_human_size(1234567) assert_equal '1.1 GB', number_to_human_size(1234567890) assert_equal '1.1 TB', number_to_human_size(1234567890123) - assert_equal '1025 TB', number_to_human_size(1025.terabytes) - assert_equal '444 KB', number_to_human_size(444.kilobytes) - assert_equal '1023 MB', number_to_human_size(1023.megabytes) - assert_equal '3 TB', number_to_human_size(3.terabytes) + assert_equal '1025 TB', number_to_human_size(terabytes(1025)) + assert_equal '444 KB', number_to_human_size(kilobytes(444)) + assert_equal '1023 MB', number_to_human_size(megabytes(1023)) + assert_equal '3 TB', number_to_human_size(terabytes(3)) assert_equal '1.18 MB', number_to_human_size(1234567, :precision => 2) assert_equal '3 Bytes', number_to_human_size(3.14159265, :precision => 4) assert_equal("123 Bytes", number_to_human_size("123")) - assert_equal '1.01 KB', number_to_human_size(1.0123.kilobytes, :precision => 2) - assert_equal '1.01 KB', number_to_human_size(1.0100.kilobytes, :precision => 4) - assert_equal '10 KB', number_to_human_size(10.000.kilobytes, :precision => 4) + assert_equal '1.01 KB', number_to_human_size(kilobytes(1.0123), :precision => 2) + assert_equal '1.01 KB', number_to_human_size(kilobytes(1.0100), :precision => 4) + assert_equal '10 KB', number_to_human_size(kilobytes(10.000), :precision => 4) assert_equal '1 Byte', number_to_human_size(1.1) assert_equal '10 Bytes', number_to_human_size(10) #assert_nil number_to_human_size('x') # fails due to API consolidation @@ -115,9 +131,9 @@ class NumberHelperTest < ActionView::TestCase def test_number_to_human_size_with_options_hash assert_equal '1.18 MB', number_to_human_size(1234567, :precision => 2) assert_equal '3 Bytes', number_to_human_size(3.14159265, :precision => 4) - assert_equal '1.01 KB', number_to_human_size(1.0123.kilobytes, :precision => 2) - assert_equal '1.01 KB', number_to_human_size(1.0100.kilobytes, :precision => 4) - assert_equal '10 KB', number_to_human_size(10.000.kilobytes, :precision => 4) + assert_equal '1.01 KB', number_to_human_size(kilobytes(1.0123), :precision => 2) + assert_equal '1.01 KB', number_to_human_size(kilobytes(1.0100), :precision => 4) + assert_equal '10 KB', number_to_human_size(kilobytes(10.000), :precision => 4) assert_equal '1 TB', number_to_human_size(1234567890123, :precision => 0) assert_equal '500 MB', number_to_human_size(524288000, :precision=>0) assert_equal '40 KB', number_to_human_size(41010, :precision => 0) @@ -125,8 +141,8 @@ class NumberHelperTest < ActionView::TestCase end def test_number_to_human_size_with_custom_delimiter_and_separator - assert_equal '1,01 KB', number_to_human_size(1.0123.kilobytes, :precision => 2, :separator => ',') - assert_equal '1,01 KB', number_to_human_size(1.0100.kilobytes, :precision => 4, :separator => ',') - assert_equal '1.000,1 TB', number_to_human_size(1000.1.terabytes, :delimiter => '.', :separator => ',') + assert_equal '1,01 KB', number_to_human_size(kilobytes(1.0123), :precision => 2, :separator => ',') + assert_equal '1,01 KB', number_to_human_size(kilobytes(1.0100), :precision => 4, :separator => ',') + assert_equal '1.000,1 TB', number_to_human_size(terabytes(1000.1), :delimiter => '.', :separator => ',') end end diff --git a/actionpack/test/template/render_test.rb b/actionpack/test/template/render_test.rb index 20cd4cc1d4..2ed11aa3c0 100644 --- a/actionpack/test/template/render_test.rb +++ b/actionpack/test/template/render_test.rb @@ -13,7 +13,7 @@ module RenderTestCases I18n.backend.store_translations 'pt-BR', {} # Ensure original are still the same since we are reindexing view paths - assert_equal ORIGINAL_LOCALES, I18n.available_locales.map(&:to_s).sort + assert_equal ORIGINAL_LOCALES, I18n.available_locales.map {|l| l.to_s }.sort end def test_render_file |