diff options
Diffstat (limited to 'actionview')
45 files changed, 648 insertions, 439 deletions
diff --git a/actionview/CHANGELOG.md b/actionview/CHANGELOG.md index c700cb72ec..ea7f8b205e 100644 --- a/actionview/CHANGELOG.md +++ b/actionview/CHANGELOG.md @@ -1,45 +1,3 @@ -* Fix issues with `field_error_proc` wrapping `optgroup` and select divider `option`. - Fixes #31088 - *Matthias Neumayr* - -* Remove deprecated Erubis ERB handler. - - *Rafael Mendonça França* - -* Remove default `alt` text generation. - - Fixes #30096 - - *Cameron Cundiff* - -* Add `srcset` option to `image_tag` helper. - - *Roberto Miranda* - -* Fix issues with scopes and engine on `current_page?` method. - - Fixes #29401. - - *Nikita Savrov* - -* Generate field ids in `collection_check_boxes` and `collection_radio_buttons`. - - This makes sure that the labels are linked up with the fields. - - Fixes #29014. - - *Yuji Yaginuma* - -* Add `:json` type to `auto_discovery_link_tag` to support [JSON Feeds](https://jsonfeed.org/version/1) - - *Mike Gunderloy* - -* Update `distance_of_time_in_words` helper to display better error messages - for bad input. - - *Jay Hayes* - - -Please check [5-1-stable](https://github.com/rails/rails/blob/5-1-stable/actionview/CHANGELOG.md) for previous changes. +Please check [5-2-stable](https://github.com/rails/rails/blob/5-2-stable/actionview/CHANGELOG.md) for previous changes. diff --git a/actionview/MIT-LICENSE b/actionview/MIT-LICENSE index ac810e86d0..1cb3add0fc 100644 --- a/actionview/MIT-LICENSE +++ b/actionview/MIT-LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2017 David Heinemeier Hansson +Copyright (c) 2004-2018 David Heinemeier Hansson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/actionview/README.rdoc b/actionview/README.rdoc index d5029599b7..03a0723564 100644 --- a/actionview/README.rdoc +++ b/actionview/README.rdoc @@ -11,7 +11,7 @@ The latest version of Action View can be installed with RubyGems: $ gem install actionview -Source code can be downloaded as part of the Rails project on GitHub +Source code can be downloaded as part of the Rails project on GitHub: * https://github.com/rails/rails/tree/master/actionview @@ -29,7 +29,7 @@ API documentation is at * http://api.rubyonrails.org -Bug reports can be filed for the Ruby on Rails project here: +Bug reports for the Ruby on Rails project can be filed here: * https://github.com/rails/rails/issues diff --git a/actionview/RUNNING_UJS_TESTS.rdoc b/actionview/RUNNING_UJS_TESTS.rdoc index a575624a06..e30c2aee55 100644 --- a/actionview/RUNNING_UJS_TESTS.rdoc +++ b/actionview/RUNNING_UJS_TESTS.rdoc @@ -1,7 +1,8 @@ == Running UJS tests -Ensure that you can build the project and run tests. -Run rake ujs:server first, and then run the web tests by -visiting http://localhost:4567 in your browser. +Ensure that you can build the project by running: + rake ujs:server -rake ujs:server +Then run the web tests by visiting the following URL in your browser: + + http://localhost:4567 diff --git a/actionview/RUNNING_UNIT_TESTS.rdoc b/actionview/RUNNING_UNIT_TESTS.rdoc index e99d5ca1df..4442dbdb9e 100644 --- a/actionview/RUNNING_UNIT_TESTS.rdoc +++ b/actionview/RUNNING_UNIT_TESTS.rdoc @@ -2,13 +2,13 @@ The easiest way to run the unit tests is through Rake. The default task runs the entire test suite for all classes. For more information, checkout the -full array of rake tasks with "rake -T" +full array of rake tasks with <tt>rake -T</tt> Rake can be found at https://ruby.github.io/rake/. == Running by hand -To run a single test suite +Run a single test suite: rake test TEST=path/to/test.rb @@ -18,10 +18,9 @@ which can be further narrowed down to one test: == Dependency on Active Record and database setup -Test cases in the test/activerecord/ directory depend on having -activerecord and sqlite3 installed. If Active Record is not in -actionview/../activerecord directory, or the sqlite3 rubygem is not installed, -these tests are skipped. - +Test cases in the +test/activerecord/+ directory depend on having +activerecord+ and +sqlite3+ installed. If Active Record is not in +actionview/../activerecord+ directory, or the +sqlite3+ Ruby gem is not installed, + these tests are skipped. Other tests are runnable from a fresh copy of actionview without any configuration. diff --git a/actionview/app/assets/javascripts/MIT-LICENSE b/actionview/app/assets/javascripts/MIT-LICENSE index befcbdc7b7..28e1b12496 100644 --- a/actionview/app/assets/javascripts/MIT-LICENSE +++ b/actionview/app/assets/javascripts/MIT-LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2007-2017 Rails Core team +Copyright (c) 2007-2018 Rails Core team Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/actionview/app/assets/javascripts/README.md b/actionview/app/assets/javascripts/README.md index 8198011b02..185dddc7e5 100644 --- a/actionview/app/assets/javascripts/README.md +++ b/actionview/app/assets/javascripts/README.md @@ -50,6 +50,6 @@ Run `bundle exec rake ujs:server` first, and then run the web tests by visiting rails-ujs is released under the [MIT License](MIT-LICENSE). -[data]: http://www.w3.org/TR/html5/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes "Embedding custom non-visible data with the data-* attributes" +[data]: https://www.w3.org/TR/html5/dom.html#embedding-custom-non-visible-data-with-the-data-attributes "Embedding custom non-visible data with the data-* attributes" [validator]: http://validator.w3.org/ [csrf]: http://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection.html diff --git a/actionview/app/assets/javascripts/rails-ujs/utils/event.coffee b/actionview/app/assets/javascripts/rails-ujs/utils/event.coffee index a2135c9851..a7eee52060 100644 --- a/actionview/app/assets/javascripts/rails-ujs/utils/event.coffee +++ b/actionview/app/assets/javascripts/rails-ujs/utils/event.coffee @@ -11,8 +11,18 @@ if typeof CustomEvent isnt 'function' evt = document.createEvent('CustomEvent') evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail) evt + CustomEvent.prototype = window.Event.prototype + # Fix setting `defaultPrevented` when `preventDefault()` is called + # http://stackoverflow.com/questions/23349191/event-preventdefault-is-not-working-in-ie-11-for-custom-events + { preventDefault } = CustomEvent.prototype + CustomEvent.prototype.preventDefault = -> + result = preventDefault.call(this) + if @cancelable and not @defaultPrevented + Object.defineProperty(this, 'defaultPrevented', get: -> true) + result + # Triggers a custom event on an element and returns false if the event result is false # obj:: # a native DOM element diff --git a/actionview/lib/action_view.rb b/actionview/lib/action_view.rb index 9533f8d56c..c1eeda75f5 100644 --- a/actionview/lib/action_view.rb +++ b/actionview/lib/action_view.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true #-- -# Copyright (c) 2004-2017 David Heinemeier Hansson +# Copyright (c) 2004-2018 David Heinemeier Hansson # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the diff --git a/actionview/lib/action_view/digestor.rb b/actionview/lib/action_view/digestor.rb index dfd62bdcfd..1cf0bd3016 100644 --- a/actionview/lib/action_view/digestor.rb +++ b/actionview/lib/action_view/digestor.rb @@ -89,7 +89,7 @@ module ActionView end def digest(finder, stack = []) - Digest::MD5.hexdigest("#{template.source}-#{dependency_digest(finder, stack)}") + ActiveSupport::Digest.hexdigest("#{template.source}-#{dependency_digest(finder, stack)}") end def dependency_digest(finder, stack) diff --git a/actionview/lib/action_view/gem_version.rb b/actionview/lib/action_view/gem_version.rb index ed92490be7..77ae444a58 100644 --- a/actionview/lib/action_view/gem_version.rb +++ b/actionview/lib/action_view/gem_version.rb @@ -7,8 +7,8 @@ module ActionView end module VERSION - MAJOR = 5 - MINOR = 2 + MAJOR = 6 + MINOR = 0 TINY = 0 PRE = "alpha" diff --git a/actionview/lib/action_view/helpers/asset_tag_helper.rb b/actionview/lib/action_view/helpers/asset_tag_helper.rb index e362f13798..76b1c3fb6e 100644 --- a/actionview/lib/action_view/helpers/asset_tag_helper.rb +++ b/actionview/lib/action_view/helpers/asset_tag_helper.rb @@ -2,6 +2,8 @@ require "active_support/core_ext/array/extract_options" require "active_support/core_ext/hash/keys" +require "active_support/core_ext/object/inclusion" +require "active_support/core_ext/object/try" require "action_view/helpers/asset_url_helper" require "action_view/helpers/tag_helper" @@ -45,11 +47,11 @@ module ActionView # When the last parameter is a hash you can add HTML attributes using that # parameter. The following options are supported: # - # * <tt>:extname</tt> - Append an extension to the generated url unless the extension - # already exists. This only applies for relative urls. - # * <tt>:protocol</tt> - Sets the protocol of the generated url, this option only - # applies when a relative url and +host+ options are provided. - # * <tt>:host</tt> - When a relative url is provided the host is added to the + # * <tt>:extname</tt> - Append an extension to the generated URL unless the extension + # already exists. This only applies for relative URLs. + # * <tt>:protocol</tt> - Sets the protocol of the generated URL. This option only + # applies when a relative URL and +host+ options are provided. + # * <tt>:host</tt> - When a relative URL is provided the host is added to the # that path. # * <tt>:skip_pipeline</tt> - This option is used to bypass the asset pipeline # when it is set to true. @@ -91,7 +93,7 @@ module ActionView content_tag("script".freeze, "", tag_options) }.join("\n").html_safe - request.send_early_hints("Link" => early_hints_links.join("\n")) if respond_to?(:request) + request.send_early_hints("Link" => early_hints_links.join("\n")) if respond_to?(:request) && request sources_tags end @@ -131,7 +133,7 @@ module ActionView sources_tags = sources.uniq.map { |source| href = path_to_stylesheet(source, path_options) - early_hints_links << "<#{href}>; rel=preload; as=stylesheet" + early_hints_links << "<#{href}>; rel=preload; as=style" tag_options = { "rel" => "stylesheet", "media" => "screen", @@ -140,7 +142,7 @@ module ActionView tag(:link, tag_options) }.join("\n").html_safe - request.send_early_hints("Link" => early_hints_links.join("\n")) if respond_to?(:request) + request.send_early_hints("Link" => early_hints_links.join("\n")) if respond_to?(:request) && request sources_tags end @@ -221,8 +223,69 @@ module ActionView }.merge!(options.symbolize_keys)) end + # Returns a link tag that browsers can use to preload the +source+. + # The +source+ can be the path of a resource managed by asset pipeline, + # a full path, or an URI. + # + # ==== Options + # + # * <tt>:type</tt> - Override the auto-generated mime type, defaults to the mime type for +source+ extension. + # * <tt>:as</tt> - Override the auto-generated value for as attribute, calculated using +source+ extension and mime type. + # * <tt>:crossorigin</tt> - Specify the crossorigin attribute, required to load cross-origin resources. + # * <tt>:nopush</tt> - Specify if the use of server push is not desired for the resource. Defaults to +false+. + # + # ==== Examples + # + # preload_link_tag("custom_theme.css") + # # => <link rel="preload" href="/assets/custom_theme.css" as="style" type="text/css" /> + # + # preload_link_tag("/videos/video.webm") + # # => <link rel="preload" href="/videos/video.mp4" as="video" type="video/webm" /> + # + # preload_link_tag(post_path(format: :json), as: "fetch") + # # => <link rel="preload" href="/posts.json" as="fetch" type="application/json" /> + # + # preload_link_tag("worker.js", as: "worker") + # # => <link rel="preload" href="/assets/worker.js" as="worker" type="text/javascript" /> + # + # preload_link_tag("//example.com/font.woff2") + # # => <link rel="preload" href="//example.com/font.woff2" as="font" type="font/woff2" crossorigin="anonymous"/> + # + # preload_link_tag("//example.com/font.woff2", crossorigin: "use-credentials") + # # => <link rel="preload" href="//example.com/font.woff2" as="font" type="font/woff2" crossorigin="use-credentials" /> + # + # preload_link_tag("/media/audio.ogg", nopush: true) + # # => <link rel="preload" href="/media/audio.ogg" as="audio" type="audio/ogg" /> + # + def preload_link_tag(source, options = {}) + href = asset_path(source, skip_pipeline: options.delete(:skip_pipeline)) + extname = File.extname(source).downcase.delete(".") + mime_type = options.delete(:type) || Template::Types[extname].try(:to_s) + as_type = options.delete(:as) || resolve_link_as(extname, mime_type) + crossorigin = options.delete(:crossorigin) + crossorigin = "anonymous" if crossorigin == true || (crossorigin.blank? && as_type == "font") + nopush = options.delete(:nopush) || false + + link_tag = tag.link({ + rel: "preload", + href: href, + as: as_type, + type: mime_type, + crossorigin: crossorigin + }.merge!(options.symbolize_keys)) + + early_hints_link = "<#{href}>; rel=preload; as=#{as_type}" + early_hints_link += "; type=#{mime_type}" if mime_type + early_hints_link += "; crossorigin=#{crossorigin}" if crossorigin + early_hints_link += "; nopush" if nopush + + request.send_early_hints("Link" => early_hints_link) if respond_to?(:request) && request + + link_tag + end + # Returns an HTML image tag for the +source+. The +source+ can be a full - # path, a file or an Active Storage attachment. + # path, a file, or an Active Storage attachment. # # ==== Options # @@ -310,12 +373,13 @@ module ActionView # Returns an HTML video tag for the +sources+. If +sources+ is a string, # a single video tag will be returned. If +sources+ is an array, a video # tag with nested source tags for each source will be returned. The - # +sources+ can be full paths or files that exists in your public videos + # +sources+ can be full paths or files that exist in your public videos # directory. # # ==== Options - # You can add HTML attributes using the +options+. The +options+ supports - # two additional keys for convenience and conformance: + # + # When the last parameter is a hash you can add HTML attributes using that + # parameter. The following options are supported: # # * <tt>:poster</tt> - Set an image (like a screenshot) to be shown # before the video loads. The path is calculated like the +src+ of +image_tag+. @@ -332,7 +396,7 @@ module ActionView # video_tag("trailer.ogg") # # => <video src="/videos/trailer.ogg"></video> # video_tag("trailer.ogg", controls: true, preload: 'none') - # # => <video preload="none" controls="controls" src="/videos/trailer.ogg" ></video> + # # => <video preload="none" controls="controls" src="/videos/trailer.ogg"></video> # video_tag("trailer.m4v", size: "16x10", poster: "screenshot.png") # # => <video src="/videos/trailer.m4v" width="16" height="10" poster="/assets/screenshot.png"></video> # video_tag("trailer.m4v", size: "16x10", poster: "screenshot.png", poster_skip_pipeline: true) @@ -359,9 +423,14 @@ module ActionView end end - # Returns an HTML audio tag for the +source+. - # The +source+ can be full path or file that exists in - # your public audios directory. + # Returns an HTML audio tag for the +sources+. If +sources+ is a string, + # a single audio tag will be returned. If +sources+ is an array, an audio + # tag with nested source tags for each source will be returned. The + # +sources+ can be full paths or files that exist in your public audios + # directory. + # + # When the last parameter is a hash you can add HTML attributes using that + # parameter. # # audio_tag("sound") # # => <audio src="/audios/sound"></audio> @@ -417,6 +486,18 @@ module ActionView raise ArgumentError, "Cannot pass a :size option with a :height or :width option" end end + + def resolve_link_as(extname, mime_type) + if extname == "js" + "script" + elsif extname == "css" + "style" + elsif extname == "vtt" + "track" + elsif (type = mime_type.to_s.split("/")[0]) && type.in?(%w(audio video font)) + type + end + end end end end diff --git a/actionview/lib/action_view/helpers/asset_url_helper.rb b/actionview/lib/action_view/helpers/asset_url_helper.rb index a4dcfc9a6c..8cbe107e41 100644 --- a/actionview/lib/action_view/helpers/asset_url_helper.rb +++ b/actionview/lib/action_view/helpers/asset_url_helper.rb @@ -6,7 +6,7 @@ module ActionView # = Action View Asset URL Helpers module Helpers #:nodoc: # This module provides methods for generating asset paths and - # urls. + # URLs. # # image_path("rails.png") # # => "/assets/rails.png" @@ -57,8 +57,8 @@ module ActionView # You can read more about setting up your DNS CNAME records from your ISP. # # Note: This is purely a browser performance optimization and is not meant - # for server load balancing. See http://www.die.net/musings/page_load_time/ - # for background and http://www.browserscope.org/?category=network for + # for server load balancing. See https://www.die.net/musings/page_load_time/ + # for background and https://www.browserscope.org/?category=network for # connection limit data. # # Alternatively, you can exert more control over the asset host by setting @@ -97,7 +97,7 @@ module ActionView # still sending assets for plain HTTP requests from asset hosts. If you don't # have SSL certificates for each of the asset hosts this technique allows you # to avoid warnings in the client about mixed media. - # Note that the request parameter might not be supplied, e.g. when the assets + # Note that the +request+ parameter might not be supplied, e.g. when the assets # are precompiled via a Rake task. Make sure to use a +Proc+ instead of a lambda, # since a +Proc+ allows missing parameters and sets them to +nil+. # @@ -149,13 +149,13 @@ module ActionView # Below lists scenarios that apply to +asset_path+ whether or not you're # using the asset pipeline. # - # - All fully qualified urls are returned immediately. This bypasses the + # - All fully qualified URLs are returned immediately. This bypasses the # asset pipeline and all other behavior described. # # asset_path("http://www.example.com/js/xmlhr.js") # => "http://www.example.com/js/xmlhr.js" # # - All assets that begin with a forward slash are assumed to be full - # urls and will not be expanded. This will bypass the asset pipeline. + # URLs and will not be expanded. This will bypass the asset pipeline. # # asset_path("/foo.png") # => "/foo.png" # @@ -324,7 +324,7 @@ module ActionView # Since +javascript_url+ is based on +asset_url+ method you can set :host options. If :host # options is set, it overwrites global +config.action_controller.asset_host+ setting. # - # javascript_url "js/xmlhr.js", host: "http://stage.example.com" # => http://stage.example.com/assets/dir/xmlhr.js + # javascript_url "js/xmlhr.js", host: "http://stage.example.com" # => http://stage.example.com/assets/js/xmlhr.js # def javascript_url(source, options = {}) url_to_asset(source, { type: :javascript }.merge!(options)) @@ -351,7 +351,7 @@ module ActionView # Since +stylesheet_url+ is based on +asset_url+ method you can set :host options. If :host # options is set, it overwrites global +config.action_controller.asset_host+ setting. # - # stylesheet_url "css/style.css", host: "http://stage.example.com" # => http://stage.example.com/css/style.css + # stylesheet_url "css/style.css", host: "http://stage.example.com" # => http://stage.example.com/assets/css/style.css # def stylesheet_url(source, options = {}) url_to_asset(source, { type: :stylesheet }.merge!(options)) @@ -381,7 +381,7 @@ module ActionView # Since +image_url+ is based on +asset_url+ method you can set :host options. If :host # options is set, it overwrites global +config.action_controller.asset_host+ setting. # - # image_url "edit.png", host: "http://stage.example.com" # => http://stage.example.com/edit.png + # image_url "edit.png", host: "http://stage.example.com" # => http://stage.example.com/assets/edit.png # def image_url(source, options = {}) url_to_asset(source, { type: :image }.merge!(options)) @@ -407,7 +407,7 @@ module ActionView # Since +video_url+ is based on +asset_url+ method you can set :host options. If :host # options is set, it overwrites global +config.action_controller.asset_host+ setting. # - # video_url "hd.avi", host: "http://stage.example.com" # => http://stage.example.com/hd.avi + # video_url "hd.avi", host: "http://stage.example.com" # => http://stage.example.com/videos/hd.avi # def video_url(source, options = {}) url_to_asset(source, { type: :video }.merge!(options)) @@ -433,7 +433,7 @@ module ActionView # Since +audio_url+ is based on +asset_url+ method you can set :host options. If :host # options is set, it overwrites global +config.action_controller.asset_host+ setting. # - # audio_url "horse.wav", host: "http://stage.example.com" # => http://stage.example.com/horse.wav + # audio_url "horse.wav", host: "http://stage.example.com" # => http://stage.example.com/audios/horse.wav # def audio_url(source, options = {}) url_to_asset(source, { type: :audio }.merge!(options)) @@ -458,7 +458,7 @@ module ActionView # Since +font_url+ is based on +asset_url+ method you can set :host options. If :host # options is set, it overwrites global +config.action_controller.asset_host+ setting. # - # font_url "font.ttf", host: "http://stage.example.com" # => http://stage.example.com/font.ttf + # font_url "font.ttf", host: "http://stage.example.com" # => http://stage.example.com/fonts/font.ttf # def font_url(source, options = {}) url_to_asset(source, { type: :font }.merge!(options)) diff --git a/actionview/lib/action_view/helpers/date_helper.rb b/actionview/lib/action_view/helpers/date_helper.rb index 09040ccbc4..4c45f122fe 100644 --- a/actionview/lib/action_view/helpers/date_helper.rb +++ b/actionview/lib/action_view/helpers/date_helper.rb @@ -116,7 +116,7 @@ module ActionView when 10..19 then locale.t :less_than_x_seconds, count: 20 when 20..39 then locale.t :half_a_minute when 40..59 then locale.t :less_than_x_minutes, count: 1 - else locale.t :x_minutes, count: 1 + else locale.t :x_minutes, count: 1 end when 2...45 then locale.t :x_minutes, count: distance_in_minutes @@ -131,7 +131,7 @@ module ActionView when 43200...86400 then locale.t :about_x_months, count: (distance_in_minutes.to_f / 43200.0).round # 60 days up to 365 days when 86400...525600 then locale.t :x_months, count: (distance_in_minutes.to_f / 43200.0).round - else + else from_year = from_time.year from_year += 1 if from_time.month >= 3 to_year = to_time.year diff --git a/actionview/lib/action_view/helpers/form_helper.rb b/actionview/lib/action_view/helpers/form_helper.rb index 6d2ace8cf8..15aa9ec2dd 100644 --- a/actionview/lib/action_view/helpers/form_helper.rb +++ b/actionview/lib/action_view/helpers/form_helper.rb @@ -19,7 +19,7 @@ module ActionView # compared to using vanilla HTML. # # Typically, a form designed to create or update a resource reflects the - # identity of the resource in several ways: (i) the url that the form is + # identity of the resource in several ways: (i) the URL that the form is # sent to (the form element's +action+ attribute) should result in a request # being routed to the appropriate controller action (with the appropriate <tt>:id</tt> # parameter in the case of an existing resource), (ii) input fields should @@ -166,7 +166,7 @@ module ActionView # So for example you may use a named route directly. When the model is # represented by a string or symbol, as in the example above, if the # <tt>:url</tt> option is not specified, by default the form will be - # sent back to the current url (We will describe below an alternative + # sent back to the current URL (We will describe below an alternative # resource-oriented usage of +form_for+ in which the URL does not need # to be specified explicitly). # * <tt>:namespace</tt> - A namespace for your form to ensure uniqueness of @@ -478,6 +478,8 @@ module ActionView mattr_accessor :form_with_generates_remote_forms, default: true + mattr_accessor :form_with_generates_ids, default: false + # Creates a form tag based on mixing URLs, scopes, or models. # # # Using just a URL: @@ -606,7 +608,7 @@ module ActionView # This is helpful when fragment-caching the form. Remote forms # get the authenticity token from the <tt>meta</tt> tag, so embedding is # unnecessary unless you support browsers without JavaScript. - # * <tt>:local</tt> - By default form submits are remote and unobstrusive XHRs. + # * <tt>:local</tt> - By default form submits are remote and unobtrusive XHRs. # Disable remote submits with <tt>local: true</tt>. # * <tt>:skip_enforcing_utf8</tt> - By default a hidden field named +utf8+ # is output to enforce UTF-8 submits. Set to true to skip the field. @@ -640,16 +642,6 @@ module ActionView # # Where <tt>@document = Document.find(params[:id])</tt>. # - # When using labels +form_with+ requires setting the id on the field being - # labelled: - # - # <%= form_with(model: @post) do |form| %> - # <%= form.label :title %> - # <%= form.text_field :title, id: :post_title %> - # <% end %> - # - # See +label+ for more on how the +for+ attribute is derived. - # # === Mixing with other form helpers # # While +form_with+ uses a FormBuilder object it's possible to mix and @@ -746,7 +738,7 @@ module ActionView # end def form_with(model: nil, scope: nil, url: nil, format: nil, **options) options[:allow_method_names_outside_object] = true - options[:skip_default_ids] = true + options[:skip_default_ids] = !form_with_generates_ids if model url ||= polymorphic_path(model, format: format) @@ -1022,14 +1014,13 @@ module ActionView # <%= fields :comment do |fields| %> # <%= fields.text_field :body %> # <% end %> - # # => <input type="text" name="comment[body]> + # # => <input type="text" name="comment[body]"> # # # Using a model infers the scope and assigns field values: - # <%= fields model: Comment.new(body: "full bodied") do |fields| %< + # <%= fields model: Comment.new(body: "full bodied") do |fields| %> # <%= fields.text_field :body %> # <% end %> - # # => - # <input type="text" name="comment[body] value="full bodied"> + # # => <input type="text" name="comment[body]" value="full bodied"> # # # Using +fields+ with +form_with+: # <%= form_with model: @post do |form| %> @@ -1044,16 +1035,6 @@ module ActionView # or model is yielded, so any generated field names are prefixed with # either the passed scope or the scope inferred from the <tt>:model</tt>. # - # When using labels +fields+ requires setting the id on the field being - # labelled: - # - # <%= fields :comment do |fields| %> - # <%= fields.label :body %> - # <%= fields.text_field :body, id: :comment_body %> - # <% end %> - # - # See +label+ for more on how the +for+ attribute is derived. - # # === Mixing with other form helpers # # While +form_with+ uses a FormBuilder object it's possible to mix and @@ -1072,7 +1053,7 @@ module ActionView # FormOptionsHelper#collection_select and DateHelper#datetime_select. def fields(scope = nil, model: nil, **options, &block) options[:allow_method_names_outside_object] = true - options[:skip_default_ids] = true + options[:skip_default_ids] = !form_with_generates_ids if model scope ||= model_name_from_record_or_class(model).param_key @@ -1985,7 +1966,7 @@ module ActionView # See the docs for the <tt>ActionView::FormHelper.fields</tt> helper method. def fields(scope = nil, model: nil, **options, &block) options[:allow_method_names_outside_object] = true - options[:skip_default_ids] = true + options[:skip_default_ids] = !FormHelper.form_with_generates_ids convert_to_legacy_options(options) diff --git a/actionview/lib/action_view/helpers/form_options_helper.rb b/actionview/lib/action_view/helpers/form_options_helper.rb index 02a44477c1..fe5e0b693e 100644 --- a/actionview/lib/action_view/helpers/form_options_helper.rb +++ b/actionview/lib/action_view/helpers/form_options_helper.rb @@ -214,9 +214,13 @@ module ActionView # * +method+ - The attribute of +object+ corresponding to the select tag # * +collection+ - An array of objects representing the <tt><optgroup></tt> tags. # * +group_method+ - The name of a method which, when called on a member of +collection+, returns an - # array of child objects representing the <tt><option></tt> tags. + # array of child objects representing the <tt><option></tt> tags. It can also be any object that responds + # to +call+, such as a +proc+, that will be called for each member of the +collection+ to retrieve the + # value. # * +group_label_method+ - The name of a method which, when called on a member of +collection+, returns a - # string to be used as the +label+ attribute for its <tt><optgroup></tt> tag. + # string to be used as the +label+ attribute for its <tt><optgroup></tt> tag. It can also be any object + # that responds to +call+, such as a +proc+, that will be called for each member of the +collection+ to + # retrieve the label. # * +option_key_method+ - The name of a method which, when called on a child object of a member of # +collection+, returns a value to be used as the +value+ attribute for its <tt><option></tt> tag. # * +option_value_method+ - The name of a method which, when called on a child object of a member of @@ -457,9 +461,9 @@ module ActionView def option_groups_from_collection_for_select(collection, group_method, group_label_method, option_key_method, option_value_method, selected_key = nil) collection.map do |group| option_tags = options_from_collection_for_select( - group.send(group_method), option_key_method, option_value_method, selected_key) + value_for_collection(group, group_method), option_key_method, option_value_method, selected_key) - content_tag("optgroup".freeze, option_tags, label: group.send(group_label_method)) + content_tag("optgroup".freeze, option_tags, label: value_for_collection(group, group_label_method)) end.join.html_safe end diff --git a/actionview/lib/action_view/helpers/tags/base.rb b/actionview/lib/action_view/helpers/tags/base.rb index 8934a9894c..fed908fcdb 100644 --- a/actionview/lib/action_view/helpers/tags/base.rb +++ b/actionview/lib/action_view/helpers/tags/base.rb @@ -97,7 +97,7 @@ module ActionView index = name_and_id_index(options) options["name"] = options.fetch("name") { tag_name(options["multiple"], index) } - unless skip_default_ids? + if generate_ids? options["id"] = options.fetch("id") { tag_id(index) } if namespace = options.delete("namespace") options["id"] = options["id"] ? "#{namespace}_#{options['id']}" : namespace @@ -183,8 +183,8 @@ module ActionView end end - def skip_default_ids? - @skip_default_ids + def generate_ids? + !@skip_default_ids end end end diff --git a/actionview/lib/action_view/helpers/tags/label.rb b/actionview/lib/action_view/helpers/tags/label.rb index 56b48bbd62..02bd099784 100644 --- a/actionview/lib/action_view/helpers/tags/label.rb +++ b/actionview/lib/action_view/helpers/tags/label.rb @@ -75,10 +75,6 @@ module ActionView def render_component(builder) builder.translation end - - def skip_default_ids? - false # The id is used as the `for` attribute. - end end end end diff --git a/actionview/lib/action_view/helpers/text_helper.rb b/actionview/lib/action_view/helpers/text_helper.rb index 84d38aa416..34138de00e 100644 --- a/actionview/lib/action_view/helpers/text_helper.rb +++ b/actionview/lib/action_view/helpers/text_helper.rb @@ -13,9 +13,9 @@ module ActionView # # ==== Sanitization # - # Most text helpers by default sanitize the given content, but do not escape it. - # This means HTML tags will appear in the page but all malicious code will be removed. - # Let's look at some examples using the +simple_format+ method: + # Most text helpers that generate HTML output sanitize the given input by default, + # but do not escape it. This means HTML tags will appear in the page but all malicious + # code will be removed. Let's look at some examples using the +simple_format+ method: # # simple_format('<a href="http://example.com/">Example</a>') # # => "<p><a href=\"http://example.com/\">Example</a></p>" @@ -128,7 +128,7 @@ module ActionView # # => You searched for: <a href="search?q=rails">rails</a> # # highlight('<a href="javascript:alert(\'no!\')">ruby</a> on rails', 'rails', sanitize: false) - # # => "<a>ruby</a> on <mark>rails</mark>" + # # => <a href="javascript:alert('no!')">ruby</a> on <mark>rails</mark> def highlight(text, phrases, options = {}) text = sanitize(text) if options.fetch(:sanitize, true) diff --git a/actionview/lib/action_view/helpers/url_helper.rb b/actionview/lib/action_view/helpers/url_helper.rb index 9900e0cd03..889562c478 100644 --- a/actionview/lib/action_view/helpers/url_helper.rb +++ b/actionview/lib/action_view/helpers/url_helper.rb @@ -139,6 +139,11 @@ module ActionView # link_to "Profiles", controller: "profiles" # # => <a href="/profiles">Profiles</a> # + # When name is +nil+ the href is presented instead + # + # link_to nil, "http://example.com" + # # => <a href="http://www.example.com">http://www.example.com</a> + # # You can use a block as well if your link target is hard to fit into the name parameter. ERB example: # # <%= link_to(@profile) do %> @@ -589,7 +594,7 @@ module ActionView end def add_method_to_attributes!(html_options, method) - if method && method.to_s.downcase != "get" && html_options["rel"] !~ /nofollow/ + if method_not_get_method?(method) && html_options["rel"] !~ /nofollow/ if html_options["rel"].blank? html_options["rel"] = "nofollow" else @@ -599,6 +604,19 @@ module ActionView html_options["data-method"] = method end + STRINGIFIED_COMMON_METHODS = { + get: "get", + delete: "delete", + patch: "patch", + post: "post", + put: "put", + }.freeze + + def method_not_get_method?(method) + return false unless method + (STRINGIFIED_COMMON_METHODS[method] || method.to_s.downcase) != "get" + end + def token_tag(token = nil, form_options: {}) if token != false && protect_against_forgery? token ||= form_authenticity_token(form_options: form_options) diff --git a/actionview/lib/action_view/railtie.rb b/actionview/lib/action_view/railtie.rb index b22347c55c..73dfb267bb 100644 --- a/actionview/lib/action_view/railtie.rb +++ b/actionview/lib/action_view/railtie.rb @@ -22,8 +22,15 @@ module ActionView initializer "action_view.form_with_generates_remote_forms" do |app| ActiveSupport.on_load(:action_view) do form_with_generates_remote_forms = app.config.action_view.delete(:form_with_generates_remote_forms) - unless form_with_generates_remote_forms.nil? - ActionView::Helpers::FormHelper.form_with_generates_remote_forms = form_with_generates_remote_forms + ActionView::Helpers::FormHelper.form_with_generates_remote_forms = form_with_generates_remote_forms + end + end + + initializer "action_view.form_with_generates_ids" do |app| + ActiveSupport.on_load(:action_view) do + form_with_generates_ids = app.config.action_view.delete(:form_with_generates_ids) + unless form_with_generates_ids.nil? + ActionView::Helpers::FormHelper.form_with_generates_ids = form_with_generates_ids end end end diff --git a/actionview/lib/action_view/renderer/streaming_template_renderer.rb b/actionview/lib/action_view/renderer/streaming_template_renderer.rb index ca49eb1144..276a28ce07 100644 --- a/actionview/lib/action_view/renderer/streaming_template_renderer.rb +++ b/actionview/lib/action_view/renderer/streaming_template_renderer.rb @@ -65,7 +65,9 @@ module ActionView yielder = lambda { |*name| view._layout_for(*name) } instrument(:template, identifier: template.identifier, layout: layout.try(:virtual_path)) do + outer_config = I18n.config fiber = Fiber.new do + I18n.config = outer_config if layout layout.render(view, locals, output, &yielder) else diff --git a/actionview/package.json b/actionview/package.json index 4cbf0207e5..624eb5de93 100644 --- a/actionview/package.json +++ b/actionview/package.json @@ -1,6 +1,6 @@ { "name": "rails-ujs", - "version": "5.2.0-alpha", + "version": "6.0.0-alpha", "description": "Ruby on Rails unobtrusive scripting adapter", "main": "lib/assets/compiled/rails-ujs.js", "files": [ diff --git a/actionview/test/actionpack/controller/render_test.rb b/actionview/test/actionpack/controller/render_test.rb index 9df2a73448..8a9d7982d3 100644 --- a/actionview/test/actionpack/controller/render_test.rb +++ b/actionview/test/actionpack/controller/render_test.rb @@ -9,7 +9,7 @@ class ApplicationController < ActionController::Base end module Quiz - #Models + # Models Question = Struct.new(:name, :id) do extend ActiveModel::Naming include ActiveModel::Conversion diff --git a/actionview/test/active_record_unit.rb b/actionview/test/active_record_unit.rb index b39ecd8813..7f48b515a0 100644 --- a/actionview/test/active_record_unit.rb +++ b/actionview/test/active_record_unit.rb @@ -38,7 +38,7 @@ class ActiveRecordTestConnector end rescue Exception => e # errors from ActiveRecord setup $stderr.puts "\nSkipping ActiveRecord assertion tests: #{e}" - #$stderr.puts " #{e.backtrace.join("\n ")}\n" + # $stderr.puts " #{e.backtrace.join("\n ")}\n" self.able_to_connect = false end diff --git a/actionview/test/fixtures/layouts/streaming_with_locale.erb b/actionview/test/fixtures/layouts/streaming_with_locale.erb new file mode 100644 index 0000000000..e1fdad2073 --- /dev/null +++ b/actionview/test/fixtures/layouts/streaming_with_locale.erb @@ -0,0 +1,2 @@ +layout.locale: <%= I18n.locale %> +<%= yield %> diff --git a/actionview/test/fixtures/test/streaming_with_locale.erb b/actionview/test/fixtures/test/streaming_with_locale.erb new file mode 100644 index 0000000000..b0f2b2f7e9 --- /dev/null +++ b/actionview/test/fixtures/test/streaming_with_locale.erb @@ -0,0 +1 @@ +view.locale: <%= I18n.locale %> diff --git a/actionview/test/template/asset_tag_helper_test.rb b/actionview/test/template/asset_tag_helper_test.rb index 7475f5cc3c..6d98eacfb8 100644 --- a/actionview/test/template/asset_tag_helper_test.rb +++ b/actionview/test/template/asset_tag_helper_test.rb @@ -214,6 +214,17 @@ class AssetTagHelperTest < ActionView::TestCase %(favicon_link_tag 'mb-icon.png', :rel => 'apple-touch-icon', :type => 'image/png') => %(<link href="/images/mb-icon.png" rel="apple-touch-icon" type="image/png" />) } + PreloadLinkToTag = { + %(preload_link_tag '/styles/custom_theme.css') => %(<link rel="preload" href="/styles/custom_theme.css" as="style" type="text/css" />), + %(preload_link_tag '/videos/video.webm') => %(<link rel="preload" href="/videos/video.webm" as="video" type="video/webm" />), + %(preload_link_tag '/posts.json', as: 'fetch') => %(<link rel="preload" href="/posts.json" as="fetch" type="application/json" />), + %(preload_link_tag '/users', as: 'fetch', type: 'application/json') => %(<link rel="preload" href="/users" as="fetch" type="application/json" />), + %(preload_link_tag '//example.com/map?callback=initMap', as: 'fetch', type: 'application/javascript') => %(<link rel="preload" href="//example.com/map?callback=initMap" as="fetch" type="application/javascript" />), + %(preload_link_tag '//example.com/font.woff2') => %(<link rel="preload" href="//example.com/font.woff2" as="font" type="font/woff2" crossorigin="anonymous"/>), + %(preload_link_tag '//example.com/font.woff2', crossorigin: 'use-credentials') => %(<link rel="preload" href="//example.com/font.woff2" as="font" type="font/woff2" crossorigin="use-credentials" />), + %(preload_link_tag '/media/audio.ogg', nopush: true) => %(<link rel="preload" href="/media/audio.ogg" as="audio" type="audio/ogg" />) + } + VideoPathToTag = { %(video_path("xml")) => %(/videos/xml), %(video_path("xml.ogg")) => %(/videos/xml.ogg), @@ -396,7 +407,7 @@ class AssetTagHelperTest < ActionView::TestCase end def test_javascript_include_tag_is_html_safe - assert javascript_include_tag("prototype").html_safe? + assert_predicate javascript_include_tag("prototype"), :html_safe? end def test_javascript_include_tag_relative_protocol @@ -440,9 +451,17 @@ class AssetTagHelperTest < ActionView::TestCase } end + def test_stylesheet_link_tag_without_request + @request = nil + assert_dom_equal( + %(<link rel="stylesheet" media="screen" href="/stylesheets/foo.css" />), + stylesheet_link_tag("foo.css") + ) + end + def test_stylesheet_link_tag_is_html_safe - assert stylesheet_link_tag("dir/file").html_safe? - assert stylesheet_link_tag("dir/other/file", "dir/file2").html_safe? + assert_predicate stylesheet_link_tag("dir/file"), :html_safe? + assert_predicate stylesheet_link_tag("dir/other/file", "dir/file2"), :html_safe? end def test_stylesheet_link_tag_escapes_options @@ -464,6 +483,11 @@ class AssetTagHelperTest < ActionView::TestCase assert_dom_equal %(<link href="//assets.example.com/stylesheets/wellington.css" media="screen" rel="stylesheet" />), stylesheet_link_tag("wellington") end + def test_javascript_include_tag_without_request + @request = nil + assert_dom_equal %(<script src="/javascripts/foo.js"></script>), javascript_include_tag("foo.js") + end + def test_image_path ImagePathToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) } end @@ -522,6 +546,10 @@ class AssetTagHelperTest < ActionView::TestCase FaviconLinkToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) } end + def test_preload_link_tag + PreloadLinkToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) } + end + def test_video_path VideoPathToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) } end @@ -778,6 +806,23 @@ class AssetTagHelperNonVhostTest < ActionView::TestCase end end +class AssetTagHelperWithoutRequestTest < ActionView::TestCase + tests ActionView::Helpers::AssetTagHelper + + undef :request + + def test_stylesheet_link_tag_without_request + assert_dom_equal( + %(<link rel="stylesheet" media="screen" href="/stylesheets/foo.css" />), + stylesheet_link_tag("foo.css") + ) + end + + def test_javascript_include_tag_without_request + assert_dom_equal %(<script src="/javascripts/foo.js"></script>), javascript_include_tag("foo.js") + end +end + class AssetUrlHelperControllerTest < ActionView::TestCase tests ActionView::Helpers::AssetUrlHelper diff --git a/actionview/test/template/atom_feed_helper_test.rb b/actionview/test/template/atom_feed_helper_test.rb index 1be20dcaae..8e683cb48a 100644 --- a/actionview/test/template/atom_feed_helper_test.rb +++ b/actionview/test/template/atom_feed_helper_test.rb @@ -257,7 +257,7 @@ class AtomFeedTest < ActionController::TestCase get :index, params: { id: "provide_builder" } # because we pass in the non-default builder, the content generated by the # helper should go 'nowhere'. Leaving the response body blank. - assert @response.body.blank? + assert_predicate @response.body, :blank? end end diff --git a/actionview/test/template/capture_helper_test.rb b/actionview/test/template/capture_helper_test.rb index 8a1c00fd00..31c280a91c 100644 --- a/actionview/test/template/capture_helper_test.rb +++ b/actionview/test/template/capture_helper_test.rb @@ -155,12 +155,12 @@ class CaptureHelperTest < ActionView::TestCase content_for :title do content_tag(:p, "title") end - assert content_for(:title).html_safe? + assert_predicate content_for(:title), :html_safe? content_for :title, "", flush: true content_for(:title) do content_tag(:p, "title") end - assert content_for(:title).html_safe? + assert_predicate content_for(:title), :html_safe? end def test_provide diff --git a/actionview/test/template/date_helper_test.rb b/actionview/test/template/date_helper_test.rb index 5a5550438b..79e52ccc47 100644 --- a/actionview/test/template/date_helper_test.rb +++ b/actionview/test/template/date_helper_test.rb @@ -687,7 +687,7 @@ class DateHelperTest < ActionView::TestCase expected << %(<option value=""></option>\n<option value="00">00</option>\n<option value="15">15</option>\n<option value="30">30</option>\n<option value="45">45</option>\n) expected << "</select>\n" - assert_dom_equal expected, select_minute(Time.mktime(2003, 8, 16, 8, 4, 18), include_blank: true , minute_step: 15) + assert_dom_equal expected, select_minute(Time.mktime(2003, 8, 16, 8, 4, 18), include_blank: true, minute_step: 15) end def test_select_minute_nil_with_blank @@ -703,7 +703,7 @@ class DateHelperTest < ActionView::TestCase expected << %(<option value=""></option>\n<option value="00">00</option>\n<option value="15">15</option>\n<option value="30">30</option>\n<option value="45">45</option>\n) expected << "</select>\n" - assert_dom_equal expected, select_minute(nil, include_blank: true , minute_step: 15) + assert_dom_equal expected, select_minute(nil, include_blank: true, minute_step: 15) end def test_select_minute_with_hidden @@ -3593,25 +3593,25 @@ class DateHelperTest < ActionView::TestCase end def test_select_html_safety - assert select_day(16).html_safe? - assert select_month(8).html_safe? - assert select_year(Time.mktime(2003, 8, 16, 8, 4, 18)).html_safe? - assert select_minute(Time.mktime(2003, 8, 16, 8, 4, 18)).html_safe? - assert select_second(Time.mktime(2003, 8, 16, 8, 4, 18)).html_safe? + assert_predicate select_day(16), :html_safe? + assert_predicate select_month(8), :html_safe? + assert_predicate select_year(Time.mktime(2003, 8, 16, 8, 4, 18)), :html_safe? + assert_predicate select_minute(Time.mktime(2003, 8, 16, 8, 4, 18)), :html_safe? + assert_predicate select_second(Time.mktime(2003, 8, 16, 8, 4, 18)), :html_safe? - assert select_minute(8, use_hidden: true).html_safe? - assert select_month(8, prompt: "Choose month").html_safe? + assert_predicate select_minute(8, use_hidden: true), :html_safe? + assert_predicate select_month(8, prompt: "Choose month"), :html_safe? - assert select_time(Time.mktime(2003, 8, 16, 8, 4, 18), {}, { class: "selector" }).html_safe? - assert select_date(Time.mktime(2003, 8, 16), date_separator: " / ", start_year: 2003, end_year: 2005, prefix: "date[first]").html_safe? + assert_predicate select_time(Time.mktime(2003, 8, 16, 8, 4, 18), {}, { class: "selector" }), :html_safe? + assert_predicate select_date(Time.mktime(2003, 8, 16), date_separator: " / ", start_year: 2003, end_year: 2005, prefix: "date[first]"), :html_safe? end def test_object_select_html_safety @post = Post.new @post.written_on = Date.new(2004, 6, 15) - assert date_select("post", "written_on", default: Time.local(2006, 9, 19, 15, 16, 35), include_blank: true).html_safe? - assert time_select("post", "written_on", ignore_date: true).html_safe? + assert_predicate date_select("post", "written_on", default: Time.local(2006, 9, 19, 15, 16, 35), include_blank: true), :html_safe? + assert_predicate time_select("post", "written_on", ignore_date: true), :html_safe? end def test_time_tag_with_date diff --git a/actionview/test/template/erb_util_test.rb b/actionview/test/template/erb_util_test.rb index 8b804105f4..bd702dbe94 100644 --- a/actionview/test/template/erb_util_test.rb +++ b/actionview/test/template/erb_util_test.rb @@ -70,24 +70,24 @@ class ErbUtilTest < ActiveSupport::TestCase def test_json_escape_returns_unsafe_strings_when_passed_unsafe_strings value = json_escape("asdf") - assert !value.html_safe? + assert_not_predicate value, :html_safe? end def test_json_escape_returns_safe_strings_when_passed_safe_strings value = json_escape("asdf".html_safe) - assert value.html_safe? + assert_predicate value, :html_safe? end def test_html_escape_is_html_safe escaped = h("<p>") assert_equal "<p>", escaped - assert escaped.html_safe? + assert_predicate escaped, :html_safe? end def test_html_escape_passes_html_escape_unmodified escaped = h("<p>".html_safe) assert_equal "<p>", escaped - assert escaped.html_safe? + assert_predicate escaped, :html_safe? end def test_rest_in_ascii @@ -104,11 +104,11 @@ class ErbUtilTest < ActiveSupport::TestCase def test_html_escape_once_returns_unsafe_strings_when_passed_unsafe_strings value = html_escape_once("1 < 2 & 3") - assert !value.html_safe? + assert_not_predicate value, :html_safe? end def test_html_escape_once_returns_safe_strings_when_passed_safe_strings value = html_escape_once("1 < 2 & 3".html_safe) - assert value.html_safe? + assert_predicate value, :html_safe? end end diff --git a/actionview/test/template/form_helper/form_with_test.rb b/actionview/test/template/form_helper/form_with_test.rb index c7d49070ce..0d224d0c46 100644 --- a/actionview/test/template/form_helper/form_with_test.rb +++ b/actionview/test/template/form_helper/form_with_test.rb @@ -5,6 +5,15 @@ require "controller/fake_models" class FormWithTest < ActionView::TestCase include RenderERBUtils + + setup do + @old_value = ActionView::Helpers::FormHelper.form_with_generates_ids + ActionView::Helpers::FormHelper.form_with_generates_ids = true + end + + teardown do + ActionView::Helpers::FormHelper.form_with_generates_ids = @old_value + end end class FormWithActsLikeFormTagTest < FormWithTest @@ -99,7 +108,7 @@ class FormWithActsLikeFormTagTest < FormWithTest actual = form_with(skip_enforcing_utf8: true) expected = whole_form("http://www.example.com", skip_enforcing_utf8: true) assert_dom_equal expected, actual - assert actual.html_safe? + assert_predicate actual, :html_safe? end def test_form_with_with_block_in_erb @@ -218,7 +227,7 @@ class FormWithActsLikeFormForTest < FormWithTest @post = Post.new @comment = Comment.new - def @post.errors() + def @post.errors Class.new { def [](field); field == "author_name" ? ["can't be empty"] : [] end def empty?() false end @@ -314,17 +323,45 @@ class FormWithActsLikeFormForTest < FormWithTest expected = whole_form("/posts/123", "create-post", method: "patch") do "<label for='post_title'>The Title</label>" \ + "<input name='post[title]' type='text' value='Hello World' id='post_title' />" \ + "<textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea>" \ + "<input name='post[secret]' type='hidden' value='0' />" \ + "<input name='post[secret]' checked='checked' type='checkbox' value='1' id='post_secret' />" \ + "<select name='post[category]' id='post_category'><option value='animal'>animal</option>\n<option value='economy'>economy</option>\n<option value='sports'>sports</option></select>" \ + "<input name='commit' data-disable-with='Create post' type='submit' value='Create post' />" \ + "<button name='button' type='submit'>Create post</button>" \ + "<button name='button' type='submit'><span>Create post</span></button>" + end + + assert_dom_equal expected, output_buffer + end + + def test_form_with_not_outputting_ids + old_value = ActionView::Helpers::FormHelper.form_with_generates_ids + ActionView::Helpers::FormHelper.form_with_generates_ids = false + + form_with(model: @post, id: "create-post") do |f| + concat f.label(:title) { "The Title" } + concat f.text_field(:title) + concat f.text_area(:body) + concat f.check_box(:secret) + concat f.select(:category, %w( animal economy sports )) + concat f.submit("Create post") + end + + expected = whole_form("/posts/123", "create-post", method: "patch") do + "<label>The Title</label>" \ "<input name='post[title]' type='text' value='Hello World' />" \ "<textarea name='post[body]'>\nBack to the hill and over it again!</textarea>" \ "<input name='post[secret]' type='hidden' value='0' />" \ "<input name='post[secret]' checked='checked' type='checkbox' value='1' />" \ "<select name='post[category]'><option value='animal'>animal</option>\n<option value='economy'>economy</option>\n<option value='sports'>sports</option></select>" \ - "<input name='commit' data-disable-with='Create post' type='submit' value='Create post' />" \ - "<button name='button' type='submit'>Create post</button>" \ - "<button name='button' type='submit'><span>Create post</span></button>" + "<input name='commit' data-disable-with='Create post' type='submit' value='Create post' />" end assert_dom_equal expected, output_buffer + ensure + ActionView::Helpers::FormHelper.form_with_generates_ids = old_value end def test_form_with_only_url_on_create @@ -335,7 +372,7 @@ class FormWithActsLikeFormForTest < FormWithTest expected = whole_form("/posts") do '<label for="title">Label me</label>' \ - '<input type="text" name="title">' + '<input type="text" name="title" id="title">' end assert_dom_equal expected, output_buffer @@ -349,7 +386,7 @@ class FormWithActsLikeFormForTest < FormWithTest expected = whole_form("/posts/123") do '<label for="title">Label me</label>' \ - '<input type="text" name="title">' + '<input type="text" name="title" id="title">' end assert_dom_equal expected, output_buffer @@ -361,7 +398,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123") do - '<input type="text" name="no_model_to_back_this_badboy">' + '<input type="text" name="no_model_to_back_this_badboy" id="no_model_to_back_this_badboy" >' end assert_dom_equal expected, output_buffer @@ -373,7 +410,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: :patch) do - '<input type="text" name="post[this_dont_exist_on_post]">' + '<input type="text" name="post[this_dont_exist_on_post]" id="post_this_dont_exist_on_post" >' end assert_dom_equal expected, output_buffer @@ -391,8 +428,8 @@ class FormWithActsLikeFormForTest < FormWithTest end.new form_with(model: obj, scope: "other_name", url: "/", id: "edit-other-name") do |f| - assert_dom_equal '<input type="hidden" name="other_name[private_property]">', f.hidden_field(:private_property) - assert_dom_equal '<input type="hidden" name="other_name[protected_property]">', f.hidden_field(:protected_property) + assert_dom_equal '<input type="hidden" name="other_name[private_property]" id="other_name_private_property">', f.hidden_field(:private_property) + assert_dom_equal '<input type="hidden" name="other_name[protected_property]" id="other_name_protected_property">', f.hidden_field(:protected_property) end end @@ -459,7 +496,7 @@ class FormWithActsLikeFormForTest < FormWithTest "<label for='post_active_false'>" \ "<input checked='checked' name='post[active]' type='radio' value='false' id='post_active_false' />" \ "false</label>" \ - "<input name='post[id]' type='hidden' value='1' />" + "<input name='post[id]' type='hidden' value='1' id='post_id' />" end assert_dom_equal expected, output_buffer @@ -557,7 +594,7 @@ class FormWithActsLikeFormForTest < FormWithTest "<label for='post_tag_ids_3'>" \ "<input checked='checked' name='post[tag_ids][]' type='checkbox' value='3' id='post_tag_ids_3' />" \ "Tag 3</label>" \ - "<input name='post[id]' type='hidden' value='1' />" + "<input name='post[id]' type='hidden' value='1' id='post_id' />" end assert_dom_equal expected, output_buffer @@ -587,7 +624,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", "create-post", method: "patch", multipart: true) do - "<input name='post[file]' type='file' />" + "<input name='post[file]' type='file' id='post_file' />" end assert_dom_equal expected, output_buffer @@ -601,7 +638,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch", multipart: true) do - "<input name='post[comment][file]' type='file' />" + "<input name='post[comment][file]' type='file' id='post_comment_file'/>" end assert_dom_equal expected, output_buffer @@ -640,7 +677,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/44", method: "patch") do - "<input name='post[title]' type='text' value='And his name will be forty and four.' />" \ + "<input name='post[title]' type='text' value='And his name will be forty and four.' id='post_title' />" \ "<input name='commit' data-disable-with='Edit post' type='submit' value='Edit post' />" end @@ -658,10 +695,10 @@ class FormWithActsLikeFormForTest < FormWithTest expected = whole_form("/posts/123", "create-post", method: "patch") do "<label for='other_name_title' class='post_title'>Title</label>" \ - "<input name='other_name[title]' value='Hello World' type='text' />" \ - "<textarea name='other_name[body]'>\nBack to the hill and over it again!</textarea>" \ + "<input name='other_name[title]' value='Hello World' type='text' id='other_name_title' />" \ + "<textarea name='other_name[body]' id='other_name_body'>\nBack to the hill and over it again!</textarea>" \ "<input name='other_name[secret]' value='0' type='hidden' />" \ - "<input name='other_name[secret]' checked='checked' value='1' type='checkbox' />" \ + "<input name='other_name[secret]' checked='checked' value='1' type='checkbox' id='other_name_secret' />" \ "<input name='commit' value='Create post' data-disable-with='Create post' type='submit' />" end @@ -676,10 +713,10 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/", "create-post", method: "delete") do - "<input name='post[title]' type='text' value='Hello World' />" \ - "<textarea name='post[body]'>\nBack to the hill and over it again!</textarea>" \ + "<input name='post[title]' type='text' value='Hello World' id='post_title' />" \ + "<textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea>" \ "<input name='post[secret]' type='hidden' value='0' />" \ - "<input name='post[secret]' checked='checked' type='checkbox' value='1' />" + "<input name='post[secret]' checked='checked' type='checkbox' value='1' id='post_secret'/>" end assert_dom_equal expected, output_buffer @@ -693,10 +730,10 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/", "create-post", method: "delete") do - "<input name='post[title]' type='text' value='Hello World' />" \ - "<textarea name='post[body]'>\nBack to the hill and over it again!</textarea>" \ + "<input name='post[title]' type='text' value='Hello World' id='post_title' />" \ + "<textarea name='post[body]' id='post_body' >\nBack to the hill and over it again!</textarea>" \ "<input name='post[secret]' type='hidden' value='0' />" \ - "<input name='post[secret]' checked='checked' type='checkbox' value='1' />" + "<input name='post[secret]' checked='checked' type='checkbox' value='1' id='post_secret' />" end assert_dom_equal expected, output_buffer @@ -710,7 +747,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/search", "search-post", method: "get") do - "<input name='post[title]' type='search' />" + "<input name='post[title]' type='search' id='post_title' />" end assert_dom_equal expected, output_buffer @@ -724,10 +761,10 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/", "create-post", method: "patch") do - "<input name='post[title]' type='text' value='Hello World' />" \ - "<textarea name='post[body]'>\nBack to the hill and over it again!</textarea>" \ + "<input name='post[title]' type='text' value='Hello World' id='post_title' />" \ + "<textarea name='post[body]' id='post_body' >\nBack to the hill and over it again!</textarea>" \ "<input name='post[secret]' type='hidden' value='0' />" \ - "<input name='post[secret]' checked='checked' type='checkbox' value='1' />" + "<input name='post[secret]' checked='checked' type='checkbox' value='1' id='post_secret' />" end assert_dom_equal expected, output_buffer @@ -744,10 +781,10 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/", "create-post", method: "patch", local: true) do - "<input name='post[title]' type='text' value='Hello World' />" \ - "<textarea name='post[body]'>\nBack to the hill and over it again!</textarea>" \ + "<input name='post[title]' type='text' value='Hello World' id='post_title' />" \ + "<textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea>" \ "<input name='post[secret]' type='hidden' value='0' />" \ - "<input name='post[secret]' checked='checked' type='checkbox' value='1' />" + "<input name='post[secret]' checked='checked' type='checkbox' value='1' id='post_secret' />" end assert_dom_equal expected, output_buffer @@ -761,7 +798,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/", skip_enforcing_utf8: true) do - "<input name='post[title]' type='text' value='Hello World' />" + "<input name='post[title]' type='text' value='Hello World' id='post_title' />" end assert_dom_equal expected, output_buffer @@ -773,7 +810,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/", skip_enforcing_utf8: false) do - "<input name='post[title]' type='text' value='Hello World' />" + "<input name='post[title]' type='text' value='Hello World' id='post_title' />" end assert_dom_equal expected, output_buffer @@ -787,10 +824,10 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/", "create-post") do - "<input name='post[title]' type='text' value='Hello World' />" \ - "<textarea name='post[body]'>\nBack to the hill and over it again!</textarea>" \ + "<input name='post[title]' type='text' value='Hello World' id='post_title' />" \ + "<textarea name='post[body]' id='post_body' >\nBack to the hill and over it again!</textarea>" \ "<input name='post[secret]' type='hidden' value='0' />" \ - "<input name='post[secret]' checked='checked' type='checkbox' value='1' />" + "<input name='post[secret]' checked='checked' type='checkbox' value='1' id='post_secret' />" end assert_dom_equal expected, output_buffer @@ -806,10 +843,10 @@ class FormWithActsLikeFormForTest < FormWithTest expected = whole_form("/posts/123", method: "patch") do "<label for='post_123_title'>Title</label>" \ - "<input name='post[123][title]' type='text' value='Hello World' />" \ - "<textarea name='post[123][body]'>\nBack to the hill and over it again!</textarea>" \ + "<input name='post[123][title]' type='text' value='Hello World' id='post_123_title' />" \ + "<textarea name='post[123][body]' id='post_123_body'>\nBack to the hill and over it again!</textarea>" \ "<input name='post[123][secret]' type='hidden' value='0' />" \ - "<input name='post[123][secret]' checked='checked' type='checkbox' value='1' />" + "<input name='post[123][secret]' checked='checked' type='checkbox' value='1' id='post_123_secret' />" end assert_dom_equal expected, output_buffer @@ -823,10 +860,10 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - "<input name='post[][title]' type='text' value='Hello World' />" \ - "<textarea name='post[][body]'>\nBack to the hill and over it again!</textarea>" \ + "<input name='post[][title]' type='text' value='Hello World' id='post__title' />" \ + "<textarea name='post[][body]' id='post__body' >\nBack to the hill and over it again!</textarea>" \ "<input name='post[][secret]' type='hidden' value='0' />" \ - "<input name='post[][secret]' checked='checked' type='checkbox' value='1' />" + "<input name='post[][secret]' checked='checked' type='checkbox' value='1' id='post__secret' />" end assert_dom_equal expected, output_buffer @@ -841,7 +878,7 @@ class FormWithActsLikeFormForTest < FormWithTest expected = whole_form("/posts/123", method: "patch") do "<div class='field_with_errors'><label for='post_author_name' class='label'>Author name</label></div>" \ - "<div class='field_with_errors'><input name='post[author_name]' type='text' value='' /></div>" \ + "<div class='field_with_errors'><input name='post[author_name]' type='text' value='' id='post_author_name' /></div>" \ "<input name='commit' data-disable-with='Create post' type='submit' value='Create post' />" end @@ -859,7 +896,7 @@ class FormWithActsLikeFormForTest < FormWithTest expected = whole_form("/posts/123", method: "patch") do "<div class='field_with_errors'><label for='post_author_name' class='label'>Author name</label></div>" \ - "<div class='field_with_errors'><input name='post[author_name]' type='text' value='' /></div>" \ + "<div class='field_with_errors'><input name='post[author_name]' type='text' value='' id='post_author_name' /></div>" \ "<input name='commit' data-disable-with='Create post' type='submit' value='Create post' />" end @@ -947,7 +984,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: :patch) do - '<input type="text" name="post[comment][dont_exist_on_model]">' + '<input type="text" name="post[comment][dont_exist_on_model]" id="post_comment_dont_exist_on_model" >' end assert_dom_equal expected, output_buffer @@ -967,7 +1004,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form do - '<input name="posts[post][0][comment][1][dont_exist_on_model]" type="text">' + '<input name="posts[post][0][comment][1][dont_exist_on_model]" type="text" id="posts_post_0_comment_1_dont_exist_on_model" >' end assert_dom_equal expected, output_buffer @@ -982,7 +1019,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - "<input name='post[comment][body]' type='text' value='Hello World' />" + "<input name='post[comment][body]' type='text' value='Hello World' id='post_comment_body' />" end assert_dom_equal expected, output_buffer @@ -1002,7 +1039,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form do - "<input name='posts[post][0][comment][1][name]' type='text' value='comment #1' />" + "<input name='posts[post][0][comment][1][name]' type='text' value='comment #1' id='posts_post_0_comment_1_name' />" end assert_dom_equal expected, output_buffer @@ -1017,8 +1054,8 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - "<input name='post[123][title]' type='text' value='Hello World' />" \ - "<input name='post[123][comment][][name]' type='text' value='new comment' />" + "<input name='post[123][title]' type='text' value='Hello World' id='post_123_title' />" \ + "<input name='post[123][comment][][name]' type='text' value='new comment' id='post_123_comment__name' />" end assert_dom_equal expected, output_buffer @@ -1033,8 +1070,8 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - "<input name='post[1][title]' type='text' value='Hello World' />" \ - "<input name='post[1][comment][1][name]' type='text' value='new comment' />" + "<input name='post[1][title]' type='text' value='Hello World' id='post_1_title' />" \ + "<input name='post[1][comment][1][name]' type='text' value='new comment' id='post_1_comment_1_name' />" end assert_dom_equal expected, output_buffer @@ -1048,7 +1085,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - "<input name='post[1][comment][title]' type='text' value='Hello World' />" + "<input name='post[1][comment][title]' type='text' value='Hello World' id='post_1_comment_title' />" end assert_dom_equal expected, output_buffer @@ -1062,7 +1099,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - "<input name='post[1][comment][5][title]' type='text' value='Hello World' />" + "<input name='post[1][comment][5][title]' type='text' value='Hello World' id='post_1_comment_5_title' />" end assert_dom_equal expected, output_buffer @@ -1076,7 +1113,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - "<input name='post[123][comment][title]' type='text' value='Hello World' />" + "<input name='post[123][comment][title]' type='text' value='Hello World' id='post_123_comment_title' />" end assert_dom_equal expected, output_buffer @@ -1090,7 +1127,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - "<input name='post[comment][5][title]' type='radio' value='hello' />" + "<input name='post[comment][5][title]' type='radio' value='hello' id='post_comment_5_title_hello' />" end assert_dom_equal expected, output_buffer @@ -1104,7 +1141,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - "<input name='post[123][comment][123][title]' type='text' value='Hello World' />" + "<input name='post[123][comment][123][title]' type='text' value='Hello World' id='post_123_comment_123_title' />" end assert_dom_equal expected, output_buffer @@ -1124,9 +1161,9 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - "<input name='post[123][comment][5][title]' type='text' value='Hello World' />" + "<input name='post[123][comment][5][title]' type='text' value='Hello World' id='post_123_comment_5_title' />" end + whole_form("/posts/123", method: "patch") do - "<input name='post[1][comment][123][title]' type='text' value='Hello World' />" + "<input name='post[1][comment][123][title]' type='text' value='Hello World' id='post_1_comment_123_title' />" end assert_dom_equal expected, output_buffer @@ -1143,8 +1180,8 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[title]" type="text" value="Hello World" />' \ - '<input name="post[author_attributes][name]" type="text" value="new author" />' + '<input name="post[title]" type="text" value="Hello World" id="post_title" />' \ + '<input name="post[author_attributes][name]" type="text" value="new author" id="post_author_attributes_name" />' end assert_dom_equal expected, output_buffer @@ -1170,9 +1207,9 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[title]" type="text" value="Hello World" />' \ - '<input name="post[author_attributes][name]" type="text" value="author #321" />' \ - '<input name="post[author_attributes][id]" type="hidden" value="321" />' + '<input name="post[title]" type="text" value="Hello World" id="post_title" />' \ + '<input name="post[author_attributes][name]" type="text" value="author #321" id="post_author_attributes_name" />' \ + '<input name="post[author_attributes][id]" type="hidden" value="321" id="post_author_attributes_id" />' end assert_dom_equal expected, output_buffer @@ -1189,9 +1226,9 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[title]" type="text" value="Hello World" />' \ - '<input name="post[author_attributes][name]" type="text" value="author #321" />' \ - '<input name="post[author_attributes][id]" type="hidden" value="321" />' + '<input name="post[title]" type="text" value="Hello World" id="post_title" />' \ + '<input name="post[author_attributes][name]" type="text" value="author #321" id="post_author_attributes_name" />' \ + '<input name="post[author_attributes][id]" type="hidden" value="321" id="post_author_attributes_id" />' end assert_dom_equal expected, output_buffer @@ -1208,8 +1245,8 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[title]" type="text" value="Hello World" />' \ - '<input name="post[author_attributes][name]" type="text" value="author #321" />' + '<input name="post[title]" type="text" value="Hello World" id="post_title" />' \ + '<input name="post[author_attributes][name]" type="text" value="author #321" id="post_author_attributes_name" />' end assert_dom_equal expected, output_buffer @@ -1226,8 +1263,8 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[title]" type="text" value="Hello World" />' \ - '<input name="post[author_attributes][name]" type="text" value="author #321" />' + '<input name="post[title]" type="text" value="Hello World" id="post_title" />' \ + '<input name="post[author_attributes][name]" type="text" value="author #321" id="post_author_attributes_name" />' end assert_dom_equal expected, output_buffer @@ -1244,9 +1281,9 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[title]" type="text" value="Hello World" />' \ - '<input name="post[author_attributes][name]" type="text" value="author #321" />' \ - '<input name="post[author_attributes][id]" type="hidden" value="321" />' + '<input name="post[title]" type="text" value="Hello World" id="post_title" />' \ + '<input name="post[author_attributes][name]" type="text" value="author #321" id="post_author_attributes_name" />' \ + '<input name="post[author_attributes][id]" type="hidden" value="321" id="post_author_attributes_id" />' end assert_dom_equal expected, output_buffer @@ -1264,9 +1301,9 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[title]" type="text" value="Hello World" />' \ - '<input name="post[author_attributes][id]" type="hidden" value="321" />' \ - '<input name="post[author_attributes][name]" type="text" value="author #321" />' + '<input name="post[title]" type="text" value="Hello World" id="post_title" />' \ + '<input name="post[author_attributes][id]" type="hidden" value="321" id="post_author_attributes_id" />' \ + '<input name="post[author_attributes][name]" type="text" value="author #321" id="post_author_attributes_name" />' end assert_dom_equal expected, output_buffer @@ -1285,11 +1322,11 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[title]" type="text" value="Hello World" />' \ - '<input name="post[comments_attributes][0][name]" type="text" value="comment #1" />' \ - '<input name="post[comments_attributes][0][id]" type="hidden" value="1" />' \ - '<input name="post[comments_attributes][1][name]" type="text" value="comment #2" />' \ - '<input name="post[comments_attributes][1][id]" type="hidden" value="2" />' + '<input name="post[title]" type="text" value="Hello World" id="post_title" />' \ + '<input name="post[comments_attributes][0][name]" type="text" value="comment #1" id="post_comments_attributes_0_name" />' \ + '<input name="post[comments_attributes][0][id]" type="hidden" value="1" id="post_comments_attributes_0_id" />' \ + '<input name="post[comments_attributes][1][name]" type="text" value="comment #2" id="post_comments_attributes_1_name" />' \ + '<input name="post[comments_attributes][1][id]" type="hidden" value="2" id="post_comments_attributes_1_id" />' end assert_dom_equal expected, output_buffer @@ -1312,11 +1349,11 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[title]" type="text" value="Hello World" />' \ - '<input name="post[author_attributes][name]" type="text" value="author #321" />' \ - '<input name="post[author_attributes][id]" type="hidden" value="321" />' \ - '<input name="post[comments_attributes][0][name]" type="text" value="comment #1" />' \ - '<input name="post[comments_attributes][1][name]" type="text" value="comment #2" />' + '<input name="post[title]" type="text" value="Hello World" id="post_title" />' \ + '<input name="post[author_attributes][name]" type="text" value="author #321" id="post_author_attributes_name" />' \ + '<input name="post[author_attributes][id]" type="hidden" value="321" id="post_author_attributes_id" />' \ + '<input name="post[comments_attributes][0][name]" type="text" value="comment #1" id="post_comments_attributes_0_name" />' \ + '<input name="post[comments_attributes][1][name]" type="text" value="comment #2" id="post_comments_attributes_1_name" />' end assert_dom_equal expected, output_buffer @@ -1339,10 +1376,10 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[title]" type="text" value="Hello World" />' \ - '<input name="post[author_attributes][name]" type="text" value="author #321" />' \ - '<input name="post[comments_attributes][0][name]" type="text" value="comment #1" />' \ - '<input name="post[comments_attributes][1][name]" type="text" value="comment #2" />' + '<input name="post[title]" type="text" value="Hello World" id="post_title" />' \ + '<input name="post[author_attributes][name]" type="text" value="author #321" id="post_author_attributes_name" />' \ + '<input name="post[comments_attributes][0][name]" type="text" value="comment #1" id="post_comments_attributes_0_name" />' \ + '<input name="post[comments_attributes][1][name]" type="text" value="comment #2" id="post_comments_attributes_1_name" />' end assert_dom_equal expected, output_buffer @@ -1365,11 +1402,11 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[title]" type="text" value="Hello World" />' \ - '<input name="post[author_attributes][name]" type="text" value="author #321" />' \ - '<input name="post[author_attributes][id]" type="hidden" value="321" />' \ - '<input name="post[comments_attributes][0][name]" type="text" value="comment #1" />' \ - '<input name="post[comments_attributes][1][name]" type="text" value="comment #2" />' + '<input name="post[title]" type="text" value="Hello World" id="post_title" />' \ + '<input name="post[author_attributes][name]" type="text" value="author #321" id="post_author_attributes_name" />' \ + '<input name="post[author_attributes][id]" type="hidden" value="321" id="post_author_attributes_id" />' \ + '<input name="post[comments_attributes][0][name]" type="text" value="comment #1" id="post_comments_attributes_0_name" />' \ + '<input name="post[comments_attributes][1][name]" type="text" value="comment #2" id="post_comments_attributes_1_name" />' end assert_dom_equal expected, output_buffer @@ -1388,11 +1425,11 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[title]" type="text" value="Hello World" />' \ - '<input name="post[comments_attributes][0][name]" type="text" value="comment #1" />' \ - '<input name="post[comments_attributes][0][id]" type="hidden" value="1" />' \ - '<input name="post[comments_attributes][1][name]" type="text" value="comment #2" />' \ - '<input name="post[comments_attributes][1][id]" type="hidden" value="2" />' + '<input name="post[title]" type="text" value="Hello World" id="post_title" />' \ + '<input name="post[comments_attributes][0][name]" type="text" value="comment #1" id="post_comments_attributes_0_name" />' \ + '<input name="post[comments_attributes][0][id]" type="hidden" value="1" id="post_comments_attributes_0_id" />' \ + '<input name="post[comments_attributes][1][name]" type="text" value="comment #2" id="post_comments_attributes_1_name" />' \ + '<input name="post[comments_attributes][1][id]" type="hidden" value="2" id="post_comments_attributes_1_id" />' end assert_dom_equal expected, output_buffer @@ -1412,11 +1449,11 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[title]" type="text" value="Hello World" />' \ - '<input name="post[comments_attributes][0][id]" type="hidden" value="1" />' \ - '<input name="post[comments_attributes][0][name]" type="text" value="comment #1" />' \ - '<input name="post[comments_attributes][1][id]" type="hidden" value="2" />' \ - '<input name="post[comments_attributes][1][name]" type="text" value="comment #2" />' + '<input name="post[title]" type="text" value="Hello World" id="post_title" />' \ + '<input name="post[comments_attributes][0][id]" type="hidden" value="1" id="post_comments_attributes_0_id" />' \ + '<input name="post[comments_attributes][0][name]" type="text" value="comment #1" id="post_comments_attributes_0_name" />' \ + '<input name="post[comments_attributes][1][id]" type="hidden" value="2" id="post_comments_attributes_1_id" />' \ + '<input name="post[comments_attributes][1][name]" type="text" value="comment #2" id="post_comments_attributes_1_name" />' end assert_dom_equal expected, output_buffer @@ -1435,9 +1472,9 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[title]" type="text" value="Hello World" />' \ - '<input name="post[comments_attributes][0][name]" type="text" value="new comment" />' \ - '<input name="post[comments_attributes][1][name]" type="text" value="new comment" />' + '<input name="post[title]" type="text" value="Hello World" id="post_title" />' \ + '<input name="post[comments_attributes][0][name]" type="text" value="new comment" id="post_comments_attributes_0_name" />' \ + '<input name="post[comments_attributes][1][name]" type="text" value="new comment" id="post_comments_attributes_1_name" />' end assert_dom_equal expected, output_buffer @@ -1456,10 +1493,10 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[title]" type="text" value="Hello World" />' \ - '<input name="post[comments_attributes][0][name]" type="text" value="comment #321" />' \ - '<input name="post[comments_attributes][0][id]" type="hidden" value="321" />' \ - '<input name="post[comments_attributes][1][name]" type="text" value="new comment" />' + '<input name="post[title]" type="text" value="Hello World" id="post_title" />' \ + '<input name="post[comments_attributes][0][name]" type="text" value="comment #321" id="post_comments_attributes_0_name" />' \ + '<input name="post[comments_attributes][0][id]" type="hidden" value="321" id="post_comments_attributes_0_id"/>' \ + '<input name="post[comments_attributes][1][name]" type="text" value="new comment" id="post_comments_attributes_1_name" />' end assert_dom_equal expected, output_buffer @@ -1474,7 +1511,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[title]" type="text" value="Hello World" />' + '<input name="post[title]" type="text" value="Hello World" id="post_title" />' end assert_dom_equal expected, output_buffer @@ -1491,11 +1528,11 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[title]" type="text" value="Hello World" />' \ - '<input name="post[comments_attributes][0][name]" type="text" value="comment #1" />' \ - '<input name="post[comments_attributes][0][id]" type="hidden" value="1" />' \ - '<input name="post[comments_attributes][1][name]" type="text" value="comment #2" />' \ - '<input name="post[comments_attributes][1][id]" type="hidden" value="2" />' + '<input name="post[title]" type="text" value="Hello World" id="post_title" />' \ + '<input name="post[comments_attributes][0][name]" type="text" value="comment #1" id="post_comments_attributes_0_name" />' \ + '<input name="post[comments_attributes][0][id]" type="hidden" value="1" id="post_comments_attributes_0_id" />' \ + '<input name="post[comments_attributes][1][name]" type="text" value="comment #2" id="post_comments_attributes_1_name" />' \ + '<input name="post[comments_attributes][1][id]" type="hidden" value="2" id="post_comments_attributes_1_id" />' end assert_dom_equal expected, output_buffer @@ -1512,11 +1549,11 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[title]" type="text" value="Hello World" />' \ - '<input name="post[comments_attributes][0][name]" type="text" value="comment #1" />' \ - '<input name="post[comments_attributes][0][id]" type="hidden" value="1" />' \ - '<input name="post[comments_attributes][1][name]" type="text" value="comment #2" />' \ - '<input name="post[comments_attributes][1][id]" type="hidden" value="2" />' + '<input name="post[title]" type="text" value="Hello World" id="post_title" />' \ + '<input name="post[comments_attributes][0][name]" type="text" value="comment #1" id="post_comments_attributes_0_name" />' \ + '<input name="post[comments_attributes][0][id]" type="hidden" value="1" id="post_comments_attributes_0_id" />' \ + '<input name="post[comments_attributes][1][name]" type="text" value="comment #2" id="post_comments_attributes_1_name" />' \ + '<input name="post[comments_attributes][1][id]" type="hidden" value="2" id="post_comments_attributes_1_id" />' end assert_dom_equal expected, output_buffer @@ -1547,11 +1584,11 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[title]" type="text" value="Hello World" />' \ - '<input name="post[comments_attributes][0][name]" type="text" value="comment #1" />' \ - '<input name="post[comments_attributes][0][id]" type="hidden" value="1" />' \ - '<input name="post[comments_attributes][1][name]" type="text" value="comment #2" />' \ - '<input name="post[comments_attributes][1][id]" type="hidden" value="2" />' + '<input name="post[title]" type="text" value="Hello World" id="post_title" />' \ + '<input name="post[comments_attributes][0][name]" type="text" value="comment #1" id="post_comments_attributes_0_name" />' \ + '<input name="post[comments_attributes][0][id]" type="hidden" value="1" id="post_comments_attributes_0_id" />' \ + '<input name="post[comments_attributes][1][name]" type="text" value="comment #2" id="post_comments_attributes_1_name" />' \ + '<input name="post[comments_attributes][1][id]" type="hidden" value="2" id="post_comments_attributes_1_id" />' end assert_dom_equal expected, output_buffer @@ -1570,10 +1607,10 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[title]" type="text" value="Hello World" />' \ - '<input name="post[comments_attributes][0][name]" type="text" value="comment #321" />' \ - '<input name="post[comments_attributes][0][id]" type="hidden" value="321" />' \ - '<input name="post[comments_attributes][1][name]" type="text" value="new comment" />' + '<input name="post[title]" type="text" value="Hello World" id="post_title" />' \ + '<input name="post[comments_attributes][0][name]" type="text" value="comment #321" id="post_comments_attributes_0_name" />' \ + '<input name="post[comments_attributes][0][id]" type="hidden" value="321" id="post_comments_attributes_0_id" />' \ + '<input name="post[comments_attributes][1][name]" type="text" value="new comment" id="post_comments_attributes_1_name" />' end assert_dom_equal expected, output_buffer @@ -1590,8 +1627,8 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[comments_attributes][abc][name]" type="text" value="comment #321" />' \ - '<input name="post[comments_attributes][abc][id]" type="hidden" value="321" />' + '<input name="post[comments_attributes][abc][name]" type="text" value="comment #321" id="post_comments_attributes_abc_name" />' \ + '<input name="post[comments_attributes][abc][id]" type="hidden" value="321" id="post_comments_attributes_abc_id" />' end assert_dom_equal expected, output_buffer @@ -1607,8 +1644,8 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[comments_attributes][abc][name]" type="text" value="comment #321" />' \ - '<input name="post[comments_attributes][abc][id]" type="hidden" value="321" />' + '<input name="post[comments_attributes][abc][name]" type="text" value="comment #321" id="post_comments_attributes_abc_name" />' \ + '<input name="post[comments_attributes][abc][id]" type="hidden" value="321" id="post_comments_attributes_abc_id" />' end assert_dom_equal expected, output_buffer @@ -1630,8 +1667,8 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[comments_attributes][abc][name]" type="text" value="comment #321" />' \ - '<input name="post[comments_attributes][abc][id]" type="hidden" value="321" />' + '<input name="post[comments_attributes][abc][name]" type="text" value="comment #321" id="post_comments_attributes_abc_name" />' \ + '<input name="post[comments_attributes][abc][id]" type="hidden" value="321" id="post_comments_attributes_abc_id" />' end assert_dom_equal expected, output_buffer @@ -1716,18 +1753,18 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[comments_attributes][0][name]" type="text" value="comment #321" />' \ - '<input name="post[comments_attributes][0][relevances_attributes][0][value]" type="text" value="commentrelevance #314" />' \ - '<input name="post[comments_attributes][0][relevances_attributes][0][id]" type="hidden" value="314" />' \ - '<input name="post[comments_attributes][0][id]" type="hidden" value="321" />' \ - '<input name="post[tags_attributes][0][value]" type="text" value="tag #123" />' \ - '<input name="post[tags_attributes][0][relevances_attributes][0][value]" type="text" value="tagrelevance #3141" />' \ - '<input name="post[tags_attributes][0][relevances_attributes][0][id]" type="hidden" value="3141" />' \ - '<input name="post[tags_attributes][0][id]" type="hidden" value="123" />' \ - '<input name="post[tags_attributes][1][value]" type="text" value="tag #456" />' \ - '<input name="post[tags_attributes][1][relevances_attributes][0][value]" type="text" value="tagrelevance #31415" />' \ - '<input name="post[tags_attributes][1][relevances_attributes][0][id]" type="hidden" value="31415" />' \ - '<input name="post[tags_attributes][1][id]" type="hidden" value="456" />' + '<input name="post[comments_attributes][0][name]" type="text" value="comment #321" id="post_comments_attributes_0_name" />' \ + '<input name="post[comments_attributes][0][relevances_attributes][0][value]" type="text" value="commentrelevance #314" id="post_comments_attributes_0_relevances_attributes_0_value" />' \ + '<input name="post[comments_attributes][0][relevances_attributes][0][id]" type="hidden" value="314" id="post_comments_attributes_0_relevances_attributes_0_id"/>' \ + '<input name="post[comments_attributes][0][id]" type="hidden" value="321" id="post_comments_attributes_0_id"/>' \ + '<input name="post[tags_attributes][0][value]" type="text" value="tag #123" id="post_tags_attributes_0_value"/>' \ + '<input name="post[tags_attributes][0][relevances_attributes][0][value]" type="text" value="tagrelevance #3141" id="post_tags_attributes_0_relevances_attributes_0_value"/>' \ + '<input name="post[tags_attributes][0][relevances_attributes][0][id]" type="hidden" value="3141" id="post_tags_attributes_0_relevances_attributes_0_id"/>' \ + '<input name="post[tags_attributes][0][id]" type="hidden" value="123" id="post_tags_attributes_0_id"/>' \ + '<input name="post[tags_attributes][1][value]" type="text" value="tag #456" id="post_tags_attributes_1_value"/>' \ + '<input name="post[tags_attributes][1][relevances_attributes][0][value]" type="text" value="tagrelevance #31415" id="post_tags_attributes_1_relevances_attributes_0_value"/>' \ + '<input name="post[tags_attributes][1][relevances_attributes][0][id]" type="hidden" value="31415" id="post_tags_attributes_1_relevances_attributes_0_id"/>' \ + '<input name="post[tags_attributes][1][id]" type="hidden" value="456" id="post_tags_attributes_1_id"/>' end assert_dom_equal expected, output_buffer @@ -1743,7 +1780,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[author_attributes][name]" type="text" value="hash backed author" />' + '<input name="post[author_attributes][name]" type="text" value="hash backed author" id="post_author_attributes_name" />' end assert_dom_equal expected, output_buffer @@ -1757,10 +1794,10 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = - "<input name='post[title]' type='text' value='Hello World' />" \ - "<textarea name='post[body]'>\nBack to the hill and over it again!</textarea>" \ + "<input name='post[title]' type='text' value='Hello World' id='post_title' />" \ + "<textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea>" \ "<input name='post[secret]' type='hidden' value='0' />" \ - "<input name='post[secret]' checked='checked' type='checkbox' value='1' />" + "<input name='post[secret]' checked='checked' type='checkbox' value='1' id='post_secret' />" assert_dom_equal expected, output_buffer end @@ -1773,10 +1810,10 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = - "<input name='post[123][title]' type='text' value='Hello World' />" \ - "<textarea name='post[123][body]'>\nBack to the hill and over it again!</textarea>" \ + "<input name='post[123][title]' type='text' value='Hello World' id='post_123_title' />" \ + "<textarea name='post[123][body]' id='post_123_body'>\nBack to the hill and over it again!</textarea>" \ "<input name='post[123][secret]' type='hidden' value='0' />" \ - "<input name='post[123][secret]' checked='checked' type='checkbox' value='1' />" + "<input name='post[123][secret]' checked='checked' type='checkbox' value='1' id='post_123_secret' />" assert_dom_equal expected, output_buffer end @@ -1789,10 +1826,10 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = - "<input name='post[][title]' type='text' value='Hello World' />" \ - "<textarea name='post[][body]'>\nBack to the hill and over it again!</textarea>" \ + "<input name='post[][title]' type='text' value='Hello World' id='post__title' />" \ + "<textarea name='post[][body]' id='post__body'>\nBack to the hill and over it again!</textarea>" \ "<input name='post[][secret]' type='hidden' value='0' />" \ - "<input name='post[][secret]' checked='checked' type='checkbox' value='1' />" + "<input name='post[][secret]' checked='checked' type='checkbox' value='1' id='post__secret' />" assert_dom_equal expected, output_buffer end @@ -1805,10 +1842,10 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = - "<input name='post[abc][title]' type='text' value='Hello World' />" \ - "<textarea name='post[abc][body]'>\nBack to the hill and over it again!</textarea>" \ + "<input name='post[abc][title]' type='text' value='Hello World' id='post_abc_title' />" \ + "<textarea name='post[abc][body]' id='post_abc_body'>\nBack to the hill and over it again!</textarea>" \ "<input name='post[abc][secret]' type='hidden' value='0' />" \ - "<input name='post[abc][secret]' checked='checked' type='checkbox' value='1' />" + "<input name='post[abc][secret]' checked='checked' type='checkbox' value='1' id='post_abc_secret' />" assert_dom_equal expected, output_buffer end @@ -1821,10 +1858,10 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = - "<input name='post[title]' type='text' value='Hello World' />" \ - "<textarea name='post[body]'>\nBack to the hill and over it again!</textarea>" \ + "<input name='post[title]' type='text' value='Hello World' id='post_title' />" \ + "<textarea name='post[body]' id='post_body' >\nBack to the hill and over it again!</textarea>" \ "<input name='post[secret]' type='hidden' value='0' />" \ - "<input name='post[secret]' checked='checked' type='checkbox' value='1' />" + "<input name='post[secret]' checked='checked' type='checkbox' value='1' id='post_secret' />" assert_dom_equal expected, output_buffer end @@ -1837,10 +1874,10 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = - "<input name='post[title]' type='text' value='Hello World' />" \ - "<textarea name='post[body]'>\nBack to the hill and over it again!</textarea>" \ + "<input name='post[title]' type='text' value='Hello World' id='post_title' />" \ + "<textarea name='post[body]' id='post_body' >\nBack to the hill and over it again!</textarea>" \ "<input name='post[secret]' type='hidden' value='0' />" \ - "<input name='post[secret]' checked='checked' type='checkbox' value='1' />" + "<input name='post[secret]' checked='checked' type='checkbox' value='1' id='post_secret' />" assert_dom_equal expected, output_buffer end @@ -1852,7 +1889,7 @@ class FormWithActsLikeFormForTest < FormWithTest end assert_dom_equal "<label for=\"author_post_title\">Title</label>" \ - "<input name='author[post][title]' type='text' value='Hello World' />", + "<input name='author[post][title]' type='text' value='Hello World' id='author_post_title' id='author_post_1_title' />", output_buffer end @@ -1863,7 +1900,7 @@ class FormWithActsLikeFormForTest < FormWithTest end assert_dom_equal "<label for=\"author_post_1_title\">Title</label>" \ - "<input name='author[post][1][title]' type='text' value='Hello World' />", + "<input name='author[post][1][title]' type='text' value='Hello World' id='author_post_1_title' />", output_buffer end @@ -1882,10 +1919,10 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", "create-post", method: "patch") do - "<input name='post[title]' type='text' value='Hello World' />" \ - "<textarea name='post[body]'>\nBack to the hill and over it again!</textarea>" \ + "<input name='post[title]' type='text' value='Hello World' id='post_title' />" \ + "<textarea name='post[body]' id='post_body' >\nBack to the hill and over it again!</textarea>" \ "<input name='parent_post[secret]' type='hidden' value='0' />" \ - "<input name='parent_post[secret]' checked='checked' type='checkbox' value='1' />" + "<input name='parent_post[secret]' checked='checked' type='checkbox' value='1' id='parent_post_secret' />" end assert_dom_equal expected, output_buffer @@ -1902,9 +1939,9 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", "create-post", method: "patch") do - "<input name='post[title]' type='text' value='Hello World' />" \ - "<textarea name='post[body]'>\nBack to the hill and over it again!</textarea>" \ - "<input name='post[comment][name]' type='text' value='new comment' />" + "<input name='post[title]' type='text' value='Hello World' id='post_title' />" \ + "<textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea>" \ + "<input name='post[comment][name]' type='text' value='new comment' id='post_comment_name' />" end assert_dom_equal expected, output_buffer @@ -1918,7 +1955,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - "<input name='post[category][name]' type='text' />" + "<input name='post[category][name]' type='text' id='post_category_name' />" end assert_dom_equal expected, output_buffer @@ -1942,9 +1979,9 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - "<label for='title'>Title:</label> <input name='post[title]' type='text' value='Hello World' /><br/>" \ - "<label for='body'>Body:</label> <textarea name='post[body]'>\nBack to the hill and over it again!</textarea><br/>" \ - "<label for='secret'>Secret:</label> <input name='post[secret]' type='hidden' value='0' /><input name='post[secret]' checked='checked' type='checkbox' value='1' /><br/>" + "<label for='title'>Title:</label> <input name='post[title]' type='text' value='Hello World' id='post_title'/><br/>" \ + "<label for='body'>Body:</label> <textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea><br/>" \ + "<label for='secret'>Secret:</label> <input name='post[secret]' type='hidden' value='0' /><input name='post[secret]' checked='checked' type='checkbox' value='1' id='post_secret' /><br/>" end assert_dom_equal expected, output_buffer @@ -1961,9 +1998,9 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - "<label for='title'>Title:</label> <input name='post[title]' type='text' value='Hello World' /><br/>" \ - "<label for='body'>Body:</label> <textarea name='post[body]'>\nBack to the hill and over it again!</textarea><br/>" \ - "<label for='secret'>Secret:</label> <input name='post[secret]' type='hidden' value='0' /><input name='post[secret]' checked='checked' type='checkbox' value='1' /><br/>" + "<label for='title'>Title:</label> <input name='post[title]' type='text' value='Hello World' id='post_title' /><br/>" \ + "<label for='body'>Body:</label> <textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea><br/>" \ + "<label for='secret'>Secret:</label> <input name='post[secret]' type='hidden' value='0' /><input name='post[secret]' checked='checked' type='checkbox' value='1' id='post_secret' /><br/>" end assert_dom_equal expected, output_buffer @@ -1980,7 +2017,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - "<label for='title'>Title:</label> <input name='post[title]' type='text' value='Hello World' /><br/>" + "<label for='title'>Title:</label> <input name='post[title]' type='text' value='Hello World' id='post_title' /><br/>" end assert_dom_equal expected, output_buffer @@ -1995,7 +2032,7 @@ class FormWithActsLikeFormForTest < FormWithTest concat f.text_field(:title) end - expected = "<label for='title'>Title:</label> <input name='post[title]' type='text' value='Hello World' /><br/>" + expected = "<label for='title'>Title:</label> <input name='post[title]' type='text' value='Hello World' id='post_title' /><br/>" assert_dom_equal expected, output_buffer end @@ -2007,7 +2044,7 @@ class FormWithActsLikeFormForTest < FormWithTest concat f.text_field(:title) end - expected = "<label for='title'>Title:</label> <input name='post[title]' type='text' value='Hello World' /><br/>" + expected = "<label for='title'>Title:</label> <input name='post[title]' type='text' value='Hello World' id='post_title' /><br/>" assert_dom_equal expected, output_buffer end @@ -2020,9 +2057,9 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = - "<label for='title'>Title:</label> <input name='post[title]' type='text' value='Hello World' /><br/>" \ - "<label for='body'>Body:</label> <textarea name='post[body]'>\nBack to the hill and over it again!</textarea><br/>" \ - "<label for='secret'>Secret:</label> <input name='post[secret]' type='hidden' value='0' /><input name='post[secret]' checked='checked' type='checkbox' value='1' /><br/>" + "<label for='title'>Title:</label> <input name='post[title]' type='text' value='Hello World' id='post_title'/><br/>" \ + "<label for='body'>Body:</label> <textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea><br/>" \ + "<label for='secret'>Secret:</label> <input name='post[secret]' type='hidden' value='0' /><input name='post[secret]' checked='checked' type='checkbox' value='1' id='post_secret' /><br/>" assert_dom_equal expected, output_buffer end diff --git a/actionview/test/template/form_helper_test.rb b/actionview/test/template/form_helper_test.rb index ac64096908..b8fad090c5 100644 --- a/actionview/test/template/form_helper_test.rb +++ b/actionview/test/template/form_helper_test.rb @@ -105,7 +105,7 @@ class FormHelperTest < ActionView::TestCase @post = Post.new @comment = Comment.new - def @post.errors() + def @post.errors Class.new { def [](field); field == "author_name" ? ["can't be empty"] : [] end def empty?() false end @@ -612,7 +612,7 @@ class FormHelperTest < ActionView::TestCase end def test_check_box_is_html_safe - assert check_box("post", "secret").html_safe? + assert_predicate check_box("post", "secret"), :html_safe? end def test_check_box_checked_if_object_value_is_same_that_check_value @@ -747,19 +747,19 @@ class FormHelperTest < ActionView::TestCase end def test_check_box_with_explicit_checked_and_unchecked_values_when_object_value_is_big_decimal - @post.secret = BigDecimal.new(0) + @post.secret = BigDecimal(0) assert_dom_equal( '<input name="post[secret]" type="hidden" value="1" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="0" />', check_box("post", "secret", {}, 0, 1) ) - @post.secret = BigDecimal.new(1) + @post.secret = BigDecimal(1) assert_dom_equal( '<input name="post[secret]" type="hidden" value="1" /><input id="post_secret" name="post[secret]" type="checkbox" value="0" />', check_box("post", "secret", {}, 0, 1) ) - @post.secret = BigDecimal.new(2.2, 1) + @post.secret = BigDecimal(2.2, 1) assert_dom_equal( '<input name="post[secret]" type="hidden" value="1" /><input id="post_secret" name="post[secret]" type="checkbox" value="0" />', check_box("post", "secret", {}, 0, 1) @@ -775,7 +775,7 @@ class FormHelperTest < ActionView::TestCase end def test_check_box_with_nil_unchecked_value_is_html_safe - assert check_box("post", "secret", {}, "on", nil).html_safe? + assert_predicate check_box("post", "secret", {}, "on", nil), :html_safe? end def test_check_box_with_multiple_behavior @@ -1560,6 +1560,38 @@ class FormHelperTest < ActionView::TestCase assert_dom_equal expected, output_buffer end + def test_form_for_is_not_affected_by_form_with_generates_ids + old_value = ActionView::Helpers::FormHelper.form_with_generates_ids + ActionView::Helpers::FormHelper.form_with_generates_ids = false + + form_for(@post, html: { id: "create-post" }) do |f| + concat f.label(:title) { "The Title" } + concat f.text_field(:title) + concat f.text_area(:body) + concat f.check_box(:secret) + concat f.submit("Create post") + concat f.button("Create post") + concat f.button { + concat content_tag(:span, "Create post") + } + end + + expected = whole_form("/posts/123", "create-post", "edit_post", method: "patch") do + "<label for='post_title'>The Title</label>" \ + "<input name='post[title]' type='text' id='post_title' value='Hello World' />" \ + "<textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea>" \ + "<input name='post[secret]' type='hidden' value='0' />" \ + "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" \ + "<input name='commit' data-disable-with='Create post' type='submit' value='Create post' />" \ + "<button name='button' type='submit'>Create post</button>" \ + "<button name='button' type='submit'><span>Create post</span></button>" + end + + assert_dom_equal expected, output_buffer + ensure + ActionView::Helpers::FormHelper.form_with_generates_ids = old_value + end + def test_form_for_with_collection_radio_buttons post = Post.new def post.active; false; end diff --git a/actionview/test/template/form_options_helper_test.rb b/actionview/test/template/form_options_helper_test.rb index f0eed1e290..f82eada869 100644 --- a/actionview/test/template/form_options_helper_test.rb +++ b/actionview/test/template/form_options_helper_test.rb @@ -337,8 +337,24 @@ class FormOptionsHelperTest < ActionView::TestCase ) end + def test_option_groups_from_collection_for_select_with_callable_group_method + group_proc = Proc.new { |c| c.countries } + assert_dom_equal( + "<optgroup label=\"<Africa>\"><option value=\"<sa>\"><South Africa></option>\n<option value=\"so\">Somalia</option></optgroup><optgroup label=\"Europe\"><option value=\"dk\" selected=\"selected\">Denmark</option>\n<option value=\"ie\">Ireland</option></optgroup>", + option_groups_from_collection_for_select(dummy_continents, group_proc, "continent_name", "country_id", "country_name", "dk") + ) + end + + def test_option_groups_from_collection_for_select_with_callable_group_label_method + label_proc = Proc.new { |c| c.continent_name } + assert_dom_equal( + "<optgroup label=\"<Africa>\"><option value=\"<sa>\"><South Africa></option>\n<option value=\"so\">Somalia</option></optgroup><optgroup label=\"Europe\"><option value=\"dk\" selected=\"selected\">Denmark</option>\n<option value=\"ie\">Ireland</option></optgroup>", + option_groups_from_collection_for_select(dummy_continents, "countries", label_proc, "country_id", "country_name", "dk") + ) + end + def test_option_groups_from_collection_for_select_returns_html_safe_string - assert option_groups_from_collection_for_select(dummy_continents, "countries", "continent_name", "country_id", "country_name", "dk").html_safe? + assert_predicate option_groups_from_collection_for_select(dummy_continents, "countries", "continent_name", "country_id", "country_name", "dk"), :html_safe? end def test_grouped_options_for_select_with_array @@ -367,7 +383,7 @@ class FormOptionsHelperTest < ActionView::TestCase assert_dom_equal( "<optgroup label=\"----------\"><option value=\"US\">US</option>\n<option value=\"Canada\">Canada</option></optgroup><optgroup label=\"----------\"><option value=\"GB\">GB</option>\n<option value=\"Germany\">Germany</option></optgroup>", - grouped_options_for_select([["US", "Canada"] , ["GB", "Germany"]], nil, divider: "----------") + grouped_options_for_select([["US", "Canada"], ["GB", "Germany"]], nil, divider: "----------") ) end @@ -386,7 +402,7 @@ class FormOptionsHelperTest < ActionView::TestCase end def test_grouped_options_for_select_returns_html_safe_string - assert grouped_options_for_select([["Hats", ["Baseball Cap", "Cowboy Hat"]]]).html_safe? + assert_predicate grouped_options_for_select([["Hats", ["Baseball Cap", "Cowboy Hat"]]]), :html_safe? end def test_grouped_options_for_select_with_prompt_returns_html_escaped_string @@ -476,7 +492,7 @@ class FormOptionsHelperTest < ActionView::TestCase end def test_time_zone_options_returns_html_safe_string - assert time_zone_options_for_select.html_safe? + assert_predicate time_zone_options_for_select, :html_safe? end def test_select diff --git a/actionview/test/template/form_tag_helper_test.rb b/actionview/test/template/form_tag_helper_test.rb index 5e328ebf53..0d9bf77f98 100644 --- a/actionview/test/template/form_tag_helper_test.rb +++ b/actionview/test/template/form_tag_helper_test.rb @@ -142,14 +142,14 @@ class FormTagHelperTest < ActionView::TestCase actual = form_tag({}, { enforce_utf8: true }) expected = whole_form("http://www.example.com", enforce_utf8: true) assert_dom_equal expected, actual - assert actual.html_safe? + assert_predicate actual, :html_safe? end def test_form_tag_enforce_utf8_false actual = form_tag({}, { enforce_utf8: false }) expected = whole_form("http://www.example.com", enforce_utf8: false) assert_dom_equal expected, actual - assert actual.html_safe? + assert_predicate actual, :html_safe? end def test_form_tag_with_block_in_erb diff --git a/actionview/test/template/lookup_context_test.rb b/actionview/test/template/lookup_context_test.rb index 402ee9b6ae..beee76f711 100644 --- a/actionview/test/template/lookup_context_test.rb +++ b/actionview/test/template/lookup_context_test.rb @@ -35,7 +35,7 @@ class LookupContextTest < ActiveSupport::TestCase test "allows me to freeze and retrieve frozen formats" do @lookup_context.formats.freeze - assert @lookup_context.formats.frozen? + assert_predicate @lookup_context.formats, :frozen? end test "provides getters and setters for variants" do diff --git a/actionview/test/template/number_helper_test.rb b/actionview/test/template/number_helper_test.rb index 2b671a6685..357ae1326a 100644 --- a/actionview/test/template/number_helper_test.rb +++ b/actionview/test/template/number_helper_test.rb @@ -79,7 +79,7 @@ class NumberHelperTest < ActionView::TestCase assert_equal "1.23 <b>km3</b>", number_to_human(1_234_567_000_000, units: volume) assert_equal "1.23 <b>Pl</b>", number_to_human(1_234_567_000_000_000, units: volume) - #Including fractionals + # Including fractionals distance = { mili: "<b>mm</b>", centi: "<b>cm</b>", deci: "<b>dm</b>", unit: "<b>m</b>", ten: "<b>dam</b>", hundred: "<b>hm</b>", thousand: "<b>km</b>", micro: "<b>um</b>", nano: "<b>nm</b>", pico: "<b>pm</b>", femto: "<b>fm</b>" } @@ -126,43 +126,43 @@ class NumberHelperTest < ActionView::TestCase end def test_number_helpers_outputs_are_html_safe - assert number_to_human(1).html_safe? - assert !number_to_human("<script></script>").html_safe? - assert number_to_human("asdf".html_safe).html_safe? - assert number_to_human("1".html_safe).html_safe? - - assert number_to_human_size(1).html_safe? - assert number_to_human_size(1000000).html_safe? - assert !number_to_human_size("<script></script>").html_safe? - assert number_to_human_size("asdf".html_safe).html_safe? - assert number_to_human_size("1".html_safe).html_safe? - - assert number_with_precision(1, strip_insignificant_zeros: false).html_safe? - assert number_with_precision(1, strip_insignificant_zeros: true).html_safe? - assert !number_with_precision("<script></script>").html_safe? - assert number_with_precision("asdf".html_safe).html_safe? - assert number_with_precision("1".html_safe).html_safe? - - assert number_to_currency(1).html_safe? - assert !number_to_currency("<script></script>").html_safe? - assert number_to_currency("asdf".html_safe).html_safe? - assert number_to_currency("1".html_safe).html_safe? - - assert number_to_percentage(1).html_safe? - assert !number_to_percentage("<script></script>").html_safe? - assert number_to_percentage("asdf".html_safe).html_safe? - assert number_to_percentage("1".html_safe).html_safe? - - assert number_to_phone(1).html_safe? + assert_predicate number_to_human(1), :html_safe? + assert_not_predicate number_to_human("<script></script>"), :html_safe? + assert_predicate number_to_human("asdf".html_safe), :html_safe? + assert_predicate number_to_human("1".html_safe), :html_safe? + + assert_predicate number_to_human_size(1), :html_safe? + assert_predicate number_to_human_size(1000000), :html_safe? + assert_not_predicate number_to_human_size("<script></script>"), :html_safe? + assert_predicate number_to_human_size("asdf".html_safe), :html_safe? + assert_predicate number_to_human_size("1".html_safe), :html_safe? + + assert_predicate number_with_precision(1, strip_insignificant_zeros: false), :html_safe? + assert_predicate number_with_precision(1, strip_insignificant_zeros: true), :html_safe? + assert_not_predicate number_with_precision("<script></script>"), :html_safe? + assert_predicate number_with_precision("asdf".html_safe), :html_safe? + assert_predicate number_with_precision("1".html_safe), :html_safe? + + assert_predicate number_to_currency(1), :html_safe? + assert_not_predicate number_to_currency("<script></script>"), :html_safe? + assert_predicate number_to_currency("asdf".html_safe), :html_safe? + assert_predicate number_to_currency("1".html_safe), :html_safe? + + assert_predicate number_to_percentage(1), :html_safe? + assert_not_predicate number_to_percentage("<script></script>"), :html_safe? + assert_predicate number_to_percentage("asdf".html_safe), :html_safe? + assert_predicate number_to_percentage("1".html_safe), :html_safe? + + assert_predicate number_to_phone(1), :html_safe? assert_equal "<script></script>", number_to_phone("<script></script>") - assert number_to_phone("<script></script>").html_safe? - assert number_to_phone("asdf".html_safe).html_safe? - assert number_to_phone("1".html_safe).html_safe? - - assert number_with_delimiter(1).html_safe? - assert !number_with_delimiter("<script></script>").html_safe? - assert number_with_delimiter("asdf".html_safe).html_safe? - assert number_with_delimiter("1".html_safe).html_safe? + assert_predicate number_to_phone("<script></script>"), :html_safe? + assert_predicate number_to_phone("asdf".html_safe), :html_safe? + assert_predicate number_to_phone("1".html_safe), :html_safe? + + assert_predicate number_with_delimiter(1), :html_safe? + assert_not_predicate number_with_delimiter("<script></script>"), :html_safe? + assert_predicate number_with_delimiter("asdf".html_safe), :html_safe? + assert_predicate number_with_delimiter("1".html_safe), :html_safe? end def test_number_helpers_should_raise_error_if_invalid_when_specified diff --git a/actionview/test/template/output_safety_helper_test.rb b/actionview/test/template/output_safety_helper_test.rb index b5e9a77105..faeeded1c8 100644 --- a/actionview/test/template/output_safety_helper_test.rb +++ b/actionview/test/template/output_safety_helper_test.rb @@ -12,7 +12,7 @@ class OutputSafetyHelperTest < ActionView::TestCase test "raw returns the safe string" do result = raw(@string) assert_equal @string, result - assert result.html_safe? + assert_predicate result, :html_safe? end test "raw handles nil values correctly" do @@ -53,11 +53,11 @@ class OutputSafetyHelperTest < ActionView::TestCase test "to_sentence should escape non-html_safe values" do actual = to_sentence(%w(< > & ' ")) - assert actual.html_safe? + assert_predicate actual, :html_safe? assert_equal("<, >, &, ', and "", actual) actual = to_sentence(%w(<script>)) - assert actual.html_safe? + assert_predicate actual, :html_safe? assert_equal("<script>", actual) end @@ -80,19 +80,19 @@ class OutputSafetyHelperTest < ActionView::TestCase url = "https://example.com" expected = %(<a href="#{url}">#{url}</a> and <p><marquee>shady stuff</marquee><br /></p>) actual = to_sentence([link_to(url, url), ptag]) - assert actual.html_safe? + assert_predicate actual, :html_safe? assert_equal(expected, actual) end test "to_sentence handles blank strings" do actual = to_sentence(["", "two", "three"]) - assert actual.html_safe? + assert_predicate actual, :html_safe? assert_equal ", two, and three", actual end test "to_sentence handles nil values" do actual = to_sentence([nil, "two", "three"]) - assert actual.html_safe? + assert_predicate actual, :html_safe? assert_equal ", two, and three", actual end diff --git a/actionview/test/template/sanitize_helper_test.rb b/actionview/test/template/sanitize_helper_test.rb index 0e690c82cb..181f09ab65 100644 --- a/actionview/test/template/sanitize_helper_test.rb +++ b/actionview/test/template/sanitize_helper_test.rb @@ -38,6 +38,6 @@ class SanitizeHelperTest < ActionView::TestCase end def test_sanitize_is_marked_safe - assert sanitize("<html><script></script></html>").html_safe? + assert_predicate sanitize("<html><script></script></html>"), :html_safe? end end diff --git a/actionview/test/template/streaming_render_test.rb b/actionview/test/template/streaming_render_test.rb index 23edf7b538..ef000300cc 100644 --- a/actionview/test/template/streaming_render_test.rb +++ b/actionview/test/template/streaming_render_test.rb @@ -5,7 +5,7 @@ require "abstract_unit" class TestController < ActionController::Base end -class FiberedTest < ActiveSupport::TestCase +class SetupFiberedBase < ActiveSupport::TestCase def setup view_paths = ActionController::Base.view_paths @assigns = { secret: "in the sauce", name: nil } @@ -25,7 +25,9 @@ class FiberedTest < ActiveSupport::TestCase end string end +end +class FiberedTest < SetupFiberedBase def test_streaming_works content = [] body = render_body(template: "test/hello_world", layout: "layouts/yield") @@ -111,3 +113,20 @@ class FiberedTest < ActiveSupport::TestCase buffered_render(template: "test/streaming", layout: "layouts/streaming_with_capture") end end + +class FiberedWithLocaleTest < SetupFiberedBase + def setup + @old_locale = I18n.locale + I18n.locale = "da" + super + end + + def teardown + I18n.locale = @old_locale + end + + def test_render_with_streaming_and_locale + assert_equal "layout.locale: da\nview.locale: da\n\n", + buffered_render(template: "test/streaming_with_locale", layout: "layouts/streaming_with_locale") + end +end diff --git a/actionview/test/template/tag_helper_test.rb b/actionview/test/template/tag_helper_test.rb index 8c57803796..9a6226fd04 100644 --- a/actionview/test/template/tag_helper_test.rb +++ b/actionview/test/template/tag_helper_test.rb @@ -81,7 +81,7 @@ class TagHelperTest < ActionView::TestCase def test_content_tag assert_equal "<a href=\"create\">Create</a>", content_tag("a", "Create", "href" => "create") - assert content_tag("a", "Create", "href" => "create").html_safe? + assert_predicate content_tag("a", "Create", "href" => "create"), :html_safe? assert_equal content_tag("a", "Create", "href" => "create"), content_tag("a", "Create", href: "create") assert_equal "<p><script>evil_js</script></p>", @@ -92,7 +92,7 @@ class TagHelperTest < ActionView::TestCase def test_tag_builder_with_content assert_equal "<div id=\"post_1\">Content</div>", tag.div("Content", id: "post_1") - assert tag.div("Content", id: "post_1").html_safe? + assert_predicate tag.div("Content", id: "post_1"), :html_safe? assert_equal tag.div("Content", id: "post_1"), tag.div("Content", "id": "post_1") assert_equal "<p><script>evil_js</script></p>", @@ -307,8 +307,8 @@ class TagHelperTest < ActionView::TestCase def test_tag_builder_disable_escaping assert_equal '<a href="&"></a>', tag.a(href: "&", escape_attributes: false) - assert_equal '<a href="&">cnt</a>', tag.a(href: "&" , escape_attributes: false) { "cnt" } - assert_equal '<br data-hidden="&">', tag.br("data-hidden": "&" , escape_attributes: false) + assert_equal '<a href="&">cnt</a>', tag.a(href: "&", escape_attributes: false) { "cnt" } + assert_equal '<br data-hidden="&">', tag.br("data-hidden": "&", escape_attributes: false) assert_equal '<a href="&">content</a>', tag.a("content", href: "&", escape_attributes: false) assert_equal '<a href="&">content</a>', tag.a(href: "&", escape_attributes: false) { "content" } end @@ -316,18 +316,18 @@ class TagHelperTest < ActionView::TestCase def test_data_attributes ["data", :data].each { |data| assert_dom_equal '<a data-a-float="3.14" data-a-big-decimal="-123.456" data-a-number="1" data-array="[1,2,3]" data-hash="{"key":"value"}" data-string-with-quotes="double"quote"party"" data-string="hello" data-symbol="foo" />', - tag("a", data => { a_float: 3.14, a_big_decimal: BigDecimal.new("-123.456"), a_number: 1, string: "hello", symbol: :foo, array: [1, 2, 3], hash: { key: "value" }, string_with_quotes: 'double"quote"party"' }) + tag("a", data => { a_float: 3.14, a_big_decimal: BigDecimal("-123.456"), a_number: 1, string: "hello", symbol: :foo, array: [1, 2, 3], hash: { key: "value" }, string_with_quotes: 'double"quote"party"' }) assert_dom_equal '<a data-a-float="3.14" data-a-big-decimal="-123.456" data-a-number="1" data-array="[1,2,3]" data-hash="{"key":"value"}" data-string-with-quotes="double"quote"party"" data-string="hello" data-symbol="foo" />', - tag.a(data: { a_float: 3.14, a_big_decimal: BigDecimal.new("-123.456"), a_number: 1, string: "hello", symbol: :foo, array: [1, 2, 3], hash: { key: "value" }, string_with_quotes: 'double"quote"party"' }) + tag.a(data: { a_float: 3.14, a_big_decimal: BigDecimal("-123.456"), a_number: 1, string: "hello", symbol: :foo, array: [1, 2, 3], hash: { key: "value" }, string_with_quotes: 'double"quote"party"' }) } end def test_aria_attributes ["aria", :aria].each { |aria| assert_dom_equal '<a aria-a-float="3.14" aria-a-big-decimal="-123.456" aria-a-number="1" aria-array="[1,2,3]" aria-hash="{"key":"value"}" aria-string-with-quotes="double"quote"party"" aria-string="hello" aria-symbol="foo" />', - tag("a", aria => { a_float: 3.14, a_big_decimal: BigDecimal.new("-123.456"), a_number: 1, string: "hello", symbol: :foo, array: [1, 2, 3], hash: { key: "value" }, string_with_quotes: 'double"quote"party"' }) + tag("a", aria => { a_float: 3.14, a_big_decimal: BigDecimal("-123.456"), a_number: 1, string: "hello", symbol: :foo, array: [1, 2, 3], hash: { key: "value" }, string_with_quotes: 'double"quote"party"' }) assert_dom_equal '<a aria-a-float="3.14" aria-a-big-decimal="-123.456" aria-a-number="1" aria-array="[1,2,3]" aria-hash="{"key":"value"}" aria-string-with-quotes="double"quote"party"" aria-string="hello" aria-symbol="foo" />', - tag.a(aria: { a_float: 3.14, a_big_decimal: BigDecimal.new("-123.456"), a_number: 1, string: "hello", symbol: :foo, array: [1, 2, 3], hash: { key: "value" }, string_with_quotes: 'double"quote"party"' }) + tag.a(aria: { a_float: 3.14, a_big_decimal: BigDecimal("-123.456"), a_number: 1, string: "hello", symbol: :foo, array: [1, 2, 3], hash: { key: "value" }, string_with_quotes: 'double"quote"party"' }) } end diff --git a/actionview/test/template/text_helper_test.rb b/actionview/test/template/text_helper_test.rb index f247de066f..45edfe18be 100644 --- a/actionview/test/template/text_helper_test.rb +++ b/actionview/test/template/text_helper_test.rb @@ -19,12 +19,12 @@ class TextHelperTest < ActionView::TestCase end def test_simple_format_should_be_html_safe - assert simple_format("<b> test with html tags </b>").html_safe? + assert_predicate simple_format("<b> test with html tags </b>"), :html_safe? end def test_simple_format_included_in_isolation helper_klass = Class.new { include ActionView::Helpers::TextHelper } - assert helper_klass.new.simple_format("<b> test with html tags </b>").html_safe? + assert_predicate helper_klass.new.simple_format("<b> test with html tags </b>"), :html_safe? end def test_simple_format @@ -123,7 +123,7 @@ class TextHelperTest < ActionView::TestCase end def test_truncate_should_be_html_safe - assert truncate("Hello World!", length: 12).html_safe? + assert_predicate truncate("Hello World!", length: 12), :html_safe? end def test_truncate_should_escape_the_input @@ -136,12 +136,12 @@ class TextHelperTest < ActionView::TestCase def test_truncate_with_escape_false_should_be_html_safe truncated = truncate("Hello <script>code!</script>World!!", length: 12, escape: false) - assert truncated.html_safe? + assert_predicate truncated, :html_safe? end def test_truncate_with_block_should_be_html_safe truncated = truncate("Here's a long test and I need a continue to read link", length: 27) { link_to "Continue", "#" } - assert truncated.html_safe? + assert_predicate truncated, :html_safe? end def test_truncate_with_block_should_escape_the_input @@ -156,7 +156,7 @@ class TextHelperTest < ActionView::TestCase def test_truncate_with_block_with_escape_false_should_be_html_safe truncated = truncate("<script>code!</script>Here's a long test and I need a continue to read link", length: 27, escape: false) { link_to "Continue", "#" } - assert truncated.html_safe? + assert_predicate truncated, :html_safe? end def test_truncate_with_block_should_escape_the_block @@ -165,7 +165,7 @@ class TextHelperTest < ActionView::TestCase end def test_highlight_should_be_html_safe - assert highlight("This is a beautiful morning", "beautiful").html_safe? + assert_predicate highlight("This is a beautiful morning", "beautiful"), :html_safe? end def test_highlight @@ -297,7 +297,7 @@ class TextHelperTest < ActionView::TestCase end def test_excerpt_should_not_be_html_safe - assert !excerpt("This is a beautiful! morning", "beautiful", radius: 5).html_safe? + assert_not_predicate excerpt("This is a beautiful! morning", "beautiful", radius: 5), :html_safe? end def test_excerpt_in_borderline_cases diff --git a/actionview/test/template/translation_helper_test.rb b/actionview/test/template/translation_helper_test.rb index 8956a584ff..f40595bf4d 100644 --- a/actionview/test/template/translation_helper_test.rb +++ b/actionview/test/template/translation_helper_test.rb @@ -75,7 +75,7 @@ class TranslationHelperTest < ActiveSupport::TestCase def test_returns_missing_translation_message_with_unescaped_interpolation expected = '<span class="translation_missing" title="translation missing: en.translations.missing, name: Kir, year: 2015, vulnerable: &quot; onclick=&quot;alert()&quot;">Missing</span>' assert_equal expected, translate(:"translations.missing", name: "Kir", year: "2015", vulnerable: %{" onclick="alert()"}) - assert translate(:"translations.missing").html_safe? + assert_predicate translate(:"translations.missing"), :html_safe? end def test_returns_missing_translation_message_does_filters_out_i18n_options @@ -145,11 +145,11 @@ class TranslationHelperTest < ActiveSupport::TestCase end def test_translate_marks_translations_named_html_as_safe_html - assert translate(:'translations.html').html_safe? + assert_predicate translate(:'translations.html'), :html_safe? end def test_translate_marks_translations_with_a_html_suffix_as_safe_html - assert translate(:'translations.hello_html').html_safe? + assert_predicate translate(:'translations.hello_html'), :html_safe? end def test_translate_escapes_interpolations_in_translations_with_a_html_suffix diff --git a/actionview/test/template/url_helper_test.rb b/actionview/test/template/url_helper_test.rb index 0cd0386cac..8bccda481b 100644 --- a/actionview/test/template/url_helper_test.rb +++ b/actionview/test/template/url_helper_test.rb @@ -663,7 +663,7 @@ class UrlHelperTest < ActiveSupport::TestCase end def test_mail_to_returns_html_safe_string - assert mail_to("david@loudthinking.com").html_safe? + assert_predicate mail_to("david@loudthinking.com"), :html_safe? end def test_mail_to_with_block |