diff options
Diffstat (limited to 'actionpack')
54 files changed, 301 insertions, 108 deletions
diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index 913edbd8df..88cdd53336 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -64,7 +64,7 @@ *Brad Dunbar* * Include I18n locale fallbacks in view lookup. - Fixes GH#3512. + Fixes #3512. *Juan Barreneche* diff --git a/actionpack/lib/action_controller/metal/helpers.rb b/actionpack/lib/action_controller/metal/helpers.rb index 35facd13c8..243fd40a7e 100644 --- a/actionpack/lib/action_controller/metal/helpers.rb +++ b/actionpack/lib/action_controller/metal/helpers.rb @@ -94,7 +94,6 @@ module ActionController extract = /^#{Regexp.quote(_path.to_s)}\/?(.*)_helper.rb$/ names = Dir["#{_path}/**/*_helper.rb"].map { |file| file.sub(extract, '\1') } names.sort! - names end helpers.uniq! helpers diff --git a/actionpack/lib/action_controller/metal/live.rb b/actionpack/lib/action_controller/metal/live.rb index fb664a69dd..8092fd639f 100644 --- a/actionpack/lib/action_controller/metal/live.rb +++ b/actionpack/lib/action_controller/metal/live.rb @@ -34,6 +34,7 @@ module ActionController module Live class Buffer < ActionDispatch::Response::Buffer #:nodoc: def initialize(response) + @error_callback = nil super(response, SizedQueue.new(10)) end @@ -56,6 +57,14 @@ module ActionController super @buf.push nil end + + def on_error(&block) + @error_callback = block + end + + def call_on_error + @error_callback.call + end end class Response < ActionDispatch::Response #:nodoc: all @@ -121,6 +130,16 @@ module ActionController begin super(name) + rescue => e + begin + @_response.stream.write(ActionView::Base.streaming_completion_on_exception) if request.format == :html + @_response.stream.call_on_error + rescue => exception + log_error(exception) + ensure + log_error(e) + @_response.stream.close + end ensure @_response.commit! end @@ -129,6 +148,16 @@ module ActionController @_response.await_commit end + def log_error(exception) + logger = ActionController::Base.logger + return unless logger + + message = "\n#{exception.class} (#{exception.message}):\n" + message << exception.annoted_source_code.to_s if exception.respond_to?(:annoted_source_code) + message << " " << exception.backtrace.join("\n ") + logger.fatal("#{message}\n\n") + end + def response_body=(body) super response.stream.close if response diff --git a/actionpack/lib/action_controller/metal/rendering.rb b/actionpack/lib/action_controller/metal/rendering.rb index c5e7d4e357..bea6b88f91 100644 --- a/actionpack/lib/action_controller/metal/rendering.rb +++ b/actionpack/lib/action_controller/metal/rendering.rb @@ -6,7 +6,7 @@ module ActionController # Before processing, set the request formats in current controller formats. def process_action(*) #:nodoc: - self.formats = request.formats.map { |x| x.ref } + self.formats = request.formats.map(&:ref).compact super end diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb index b9a5e78fe9..a35a613158 100644 --- a/actionpack/lib/action_controller/test_case.rb +++ b/actionpack/lib/action_controller/test_case.rb @@ -18,7 +18,7 @@ module ActionController @_layouts = Hash.new(0) @_files = Hash.new(0) - ActiveSupport::Notifications.subscribe("render_template.action_view") do |name, start, finish, id, payload| + ActiveSupport::Notifications.subscribe("render_template.action_view") do |_name, _start, _finish, _id, payload| path = payload[:layout] if path @_layouts[path] += 1 @@ -28,7 +28,7 @@ module ActionController end end - ActiveSupport::Notifications.subscribe("!render_template.action_view") do |name, start, finish, id, payload| + ActiveSupport::Notifications.subscribe("!render_template.action_view") do |_name, _start, _finish, _id, payload| path = payload[:virtual_path] next unless path partial = path =~ /^.*\/_[^\/]*$/ @@ -41,7 +41,7 @@ module ActionController @_templates[path] += 1 end - ActiveSupport::Notifications.subscribe("!render_template.action_view") do |name, start, finish, id, payload| + ActiveSupport::Notifications.subscribe("!render_template.action_view") do |_name, _start, _finish, _id, payload| next if payload[:virtual_path] # files don't have virtual path path = payload[:identifier] diff --git a/actionpack/lib/action_dispatch/http/mime_type.rb b/actionpack/lib/action_dispatch/http/mime_type.rb index 912da741b7..f29ad359ac 100644 --- a/actionpack/lib/action_dispatch/http/mime_type.rb +++ b/actionpack/lib/action_dispatch/http/mime_type.rb @@ -223,8 +223,8 @@ module Mime Mime.instance_eval { remove_const(symbol) } SET.delete_if { |v| v.eql?(mime) } - LOOKUP.delete_if { |k,v| v.eql?(mime) } - EXTENSION_LOOKUP.delete_if { |k,v| v.eql?(mime) } + LOOKUP.delete_if { |_,v| v.eql?(mime) } + EXTENSION_LOOKUP.delete_if { |_,v| v.eql?(mime) } end end @@ -306,12 +306,20 @@ module Mime method.to_s.ends_with? '?' end end - + class NullType def nil? true end + def ref + nil + end + + def respond_to_missing?(method, include_private = false) + method.to_s.ends_with? '?' + end + private def method_missing(method, *args) false if method.to_s.ends_with? '?' diff --git a/actionpack/lib/action_dispatch/journey/formatter.rb b/actionpack/lib/action_dispatch/journey/formatter.rb index 82c55660ea..a732e570f2 100644 --- a/actionpack/lib/action_dispatch/journey/formatter.rb +++ b/actionpack/lib/action_dispatch/journey/formatter.rb @@ -58,7 +58,7 @@ module ActionDispatch end end - parameterized_parts.keep_if { |_, v| v } + parameterized_parts.keep_if { |_, v| v } parameterized_parts end diff --git a/actionpack/lib/action_dispatch/middleware/request_id.rb b/actionpack/lib/action_dispatch/middleware/request_id.rb index 44290445d4..5d1740d0d4 100644 --- a/actionpack/lib/action_dispatch/middleware/request_id.rb +++ b/actionpack/lib/action_dispatch/middleware/request_id.rb @@ -18,7 +18,7 @@ module ActionDispatch def call(env) env["action_dispatch.request_id"] = external_request_id(env) || internal_request_id - @app.call(env).tap { |status, headers, body| headers["X-Request-Id"] = env["action_dispatch.request_id"] } + @app.call(env).tap { |_status, headers, _body| headers["X-Request-Id"] = env["action_dispatch.request_id"] } end private diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb index 550f4dbd0d..db219c8fa9 100644 --- a/actionpack/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb @@ -13,7 +13,7 @@ request_dump = clean_params.empty? ? 'None' : clean_params.inspect.gsub(',', ",\n") def debug_hash(object) - object.to_hash.sort_by { |k, v| k.to_s }.map { |k, v| "#{k}: #{v.inspect rescue $!.message}" }.join("\n") + object.to_hash.sort_by { |k, _| k.to_s }.map { |k, v| "#{k}: #{v.inspect rescue $!.message}" }.join("\n") end unless self.class.method_defined?(:debug_hash) %> diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.erb index 9d947aea40..b181909bff 100644 --- a/actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.erb +++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.erb @@ -1,10 +1,8 @@ <% - traces = [ - ["Application Trace", @application_trace], - ["Framework Trace", @framework_trace], - ["Full Trace", @full_trace] - ] - names = traces.collect {|name, trace| name} + traces = { "Application Trace" => @application_trace, + "Framework Trace" => @framework_trace, + "Full Trace" => @full_trace } + names = traces.keys %> <p><code>Rails.root: <%= defined?(Rails) && Rails.respond_to?(:root) ? Rails.root : "unset" %></code></p> diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/template_error.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/template_error.erb index 63216ef7c5..31f46ee340 100644 --- a/actionpack/lib/action_dispatch/middleware/templates/rescues/template_error.erb +++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/template_error.erb @@ -2,7 +2,7 @@ <header> <h1> <%= @exception.original_exception.class.to_s %> in - <%= @request.parameters["controller"].capitalize if @request.parameters["controller"]%>#<%= @request.parameters["action"] %> + <%= @request.parameters["controller"].camelize if @request.parameters["controller"] %>#<%= @request.parameters["action"] %> </h1> </header> diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 8c095d605a..80054c8a40 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -489,7 +489,7 @@ module ActionDispatch end options = app - app, path = options.find { |k, v| k.respond_to?(:call) } + app, path = options.find { |k, _| k.respond_to?(:call) } options.delete(app) if app end @@ -1361,7 +1361,7 @@ module ActionDispatch def match(path, *rest) if rest.empty? && Hash === path options = path - path, to = options.find { |name, value| name.is_a?(String) } + path, to = options.find { |name, _value| name.is_a?(String) } options[:to] = to options.delete(path) paths = [path] diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 07203428d4..d48a83e6c6 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -665,7 +665,7 @@ module ActionDispatch end req = @request_class.new(env) - @router.recognize(req) do |route, matches, params| + @router.recognize(req) do |route, _matches, params| params.merge!(extras) params.each do |key, value| if value.is_a?(String) diff --git a/actionpack/lib/action_dispatch/testing/assertions/routing.rb b/actionpack/lib/action_dispatch/testing/assertions/routing.rb index 9210bffd1d..496682e8bd 100644 --- a/actionpack/lib/action_dispatch/testing/assertions/routing.rb +++ b/actionpack/lib/action_dispatch/testing/assertions/routing.rb @@ -81,7 +81,7 @@ module ActionDispatch # Load routes.rb if it hasn't been loaded. generated_path, extra_keys = @routes.generate_extras(options, defaults) - found_extras = options.reject {|k, v| ! extra_keys.include? k} + found_extras = options.reject { |k, _| ! extra_keys.include? k } msg = message || sprintf("found extras <%s>, not <%s>", found_extras, extras) assert_equal(extras, found_extras, msg) @@ -120,7 +120,7 @@ module ActionDispatch options[:controller] = "/#{controller}" end - generate_options = options.dup.delete_if{ |k,v| defaults.key?(k) } + generate_options = options.dup.delete_if{ |k, _| defaults.key?(k) } assert_generates(path.is_a?(Hash) ? path[:path] : path, generate_options, defaults, extras, message) end diff --git a/actionpack/lib/action_dispatch/testing/assertions/selector.rb b/actionpack/lib/action_dispatch/testing/assertions/selector.rb index e481f3b245..3253a3d424 100644 --- a/actionpack/lib/action_dispatch/testing/assertions/selector.rb +++ b/actionpack/lib/action_dispatch/testing/assertions/selector.rb @@ -377,8 +377,8 @@ module ActionDispatch node.content.gsub(/<!\[CDATA\[(.*)(\]\]>)?/m) { Rack::Utils.escapeHTML($1) } end - selected = elements.map do |_element| - text = _element.children.select{ |c| not c.tag? }.map{ |c| fix_content[c] }.join + selected = elements.map do |elem| + text = elem.children.select{ |c| not c.tag? }.map{ |c| fix_content[c] }.join root = HTML::Document.new(CGI.unescapeHTML("<encoded>#{text}</encoded>")).root css_select(root, "encoded:root", &block)[0] end diff --git a/actionpack/lib/action_dispatch/testing/test_process.rb b/actionpack/lib/action_dispatch/testing/test_process.rb index e657283cec..630e6a9b78 100644 --- a/actionpack/lib/action_dispatch/testing/test_process.rb +++ b/actionpack/lib/action_dispatch/testing/test_process.rb @@ -6,7 +6,7 @@ module ActionDispatch module TestProcess def assigns(key = nil) assigns = {}.with_indifferent_access - @controller.view_assigns.each {|k, v| assigns.regular_writer(k, v)} + @controller.view_assigns.each { |k, v| assigns.regular_writer(k, v) } key.nil? ? assigns : assigns[key] end diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb index 521eaf25d2..693b6bdfcc 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb @@ -14,7 +14,6 @@ module ActionView # # => <img alt="Rails" src="/assets/rails.png" /> # stylesheet_link_tag("application") # # => <link href="/assets/application.css?body=1" media="screen" rel="stylesheet" /> - # module AssetTagHelper extend ActiveSupport::Concern @@ -50,7 +49,6 @@ module ActionView # # javascript_include_tag "http://www.example.com/xmlhr.js" # # => <script src="http://www.example.com/xmlhr.js"></script> - # def javascript_include_tag(*sources) options = sources.extract_options!.stringify_keys path_options = options.extract!('protocol').symbolize_keys @@ -67,7 +65,7 @@ module ActionView # you don't specify an extension, <tt>.css</tt> will be appended automatically. # You can modify the link attributes by passing a hash as the last argument. # For historical reasons, the 'media' attribute will always be present and defaults - # to "screen", so you must explicitely set it to "all" for the stylesheet(s) to + # to "screen", so you must explicitly set it to "all" for the stylesheet(s) to # apply to all media types. # # stylesheet_link_tag "style" @@ -88,7 +86,6 @@ module ActionView # stylesheet_link_tag "random.styles", "/css/stylish" # # => <link href="/assets/random.styles" media="screen" rel="stylesheet" /> # # <link href="/css/stylish.css" media="screen" rel="stylesheet" /> - # def stylesheet_link_tag(*sources) options = sources.extract_options!.stringify_keys path_options = options.extract!('protocol').symbolize_keys @@ -109,10 +106,13 @@ module ActionView # +url_options+. You can modify the LINK tag itself in +tag_options+. # # ==== Options + # # * <tt>:rel</tt> - Specify the relation of this link, defaults to "alternate" # * <tt>:type</tt> - Override the auto-generated mime type # * <tt>:title</tt> - Specify the title of the link, defaults to the +type+ # + # ==== Examples + # # auto_discovery_link_tag # # => <link rel="alternate" type="application/rss+xml" title="RSS" href="http://www.currenthost.com/controller/action" /> # auto_discovery_link_tag(:atom) @@ -148,9 +148,12 @@ module ActionView # you can override "rel" and "type". # # ==== Options + # # * <tt>:rel</tt> - Specify the relation of this link, defaults to 'shortcut icon' # * <tt>:type</tt> - Override the auto-generated mime type, defaults to 'image/vnd.microsoft.icon' # + # ==== Examples + # # favicon_link_tag '/myicon.ico' # # => <link href="/assets/favicon.ico" rel="shortcut icon" type="image/vnd.microsoft.icon" /> # @@ -160,7 +163,6 @@ module ActionView # # favicon_link_tag '/mb-icon.png', rel: 'apple-touch-icon', type: 'image/png' # # => <link href="/assets/mb-icon.png" rel="apple-touch-icon" type="image/png" /> - # def favicon_link_tag(source='favicon.ico', options={}) tag('link', { :rel => 'shortcut icon', @@ -173,6 +175,7 @@ module ActionView # path or a file. # # ==== Options + # # You can add HTML attributes using the +options+. The +options+ supports # three additional keys for convenience and conformance: # @@ -250,6 +253,8 @@ module ActionView # width="30" and height="45". <tt>:size</tt> will be ignored if the # value is not in the correct format. # + # ==== Examples + # # video_tag("trailer") # # => <video src="/videos/trailer" /> # video_tag("trailer.ogg") diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index 36cfb7fca7..36dedf0676 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -1152,12 +1152,65 @@ module ActionView end end + # A +FormBuilder+ object is associated with a particular model object and + # allows you to generate fields associated with the model object. The + # +FormBuilder+ object is yielded when using +form_for+ or +fields_for+. + # For example: + # + # <%= form_for @person do |person_form| %> + # Name: <%= person_form.text_field :name %> + # Admin: <%= person_form.check_box :admin %> + # <% end %> + # + # In the above block, the a +FormBuilder+ object is yielded as the + # +person_form+ variable. This allows you to generate the +text_field+ + # and +check_box+ fields by specifying their eponymous methods, which + # modify the underlying template and associates the +@person+ model object + # with the form. + # + # The +FormBuilder+ object can be thought of as serving as a proxy for the + # methods in the +FormHelper+ module. This class, however, allows you to + # call methods with the model object you are building the form for. + # + # You can create your own custom FormBuilder templates by subclasses this + # class. For example: + # + # class MyFormBuilder < ActionView::Helpers::FormBuilder + # def div_radio_button(method, tag_value, options = {}) + # @template.content_tag(:div, + # @template.radio_button( + # @object_name, method, tag_value, objectify_options(options) + # ) + # ) + # end + # + # The above code creates a new method +div_radio_button+ which wraps a div + # around the a new radio button. Note that when options are passed in, you + # must called +objectify_options+ in order for the model object to get + # correctly passed to the method. If +objectify_options+ is not called, + # then the newly created helper will not be linked back to the model. + # + # The +div_radio_button+ code from above can now be used as follows: + # + # <%= form_for @person, :builder => MyFormBuilder do |f| %> + # I am a child: <%= f.div_radio_button(:admin, "child") %> + # I am an adult: <%= f.div_radio_button(:admin, "adult") %> + # <% end -%> + # + # The standard set of helper methods for form building are located in the + # +field_helpers+ class attribute. class FormBuilder include ModelNaming # The methods which wrap a form helper call. class_attribute :field_helpers - self.field_helpers = FormHelper.instance_methods - [:form_for, :convert_to_model, :model_name_from_record_or_class] + self.field_helpers = [:fields_for, :label, :text_field, :password_field, + :hidden_field, :file_field, :text_area, :check_box, + :radio_button, :color_field, :search_field, + :telephone_field, :phone_field, :date_field, + :time_field, :datetime_field, :datetime_local_field, + :month_field, :week_field, :url_field, :email_field, + :number_field, :range_field] attr_accessor :object_name, :object, :options @@ -1239,7 +1292,7 @@ module ActionView # Admin? : <%= permission_fields.check_box :admin %> # <% end %> # - # <%= f.submit %> + # <%= person_form.submit %> # <% end %> # # In this case, the checkbox field will be represented by an HTML +input+ diff --git a/actionpack/lib/action_view/helpers/number_helper.rb b/actionpack/lib/action_view/helpers/number_helper.rb index 9e1be65b1a..fda7038a5d 100644 --- a/actionpack/lib/action_view/helpers/number_helper.rb +++ b/actionpack/lib/action_view/helpers/number_helper.rb @@ -28,6 +28,8 @@ module ActionView # Formats a +number+ into a US phone number (e.g., (555) # 123-9876). You can customize the format in the +options+ hash. # + # ==== Options + # # * <tt>:area_code</tt> - Adds parentheses around the area code. # * <tt>:delimiter</tt> - Specifies the delimiter to use # (defaults to "-"). @@ -38,6 +40,8 @@ module ActionView # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when # the argument is invalid. # + # ==== Examples + # # number_to_phone(5551234) # => 555-1234 # number_to_phone("5551234") # => 555-1234 # number_to_phone(1235551234) # => 123-555-1234 @@ -61,6 +65,8 @@ module ActionView # Formats a +number+ into a currency string (e.g., $13.65). You # can customize the format in the +options+ hash. # + # ==== Options + # # * <tt>:locale</tt> - Sets the locale to be used for formatting # (defaults to current locale). # * <tt>:precision</tt> - Sets the level of precision (defaults @@ -82,6 +88,8 @@ module ActionView # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when # the argument is invalid. # + # ==== Examples + # # number_to_currency(1234567890.50) # => $1,234,567,890.50 # number_to_currency(1234567890.506) # => $1,234,567,890.51 # number_to_currency(1234567890.506, precision: 3) # => $1,234,567,890.506 @@ -108,6 +116,7 @@ module ActionView # Formats a +number+ as a percentage string (e.g., 65%). You can # customize the format in the +options+ hash. # + # ==== Options # # * <tt>:locale</tt> - Sets the locale to be used for formatting # (defaults to current locale). @@ -128,6 +137,8 @@ module ActionView # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when # the argument is invalid. # + # ==== Examples + # # number_to_percentage(100) # => 100.000% # number_to_percentage("98") # => 98.000% # number_to_percentage(100, precision: 0) # => 100% @@ -151,6 +162,8 @@ module ActionView # (e.g., 12,324). You can customize the format in the +options+ # hash. # + # ==== Options + # # * <tt>:locale</tt> - Sets the locale to be used for formatting # (defaults to current locale). # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults @@ -160,6 +173,8 @@ module ActionView # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when # the argument is invalid. # + # ==== Examples + # # number_with_delimiter(12345678) # => 12,345,678 # number_with_delimiter("123456") # => 123,456 # number_with_delimiter(12345678.05) # => 12,345,678.05 @@ -185,6 +200,8 @@ module ActionView # +:significant+ is +false+, and 5 if +:significant+ is +true+). # You can customize the format in the +options+ hash. # + # ==== Options + # # * <tt>:locale</tt> - Sets the locale to be used for formatting # (defaults to current locale). # * <tt>:precision</tt> - Sets the precision of the number @@ -202,6 +219,8 @@ module ActionView # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when # the argument is invalid. # + # ==== Examples + # # number_with_precision(111.2345) # => 111.235 # number_with_precision(111.2345, precision: 2) # => 111.23 # number_with_precision(13, precision: 5) # => 13.00000 @@ -233,6 +252,8 @@ module ActionView # See <tt>number_to_human</tt> if you want to pretty-print a # generic number. # + # ==== Options + # # * <tt>:locale</tt> - Sets the locale to be used for formatting # (defaults to current locale). # * <tt>:precision</tt> - Sets the precision of the number @@ -252,6 +273,8 @@ module ActionView # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when # the argument is invalid. # + # ==== Examples + # # number_to_human_size(123) # => 123 Bytes # number_to_human_size(1234) # => 1.21 KB # number_to_human_size(12345) # => 12.1 KB @@ -324,6 +347,8 @@ module ActionView # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when # the argument is invalid. # + # ==== Examples + # # number_to_human(123) # => "123" # number_to_human(1234) # => "1.23 Thousand" # number_to_human(12345) # => "12.3 Thousand" diff --git a/actionpack/lib/action_view/helpers/tags/base.rb b/actionpack/lib/action_view/helpers/tags/base.rb index 10dec66b4f..3fe3f4e9df 100644 --- a/actionpack/lib/action_view/helpers/tags/base.rb +++ b/actionpack/lib/action_view/helpers/tags/base.rb @@ -1,7 +1,7 @@ module ActionView module Helpers - module Tags - class Base #:nodoc: + module Tags # :nodoc: + class Base # :nodoc: include Helpers::ActiveModelInstanceTag, Helpers::TagHelper, Helpers::FormTagHelper include FormOptionsHelper diff --git a/actionpack/lib/action_view/helpers/tags/check_box.rb b/actionpack/lib/action_view/helpers/tags/check_box.rb index e21cc07746..6d51f2629a 100644 --- a/actionpack/lib/action_view/helpers/tags/check_box.rb +++ b/actionpack/lib/action_view/helpers/tags/check_box.rb @@ -2,7 +2,7 @@ require 'action_view/helpers/tags/checkable' module ActionView module Helpers - module Tags + module Tags # :nodoc: class CheckBox < Base #:nodoc: include Checkable diff --git a/actionpack/lib/action_view/helpers/tags/checkable.rb b/actionpack/lib/action_view/helpers/tags/checkable.rb index b97c0c68d7..052e9df662 100644 --- a/actionpack/lib/action_view/helpers/tags/checkable.rb +++ b/actionpack/lib/action_view/helpers/tags/checkable.rb @@ -1,7 +1,7 @@ module ActionView module Helpers - module Tags - module Checkable + module Tags # :nodoc: + module Checkable # :nodoc: def input_checked?(object, options) if options.has_key?("checked") checked = options.delete "checked" diff --git a/actionpack/lib/action_view/helpers/tags/collection_check_boxes.rb b/actionpack/lib/action_view/helpers/tags/collection_check_boxes.rb index 9655008fe2..52006d856b 100644 --- a/actionpack/lib/action_view/helpers/tags/collection_check_boxes.rb +++ b/actionpack/lib/action_view/helpers/tags/collection_check_boxes.rb @@ -2,11 +2,11 @@ require 'action_view/helpers/tags/collection_helpers' module ActionView module Helpers - module Tags - class CollectionCheckBoxes < Base + module Tags # :nodoc: + class CollectionCheckBoxes < Base # :nodoc: include CollectionHelpers - class CheckBoxBuilder < Builder + class CheckBoxBuilder < Builder # :nodoc: def check_box(extra_html_options={}) html_options = extra_html_options.merge(@input_html_options) @template_object.check_box(@object_name, @method_name, html_options, @value, nil) diff --git a/actionpack/lib/action_view/helpers/tags/collection_helpers.rb b/actionpack/lib/action_view/helpers/tags/collection_helpers.rb index e92a318c73..cd12ddaf65 100644 --- a/actionpack/lib/action_view/helpers/tags/collection_helpers.rb +++ b/actionpack/lib/action_view/helpers/tags/collection_helpers.rb @@ -1,8 +1,8 @@ module ActionView module Helpers - module Tags - module CollectionHelpers - class Builder + module Tags # :nodoc: + module CollectionHelpers # :nodoc: + class Builder # :nodoc: attr_reader :object, :text, :value def initialize(template_object, object_name, method_name, object, diff --git a/actionpack/lib/action_view/helpers/tags/collection_radio_buttons.rb b/actionpack/lib/action_view/helpers/tags/collection_radio_buttons.rb index 893f4411e7..20be34c1f2 100644 --- a/actionpack/lib/action_view/helpers/tags/collection_radio_buttons.rb +++ b/actionpack/lib/action_view/helpers/tags/collection_radio_buttons.rb @@ -2,11 +2,11 @@ require 'action_view/helpers/tags/collection_helpers' module ActionView module Helpers - module Tags - class CollectionRadioButtons < Base + module Tags # :nodoc: + class CollectionRadioButtons < Base # :nodoc: include CollectionHelpers - class RadioButtonBuilder < Builder + class RadioButtonBuilder < Builder # :nodoc: def radio_button(extra_html_options={}) html_options = extra_html_options.merge(@input_html_options) @template_object.radio_button(@object_name, @method_name, @value, html_options) diff --git a/actionpack/lib/action_view/helpers/tags/collection_select.rb b/actionpack/lib/action_view/helpers/tags/collection_select.rb index ec78e6e5f9..6cb2b2e0d3 100644 --- a/actionpack/lib/action_view/helpers/tags/collection_select.rb +++ b/actionpack/lib/action_view/helpers/tags/collection_select.rb @@ -1,6 +1,6 @@ module ActionView module Helpers - module Tags + module Tags # :nodoc: class CollectionSelect < Base #:nodoc: def initialize(object_name, method_name, template_object, collection, value_method, text_method, options, html_options) @collection = collection diff --git a/actionpack/lib/action_view/helpers/tags/color_field.rb b/actionpack/lib/action_view/helpers/tags/color_field.rb index 6f08f8483a..d8fc797035 100644 --- a/actionpack/lib/action_view/helpers/tags/color_field.rb +++ b/actionpack/lib/action_view/helpers/tags/color_field.rb @@ -1,7 +1,7 @@ module ActionView module Helpers - module Tags - class ColorField < TextField #:nodoc: + module Tags # :nodoc: + class ColorField < TextField # :nodoc: def render options = @options.stringify_keys options["value"] = @options.fetch("value") { validate_color_string(value(object)) } diff --git a/actionpack/lib/action_view/helpers/tags/date_field.rb b/actionpack/lib/action_view/helpers/tags/date_field.rb index 64c29dea3d..c22be0db29 100644 --- a/actionpack/lib/action_view/helpers/tags/date_field.rb +++ b/actionpack/lib/action_view/helpers/tags/date_field.rb @@ -1,7 +1,7 @@ module ActionView module Helpers - module Tags - class DateField < DatetimeField #:nodoc: + module Tags # :nodoc: + class DateField < DatetimeField # :nodoc: private def format_date(value) diff --git a/actionpack/lib/action_view/helpers/tags/date_select.rb b/actionpack/lib/action_view/helpers/tags/date_select.rb index 734591394b..0c4ac40070 100644 --- a/actionpack/lib/action_view/helpers/tags/date_select.rb +++ b/actionpack/lib/action_view/helpers/tags/date_select.rb @@ -2,8 +2,8 @@ require 'active_support/core_ext/time/calculations' module ActionView module Helpers - module Tags - class DateSelect < Base #:nodoc: + module Tags # :nodoc: + class DateSelect < Base # :nodoc: def initialize(object_name, method_name, template_object, options, html_options) @html_options = html_options diff --git a/actionpack/lib/action_view/helpers/tags/datetime_field.rb b/actionpack/lib/action_view/helpers/tags/datetime_field.rb index e407146e96..9a2279c611 100644 --- a/actionpack/lib/action_view/helpers/tags/datetime_field.rb +++ b/actionpack/lib/action_view/helpers/tags/datetime_field.rb @@ -1,7 +1,7 @@ module ActionView module Helpers - module Tags - class DatetimeField < TextField #:nodoc: + module Tags # :nodoc: + class DatetimeField < TextField # :nodoc: def render options = @options.stringify_keys options["value"] = @options.fetch("value") { format_date(value(object)) } diff --git a/actionpack/lib/action_view/helpers/tags/datetime_local_field.rb b/actionpack/lib/action_view/helpers/tags/datetime_local_field.rb index 6668d6d718..b4a74185d1 100644 --- a/actionpack/lib/action_view/helpers/tags/datetime_local_field.rb +++ b/actionpack/lib/action_view/helpers/tags/datetime_local_field.rb @@ -1,7 +1,7 @@ module ActionView module Helpers - module Tags - class DatetimeLocalField < DatetimeField #:nodoc: + module Tags # :nodoc: + class DatetimeLocalField < DatetimeField # :nodoc: class << self def field_type @field_type ||= "datetime-local" diff --git a/actionpack/lib/action_view/helpers/tags/datetime_select.rb b/actionpack/lib/action_view/helpers/tags/datetime_select.rb index a32c840bce..563de1840e 100644 --- a/actionpack/lib/action_view/helpers/tags/datetime_select.rb +++ b/actionpack/lib/action_view/helpers/tags/datetime_select.rb @@ -1,7 +1,7 @@ module ActionView module Helpers - module Tags - class DatetimeSelect < DateSelect #:nodoc: + module Tags # :nodoc: + class DatetimeSelect < DateSelect # :nodoc: end end end diff --git a/actionpack/lib/action_view/helpers/tags/email_field.rb b/actionpack/lib/action_view/helpers/tags/email_field.rb index 45cde507d7..7ce3ccb9bf 100644 --- a/actionpack/lib/action_view/helpers/tags/email_field.rb +++ b/actionpack/lib/action_view/helpers/tags/email_field.rb @@ -1,7 +1,7 @@ module ActionView module Helpers - module Tags - class EmailField < TextField #:nodoc: + module Tags # :nodoc: + class EmailField < TextField # :nodoc: end end end diff --git a/actionpack/lib/action_view/helpers/tags/file_field.rb b/actionpack/lib/action_view/helpers/tags/file_field.rb index 59f2ff71b4..476b820d84 100644 --- a/actionpack/lib/action_view/helpers/tags/file_field.rb +++ b/actionpack/lib/action_view/helpers/tags/file_field.rb @@ -1,7 +1,7 @@ module ActionView module Helpers - module Tags - class FileField < TextField #:nodoc: + module Tags # :nodoc: + class FileField < TextField # :nodoc: end end end diff --git a/actionpack/lib/action_view/helpers/tags/grouped_collection_select.rb b/actionpack/lib/action_view/helpers/tags/grouped_collection_select.rb index 507ba8835f..2ed4712dac 100644 --- a/actionpack/lib/action_view/helpers/tags/grouped_collection_select.rb +++ b/actionpack/lib/action_view/helpers/tags/grouped_collection_select.rb @@ -1,7 +1,7 @@ module ActionView module Helpers - module Tags - class GroupedCollectionSelect < Base #:nodoc: + module Tags # :nodoc: + class GroupedCollectionSelect < Base # :nodoc: def initialize(object_name, method_name, template_object, collection, group_method, group_label_method, option_key_method, option_value_method, options, html_options) @collection = collection @group_method = group_method diff --git a/actionpack/lib/action_view/helpers/tags/hidden_field.rb b/actionpack/lib/action_view/helpers/tags/hidden_field.rb index a8d13dc1b1..c3757c2461 100644 --- a/actionpack/lib/action_view/helpers/tags/hidden_field.rb +++ b/actionpack/lib/action_view/helpers/tags/hidden_field.rb @@ -1,7 +1,7 @@ module ActionView module Helpers - module Tags - class HiddenField < TextField #:nodoc: + module Tags # :nodoc: + class HiddenField < TextField # :nodoc: end end end diff --git a/actionpack/lib/action_view/helpers/tags/label.rb b/actionpack/lib/action_view/helpers/tags/label.rb index 16135fcd5a..35d3ba8434 100644 --- a/actionpack/lib/action_view/helpers/tags/label.rb +++ b/actionpack/lib/action_view/helpers/tags/label.rb @@ -1,7 +1,7 @@ module ActionView module Helpers - module Tags - class Label < Base #:nodoc: + module Tags # :nodoc: + class Label < Base # :nodoc: def initialize(object_name, method_name, template_object, content_or_options = nil, options = nil) options ||= {} diff --git a/actionpack/lib/action_view/helpers/tags/month_field.rb b/actionpack/lib/action_view/helpers/tags/month_field.rb index 3d3c32d847..4c0fb846ee 100644 --- a/actionpack/lib/action_view/helpers/tags/month_field.rb +++ b/actionpack/lib/action_view/helpers/tags/month_field.rb @@ -1,7 +1,7 @@ module ActionView module Helpers - module Tags - class MonthField < DatetimeField #:nodoc: + module Tags # :nodoc: + class MonthField < DatetimeField # :nodoc: private def format_date(value) diff --git a/actionpack/lib/action_view/helpers/tags/number_field.rb b/actionpack/lib/action_view/helpers/tags/number_field.rb index 9cd04434f0..4f95b1b4de 100644 --- a/actionpack/lib/action_view/helpers/tags/number_field.rb +++ b/actionpack/lib/action_view/helpers/tags/number_field.rb @@ -1,7 +1,7 @@ module ActionView module Helpers - module Tags - class NumberField < TextField #:nodoc: + module Tags # :nodoc: + class NumberField < TextField # :nodoc: def render options = @options.stringify_keys diff --git a/actionpack/lib/action_view/helpers/tags/password_field.rb b/actionpack/lib/action_view/helpers/tags/password_field.rb index 6e7a4d3c36..6099fa6f19 100644 --- a/actionpack/lib/action_view/helpers/tags/password_field.rb +++ b/actionpack/lib/action_view/helpers/tags/password_field.rb @@ -1,7 +1,7 @@ module ActionView module Helpers - module Tags - class PasswordField < TextField #:nodoc: + module Tags # :nodoc: + class PasswordField < TextField # :nodoc: def render @options = {:value => nil}.merge!(@options) super diff --git a/actionpack/lib/action_view/helpers/tags/radio_button.rb b/actionpack/lib/action_view/helpers/tags/radio_button.rb index 8a0421f061..4849c537a5 100644 --- a/actionpack/lib/action_view/helpers/tags/radio_button.rb +++ b/actionpack/lib/action_view/helpers/tags/radio_button.rb @@ -2,8 +2,8 @@ require 'action_view/helpers/tags/checkable' module ActionView module Helpers - module Tags - class RadioButton < Base #:nodoc: + module Tags # :nodoc: + class RadioButton < Base # :nodoc: include Checkable def initialize(object_name, method_name, template_object, tag_value, options) diff --git a/actionpack/lib/action_view/helpers/tags/range_field.rb b/actionpack/lib/action_view/helpers/tags/range_field.rb index 47db4680e7..f98ae88043 100644 --- a/actionpack/lib/action_view/helpers/tags/range_field.rb +++ b/actionpack/lib/action_view/helpers/tags/range_field.rb @@ -1,7 +1,7 @@ module ActionView module Helpers - module Tags - class RangeField < NumberField #:nodoc: + module Tags # :nodoc: + class RangeField < NumberField # :nodoc: end end end diff --git a/actionpack/lib/action_view/helpers/tags/search_field.rb b/actionpack/lib/action_view/helpers/tags/search_field.rb index 818fd4b887..c09e2f1be7 100644 --- a/actionpack/lib/action_view/helpers/tags/search_field.rb +++ b/actionpack/lib/action_view/helpers/tags/search_field.rb @@ -1,7 +1,7 @@ module ActionView module Helpers - module Tags - class SearchField < TextField #:nodoc: + module Tags # :nodoc: + class SearchField < TextField # :nodoc: def render options = @options.stringify_keys diff --git a/actionpack/lib/action_view/helpers/tags/select.rb b/actionpack/lib/action_view/helpers/tags/select.rb index 53a108b7e6..d64e2f68ef 100644 --- a/actionpack/lib/action_view/helpers/tags/select.rb +++ b/actionpack/lib/action_view/helpers/tags/select.rb @@ -1,7 +1,7 @@ module ActionView module Helpers - module Tags - class Select < Base #:nodoc: + module Tags # :nodoc: + class Select < Base # :nodoc: def initialize(object_name, method_name, template_object, choices, options, html_options) @choices = choices @choices = @choices.to_a if @choices.is_a?(Range) @@ -31,7 +31,6 @@ module ActionView # # [nil, []] # { nil => [] } - # def grouped_choices? !@choices.empty? && @choices.first.respond_to?(:last) && Array === @choices.first.last end diff --git a/actionpack/lib/action_view/helpers/tags/tel_field.rb b/actionpack/lib/action_view/helpers/tags/tel_field.rb index 87c1f6b6b6..987bb9e67a 100644 --- a/actionpack/lib/action_view/helpers/tags/tel_field.rb +++ b/actionpack/lib/action_view/helpers/tags/tel_field.rb @@ -1,7 +1,7 @@ module ActionView module Helpers - module Tags - class TelField < TextField #:nodoc: + module Tags # :nodoc: + class TelField < TextField # :nodoc: end end end diff --git a/actionpack/lib/action_view/helpers/tags/text_area.rb b/actionpack/lib/action_view/helpers/tags/text_area.rb index f74652c5e7..c81156c0c8 100644 --- a/actionpack/lib/action_view/helpers/tags/text_area.rb +++ b/actionpack/lib/action_view/helpers/tags/text_area.rb @@ -1,7 +1,7 @@ module ActionView module Helpers - module Tags - class TextArea < Base #:nodoc: + module Tags # :nodoc: + class TextArea < Base # :nodoc: def render options = @options.stringify_keys add_default_name_and_id(options) diff --git a/actionpack/lib/action_view/helpers/tags/text_field.rb b/actionpack/lib/action_view/helpers/tags/text_field.rb index 024a1a8af2..baa5ff768e 100644 --- a/actionpack/lib/action_view/helpers/tags/text_field.rb +++ b/actionpack/lib/action_view/helpers/tags/text_field.rb @@ -1,7 +1,7 @@ module ActionView module Helpers - module Tags - class TextField < Base #:nodoc: + module Tags # :nodoc: + class TextField < Base # :nodoc: def render options = @options.stringify_keys options["size"] = options["maxlength"] unless options.key?("size") diff --git a/actionpack/lib/action_view/helpers/tags/time_field.rb b/actionpack/lib/action_view/helpers/tags/time_field.rb index a3941860c9..0e90a3aed7 100644 --- a/actionpack/lib/action_view/helpers/tags/time_field.rb +++ b/actionpack/lib/action_view/helpers/tags/time_field.rb @@ -1,7 +1,7 @@ module ActionView module Helpers - module Tags - class TimeField < DatetimeField #:nodoc: + module Tags # :nodoc: + class TimeField < DatetimeField # :nodoc: private def format_date(value) diff --git a/actionpack/lib/action_view/helpers/tags/time_select.rb b/actionpack/lib/action_view/helpers/tags/time_select.rb index 9e97deb706..0b06311d25 100644 --- a/actionpack/lib/action_view/helpers/tags/time_select.rb +++ b/actionpack/lib/action_view/helpers/tags/time_select.rb @@ -1,7 +1,7 @@ module ActionView module Helpers - module Tags - class TimeSelect < DateSelect #:nodoc: + module Tags # :nodoc: + class TimeSelect < DateSelect # :nodoc: end end end diff --git a/actionpack/lib/action_view/helpers/tags/time_zone_select.rb b/actionpack/lib/action_view/helpers/tags/time_zone_select.rb index 0a176157c3..80d165ec7e 100644 --- a/actionpack/lib/action_view/helpers/tags/time_zone_select.rb +++ b/actionpack/lib/action_view/helpers/tags/time_zone_select.rb @@ -1,7 +1,7 @@ module ActionView module Helpers - module Tags - class TimeZoneSelect < Base #:nodoc: + module Tags # :nodoc: + class TimeZoneSelect < Base # :nodoc: def initialize(object_name, method_name, template_object, priority_zones, options, html_options) @priority_zones = priority_zones @html_options = html_options diff --git a/actionpack/lib/action_view/helpers/tags/url_field.rb b/actionpack/lib/action_view/helpers/tags/url_field.rb index 1ffdfe0b3c..d76340178d 100644 --- a/actionpack/lib/action_view/helpers/tags/url_field.rb +++ b/actionpack/lib/action_view/helpers/tags/url_field.rb @@ -1,7 +1,7 @@ module ActionView module Helpers - module Tags - class UrlField < TextField #:nodoc: + module Tags # :nodoc: + class UrlField < TextField # :nodoc: end end end diff --git a/actionpack/lib/action_view/helpers/tags/week_field.rb b/actionpack/lib/action_view/helpers/tags/week_field.rb index 1e13939a0a..5b3d0494e9 100644 --- a/actionpack/lib/action_view/helpers/tags/week_field.rb +++ b/actionpack/lib/action_view/helpers/tags/week_field.rb @@ -1,7 +1,7 @@ module ActionView module Helpers - module Tags - class WeekField < DatetimeField #:nodoc: + module Tags # :nodoc: + class WeekField < DatetimeField # :nodoc: private def format_date(value) diff --git a/actionpack/lib/action_view/helpers/text_helper.rb b/actionpack/lib/action_view/helpers/text_helper.rb index 2e124cf085..147f9fd8ed 100644 --- a/actionpack/lib/action_view/helpers/text_helper.rb +++ b/actionpack/lib/action_view/helpers/text_helper.rb @@ -126,8 +126,8 @@ module ActionView # Extracts an excerpt from +text+ that matches the first instance of +phrase+. # The <tt>:radius</tt> option expands the excerpt on each side of the first occurrence of +phrase+ by the number of characters # defined in <tt>:radius</tt> (which defaults to 100). If the excerpt radius overflows the beginning or end of the +text+, - # then the <tt>:omission</tt> option (which defaults to "...") will be prepended/appended accordingly. The - # <tt>:separator</tt> enable to choose the delimation. The resulting string will be stripped in any case. If the +phrase+ + # then the <tt>:omission</tt> option (which defaults to "...") will be prepended/appended accordingly. Use the + # <tt>:separator</tt> option to choose the delimitation. The resulting string will be stripped in any case. If the +phrase+ # isn't found, nil is returned. # # excerpt('This is an example', 'an', radius: 5) @@ -145,7 +145,7 @@ module ActionView # excerpt('This is also an example', 'an', radius: 8, omission: '<chop> ') # # => <chop> is also an example # - # excerpt('This is a very beautiful morning', 'very', separator: ' ', radius: 1) + # excerpt('This is a very beautiful morning', 'very', separator: ' ', radius: 1) # # => ...a very beautiful... def excerpt(text, phrase, options = {}) return unless text && phrase @@ -250,8 +250,11 @@ module ActionView # simple_format("Look ma! A class!", class: 'description') # # => "<p class='description'>Look ma! A class!</p>" # - # simple_format("<span>I'm allowed!</span> It's true.", {}, sanitize: false) - # # => "<p><span>I'm allowed!</span> It's true.</p>" + # simple_format("<blink>Unblinkable.</blink>") + # # => "<p>Unblinkable.</p>" + # + # simple_format("<blink>Blinkable!</blink> It's true.", {}, sanitize: false) + # # => "<p><blink>Blinkable!</span> It's true.</p>" def simple_format(text, html_options = {}, options = {}) wrapper_tag = options.fetch(:wrapper_tag, :p) diff --git a/actionpack/test/controller/live_stream_test.rb b/actionpack/test/controller/live_stream_test.rb index 5755444a65..34164a19f0 100644 --- a/actionpack/test/controller/live_stream_test.rb +++ b/actionpack/test/controller/live_stream_test.rb @@ -52,6 +52,29 @@ module ActionController def with_stale render :text => 'stale' if stale?(:etag => "123") end + + def exception_in_view + render 'doesntexist' + end + + def exception_with_callback + response.headers['Content-Type'] = 'text/event-stream' + + response.stream.on_error do + response.stream.write %(data: "500 Internal Server Error"\n\n) + response.stream.close + end + + raise 'An exception occurred...' + end + + def exception_in_exception_callback + response.headers['Content-Type'] = 'text/event-stream' + response.stream.on_error do + raise 'We need to go deeper.' + end + response.stream.write params[:widget][:didnt_check_for_nil] + end end tests TestController @@ -66,6 +89,21 @@ module ActionController TestResponse.new end + def assert_stream_closed + assert response.stream.closed?, 'stream should be closed' + end + + def capture_log_output + output = StringIO.new + old_logger, ActionController::Base.logger = ActionController::Base.logger, ActiveSupport::Logger.new(output) + + begin + yield output + ensure + ActionController::Base.logger = old_logger + end + end + def test_set_response! @controller.set_response!(@request) assert_kind_of(Live::Response, @controller.response) @@ -119,7 +157,43 @@ module ActionController def test_render_text get :render_text assert_equal 'zomg', response.body - assert response.stream.closed?, 'stream should be closed' + assert_stream_closed + end + + def test_exception_handling_html + capture_log_output do |output| + get :exception_in_view + assert_match %r((window\.location = "/500\.html"</script></html>)$), response.body + assert_match 'Missing template test/doesntexist', output.rewind && output.read + assert_stream_closed + end + end + + def test_exception_handling_plain_text + capture_log_output do |output| + get :exception_in_view, format: :json + assert_equal '', response.body + assert_match 'Missing template test/doesntexist', output.rewind && output.read + assert_stream_closed + end + end + + def test_exception_callback + capture_log_output do |output| + get :exception_with_callback, format: 'text/event-stream' + assert_equal %(data: "500 Internal Server Error"\n\n), response.body + assert_match 'An exception occurred...', output.rewind && output.read + assert_stream_closed + end + end + + def test_exceptions_raised_handling_exceptions + capture_log_output do |output| + get :exception_in_exception_callback, format: 'text/event-stream' + assert_equal '', response.body + assert_match 'We need to go deeper', output.rewind && output.read + assert_stream_closed + end end def test_stale_without_etag |