diff options
119 files changed, 1150 insertions, 824 deletions
diff --git a/.gitignore b/.gitignore index 9268977c2f..4961ad588f 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ .Gemfile .ruby-version +.byebug_history debug.log pkg /.bundle diff --git a/.travis.yml b/.travis.yml index 0c59604ff4..2758d78281 100644 --- a/.travis.yml +++ b/.travis.yml @@ -74,17 +74,17 @@ matrix: - "GEM=ar:mysql2 MYSQL=mariadb" addons: mariadb: 10.0 - - rvm: jruby-9.1.6.0 + - rvm: jruby-9.1.7.0 jdk: oraclejdk8 env: - "GEM=ap" - - rvm: jruby-9.1.6.0 + - rvm: jruby-9.1.7.0 jdk: oraclejdk8 env: - "GEM=am,aj" allow_failures: - rvm: ruby-head - - rvm: jruby-9.1.6.0 + - rvm: jruby-9.1.7.0 - env: "GEM=ac:integration" fast_finish: true diff --git a/Gemfile.lock b/Gemfile.lock index 2c48518802..94d538b84b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -147,7 +147,7 @@ GEM childprocess faraday selenium-webdriver - builder (3.2.2) + builder (3.2.3) bunny (2.6.2) amq-protocol (>= 2.0.1) byebug (9.0.6) diff --git a/actioncable/app/assets/javascripts/action_cable/connection.coffee b/actioncable/app/assets/javascripts/action_cable/connection.coffee index 29ad676290..7fd68cad2f 100644 --- a/actioncable/app/assets/javascripts/action_cable/connection.coffee +++ b/actioncable/app/assets/javascripts/action_cable/connection.coffee @@ -23,7 +23,7 @@ class ActionCable.Connection open: => if @isActive() ActionCable.log("Attempted to open WebSocket, but existing socket is #{@getState()}") - throw new Error("Existing connection must be closed before opening") + false else ActionCable.log("Opening WebSocket, current state is #{@getState()}, subprotocols: #{protocols}") @uninstallEventHandlers() if @webSocket? diff --git a/actioncable/lib/action_cable/connection/client_socket.rb b/actioncable/lib/action_cable/connection/client_socket.rb index 70a2bbecb1..c7e30e78c8 100644 --- a/actioncable/lib/action_cable/connection/client_socket.rb +++ b/actioncable/lib/action_cable/connection/client_socket.rb @@ -90,8 +90,8 @@ module ActionCable reason ||= "" unless code == 1000 || (code >= 3000 && code <= 4999) - raise ArgumentError, "Failed to execute 'close' on WebSocket: " + - "The code must be either 1000, or between 3000 and 4999. " + + raise ArgumentError, "Failed to execute 'close' on WebSocket: " \ + "The code must be either 1000, or between 3000 and 4999. " \ "#{code} is neither." end diff --git a/actioncable/lib/action_cable/connection/subscriptions.rb b/actioncable/lib/action_cable/connection/subscriptions.rb index abf42c99d5..44bce1e195 100644 --- a/actioncable/lib/action_cable/connection/subscriptions.rb +++ b/actioncable/lib/action_cable/connection/subscriptions.rb @@ -19,7 +19,7 @@ module ActionCable logger.error "Received unrecognized command in #{data.inspect}" end rescue Exception => e - logger.error "Could not execute command from #{data.inspect}) [#{e.class} - #{e.message}]: #{e.backtrace.first(5).join(" | ")}" + logger.error "Could not execute command from (#{data.inspect}) [#{e.class} - #{e.message}]: #{e.backtrace.first(5).join(" | ")}" end def add(data) diff --git a/actioncable/test/javascript/src/unit/consumer_test.coffee b/actioncable/test/javascript/src/unit/consumer_test.coffee index cf8a592255..41445274eb 100644 --- a/actioncable/test/javascript/src/unit/consumer_test.coffee +++ b/actioncable/test/javascript/src/unit/consumer_test.coffee @@ -2,8 +2,11 @@ {consumerTest} = ActionCable.TestHelpers module "ActionCable.Consumer", -> - consumerTest "#connect", connect: false, ({consumer, server, done}) -> - server.on("connection", done) + consumerTest "#connect", connect: false, ({consumer, server, assert, done}) -> + server.on "connection", -> + assert.equal consumer.connect(), false + done() + consumer.connect() consumerTest "#disconnect", ({consumer, client, done}) -> diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 8205743de3..5aa3c4fa97 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -580,7 +580,7 @@ module ActionMailer end def respond_to_missing?(method, include_all = false) - action_methods.include?(method.to_s) + action_methods.include?(method.to_s) || super end end diff --git a/actionmailer/lib/action_mailer/test_case.rb b/actionmailer/lib/action_mailer/test_case.rb index cbd841466d..9ead03a40c 100644 --- a/actionmailer/lib/action_mailer/test_case.rb +++ b/actionmailer/lib/action_mailer/test_case.rb @@ -4,8 +4,8 @@ require "rails-dom-testing" module ActionMailer class NonInferrableMailerError < ::StandardError def initialize(name) - super "Unable to determine the mailer to test from #{name}. " + - "You'll need to specify it using tests YourMailer in your " + + super "Unable to determine the mailer to test from #{name}. " \ + "You'll need to specify it using tests YourMailer in your " \ "test case definition" end end diff --git a/actionmailer/test/abstract_unit.rb b/actionmailer/test/abstract_unit.rb index 82f03f5cba..51de03c4ce 100644 --- a/actionmailer/test/abstract_unit.rb +++ b/actionmailer/test/abstract_unit.rb @@ -3,8 +3,8 @@ require "active_support/core_ext/kernel/reporting" # These are the normal settings that will be set up by Railties # TODO: Have these tests support other combinations of these values silence_warnings do - Encoding.default_internal = "UTF-8" - Encoding.default_external = "UTF-8" + Encoding.default_internal = Encoding::UTF_8 + Encoding.default_external = Encoding::UTF_8 end module Rails diff --git a/actionmailer/test/mail_helper_test.rb b/actionmailer/test/mail_helper_test.rb index a2e04b5f48..6042548aef 100644 --- a/actionmailer/test/mail_helper_test.rb +++ b/actionmailer/test/mail_helper_test.rb @@ -2,11 +2,11 @@ require "abstract_unit" class HelperMailer < ActionMailer::Base def use_mail_helper - @text = "But soft! What light through yonder window breaks? It is the east, " + - "and Juliet is the sun. Arise, fair sun, and kill the envious moon, " + - "which is sick and pale with grief that thou, her maid, art far more " + - "fair than she. Be not her maid, for she is envious! Her vestal " + - "livery is but sick and green, and none but fools do wear it. Cast " + + @text = "But soft! What light through yonder window breaks? It is the east, " \ + "and Juliet is the sun. Arise, fair sun, and kill the envious moon, " \ + "which is sick and pale with grief that thou, her maid, art far more " \ + "fair than she. Be not her maid, for she is envious! Her vestal " \ + "livery is but sick and green, and none but fools do wear it. Cast " \ "it off!" mail_with_defaults do |format| diff --git a/actionpack/lib/action_controller/renderer.rb b/actionpack/lib/action_controller/renderer.rb index 3ff80e6a39..acb400cd15 100644 --- a/actionpack/lib/action_controller/renderer.rb +++ b/actionpack/lib/action_controller/renderer.rb @@ -60,7 +60,8 @@ module ActionController end # Accepts a custom Rack environment to render templates in. - # It will be merged with ActionController::Renderer.defaults + # It will be merged with the default Rack environment defined by + # +ActionController::Renderer::DEFAULTS+. def initialize(controller, env, defaults) @controller = controller @defaults = defaults diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb index 57dd605b51..7b620ac95e 100644 --- a/actionpack/lib/action_controller/test_case.rb +++ b/actionpack/lib/action_controller/test_case.rb @@ -389,7 +389,9 @@ module ActionController # Note that the request method is not verified. The different methods are # available to make the tests more expressive. def get(action, **args) - process(action, method: "GET", **args) + res = process(action, method: "GET", **args) + cookies.update res.cookies + res end # Simulate a POST request with the given parameters and set/volley the response. @@ -517,7 +519,6 @@ module ActionController unless @request.cookie_jar.committed? @request.cookie_jar.write(@response) cookies.update(@request.cookie_jar.instance_variable_get(:@cookies)) - cookies.update(@response.cookies) end end @response.prepare! diff --git a/actionpack/lib/action_dispatch/http/mime_type.rb b/actionpack/lib/action_dispatch/http/mime_type.rb index 6b718e3682..1a65e2d1cb 100644 --- a/actionpack/lib/action_dispatch/http/mime_type.rb +++ b/actionpack/lib/action_dispatch/http/mime_type.rb @@ -298,7 +298,7 @@ module Mime end def respond_to_missing?(method, include_private = false) - method.to_s.ends_with? "?" + (method.to_s.ends_with? "?") || super end end diff --git a/actionpack/lib/action_dispatch/http/parameters.rb b/actionpack/lib/action_dispatch/http/parameters.rb index ad4aadacf5..8f21eca440 100644 --- a/actionpack/lib/action_dispatch/http/parameters.rb +++ b/actionpack/lib/action_dispatch/http/parameters.rb @@ -22,6 +22,7 @@ module ActionDispatch included do class << self + # Returns the parameter parsers. attr_reader :parameter_parsers end @@ -29,7 +30,16 @@ module ActionDispatch end module ClassMethods - def parameter_parsers=(parsers) # :nodoc: + # Configure the parameter parser for a given mime type. + # + # It accepts a hash where the key is the symbol of the mime type + # and the value is a proc. + # + # original_parsers = ActionDispatch::Request.parameter_parsers + # xml_parser = -> (raw_post) { Hash.from_xml(raw_post) || {} } + # new_parsers = original_parsers.merge(xml: xml_parser) + # ActionDispatch::Request.parameter_parsers = new_parsers + def parameter_parsers=(parsers) @parameter_parsers = parsers.transform_keys { |key| key.respond_to?(:symbol) ? key.symbol : key } end end diff --git a/actionpack/lib/action_dispatch/http/response.rb b/actionpack/lib/action_dispatch/http/response.rb index 516a2af69a..dc159596c4 100644 --- a/actionpack/lib/action_dispatch/http/response.rb +++ b/actionpack/lib/action_dispatch/http/response.rb @@ -425,7 +425,7 @@ module ActionDispatch # :nodoc: def set_content_type(content_type, charset) type = (content_type || "").dup - type << "; charset=#{charset}" if charset + type << "; charset=#{charset.to_s.downcase}" if charset set_header CONTENT_TYPE, type end diff --git a/actionpack/lib/action_dispatch/journey/visitors.rb b/actionpack/lib/action_dispatch/journey/visitors.rb index cda859cba4..1c50192867 100644 --- a/actionpack/lib/action_dispatch/journey/visitors.rb +++ b/actionpack/lib/action_dispatch/journey/visitors.rb @@ -5,7 +5,7 @@ module ActionDispatch ESCAPE_PATH = ->(value) { Router::Utils.escape_path(value) } ESCAPE_SEGMENT = ->(value) { Router::Utils.escape_segment(value) } - class Parameter < Struct.new(:name, :escaper) + Parameter = Struct.new(:name, :escaper) do def escape(value); escaper.call value; end end diff --git a/actionpack/lib/action_dispatch/middleware/cookies.rb b/actionpack/lib/action_dispatch/middleware/cookies.rb index 956c53e813..c61cb3fd68 100644 --- a/actionpack/lib/action_dispatch/middleware/cookies.rb +++ b/actionpack/lib/action_dispatch/middleware/cookies.rb @@ -572,7 +572,7 @@ module ActionDispatch super if ActiveSupport::LegacyKeyGenerator === key_generator - raise "You didn't set secrets.secret_key_base, which is required for this cookie jar. " + + raise "You didn't set secrets.secret_key_base, which is required for this cookie jar. " \ "Read the upgrade documentation to learn more about this new config option." end diff --git a/actionpack/lib/action_dispatch/middleware/remote_ip.rb b/actionpack/lib/action_dispatch/middleware/remote_ip.rb index 9f1ae80b97..8bae5bfeff 100644 --- a/actionpack/lib/action_dispatch/middleware/remote_ip.rb +++ b/actionpack/lib/action_dispatch/middleware/remote_ip.rb @@ -131,8 +131,8 @@ module ActionDispatch should_check_ip = @check_ip && client_ips.last && forwarded_ips.last if should_check_ip && !forwarded_ips.include?(client_ips.last) # We don't know which came from the proxy, and which from the user - raise IpSpoofAttackError, "IP spoofing attack?! " + - "HTTP_CLIENT_IP=#{@req.client_ip.inspect} " + + raise IpSpoofAttackError, "IP spoofing attack?! " \ + "HTTP_CLIENT_IP=#{@req.client_ip.inspect} " \ "HTTP_X_FORWARDED_FOR=#{@req.x_forwarded_for.inspect}" end diff --git a/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb b/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb index 97c937b0b1..d9f018c8ac 100644 --- a/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb +++ b/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb @@ -8,8 +8,8 @@ module ActionDispatch module Session class SessionRestoreError < StandardError #:nodoc: def initialize - super("Session contains objects whose class definition isn't available.\n" + - "Remember to require the classes for all objects kept in the session.\n" + + super("Session contains objects whose class definition isn't available.\n" \ + "Remember to require the classes for all objects kept in the session.\n" \ "(Original exception: #{$!.message} [#{$!.class}])\n") set_backtrace $!.backtrace end diff --git a/actionpack/lib/action_dispatch/middleware/static.rb b/actionpack/lib/action_dispatch/middleware/static.rb index 5c71f0fc48..5d10129d21 100644 --- a/actionpack/lib/action_dispatch/middleware/static.rb +++ b/actionpack/lib/action_dispatch/middleware/static.rb @@ -33,7 +33,7 @@ module ActionDispatch paths = [path, "#{path}#{ext}", "#{path}/#{@index}#{ext}"] if match = paths.detect { |p| - path = File.join(@root, p.force_encoding("UTF-8".freeze)) + path = File.join(@root, p.force_encoding(Encoding::UTF_8)) begin File.file?(path) && File.readable?(path) rescue SystemCallError diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb index 021ffec862..15f816a0ae 100644 --- a/actionpack/lib/action_dispatch/testing/integration.rb +++ b/actionpack/lib/action_dispatch/testing/integration.rb @@ -145,8 +145,8 @@ module ActionDispatch self.host = DEFAULT_HOST self.remote_addr = "127.0.0.1" - self.accept = "text/xml,application/xml,application/xhtml+xml," + - "text/html;q=0.9,text/plain;q=0.8,image/png," + + self.accept = "text/xml,application/xml,application/xhtml+xml," \ + "text/html;q=0.9,text/plain;q=0.8,image/png," \ "*/*;q=0.5" unless defined? @named_routes_configured diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb index bfd9068f23..7c113426a5 100644 --- a/actionpack/test/abstract_unit.rb +++ b/actionpack/test/abstract_unit.rb @@ -7,8 +7,8 @@ require "active_support/core_ext/kernel/reporting" # These are the normal settings that will be set up by Railties # TODO: Have these tests support other combinations of these values silence_warnings do - Encoding.default_internal = "UTF-8" - Encoding.default_external = "UTF-8" + Encoding.default_internal = Encoding::UTF_8 + Encoding.default_external = Encoding::UTF_8 end require "drb" diff --git a/actionpack/test/controller/filters_test.rb b/actionpack/test/controller/filters_test.rb index f9701585a9..90b3f7ea88 100644 --- a/actionpack/test/controller/filters_test.rb +++ b/actionpack/test/controller/filters_test.rb @@ -704,7 +704,7 @@ class FilterTest < ActionController::TestCase def test_prepending_and_appending_around_action test_process(MixedFilterController) - assert_equal " before aroundfilter before procfilter before appended aroundfilter " + + assert_equal " before aroundfilter before procfilter before appended aroundfilter " \ " after appended aroundfilter after procfilter after aroundfilter ", MixedFilterController.execution_log end diff --git a/actionpack/test/dispatch/cookies_test.rb b/actionpack/test/dispatch/cookies_test.rb index 73ad677419..664faa31bb 100644 --- a/actionpack/test/dispatch/cookies_test.rb +++ b/actionpack/test/dispatch/cookies_test.rb @@ -395,15 +395,6 @@ class CookiesTest < ActionController::TestCase assert_equal false, cookies.deleted?("another") end - # Ensure all HTTP methods have their cookies updated - [:get, :post, :patch, :put, :delete, :head].each do |method| - define_method("test_deleting_cookie_#{method}") do - request.cookies[:user_name] = "Joe" - public_send method, :logout - assert_nil cookies[:user_name] - end - end - def test_deleted_cookie_predicate_with_mismatching_options cookies[:user_name] = "Joe" cookies.delete("user_name", path: "/path") diff --git a/actionpack/test/dispatch/request_test.rb b/actionpack/test/dispatch/request_test.rb index e11b93b4f0..2f9228a62d 100644 --- a/actionpack/test/dispatch/request_test.rb +++ b/actionpack/test/dispatch/request_test.rb @@ -760,8 +760,8 @@ class RequestMethod < BaseRequestTest end test "post uneffected by local inflections" do - existing_acrnoyms = ActiveSupport::Inflector.inflections.acronyms.dup - existing_acrnoym_regex = ActiveSupport::Inflector.inflections.acronym_regex.dup + existing_acronyms = ActiveSupport::Inflector.inflections.acronyms.dup + existing_acronym_regex = ActiveSupport::Inflector.inflections.acronym_regex.dup begin ActiveSupport::Inflector.inflections do |inflect| inflect.acronym "POS" @@ -774,8 +774,8 @@ class RequestMethod < BaseRequestTest ensure # Reset original acronym set ActiveSupport::Inflector.inflections do |inflect| - inflect.send(:instance_variable_set, "@acronyms", existing_acrnoyms) - inflect.send(:instance_variable_set, "@acronym_regex", existing_acrnoym_regex) + inflect.send(:instance_variable_set, "@acronyms", existing_acronyms) + inflect.send(:instance_variable_set, "@acronym_regex", existing_acronym_regex) end end end diff --git a/actionpack/test/dispatch/session/cookie_store_test.rb b/actionpack/test/dispatch/session/cookie_store_test.rb index 2a1053be16..63dfc07c0d 100644 --- a/actionpack/test/dispatch/session/cookie_store_test.rb +++ b/actionpack/test/dispatch/session/cookie_store_test.rb @@ -175,7 +175,7 @@ class CookieStoreTest < ActionDispatch::IntegrationTest def test_doesnt_write_session_cookie_if_session_is_unchanged with_test_route_set do - cookies[SessionKey] = "BAh7BjoIZm9vIghiYXI%3D--" + + cookies[SessionKey] = "BAh7BjoIZm9vIghiYXI%3D--" \ "fef868465920f415f2c0652d6910d3af288a0367" get "/no_session_access" assert_response :success diff --git a/actionpack/test/dispatch/ssl_test.rb b/actionpack/test/dispatch/ssl_test.rb index e29ffa750c..53b99ebbc4 100644 --- a/actionpack/test/dispatch/ssl_test.rb +++ b/actionpack/test/dispatch/ssl_test.rb @@ -130,7 +130,7 @@ class StrictTransportSecurityTest < SSLTest end test ":expires supports AS::Duration arguments" do - assert_hsts "max-age=31557600; includeSubDomains", hsts: { expires: 1.year } + assert_hsts "max-age=31556952; includeSubDomains", hsts: { expires: 1.year } end test "include subdomains" do diff --git a/actionpack/test/lib/controller/fake_models.rb b/actionpack/test/lib/controller/fake_models.rb index 046b4167bb..b768553e7a 100644 --- a/actionpack/test/lib/controller/fake_models.rb +++ b/actionpack/test/lib/controller/fake_models.rb @@ -1,6 +1,6 @@ require "active_model" -class Customer < Struct.new(:name, :id) +Customer = Struct.new(:name, :id) do extend ActiveModel::Naming include ActiveModel::Conversion @@ -28,7 +28,7 @@ class Customer < Struct.new(:name, :id) end end -class Post < Struct.new(:title, :author_name, :body, :secret, :persisted, :written_on, :cost) +Post = Struct.new(:title, :author_name, :body, :secret, :persisted, :written_on, :cost) do extend ActiveModel::Naming include ActiveModel::Conversion extend ActiveModel::Translation diff --git a/actionview/CHANGELOG.md b/actionview/CHANGELOG.md index 59afed1f98..c12fb2e5ae 100644 --- a/actionview/CHANGELOG.md +++ b/actionview/CHANGELOG.md @@ -1,3 +1,9 @@ +* Allow render locals to be assigned to instance variables in a view. + + Fixes #27480. + + *Andrew White* + * Add `check_parameters` option to `current_page?` which makes it more strict. *Maksym Pugach* diff --git a/actionview/lib/action_view/helpers/asset_tag_helper.rb b/actionview/lib/action_view/helpers/asset_tag_helper.rb index 72a094c629..750f96f29e 100644 --- a/actionview/lib/action_view/helpers/asset_tag_helper.rb +++ b/actionview/lib/action_view/helpers/asset_tag_helper.rb @@ -40,7 +40,7 @@ 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 a extention to the generated url unless the extension + # * <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. diff --git a/actionview/lib/action_view/helpers/asset_url_helper.rb b/actionview/lib/action_view/helpers/asset_url_helper.rb index c6a5e04aba..bdabaed85c 100644 --- a/actionview/lib/action_view/helpers/asset_url_helper.rb +++ b/actionview/lib/action_view/helpers/asset_url_helper.rb @@ -406,7 +406,7 @@ module ActionView def video_url(source, options = {}) url_to_asset(source, { type: :video }.merge!(options)) end - alias_method :url_to_video, :video_url # aliased to avoid conflicts with an video_url named route + alias_method :url_to_video, :video_url # aliased to avoid conflicts with a video_url named route # Computes the path to an audio asset in the public audios directory. # Full paths from the document root will be passed through. @@ -445,7 +445,7 @@ module ActionView def font_path(source, options = {}) path_to_asset(source, { type: :font }.merge!(options)) end - alias_method :path_to_font, :font_path # aliased to avoid conflicts with an font_path named route + alias_method :path_to_font, :font_path # aliased to avoid conflicts with a font_path named route # Computes the full URL to a font asset. # This will use +font_path+ internally, so most of their behaviors will be the same. @@ -457,7 +457,7 @@ module ActionView def font_url(source, options = {}) url_to_asset(source, { type: :font }.merge!(options)) end - alias_method :url_to_font, :font_url # aliased to avoid conflicts with an font_url named route + alias_method :url_to_font, :font_url # aliased to avoid conflicts with a font_url named route end end end diff --git a/actionview/lib/action_view/helpers/output_safety_helper.rb b/actionview/lib/action_view/helpers/output_safety_helper.rb index 9f1a890f6a..e9febb8be9 100644 --- a/actionview/lib/action_view/helpers/output_safety_helper.rb +++ b/actionview/lib/action_view/helpers/output_safety_helper.rb @@ -25,7 +25,7 @@ module ActionView #:nodoc: # safe_join([raw("<p>foo</p>"), "<p>bar</p>"], "<br />") # # => "<p>foo</p><br /><p>bar</p>" # - # safe_join([raw("<p>foo</p>"), raw("<p>bar</p>")], raw("<br />") + # safe_join([raw("<p>foo</p>"), raw("<p>bar</p>")], raw("<br />")) # # => "<p>foo</p><br /><p>bar</p>" # def safe_join(array, sep = $,) diff --git a/actionview/lib/action_view/helpers/url_helper.rb b/actionview/lib/action_view/helpers/url_helper.rb index 1f753bccd6..a306903c60 100644 --- a/actionview/lib/action_view/helpers/url_helper.rb +++ b/actionview/lib/action_view/helpers/url_helper.rb @@ -35,7 +35,7 @@ module ActionView when :back _back_url else - raise ArgumentError, "arguments passed to url_for can't be handled. Please require " + + raise ArgumentError, "arguments passed to url_for can't be handled. Please require " \ "routes or provide your own implementation" end end diff --git a/actionview/lib/action_view/renderer/partial_renderer.rb b/actionview/lib/action_view/renderer/partial_renderer.rb index b8a79da97f..af3df52b28 100644 --- a/actionview/lib/action_view/renderer/partial_renderer.rb +++ b/actionview/lib/action_view/renderer/partial_renderer.rb @@ -532,11 +532,11 @@ module ActionView [variable, variable_counter, variable_iteration] end - IDENTIFIER_ERROR_MESSAGE = "The partial name (%s) is not a valid Ruby identifier; " + + IDENTIFIER_ERROR_MESSAGE = "The partial name (%s) is not a valid Ruby identifier; " \ "make sure your partial name starts with underscore." - OPTION_AS_ERROR_MESSAGE = "The value (%s) of the option `as` is not a valid Ruby identifier; " + - "make sure it starts with lowercase letter, " + + OPTION_AS_ERROR_MESSAGE = "The value (%s) of the option `as` is not a valid Ruby identifier; " \ + "make sure it starts with lowercase letter, " \ "and is followed by any combination of letters, numbers and underscores." def raise_invalid_identifier(path) diff --git a/actionview/lib/action_view/template.rb b/actionview/lib/action_view/template.rb index 4b793c3b16..c067031d2d 100644 --- a/actionview/lib/action_view/template.rb +++ b/actionview/lib/action_view/template.rb @@ -326,7 +326,7 @@ module ActionView # Only locals with valid variable names get set directly. Others will # still be available in local_assigns. locals = @locals - Module::RUBY_RESERVED_KEYWORDS - locals = locals.grep(/\A(?![A-Z0-9])(?:[[:alnum:]_]|[^\0-\177])+\z/) + locals = locals.grep(/\A@?(?![A-Z0-9])(?:[[:alnum:]_]|[^\0-\177])+\z/) # Double assign to suppress the dreaded 'assigned but unused variable' warning locals.each_with_object("") { |key, code| code << "#{key} = #{key} = local_assigns[:#{key}];" } diff --git a/actionview/lib/action_view/template/handlers/builder.rb b/actionview/lib/action_view/template/handlers/builder.rb index 494b543152..e99b921cb7 100644 --- a/actionview/lib/action_view/template/handlers/builder.rb +++ b/actionview/lib/action_view/template/handlers/builder.rb @@ -7,7 +7,7 @@ module ActionView def call(template) require_engine - "xml = ::Builder::XmlMarkup.new(:indent => 2);" + + "xml = ::Builder::XmlMarkup.new(:indent => 2);" \ "self.output_buffer = xml.target!;" + template.source + ";xml.target!;" diff --git a/actionview/test/abstract_unit.rb b/actionview/test/abstract_unit.rb index 5bc4151087..fbdaa07fb0 100644 --- a/actionview/test/abstract_unit.rb +++ b/actionview/test/abstract_unit.rb @@ -9,8 +9,8 @@ require "active_support/core_ext/kernel/reporting" # These are the normal settings that will be set up by Railties # TODO: Have these tests support other combinations of these values silence_warnings do - Encoding.default_internal = "UTF-8" - Encoding.default_external = "UTF-8" + Encoding.default_internal = Encoding::UTF_8 + Encoding.default_external = Encoding::UTF_8 end require "active_support/testing/autorun" diff --git a/actionview/test/actionpack/controller/render_test.rb b/actionview/test/actionpack/controller/render_test.rb index b4a757d6b8..890041914c 100644 --- a/actionview/test/actionpack/controller/render_test.rb +++ b/actionview/test/actionpack/controller/render_test.rb @@ -5,7 +5,7 @@ class ApplicationController < ActionController::Base self.view_paths = File.join(FIXTURE_LOAD_PATH, "actionpack") end -class Customer < Struct.new(:name, :id) +Customer = Struct.new(:name, :id) do extend ActiveModel::Naming include ActiveModel::Conversion @@ -39,7 +39,7 @@ end module Quiz #Models - class Question < Struct.new(:name, :id) + Question = Struct.new(:name, :id) do extend ActiveModel::Naming include ActiveModel::Conversion diff --git a/actionview/test/activerecord/form_helper_activerecord_test.rb b/actionview/test/activerecord/form_helper_activerecord_test.rb index 0f7960b408..3b314588c7 100644 --- a/actionview/test/activerecord/form_helper_activerecord_test.rb +++ b/actionview/test/activerecord/form_helper_activerecord_test.rb @@ -45,7 +45,7 @@ class FormHelperActiveRecordTest < ActionView::TestCase end expected = whole_form("/developers/123", "edit_developer_123", "edit_developer", method: "patch") do - '<input id="developer_projects_attributes_abc_name" name="developer[projects_attributes][abc][name]" type="text" value="project #321" />' + + '<input id="developer_projects_attributes_abc_name" name="developer[projects_attributes][abc][name]" type="text" value="project #321" />' \ '<input id="developer_projects_attributes_abc_id" name="developer[projects_attributes][abc][id]" type="hidden" value="321" />' end diff --git a/actionview/test/activerecord/render_partial_with_record_identification_test.rb b/actionview/test/activerecord/render_partial_with_record_identification_test.rb index 55886da30f..60c3ab3045 100644 --- a/actionview/test/activerecord/render_partial_with_record_identification_test.rb +++ b/actionview/test/activerecord/render_partial_with_record_identification_test.rb @@ -87,7 +87,7 @@ class RenderPartialWithRecordIdentificationTest < ActiveRecordTestCase end end -class Game < Struct.new(:name, :id) +Game = Struct.new(:name, :id) do extend ActiveModel::Naming include ActiveModel::Conversion def to_param diff --git a/actionview/test/fixtures/test/render_file_instance_variable.erb b/actionview/test/fixtures/test/render_file_instance_variable.erb new file mode 100644 index 0000000000..5344ac8a66 --- /dev/null +++ b/actionview/test/fixtures/test/render_file_instance_variable.erb @@ -0,0 +1 @@ +<%= @foo %>
\ No newline at end of file diff --git a/actionview/test/lib/controller/fake_models.rb b/actionview/test/lib/controller/fake_models.rb index ddc915895d..8db52ccbe1 100644 --- a/actionview/test/lib/controller/fake_models.rb +++ b/actionview/test/lib/controller/fake_models.rb @@ -1,6 +1,6 @@ require "active_model" -class Customer < Struct.new(:name, :id) +Customer = Struct.new(:name, :id) do extend ActiveModel::Naming include ActiveModel::Conversion @@ -31,7 +31,7 @@ end class GoodCustomer < Customer end -class Post < Struct.new(:title, :author_name, :body, :secret, :persisted, :written_on, :cost) +Post = Struct.new(:title, :author_name, :body, :secret, :persisted, :written_on, :cost) do extend ActiveModel::Naming include ActiveModel::Conversion extend ActiveModel::Translation @@ -163,7 +163,7 @@ module Blog true end - class Post < Struct.new(:title, :id) + Post = Struct.new(:title, :id) do extend ActiveModel::Naming include ActiveModel::Conversion @@ -183,8 +183,7 @@ class ArelLike end end -class Car < Struct.new(:color) -end +Car = Struct.new(:color) class Plane attr_reader :to_key diff --git a/actionview/test/template/active_model_helper_test.rb b/actionview/test/template/active_model_helper_test.rb index 8b8f686f96..6b63aa25a5 100644 --- a/actionview/test/template/active_model_helper_test.rb +++ b/actionview/test/template/active_model_helper_test.rb @@ -4,7 +4,7 @@ class ActiveModelHelperTest < ActionView::TestCase tests ActionView::Helpers::ActiveModelHelper silence_warnings do - class Post < Struct.new(:author_name, :body, :updated_at) + Post = Struct.new(:author_name, :body, :updated_at) do include ActiveModel::Conversion include ActiveModel::Validations diff --git a/actionview/test/template/atom_feed_helper_test.rb b/actionview/test/template/atom_feed_helper_test.rb index e9a923dd72..1245a1a966 100644 --- a/actionview/test/template/atom_feed_helper_test.rb +++ b/actionview/test/template/atom_feed_helper_test.rb @@ -1,6 +1,6 @@ require "abstract_unit" -class Scroll < Struct.new(:id, :to_param, :title, :body, :updated_at, :created_at) +Scroll = Struct.new(:id, :to_param, :title, :body, :updated_at, :created_at) do extend ActiveModel::Naming include ActiveModel::Conversion diff --git a/actionview/test/template/compiled_templates_test.rb b/actionview/test/template/compiled_templates_test.rb index 40ac867b38..adb2be9be4 100644 --- a/actionview/test/template/compiled_templates_test.rb +++ b/actionview/test/template/compiled_templates_test.rb @@ -38,6 +38,10 @@ class CompiledTemplatesTest < ActiveSupport::TestCase assert_equal "🎂", render(file: "test/render_file_unicode_local", locals: { 🎃: "🎂" }) end + def test_template_with_instance_variable_identifier + assert_equal "bar", render(file: "test/render_file_instance_variable", locals: { "@foo": "bar" }) + end + def test_template_gets_recompiled_when_using_different_keys_in_local_assigns assert_equal "one", render(file: "test/render_file_with_locals_and_default") assert_equal "two", render(file: "test/render_file_with_locals_and_default", locals: { secret: "two" }) diff --git a/actionview/test/template/form_collections_helper_test.rb b/actionview/test/template/form_collections_helper_test.rb index 3774dcf872..6160524eb3 100644 --- a/actionview/test/template/form_collections_helper_test.rb +++ b/actionview/test/template/form_collections_helper_test.rb @@ -1,7 +1,6 @@ require "abstract_unit" -class Category < Struct.new(:id, :name) -end +Category = Struct.new(:id, :name) class FormCollectionsHelperTest < ActionView::TestCase def assert_no_select(selector, value = nil) diff --git a/actionview/test/template/form_helper/form_with_test.rb b/actionview/test/template/form_helper/form_with_test.rb index 3a91c7dce7..a4a2966ff9 100644 --- a/actionview/test/template/form_helper/form_with_test.rb +++ b/actionview/test/template/form_helper/form_with_test.rb @@ -310,13 +310,13 @@ class FormWithActsLikeFormForTest < FormWithTest end 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' />" + - "<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' />" + - "<input name='commit' data-disable-with='Create post' type='submit' value='Create post' />" + - "<button name='button' type='submit'>Create post</button>" + + "<label for='post_title'>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' />" \ + "<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 @@ -330,7 +330,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts") do - '<label for="title">Label me</label>' + + '<label for="title">Label me</label>' \ '<input type="text" name="title">' end @@ -344,7 +344,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123") do - '<label for="title">Label me</label>' + + '<label for="title">Label me</label>' \ '<input type="text" name="title">' end @@ -400,10 +400,10 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts") do - "<input type='hidden' name='post[active]' value='' />" + - "<input name='post[active]' type='radio' value='true' />" + - "<label for='post_active_true'>true</label>" + - "<input checked='checked' name='post[active]' type='radio' value='false' />" + + "<input type='hidden' name='post[active]' value='' />" \ + "<input name='post[active]' type='radio' value='true' />" \ + "<label for='post_active_true'>true</label>" \ + "<input checked='checked' name='post[active]' type='radio' value='false' />" \ "<label for='post_active_false'>false</label>" end @@ -422,12 +422,12 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts") do - "<input type='hidden' name='post[active]' value='' />" + - "<label for='post_active_true'>" + - "<input name='post[active]' type='radio' value='true' />" + - "true</label>" + - "<label for='post_active_false'>" + - "<input checked='checked' name='post[active]' type='radio' value='false' />" + + "<input type='hidden' name='post[active]' value='' />" \ + "<label for='post_active_true'>" \ + "<input name='post[active]' type='radio' value='true' />" \ + "true</label>" \ + "<label for='post_active_false'>" \ + "<input checked='checked' name='post[active]' type='radio' value='false' />" \ "false</label>" end @@ -448,13 +448,13 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts") do - "<input type='hidden' name='post[active]' value='' />" + - "<label for='post_active_true'>" + - "<input name='post[active]' type='radio' value='true' />" + - "true</label>" + - "<label for='post_active_false'>" + - "<input checked='checked' name='post[active]' type='radio' value='false' />" + - "false</label>" + + "<input type='hidden' name='post[active]' value='' />" \ + "<label for='post_active_true'>" \ + "<input name='post[active]' type='radio' value='true' />" \ + "true</label>" \ + "<label for='post_active_false'>" \ + "<input checked='checked' name='post[active]' type='radio' value='false' />" \ + "false</label>" \ "<input name='post[id]' type='hidden' value='1' />" end @@ -470,10 +470,10 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts") do - "<input type='hidden' name='post[1][active]' value='' />" + - "<input name='post[1][active]' type='radio' value='true' />" + - "<label for='post_1_active_true'>true</label>" + - "<input checked='checked' name='post[1][active]' type='radio' value='false' />" + + "<input type='hidden' name='post[1][active]' value='' />" \ + "<input name='post[1][active]' type='radio' value='true' />" \ + "<label for='post_1_active_true'>true</label>" \ + "<input checked='checked' name='post[1][active]' type='radio' value='false' />" \ "<label for='post_1_active_false'>false</label>" end @@ -489,12 +489,12 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts") do - "<input name='post[tag_ids][]' type='hidden' value='' />" + - "<input checked='checked' name='post[tag_ids][]' type='checkbox' value='1' />" + - "<label for='post_tag_ids_1'>Tag 1</label>" + - "<input name='post[tag_ids][]' type='checkbox' value='2' />" + - "<label for='post_tag_ids_2'>Tag 2</label>" + - "<input checked='checked' name='post[tag_ids][]' type='checkbox' value='3' />" + + "<input name='post[tag_ids][]' type='hidden' value='' />" \ + "<input checked='checked' name='post[tag_ids][]' type='checkbox' value='1' />" \ + "<label for='post_tag_ids_1'>Tag 1</label>" \ + "<input name='post[tag_ids][]' type='checkbox' value='2' />" \ + "<label for='post_tag_ids_2'>Tag 2</label>" \ + "<input checked='checked' name='post[tag_ids][]' type='checkbox' value='3' />" \ "<label for='post_tag_ids_3'>Tag 3</label>" end @@ -513,15 +513,15 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts") do - "<input name='post[tag_ids][]' type='hidden' value='' />" + - "<label for='post_tag_ids_1'>" + - "<input checked='checked' name='post[tag_ids][]' type='checkbox' value='1' />" + - "Tag 1</label>" + - "<label for='post_tag_ids_2'>" + - "<input name='post[tag_ids][]' type='checkbox' value='2' />" + - "Tag 2</label>" + - "<label for='post_tag_ids_3'>" + - "<input checked='checked' name='post[tag_ids][]' type='checkbox' value='3' />" + + "<input name='post[tag_ids][]' type='hidden' value='' />" \ + "<label for='post_tag_ids_1'>" \ + "<input checked='checked' name='post[tag_ids][]' type='checkbox' value='1' />" \ + "Tag 1</label>" \ + "<label for='post_tag_ids_2'>" \ + "<input name='post[tag_ids][]' type='checkbox' value='2' />" \ + "Tag 2</label>" \ + "<label for='post_tag_ids_3'>" \ + "<input checked='checked' name='post[tag_ids][]' type='checkbox' value='3' />" \ "Tag 3</label>" end @@ -543,16 +543,16 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts") do - "<input name='post[tag_ids][]' type='hidden' value='' />" + - "<label for='post_tag_ids_1'>" + - "<input checked='checked' name='post[tag_ids][]' type='checkbox' value='1' />" + - "Tag 1</label>" + - "<label for='post_tag_ids_2'>" + - "<input name='post[tag_ids][]' type='checkbox' value='2' />" + - "Tag 2</label>" + - "<label for='post_tag_ids_3'>" + - "<input checked='checked' name='post[tag_ids][]' type='checkbox' value='3' />" + - "Tag 3</label>" + + "<input name='post[tag_ids][]' type='hidden' value='' />" \ + "<label for='post_tag_ids_1'>" \ + "<input checked='checked' name='post[tag_ids][]' type='checkbox' value='1' />" \ + "Tag 1</label>" \ + "<label for='post_tag_ids_2'>" \ + "<input name='post[tag_ids][]' type='checkbox' value='2' />" \ + "Tag 2</label>" \ + "<label for='post_tag_ids_3'>" \ + "<input checked='checked' name='post[tag_ids][]' type='checkbox' value='3' />" \ + "Tag 3</label>" \ "<input name='post[id]' type='hidden' value='1' />" end @@ -569,8 +569,8 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts") do - "<input name='post[1][tag_ids][]' type='hidden' value='' />" + - "<input checked='checked' name='post[1][tag_ids][]' type='checkbox' value='1' />" + + "<input name='post[1][tag_ids][]' type='hidden' value='' />" \ + "<input checked='checked' name='post[1][tag_ids][]' type='checkbox' value='1' />" \ "<label for='post_1_tag_ids_1'>Tag 1</label>" end @@ -636,7 +636,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.' />" \ "<input name='commit' data-disable-with='Edit post' type='submit' value='Edit post' />" end @@ -653,11 +653,11 @@ class FormWithActsLikeFormForTest < FormWithTest end 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[secret]' value='0' type='hidden' />" + - "<input name='other_name[secret]' checked='checked' value='1' type='checkbox' />" + + "<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[secret]' value='0' type='hidden' />" \ + "<input name='other_name[secret]' checked='checked' value='1' type='checkbox' />" \ "<input name='commit' value='Create post' data-disable-with='Create post' type='submit' />" end @@ -672,9 +672,9 @@ 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[secret]' type='hidden' value='0' />" + + "<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' />" end @@ -689,9 +689,9 @@ 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[secret]' type='hidden' value='0' />" + + "<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' />" end @@ -720,9 +720,9 @@ 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[secret]' type='hidden' value='0' />" + + "<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' />" end @@ -761,9 +761,9 @@ 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[secret]' type='hidden' value='0' />" + + "<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' />" end @@ -779,10 +779,10 @@ class FormWithActsLikeFormForTest < FormWithTest end 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][secret]' type='hidden' value='0' />" + + "<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][secret]' type='hidden' value='0' />" \ "<input name='post[123][secret]' checked='checked' type='checkbox' value='1' />" end @@ -797,9 +797,9 @@ 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[][secret]' type='hidden' value='0' />" + + "<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' />" end @@ -814,8 +814,8 @@ class FormWithActsLikeFormForTest < FormWithTest end 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'><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>" \ "<input name='commit' data-disable-with='Create post' type='submit' value='Create post' />" end @@ -832,8 +832,8 @@ class FormWithActsLikeFormForTest < FormWithTest end 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'><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>" \ "<input name='commit' data-disable-with='Create post' type='submit' value='Create post' />" end @@ -847,7 +847,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - "<div class='field_with_errors'><label for='post_author_name' class='label'>Name</label></div>" + + "<div class='field_with_errors'><label for='post_author_name' class='label'>Name</label></div>" \ "<div class='field_with_errors'><label for='post_author_name' class='label'>Name</label></div>" end @@ -863,9 +863,9 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", "namespace_edit_post_123", "edit_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[secret]' type='hidden' value='0' />" + + "<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' />" end @@ -1009,7 +1009,7 @@ 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][title]' type='text' value='Hello World' />" \ "<input name='post[123][comment][][name]' type='text' value='new comment' />" end @@ -1025,7 +1025,7 @@ 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][title]' type='text' value='Hello World' />" \ "<input name='post[1][comment][1][name]' type='text' value='new comment' />" end @@ -1135,7 +1135,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" />' \ '<input name="post[author_attributes][name]" type="text" value="new author" />' end @@ -1162,8 +1162,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" />' \ + '<input name="post[author_attributes][name]" type="text" value="author #321" />' \ '<input name="post[author_attributes][id]" type="hidden" value="321" />' end @@ -1181,8 +1181,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" />' \ + '<input name="post[author_attributes][name]" type="text" value="author #321" />' \ '<input name="post[author_attributes][id]" type="hidden" value="321" />' end @@ -1200,7 +1200,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" />' \ '<input name="post[author_attributes][name]" type="text" value="author #321" />' end @@ -1218,7 +1218,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" />' \ '<input name="post[author_attributes][name]" type="text" value="author #321" />' end @@ -1236,8 +1236,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" />' \ + '<input name="post[author_attributes][name]" type="text" value="author #321" />' \ '<input name="post[author_attributes][id]" type="hidden" value="321" />' end @@ -1256,8 +1256,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][id]" type="hidden" value="321" />' + + '<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" />' end @@ -1277,10 +1277,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 #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[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" />' end @@ -1304,10 +1304,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[author_attributes][id]" type="hidden" value="321" />' + - '<input name="post[comments_attributes][0][name]" type="text" value="comment #1" />' + + '<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" />' end @@ -1331,9 +1331,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[comments_attributes][0][name]" type="text" value="comment #1" />' + + '<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" />' end @@ -1357,10 +1357,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[author_attributes][id]" type="hidden" value="321" />' + - '<input name="post[comments_attributes][0][name]" type="text" value="comment #1" />' + + '<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" />' end @@ -1380,10 +1380,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 #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[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" />' end @@ -1404,10 +1404,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][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[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" />' end @@ -1427,8 +1427,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[comments_attributes][0][name]" type="text" value="new comment" />' + + '<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" />' end @@ -1448,9 +1448,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="comment #321" />' + - '<input name="post[comments_attributes][0][id]" type="hidden" value="321" />' + + '<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" />' end @@ -1483,10 +1483,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 #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[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" />' end @@ -1504,10 +1504,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 #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[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" />' end @@ -1539,10 +1539,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 #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[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" />' end @@ -1562,9 +1562,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="comment #321" />' + - '<input name="post[comments_attributes][0][id]" type="hidden" value="321" />' + + '<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" />' end @@ -1582,7 +1582,7 @@ 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][name]" type="text" value="comment #321" />' \ '<input name="post[comments_attributes][abc][id]" type="hidden" value="321" />' end @@ -1599,7 +1599,7 @@ 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][name]" type="text" value="comment #321" />' \ '<input name="post[comments_attributes][abc][id]" type="hidden" value="321" />' end @@ -1622,7 +1622,7 @@ 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][name]" type="text" value="comment #321" />' \ '<input name="post[comments_attributes][abc][id]" type="hidden" value="321" />' end @@ -1708,17 +1708,17 @@ 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[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" />' end @@ -1749,9 +1749,9 @@ 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[secret]' type='hidden' value='0' />" + + "<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' />" assert_dom_equal expected, output_buffer @@ -1765,9 +1765,9 @@ 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][secret]' type='hidden' value='0' />" + + "<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][secret]' type='hidden' value='0' />" \ "<input name='post[123][secret]' checked='checked' type='checkbox' value='1' />" assert_dom_equal expected, output_buffer @@ -1781,9 +1781,9 @@ 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[][secret]' type='hidden' value='0' />" + + "<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' />" assert_dom_equal expected, output_buffer @@ -1797,9 +1797,9 @@ 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][secret]' type='hidden' value='0' />" + + "<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][secret]' type='hidden' value='0' />" \ "<input name='post[abc][secret]' checked='checked' type='checkbox' value='1' />" assert_dom_equal expected, output_buffer @@ -1813,9 +1813,9 @@ 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[secret]' type='hidden' value='0' />" + + "<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' />" assert_dom_equal expected, output_buffer @@ -1829,9 +1829,9 @@ 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[secret]' type='hidden' value='0' />" + + "<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' />" assert_dom_equal expected, output_buffer @@ -1843,7 +1843,7 @@ class FormWithActsLikeFormForTest < FormWithTest concat f.text_field(:title) end - assert_dom_equal "<label for=\"author_post_title\">Title</label>" + + assert_dom_equal "<label for=\"author_post_title\">Title</label>" \ "<input name='author[post][title]' type='text' value='Hello World' />", output_buffer end @@ -1854,7 +1854,7 @@ class FormWithActsLikeFormForTest < FormWithTest concat f.text_field(:title) end - assert_dom_equal "<label for=\"author_post_1_title\">Title</label>" + + assert_dom_equal "<label for=\"author_post_1_title\">Title</label>" \ "<input name='author[post][1][title]' type='text' value='Hello World' />", output_buffer end @@ -1874,9 +1874,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='parent_post[secret]' type='hidden' value='0' />" + + "<input name='post[title]' type='text' value='Hello World' />" \ + "<textarea name='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' />" end @@ -1894,8 +1894,8 @@ 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' />" \ + "<textarea name='post[body]'>\nBack to the hill and over it again!</textarea>" \ "<input name='post[comment][name]' type='text' value='new comment' />" end @@ -1934,8 +1934,8 @@ 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='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/>" end @@ -1953,8 +1953,8 @@ 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='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/>" end @@ -2012,8 +2012,8 @@ 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='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/>" assert_dom_equal expected, output_buffer diff --git a/actionview/test/template/form_helper_test.rb b/actionview/test/template/form_helper_test.rb index 2bc0434771..83231d5277 100644 --- a/actionview/test/template/form_helper_test.rb +++ b/actionview/test/template/form_helper_test.rb @@ -1515,13 +1515,13 @@ class FormHelperTest < ActionView::TestCase 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>" + + "<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 @@ -1536,10 +1536,10 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts", "new_post", "new_post") do - "<input type='hidden' name='post[active]' value='' />" + - "<input id='post_active_true' name='post[active]' type='radio' value='true' />" + - "<label for='post_active_true'>true</label>" + - "<input checked='checked' id='post_active_false' name='post[active]' type='radio' value='false' />" + + "<input type='hidden' name='post[active]' value='' />" \ + "<input id='post_active_true' name='post[active]' type='radio' value='true' />" \ + "<label for='post_active_true'>true</label>" \ + "<input checked='checked' id='post_active_false' name='post[active]' type='radio' value='false' />" \ "<label for='post_active_false'>false</label>" end @@ -1558,12 +1558,12 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts", "new_post", "new_post") do - "<input type='hidden' name='post[active]' value='' />" + - "<label for='post_active_true'>" + - "<input id='post_active_true' name='post[active]' type='radio' value='true' />" + - "true</label>" + - "<label for='post_active_false'>" + - "<input checked='checked' id='post_active_false' name='post[active]' type='radio' value='false' />" + + "<input type='hidden' name='post[active]' value='' />" \ + "<label for='post_active_true'>" \ + "<input id='post_active_true' name='post[active]' type='radio' value='true' />" \ + "true</label>" \ + "<label for='post_active_false'>" \ + "<input checked='checked' id='post_active_false' name='post[active]' type='radio' value='false' />" \ "false</label>" end @@ -1584,13 +1584,13 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts", "new_post_1", "new_post") do - "<input type='hidden' name='post[active]' value='' />" + - "<label for='post_active_true'>" + - "<input id='post_active_true' name='post[active]' type='radio' value='true' />" + - "true</label>" + - "<label for='post_active_false'>" + - "<input checked='checked' id='post_active_false' name='post[active]' type='radio' value='false' />" + - "false</label>" + + "<input type='hidden' name='post[active]' value='' />" \ + "<label for='post_active_true'>" \ + "<input id='post_active_true' name='post[active]' type='radio' value='true' />" \ + "true</label>" \ + "<label for='post_active_false'>" \ + "<input checked='checked' id='post_active_false' name='post[active]' type='radio' value='false' />" \ + "false</label>" \ "<input id='post_id' name='post[id]' type='hidden' value='1' />" end @@ -1606,10 +1606,10 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts", "foo_new_post", "new_post") do - "<input type='hidden' name='post[active]' value='' />" + - "<input id='foo_post_active_true' name='post[active]' type='radio' value='true' />" + - "<label for='foo_post_active_true'>true</label>" + - "<input checked='checked' id='foo_post_active_false' name='post[active]' type='radio' value='false' />" + + "<input type='hidden' name='post[active]' value='' />" \ + "<input id='foo_post_active_true' name='post[active]' type='radio' value='true' />" \ + "<label for='foo_post_active_true'>true</label>" \ + "<input checked='checked' id='foo_post_active_false' name='post[active]' type='radio' value='false' />" \ "<label for='foo_post_active_false'>false</label>" end @@ -1625,10 +1625,10 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts", "new_post", "new_post") do - "<input type='hidden' name='post[1][active]' value='' />" + - "<input id='post_1_active_true' name='post[1][active]' type='radio' value='true' />" + - "<label for='post_1_active_true'>true</label>" + - "<input checked='checked' id='post_1_active_false' name='post[1][active]' type='radio' value='false' />" + + "<input type='hidden' name='post[1][active]' value='' />" \ + "<input id='post_1_active_true' name='post[1][active]' type='radio' value='true' />" \ + "<label for='post_1_active_true'>true</label>" \ + "<input checked='checked' id='post_1_active_false' name='post[1][active]' type='radio' value='false' />" \ "<label for='post_1_active_false'>false</label>" end @@ -1644,12 +1644,12 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts", "new_post", "new_post") do - "<input name='post[tag_ids][]' type='hidden' value='' />" + - "<input checked='checked' id='post_tag_ids_1' name='post[tag_ids][]' type='checkbox' value='1' />" + - "<label for='post_tag_ids_1'>Tag 1</label>" + - "<input id='post_tag_ids_2' name='post[tag_ids][]' type='checkbox' value='2' />" + - "<label for='post_tag_ids_2'>Tag 2</label>" + - "<input checked='checked' id='post_tag_ids_3' name='post[tag_ids][]' type='checkbox' value='3' />" + + "<input name='post[tag_ids][]' type='hidden' value='' />" \ + "<input checked='checked' id='post_tag_ids_1' name='post[tag_ids][]' type='checkbox' value='1' />" \ + "<label for='post_tag_ids_1'>Tag 1</label>" \ + "<input id='post_tag_ids_2' name='post[tag_ids][]' type='checkbox' value='2' />" \ + "<label for='post_tag_ids_2'>Tag 2</label>" \ + "<input checked='checked' id='post_tag_ids_3' name='post[tag_ids][]' type='checkbox' value='3' />" \ "<label for='post_tag_ids_3'>Tag 3</label>" end @@ -1668,15 +1668,15 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts", "new_post", "new_post") do - "<input name='post[tag_ids][]' type='hidden' value='' />" + - "<label for='post_tag_ids_1'>" + - "<input checked='checked' id='post_tag_ids_1' name='post[tag_ids][]' type='checkbox' value='1' />" + - "Tag 1</label>" + - "<label for='post_tag_ids_2'>" + - "<input id='post_tag_ids_2' name='post[tag_ids][]' type='checkbox' value='2' />" + - "Tag 2</label>" + - "<label for='post_tag_ids_3'>" + - "<input checked='checked' id='post_tag_ids_3' name='post[tag_ids][]' type='checkbox' value='3' />" + + "<input name='post[tag_ids][]' type='hidden' value='' />" \ + "<label for='post_tag_ids_1'>" \ + "<input checked='checked' id='post_tag_ids_1' name='post[tag_ids][]' type='checkbox' value='1' />" \ + "Tag 1</label>" \ + "<label for='post_tag_ids_2'>" \ + "<input id='post_tag_ids_2' name='post[tag_ids][]' type='checkbox' value='2' />" \ + "Tag 2</label>" \ + "<label for='post_tag_ids_3'>" \ + "<input checked='checked' id='post_tag_ids_3' name='post[tag_ids][]' type='checkbox' value='3' />" \ "Tag 3</label>" end @@ -1698,16 +1698,16 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts", "new_post_1", "new_post") do - "<input name='post[tag_ids][]' type='hidden' value='' />" + - "<label for='post_tag_ids_1'>" + - "<input checked='checked' id='post_tag_ids_1' name='post[tag_ids][]' type='checkbox' value='1' />" + - "Tag 1</label>" + - "<label for='post_tag_ids_2'>" + - "<input id='post_tag_ids_2' name='post[tag_ids][]' type='checkbox' value='2' />" + - "Tag 2</label>" + - "<label for='post_tag_ids_3'>" + - "<input checked='checked' id='post_tag_ids_3' name='post[tag_ids][]' type='checkbox' value='3' />" + - "Tag 3</label>" + + "<input name='post[tag_ids][]' type='hidden' value='' />" \ + "<label for='post_tag_ids_1'>" \ + "<input checked='checked' id='post_tag_ids_1' name='post[tag_ids][]' type='checkbox' value='1' />" \ + "Tag 1</label>" \ + "<label for='post_tag_ids_2'>" \ + "<input id='post_tag_ids_2' name='post[tag_ids][]' type='checkbox' value='2' />" \ + "Tag 2</label>" \ + "<label for='post_tag_ids_3'>" \ + "<input checked='checked' id='post_tag_ids_3' name='post[tag_ids][]' type='checkbox' value='3' />" \ + "Tag 3</label>" \ "<input id='post_id' name='post[id]' type='hidden' value='1' />" end @@ -1724,8 +1724,8 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts", "foo_new_post", "new_post") do - "<input name='post[tag_ids][]' type='hidden' value='' />" + - "<input checked='checked' id='foo_post_tag_ids_1' name='post[tag_ids][]' type='checkbox' value='1' />" + + "<input name='post[tag_ids][]' type='hidden' value='' />" \ + "<input checked='checked' id='foo_post_tag_ids_1' name='post[tag_ids][]' type='checkbox' value='1' />" \ "<label for='foo_post_tag_ids_1'>Tag 1</label>" end @@ -1742,8 +1742,8 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts", "new_post", "new_post") do - "<input name='post[1][tag_ids][]' type='hidden' value='' />" + - "<input checked='checked' id='post_1_tag_ids_1' name='post[1][tag_ids][]' type='checkbox' value='1' />" + + "<input name='post[1][tag_ids][]' type='hidden' value='' />" \ + "<input checked='checked' id='post_1_tag_ids_1' name='post[1][tag_ids][]' type='checkbox' value='1' />" \ "<label for='post_1_tag_ids_1'>Tag 1</label>" end @@ -1797,7 +1797,7 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts/44", "edit_post_44", "edit_post", method: "patch") do - "<input name='post[title]' type='text' id='post_title' value='And his name will be forty and four.' />" + + "<input name='post[title]' type='text' id='post_title' value='And his name will be forty and four.' />" \ "<input name='commit' data-disable-with='Edit post' type='submit' value='Edit post' />" end @@ -1814,11 +1814,11 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts/123", "create-post", "edit_other_name", method: "patch") do - "<label for='other_name_title' class='post_title'>Title</label>" + - "<input name='other_name[title]' id='other_name_title' value='Hello World' type='text' />" + - "<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' id='other_name_secret' value='1' type='checkbox' />" + + "<label for='other_name_title' class='post_title'>Title</label>" \ + "<input name='other_name[title]' id='other_name_title' value='Hello World' type='text' />" \ + "<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' id='other_name_secret' value='1' type='checkbox' />" \ "<input name='commit' value='Create post' data-disable-with='Create post' type='submit' />" end @@ -1847,9 +1847,9 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/", "create-post", "edit_post", method: "delete") do - "<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[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' />" end @@ -1864,9 +1864,9 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/", "create-post", "edit_post", method: "delete") do - "<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[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' />" end @@ -1895,9 +1895,9 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/", "create-post", "edit_post", method: "patch", remote: true) do - "<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[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' />" end @@ -1936,9 +1936,9 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/", "create-post", "edit_post", method: "patch", remote: true) do - "<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[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' />" end @@ -1955,9 +1955,9 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts", "new_post", "new_post", remote: true) do - "<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[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' />" end @@ -1973,9 +1973,9 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/", "create-post") do - "<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[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' />" end @@ -1991,10 +1991,10 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts/123", "edit_post[]", "edit_post[]", method: "patch") do - "<label for='post_123_title'>Title</label>" + - "<input name='post[123][title]' type='text' id='post_123_title' value='Hello World' />" + - "<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' />" + + "<label for='post_123_title'>Title</label>" \ + "<input name='post[123][title]' type='text' id='post_123_title' value='Hello World' />" \ + "<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' id='post_123_secret' value='1' />" end @@ -2009,9 +2009,9 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts/123", "edit_post[]", "edit_post[]", method: "patch") do - "<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[][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' />" end @@ -2026,8 +2026,8 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts/123", "edit_post_123", "edit_post", 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' id='post_author_name' value='' /></div>" + + "<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' id='post_author_name' value='' /></div>" \ "<input name='commit' data-disable-with='Create post' type='submit' value='Create post' />" end @@ -2044,8 +2044,8 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts/123", "edit_post_123", "edit_post", 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' id='post_author_name' value='' /></div>" + + "<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' id='post_author_name' value='' /></div>" \ "<input name='commit' data-disable-with='Create post' type='submit' value='Create post' />" end @@ -2059,7 +2059,7 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts/123", "edit_post_123", "edit_post", method: "patch") do - "<div class='field_with_errors'><label for='post_author_name' class='label'>Name</label></div>" + + "<div class='field_with_errors'><label for='post_author_name' class='label'>Name</label></div>" \ "<div class='field_with_errors'><label for='post_author_name' class='label'>Name</label></div>" end @@ -2074,9 +2074,9 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts/123", "namespace_edit_post_123", "edit_post", method: "patch") do - "<input name='post[title]' type='text' id='namespace_post_title' value='Hello World' />" + - "<textarea name='post[body]' id='namespace_post_body'>\nBack to the hill and over it again!</textarea>" + - "<input name='post[secret]' type='hidden' value='0' />" + + "<input name='post[title]' type='text' id='namespace_post_title' value='Hello World' />" \ + "<textarea name='post[body]' id='namespace_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='namespace_post_secret' value='1' />" end @@ -2098,7 +2098,7 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts/123", "namespace_edit_post_123", "edit_post", method: "patch") do - "<label for='namespace_post_title'>Title</label>" + + "<label for='namespace_post_title'>Title</label>" \ "<input name='post[title]' type='text' id='namespace_post_title' value='Hello World' />" end @@ -2124,7 +2124,7 @@ class FormHelperTest < ActionView::TestCase end expected_1 = whole_form("/posts/123", "namespace_1_edit_post_123", "edit_post", method: "patch") do - "<label for='namespace_1_post_title'>Title</label>" + + "<label for='namespace_1_post_title'>Title</label>" \ "<input name='post[title]' type='text' id='namespace_1_post_title' value='Hello World' />" end @@ -2136,7 +2136,7 @@ class FormHelperTest < ActionView::TestCase end expected_2 = whole_form("/posts/123", "namespace_2_edit_post_123", "edit_post", method: "patch") do - "<label for='namespace_2_post_title'>Title</label>" + + "<label for='namespace_2_post_title'>Title</label>" \ "<input name='post[title]' type='text' id='namespace_2_post_title' value='Hello World' />" end @@ -2154,8 +2154,8 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts/123", "namespace_edit_post_123", "edit_post", method: "patch") do - "<input name='post[title]' type='text' id='namespace_post_title' value='Hello World' />" + - "<textarea name='post[body]' id='namespace_post_body'>\nBack to the hill and over it again!</textarea>" + + "<input name='post[title]' type='text' id='namespace_post_title' value='Hello World' />" \ + "<textarea name='post[body]' id='namespace_post_body'>\nBack to the hill and over it again!</textarea>" \ "<input name='post[comment][body]' type='text' id='namespace_post_comment_body' value='Hello World' />" end @@ -2266,8 +2266,8 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts/123", "edit_post[]", "edit_post[]", method: "patch") do - "<input name='post[123][title]' type='text' id='post_123_title' value='Hello World' />" + - "<input name='post[123][comment][][name]' type='text' id='post_123_comment__name' value='new comment' />" + + "<input name='post[123][title]' type='text' id='post_123_title' value='Hello World' />" \ + "<input name='post[123][comment][][name]' type='text' id='post_123_comment__name' value='new comment' />" \ "<input name='post[123][body]' type='text' id='post_123_body' value='Back to the hill and over it again!' />" end @@ -2283,7 +2283,7 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts/123", "edit_post_123", "edit_post", method: "patch") do - "<input name='post[1][title]' type='text' id='post_1_title' value='Hello World' />" + + "<input name='post[1][title]' type='text' id='post_1_title' value='Hello World' />" \ "<input name='post[1][comment][1][name]' type='text' id='post_1_comment_1_name' value='new comment' />" end @@ -2393,7 +2393,7 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts/123", "edit_post_123", "edit_post", method: "patch") do - '<input name="post[title]" type="text" id="post_title" value="Hello World" />' + + '<input name="post[title]" type="text" id="post_title" value="Hello World" />' \ '<input id="post_author_attributes_name" name="post[author_attributes][name]" type="text" value="new author" />' end @@ -2420,8 +2420,8 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts/123", "edit_post_123", "edit_post", method: "patch") do - '<input name="post[title]" type="text" id="post_title" value="Hello World" />' + - '<input id="post_author_attributes_name" name="post[author_attributes][name]" type="text" value="author #321" />' + + '<input name="post[title]" type="text" id="post_title" value="Hello World" />' \ + '<input id="post_author_attributes_name" name="post[author_attributes][name]" type="text" value="author #321" />' \ '<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />' end @@ -2439,8 +2439,8 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts/123", "edit_post_123", "edit_post", method: "patch") do - '<input name="post[title]" type="text" id="post_title" value="Hello World" />' + - '<input id="post_author_attributes_name" name="post[author_attributes][name]" type="text" value="author #321" />' + + '<input name="post[title]" type="text" id="post_title" value="Hello World" />' \ + '<input id="post_author_attributes_name" name="post[author_attributes][name]" type="text" value="author #321" />' \ '<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />' end @@ -2458,7 +2458,7 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts/123", "edit_post_123", "edit_post", method: "patch") do - '<input name="post[title]" type="text" id="post_title" value="Hello World" />' + + '<input name="post[title]" type="text" id="post_title" value="Hello World" />' \ '<input id="post_author_attributes_name" name="post[author_attributes][name]" type="text" value="author #321" />' end @@ -2476,7 +2476,7 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts/123", "edit_post_123", "edit_post", method: "patch") do - '<input name="post[title]" type="text" id="post_title" value="Hello World" />' + + '<input name="post[title]" type="text" id="post_title" value="Hello World" />' \ '<input id="post_author_attributes_name" name="post[author_attributes][name]" type="text" value="author #321" />' end @@ -2494,8 +2494,8 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts/123", "edit_post_123", "edit_post", method: "patch") do - '<input name="post[title]" type="text" id="post_title" value="Hello World" />' + - '<input id="post_author_attributes_name" name="post[author_attributes][name]" type="text" value="author #321" />' + + '<input name="post[title]" type="text" id="post_title" value="Hello World" />' \ + '<input id="post_author_attributes_name" name="post[author_attributes][name]" type="text" value="author #321" />' \ '<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />' end @@ -2514,8 +2514,8 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts/123", "edit_post_123", "edit_post", method: "patch") do - '<input name="post[title]" type="text" id="post_title" value="Hello World" />' + - '<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />' + + '<input name="post[title]" type="text" id="post_title" value="Hello World" />' \ + '<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />' \ '<input id="post_author_attributes_name" name="post[author_attributes][name]" type="text" value="author #321" />' end @@ -2535,10 +2535,10 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts/123", "edit_post_123", "edit_post", method: "patch") do - '<input name="post[title]" type="text" id="post_title" value="Hello World" />' + - '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #1" />' + - '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' + - '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" type="text" value="comment #2" />' + + '<input name="post[title]" type="text" id="post_title" value="Hello World" />' \ + '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #1" />' \ + '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' \ + '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" type="text" value="comment #2" />' \ '<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />' end @@ -2562,10 +2562,10 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts/123", "edit_post_123", "edit_post", method: "patch") do - '<input name="post[title]" type="text" id="post_title" value="Hello World" />' + - '<input id="post_author_attributes_name" name="post[author_attributes][name]" type="text" value="author #321" />' + - '<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />' + - '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #1" />' + + '<input name="post[title]" type="text" id="post_title" value="Hello World" />' \ + '<input id="post_author_attributes_name" name="post[author_attributes][name]" type="text" value="author #321" />' \ + '<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />' \ + '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #1" />' \ '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" type="text" value="comment #2" />' end @@ -2589,9 +2589,9 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts/123", "edit_post_123", "edit_post", method: "patch") do - '<input name="post[title]" type="text" id="post_title" value="Hello World" />' + - '<input id="post_author_attributes_name" name="post[author_attributes][name]" type="text" value="author #321" />' + - '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #1" />' + + '<input name="post[title]" type="text" id="post_title" value="Hello World" />' \ + '<input id="post_author_attributes_name" name="post[author_attributes][name]" type="text" value="author #321" />' \ + '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #1" />' \ '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" type="text" value="comment #2" />' end @@ -2615,10 +2615,10 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts/123", "edit_post_123", "edit_post", method: "patch") do - '<input name="post[title]" type="text" id="post_title" value="Hello World" />' + - '<input id="post_author_attributes_name" name="post[author_attributes][name]" type="text" value="author #321" />' + - '<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />' + - '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #1" />' + + '<input name="post[title]" type="text" id="post_title" value="Hello World" />' \ + '<input id="post_author_attributes_name" name="post[author_attributes][name]" type="text" value="author #321" />' \ + '<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />' \ + '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #1" />' \ '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" type="text" value="comment #2" />' end @@ -2638,10 +2638,10 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts/123", "edit_post_123", "edit_post", method: "patch") do - '<input name="post[title]" type="text" id="post_title" value="Hello World" />' + - '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #1" />' + - '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' + - '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" type="text" value="comment #2" />' + + '<input name="post[title]" type="text" id="post_title" value="Hello World" />' \ + '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #1" />' \ + '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' \ + '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" type="text" value="comment #2" />' \ '<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />' end @@ -2662,10 +2662,10 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts/123", "edit_post_123", "edit_post", method: "patch") do - '<input name="post[title]" type="text" id="post_title" value="Hello World" />' + - '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' + - '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #1" />' + - '<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />' + + '<input name="post[title]" type="text" id="post_title" value="Hello World" />' \ + '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' \ + '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #1" />' \ + '<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />' \ '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" type="text" value="comment #2" />' end @@ -2685,8 +2685,8 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts/123", "edit_post_123", "edit_post", method: "patch") do - '<input name="post[title]" type="text" id="post_title" value="Hello World" />' + - '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="new comment" />' + + '<input name="post[title]" type="text" id="post_title" value="Hello World" />' \ + '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="new comment" />' \ '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" type="text" value="new comment" />' end @@ -2706,9 +2706,9 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts/123", "edit_post_123", "edit_post", method: "patch") do - '<input name="post[title]" type="text" id="post_title" value="Hello World" />' + - '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #321" />' + - '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' + + '<input name="post[title]" type="text" id="post_title" value="Hello World" />' \ + '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #321" />' \ + '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' \ '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" type="text" value="new comment" />' end @@ -2741,10 +2741,10 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts/123", "edit_post_123", "edit_post", method: "patch") do - '<input name="post[title]" type="text" id="post_title" value="Hello World" />' + - '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #1" />' + - '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' + - '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" type="text" value="comment #2" />' + + '<input name="post[title]" type="text" id="post_title" value="Hello World" />' \ + '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #1" />' \ + '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' \ + '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" type="text" value="comment #2" />' \ '<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />' end @@ -2762,10 +2762,10 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts/123", "edit_post_123", "edit_post", method: "patch") do - '<input name="post[title]" type="text" id="post_title" value="Hello World" />' + - '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #1" />' + - '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' + - '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" type="text" value="comment #2" />' + + '<input name="post[title]" type="text" id="post_title" value="Hello World" />' \ + '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #1" />' \ + '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' \ + '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" type="text" value="comment #2" />' \ '<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />' end @@ -2797,10 +2797,10 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts/123", "edit_post_123", "edit_post", method: "patch") do - '<input name="post[title]" type="text" id="post_title" value="Hello World" />' + - '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #1" />' + - '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' + - '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" type="text" value="comment #2" />' + + '<input name="post[title]" type="text" id="post_title" value="Hello World" />' \ + '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #1" />' \ + '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' \ + '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" type="text" value="comment #2" />' \ '<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />' end @@ -2820,9 +2820,9 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts/123", "edit_post_123", "edit_post", method: "patch") do - '<input name="post[title]" type="text" id="post_title" value="Hello World" />' + - '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #321" />' + - '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' + + '<input name="post[title]" type="text" id="post_title" value="Hello World" />' \ + '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #321" />' \ + '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' \ '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" type="text" value="new comment" />' end @@ -2840,7 +2840,7 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts/123", "edit_post_123", "edit_post", method: "patch") do - '<input id="post_comments_attributes_abc_name" name="post[comments_attributes][abc][name]" type="text" value="comment #321" />' + + '<input id="post_comments_attributes_abc_name" name="post[comments_attributes][abc][name]" type="text" value="comment #321" />' \ '<input id="post_comments_attributes_abc_id" name="post[comments_attributes][abc][id]" type="hidden" value="321" />' end @@ -2857,7 +2857,7 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts/123", "edit_post_123", "edit_post", method: "patch") do - '<input id="post_comments_attributes_abc_name" name="post[comments_attributes][abc][name]" type="text" value="comment #321" />' + + '<input id="post_comments_attributes_abc_name" name="post[comments_attributes][abc][name]" type="text" value="comment #321" />' \ '<input id="post_comments_attributes_abc_id" name="post[comments_attributes][abc][id]" type="hidden" value="321" />' end @@ -2880,7 +2880,7 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts/123", "edit_post_123", "edit_post", method: "patch") do - '<input id="post_comments_attributes_abc_name" name="post[comments_attributes][abc][name]" type="text" value="comment #321" />' + + '<input id="post_comments_attributes_abc_name" name="post[comments_attributes][abc][name]" type="text" value="comment #321" />' \ '<input id="post_comments_attributes_abc_id" name="post[comments_attributes][abc][id]" type="hidden" value="321" />' end @@ -2966,17 +2966,17 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts/123", "edit_post_123", "edit_post", method: "patch") do - '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #321" />' + - '<input id="post_comments_attributes_0_relevances_attributes_0_value" name="post[comments_attributes][0][relevances_attributes][0][value]" type="text" value="commentrelevance #314" />' + - '<input id="post_comments_attributes_0_relevances_attributes_0_id" name="post[comments_attributes][0][relevances_attributes][0][id]" type="hidden" value="314" />' + - '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' + - '<input id="post_tags_attributes_0_value" name="post[tags_attributes][0][value]" type="text" value="tag #123" />' + - '<input id="post_tags_attributes_0_relevances_attributes_0_value" name="post[tags_attributes][0][relevances_attributes][0][value]" type="text" value="tagrelevance #3141" />' + - '<input id="post_tags_attributes_0_relevances_attributes_0_id" name="post[tags_attributes][0][relevances_attributes][0][id]" type="hidden" value="3141" />' + - '<input id="post_tags_attributes_0_id" name="post[tags_attributes][0][id]" type="hidden" value="123" />' + - '<input id="post_tags_attributes_1_value" name="post[tags_attributes][1][value]" type="text" value="tag #456" />' + - '<input id="post_tags_attributes_1_relevances_attributes_0_value" name="post[tags_attributes][1][relevances_attributes][0][value]" type="text" value="tagrelevance #31415" />' + - '<input id="post_tags_attributes_1_relevances_attributes_0_id" name="post[tags_attributes][1][relevances_attributes][0][id]" type="hidden" value="31415" />' + + '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #321" />' \ + '<input id="post_comments_attributes_0_relevances_attributes_0_value" name="post[comments_attributes][0][relevances_attributes][0][value]" type="text" value="commentrelevance #314" />' \ + '<input id="post_comments_attributes_0_relevances_attributes_0_id" name="post[comments_attributes][0][relevances_attributes][0][id]" type="hidden" value="314" />' \ + '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' \ + '<input id="post_tags_attributes_0_value" name="post[tags_attributes][0][value]" type="text" value="tag #123" />' \ + '<input id="post_tags_attributes_0_relevances_attributes_0_value" name="post[tags_attributes][0][relevances_attributes][0][value]" type="text" value="tagrelevance #3141" />' \ + '<input id="post_tags_attributes_0_relevances_attributes_0_id" name="post[tags_attributes][0][relevances_attributes][0][id]" type="hidden" value="3141" />' \ + '<input id="post_tags_attributes_0_id" name="post[tags_attributes][0][id]" type="hidden" value="123" />' \ + '<input id="post_tags_attributes_1_value" name="post[tags_attributes][1][value]" type="text" value="tag #456" />' \ + '<input id="post_tags_attributes_1_relevances_attributes_0_value" name="post[tags_attributes][1][relevances_attributes][0][value]" type="text" value="tagrelevance #31415" />' \ + '<input id="post_tags_attributes_1_relevances_attributes_0_id" name="post[tags_attributes][1][relevances_attributes][0][id]" type="hidden" value="31415" />' \ '<input id="post_tags_attributes_1_id" name="post[tags_attributes][1][id]" type="hidden" value="456" />' end @@ -3007,9 +3007,9 @@ class FormHelperTest < ActionView::TestCase end expected = - "<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[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' />" assert_dom_equal expected, output_buffer @@ -3023,9 +3023,9 @@ class FormHelperTest < ActionView::TestCase end expected = - "<input name='post[123][title]' type='text' id='post_123_title' value='Hello World' />" + - "<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][title]' type='text' id='post_123_title' value='Hello World' />" \ + "<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' id='post_123_secret' value='1' />" assert_dom_equal expected, output_buffer @@ -3039,9 +3039,9 @@ class FormHelperTest < ActionView::TestCase end expected = - "<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[][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' />" assert_dom_equal expected, output_buffer @@ -3055,9 +3055,9 @@ class FormHelperTest < ActionView::TestCase end expected = - "<input name='post[abc][title]' type='text' id='post_abc_title' value='Hello World' />" + - "<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][title]' type='text' id='post_abc_title' value='Hello World' />" \ + "<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' id='post_abc_secret' value='1' />" assert_dom_equal expected, output_buffer @@ -3071,9 +3071,9 @@ class FormHelperTest < ActionView::TestCase end expected = - "<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[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' />" assert_dom_equal expected, output_buffer @@ -3087,9 +3087,9 @@ class FormHelperTest < ActionView::TestCase end expected = - "<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[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' />" assert_dom_equal expected, output_buffer @@ -3101,7 +3101,7 @@ class FormHelperTest < ActionView::TestCase concat f.text_field(:title) end - assert_dom_equal "<label for=\"author_post_title\">Title</label>" + + assert_dom_equal "<label for=\"author_post_title\">Title</label>" \ "<input name='author[post][title]' type='text' id='author_post_title' value='Hello World' />", output_buffer end @@ -3112,7 +3112,7 @@ class FormHelperTest < ActionView::TestCase concat f.text_field(:title) end - assert_dom_equal "<label for=\"author_post_1_title\">Title</label>" + + assert_dom_equal "<label for=\"author_post_1_title\">Title</label>" \ "<input name='author[post][1][title]' type='text' id='author_post_1_title' value='Hello World' />", output_buffer end @@ -3132,9 +3132,9 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts/123", "create-post", "edit_post", method: "patch") do - "<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='parent_post[secret]' type='hidden' value='0' />" + + "<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='parent_post[secret]' type='hidden' value='0' />" \ "<input name='parent_post[secret]' checked='checked' type='checkbox' id='parent_post_secret' value='1' />" end @@ -3152,8 +3152,8 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts/123", "create-post", "edit_post", method: "patch") do - "<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[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[comment][name]' type='text' id='post_comment_name' value='new comment' />" end @@ -3192,8 +3192,8 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts/123", "edit_post_123", "edit_post", method: "patch") do - "<label for='title'>Title:</label> <input name='post[title]' type='text' id='post_title' value='Hello World' /><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='title'>Title:</label> <input name='post[title]' type='text' id='post_title' value='Hello World' /><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' id='post_secret' value='1' /><br/>" end @@ -3211,8 +3211,8 @@ class FormHelperTest < ActionView::TestCase end expected = whole_form("/posts/123", "edit_post_123", "edit_post", method: "patch") do - "<label for='title'>Title:</label> <input name='post[title]' type='text' id='post_title' value='Hello World' /><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='title'>Title:</label> <input name='post[title]' type='text' id='post_title' value='Hello World' /><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' id='post_secret' value='1' /><br/>" end @@ -3270,8 +3270,8 @@ class FormHelperTest < ActionView::TestCase end expected = - "<label for='title'>Title:</label> <input name='post[title]' type='text' id='post_title' value='Hello World' /><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='title'>Title:</label> <input name='post[title]' type='text' id='post_title' value='Hello World' /><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' id='post_secret' value='1' /><br/>" assert_dom_equal expected, output_buffer diff --git a/actionview/test/template/form_options_helper_test.rb b/actionview/test/template/form_options_helper_test.rb index 51f5d25958..258dcdb806 100644 --- a/actionview/test/template/form_options_helper_test.rb +++ b/actionview/test/template/form_options_helper_test.rb @@ -393,30 +393,30 @@ class FormOptionsHelperTest < ActionView::TestCase def test_time_zone_options_no_params opts = time_zone_options_for_select - assert_dom_equal "<option value=\"A\">A</option>\n" + - "<option value=\"B\">B</option>\n" + - "<option value=\"C\">C</option>\n" + - "<option value=\"D\">D</option>\n" + + assert_dom_equal "<option value=\"A\">A</option>\n" \ + "<option value=\"B\">B</option>\n" \ + "<option value=\"C\">C</option>\n" \ + "<option value=\"D\">D</option>\n" \ "<option value=\"E\">E</option>", opts end def test_time_zone_options_with_selected opts = time_zone_options_for_select("D") - assert_dom_equal "<option value=\"A\">A</option>\n" + - "<option value=\"B\">B</option>\n" + - "<option value=\"C\">C</option>\n" + - "<option value=\"D\" selected=\"selected\">D</option>\n" + + assert_dom_equal "<option value=\"A\">A</option>\n" \ + "<option value=\"B\">B</option>\n" \ + "<option value=\"C\">C</option>\n" \ + "<option value=\"D\" selected=\"selected\">D</option>\n" \ "<option value=\"E\">E</option>", opts end def test_time_zone_options_with_unknown_selected opts = time_zone_options_for_select("K") - assert_dom_equal "<option value=\"A\">A</option>\n" + - "<option value=\"B\">B</option>\n" + - "<option value=\"C\">C</option>\n" + - "<option value=\"D\">D</option>\n" + + assert_dom_equal "<option value=\"A\">A</option>\n" \ + "<option value=\"B\">B</option>\n" \ + "<option value=\"C\">C</option>\n" \ + "<option value=\"D\">D</option>\n" \ "<option value=\"E\">E</option>", opts end @@ -424,11 +424,11 @@ class FormOptionsHelperTest < ActionView::TestCase def test_time_zone_options_with_priority_zones zones = [ ActiveSupport::TimeZone.new("B"), ActiveSupport::TimeZone.new("E") ] opts = time_zone_options_for_select(nil, zones) - assert_dom_equal "<option value=\"B\">B</option>\n" + - "<option value=\"E\">E</option>" + - "<option value=\"\" disabled=\"disabled\">-------------</option>\n" + - "<option value=\"A\">A</option>\n" + - "<option value=\"C\">C</option>\n" + + assert_dom_equal "<option value=\"B\">B</option>\n" \ + "<option value=\"E\">E</option>" \ + "<option value=\"\" disabled=\"disabled\">-------------</option>\n" \ + "<option value=\"A\">A</option>\n" \ + "<option value=\"C\">C</option>\n" \ "<option value=\"D\">D</option>", opts end @@ -436,11 +436,11 @@ class FormOptionsHelperTest < ActionView::TestCase def test_time_zone_options_with_selected_priority_zones zones = [ ActiveSupport::TimeZone.new("B"), ActiveSupport::TimeZone.new("E") ] opts = time_zone_options_for_select("E", zones) - assert_dom_equal "<option value=\"B\">B</option>\n" + - "<option value=\"E\" selected=\"selected\">E</option>" + - "<option value=\"\" disabled=\"disabled\">-------------</option>\n" + - "<option value=\"A\">A</option>\n" + - "<option value=\"C\">C</option>\n" + + assert_dom_equal "<option value=\"B\">B</option>\n" \ + "<option value=\"E\" selected=\"selected\">E</option>" \ + "<option value=\"\" disabled=\"disabled\">-------------</option>\n" \ + "<option value=\"A\">A</option>\n" \ + "<option value=\"C\">C</option>\n" \ "<option value=\"D\">D</option>", opts end @@ -448,11 +448,11 @@ class FormOptionsHelperTest < ActionView::TestCase def test_time_zone_options_with_unselected_priority_zones zones = [ ActiveSupport::TimeZone.new("B"), ActiveSupport::TimeZone.new("E") ] opts = time_zone_options_for_select("C", zones) - assert_dom_equal "<option value=\"B\">B</option>\n" + - "<option value=\"E\">E</option>" + - "<option value=\"\" disabled=\"disabled\">-------------</option>\n" + - "<option value=\"A\">A</option>\n" + - "<option value=\"C\" selected=\"selected\">C</option>\n" + + assert_dom_equal "<option value=\"B\">B</option>\n" \ + "<option value=\"E\">E</option>" \ + "<option value=\"\" disabled=\"disabled\">-------------</option>\n" \ + "<option value=\"A\">A</option>\n" \ + "<option value=\"C\" selected=\"selected\">C</option>\n" \ "<option value=\"D\">D</option>", opts end @@ -1031,12 +1031,12 @@ class FormOptionsHelperTest < ActionView::TestCase def test_time_zone_select @firm = Firm.new("D") html = time_zone_select("firm", "time_zone") - assert_dom_equal "<select id=\"firm_time_zone\" name=\"firm[time_zone]\">" + - "<option value=\"A\">A</option>\n" + - "<option value=\"B\">B</option>\n" + - "<option value=\"C\">C</option>\n" + - "<option value=\"D\" selected=\"selected\">D</option>\n" + - "<option value=\"E\">E</option>" + + assert_dom_equal "<select id=\"firm_time_zone\" name=\"firm[time_zone]\">" \ + "<option value=\"A\">A</option>\n" \ + "<option value=\"B\">B</option>\n" \ + "<option value=\"C\">C</option>\n" \ + "<option value=\"D\" selected=\"selected\">D</option>\n" \ + "<option value=\"E\">E</option>" \ "</select>", html end @@ -1049,12 +1049,12 @@ class FormOptionsHelperTest < ActionView::TestCase end assert_dom_equal( - "<select id=\"firm_time_zone\" name=\"firm[time_zone]\">" + - "<option value=\"A\">A</option>\n" + - "<option value=\"B\">B</option>\n" + - "<option value=\"C\">C</option>\n" + - "<option value=\"D\" selected=\"selected\">D</option>\n" + - "<option value=\"E\">E</option>" + + "<select id=\"firm_time_zone\" name=\"firm[time_zone]\">" \ + "<option value=\"A\">A</option>\n" \ + "<option value=\"B\">B</option>\n" \ + "<option value=\"C\">C</option>\n" \ + "<option value=\"D\" selected=\"selected\">D</option>\n" \ + "<option value=\"E\">E</option>" \ "</select>", output_buffer ) @@ -1068,12 +1068,12 @@ class FormOptionsHelperTest < ActionView::TestCase end assert_dom_equal( - "<select id=\"firm_305_time_zone\" name=\"firm[305][time_zone]\">" + - "<option value=\"A\">A</option>\n" + - "<option value=\"B\">B</option>\n" + - "<option value=\"C\">C</option>\n" + - "<option value=\"D\" selected=\"selected\">D</option>\n" + - "<option value=\"E\">E</option>" + + "<select id=\"firm_305_time_zone\" name=\"firm[305][time_zone]\">" \ + "<option value=\"A\">A</option>\n" \ + "<option value=\"B\">B</option>\n" \ + "<option value=\"C\">C</option>\n" \ + "<option value=\"D\" selected=\"selected\">D</option>\n" \ + "<option value=\"E\">E</option>" \ "</select>", output_buffer ) @@ -1088,12 +1088,12 @@ class FormOptionsHelperTest < ActionView::TestCase end assert_dom_equal( - "<select id=\"firm_305_time_zone\" name=\"firm[305][time_zone]\">" + - "<option value=\"A\">A</option>\n" + - "<option value=\"B\">B</option>\n" + - "<option value=\"C\">C</option>\n" + - "<option value=\"D\" selected=\"selected\">D</option>\n" + - "<option value=\"E\">E</option>" + + "<select id=\"firm_305_time_zone\" name=\"firm[305][time_zone]\">" \ + "<option value=\"A\">A</option>\n" \ + "<option value=\"B\">B</option>\n" \ + "<option value=\"C\">C</option>\n" \ + "<option value=\"D\" selected=\"selected\">D</option>\n" \ + "<option value=\"E\">E</option>" \ "</select>", output_buffer ) @@ -1102,13 +1102,13 @@ class FormOptionsHelperTest < ActionView::TestCase def test_time_zone_select_with_blank @firm = Firm.new("D") html = time_zone_select("firm", "time_zone", nil, include_blank: true) - assert_dom_equal "<select id=\"firm_time_zone\" name=\"firm[time_zone]\">" + - "<option value=\"\"></option>\n" + - "<option value=\"A\">A</option>\n" + - "<option value=\"B\">B</option>\n" + - "<option value=\"C\">C</option>\n" + - "<option value=\"D\" selected=\"selected\">D</option>\n" + - "<option value=\"E\">E</option>" + + assert_dom_equal "<select id=\"firm_time_zone\" name=\"firm[time_zone]\">" \ + "<option value=\"\"></option>\n" \ + "<option value=\"A\">A</option>\n" \ + "<option value=\"B\">B</option>\n" \ + "<option value=\"C\">C</option>\n" \ + "<option value=\"D\" selected=\"selected\">D</option>\n" \ + "<option value=\"E\">E</option>" \ "</select>", html end @@ -1116,13 +1116,13 @@ class FormOptionsHelperTest < ActionView::TestCase def test_time_zone_select_with_blank_as_string @firm = Firm.new("D") html = time_zone_select("firm", "time_zone", nil, include_blank: "No Zone") - assert_dom_equal "<select id=\"firm_time_zone\" name=\"firm[time_zone]\">" + - "<option value=\"\">No Zone</option>\n" + - "<option value=\"A\">A</option>\n" + - "<option value=\"B\">B</option>\n" + - "<option value=\"C\">C</option>\n" + - "<option value=\"D\" selected=\"selected\">D</option>\n" + - "<option value=\"E\">E</option>" + + assert_dom_equal "<select id=\"firm_time_zone\" name=\"firm[time_zone]\">" \ + "<option value=\"\">No Zone</option>\n" \ + "<option value=\"A\">A</option>\n" \ + "<option value=\"B\">B</option>\n" \ + "<option value=\"C\">C</option>\n" \ + "<option value=\"D\" selected=\"selected\">D</option>\n" \ + "<option value=\"E\">E</option>" \ "</select>", html end @@ -1131,12 +1131,12 @@ class FormOptionsHelperTest < ActionView::TestCase @firm = Firm.new("D") html = time_zone_select("firm", "time_zone", nil, {}, "style" => "color: red") - assert_dom_equal "<select id=\"firm_time_zone\" name=\"firm[time_zone]\" style=\"color: red\">" + - "<option value=\"A\">A</option>\n" + - "<option value=\"B\">B</option>\n" + - "<option value=\"C\">C</option>\n" + - "<option value=\"D\" selected=\"selected\">D</option>\n" + - "<option value=\"E\">E</option>" + + assert_dom_equal "<select id=\"firm_time_zone\" name=\"firm[time_zone]\" style=\"color: red\">" \ + "<option value=\"A\">A</option>\n" \ + "<option value=\"B\">B</option>\n" \ + "<option value=\"C\">C</option>\n" \ + "<option value=\"D\" selected=\"selected\">D</option>\n" \ + "<option value=\"E\">E</option>" \ "</select>", html assert_dom_equal html, time_zone_select("firm", "time_zone", nil, {}, @@ -1147,13 +1147,13 @@ class FormOptionsHelperTest < ActionView::TestCase @firm = Firm.new("D") html = time_zone_select("firm", "time_zone", nil, { include_blank: true }, "style" => "color: red") - assert_dom_equal "<select id=\"firm_time_zone\" name=\"firm[time_zone]\" style=\"color: red\">" + - "<option value=\"\"></option>\n" + - "<option value=\"A\">A</option>\n" + - "<option value=\"B\">B</option>\n" + - "<option value=\"C\">C</option>\n" + - "<option value=\"D\" selected=\"selected\">D</option>\n" + - "<option value=\"E\">E</option>" + + assert_dom_equal "<select id=\"firm_time_zone\" name=\"firm[time_zone]\" style=\"color: red\">" \ + "<option value=\"\"></option>\n" \ + "<option value=\"A\">A</option>\n" \ + "<option value=\"B\">B</option>\n" \ + "<option value=\"C\">C</option>\n" \ + "<option value=\"D\" selected=\"selected\">D</option>\n" \ + "<option value=\"E\">E</option>" \ "</select>", html assert_dom_equal html, time_zone_select("firm", "time_zone", nil, @@ -1164,13 +1164,13 @@ class FormOptionsHelperTest < ActionView::TestCase @firm = Firm.new("D") html = time_zone_select("firm", "time_zone", nil, { include_blank: "No Zone" }, "style" => "color: red") - assert_dom_equal "<select id=\"firm_time_zone\" name=\"firm[time_zone]\" style=\"color: red\">" + - "<option value=\"\">No Zone</option>\n" + - "<option value=\"A\">A</option>\n" + - "<option value=\"B\">B</option>\n" + - "<option value=\"C\">C</option>\n" + - "<option value=\"D\" selected=\"selected\">D</option>\n" + - "<option value=\"E\">E</option>" + + assert_dom_equal "<select id=\"firm_time_zone\" name=\"firm[time_zone]\" style=\"color: red\">" \ + "<option value=\"\">No Zone</option>\n" \ + "<option value=\"A\">A</option>\n" \ + "<option value=\"B\">B</option>\n" \ + "<option value=\"C\">C</option>\n" \ + "<option value=\"D\" selected=\"selected\">D</option>\n" \ + "<option value=\"E\">E</option>" \ "</select>", html assert_dom_equal html, time_zone_select("firm", "time_zone", nil, @@ -1181,13 +1181,13 @@ class FormOptionsHelperTest < ActionView::TestCase @firm = Firm.new("D") zones = [ ActiveSupport::TimeZone.new("A"), ActiveSupport::TimeZone.new("D") ] html = time_zone_select("firm", "time_zone", zones) - assert_dom_equal "<select id=\"firm_time_zone\" name=\"firm[time_zone]\">" + - "<option value=\"A\">A</option>\n" + - "<option value=\"D\" selected=\"selected\">D</option>" + - "<option value=\"\" disabled=\"disabled\">-------------</option>\n" + - "<option value=\"B\">B</option>\n" + - "<option value=\"C\">C</option>\n" + - "<option value=\"E\">E</option>" + + assert_dom_equal "<select id=\"firm_time_zone\" name=\"firm[time_zone]\">" \ + "<option value=\"A\">A</option>\n" \ + "<option value=\"D\" selected=\"selected\">D</option>" \ + "<option value=\"\" disabled=\"disabled\">-------------</option>\n" \ + "<option value=\"B\">B</option>\n" \ + "<option value=\"C\">C</option>\n" \ + "<option value=\"E\">E</option>" \ "</select>", html end @@ -1200,13 +1200,13 @@ class FormOptionsHelperTest < ActionView::TestCase end html = time_zone_select("firm", "time_zone", /A|D/) - assert_dom_equal "<select id=\"firm_time_zone\" name=\"firm[time_zone]\">" + - "<option value=\"A\">A</option>\n" + - "<option value=\"D\" selected=\"selected\">D</option>" + - "<option value=\"\" disabled=\"disabled\">-------------</option>\n" + - "<option value=\"B\">B</option>\n" + - "<option value=\"C\">C</option>\n" + - "<option value=\"E\">E</option>" + + assert_dom_equal "<select id=\"firm_time_zone\" name=\"firm[time_zone]\">" \ + "<option value=\"A\">A</option>\n" \ + "<option value=\"D\" selected=\"selected\">D</option>" \ + "<option value=\"\" disabled=\"disabled\">-------------</option>\n" \ + "<option value=\"B\">B</option>\n" \ + "<option value=\"C\">C</option>\n" \ + "<option value=\"E\">E</option>" \ "</select>", html end @@ -1221,13 +1221,13 @@ class FormOptionsHelperTest < ActionView::TestCase end html = time_zone_select("firm", "time_zone", /A|D/) - assert_dom_equal "<select id=\"firm_time_zone\" name=\"firm[time_zone]\">" + - "<option value=\"\" disabled=\"disabled\">-------------</option>\n" + - "<option value=\"A\">A</option>\n" + - "<option value=\"B\">B</option>\n" + - "<option value=\"C\">C</option>\n" + - "<option value=\"D\" selected=\"selected\">D</option>\n" + - "<option value=\"E\">E</option>" + + assert_dom_equal "<select id=\"firm_time_zone\" name=\"firm[time_zone]\">" \ + "<option value=\"\" disabled=\"disabled\">-------------</option>\n" \ + "<option value=\"A\">A</option>\n" \ + "<option value=\"B\">B</option>\n" \ + "<option value=\"C\">C</option>\n" \ + "<option value=\"D\" selected=\"selected\">D</option>\n" \ + "<option value=\"E\">E</option>" \ "</select>", html end @@ -1237,12 +1237,12 @@ class FormOptionsHelperTest < ActionView::TestCase @firm.time_zone = nil html = time_zone_select("firm", "time_zone", nil, default: "B") - assert_dom_equal "<select id=\"firm_time_zone\" name=\"firm[time_zone]\">" + - "<option value=\"A\">A</option>\n" + - "<option value=\"B\" selected=\"selected\">B</option>\n" + - "<option value=\"C\">C</option>\n" + - "<option value=\"D\">D</option>\n" + - "<option value=\"E\">E</option>" + + assert_dom_equal "<select id=\"firm_time_zone\" name=\"firm[time_zone]\">" \ + "<option value=\"A\">A</option>\n" \ + "<option value=\"B\" selected=\"selected\">B</option>\n" \ + "<option value=\"C\">C</option>\n" \ + "<option value=\"D\">D</option>\n" \ + "<option value=\"E\">E</option>" \ "</select>", html end @@ -1251,12 +1251,12 @@ class FormOptionsHelperTest < ActionView::TestCase @firm = Firm.new("D") html = time_zone_select("firm", "time_zone", nil, default: "B") - assert_dom_equal "<select id=\"firm_time_zone\" name=\"firm[time_zone]\">" + - "<option value=\"A\">A</option>\n" + - "<option value=\"B\">B</option>\n" + - "<option value=\"C\">C</option>\n" + - "<option value=\"D\" selected=\"selected\">D</option>\n" + - "<option value=\"E\">E</option>" + + assert_dom_equal "<select id=\"firm_time_zone\" name=\"firm[time_zone]\">" \ + "<option value=\"A\">A</option>\n" \ + "<option value=\"B\">B</option>\n" \ + "<option value=\"C\">C</option>\n" \ + "<option value=\"D\" selected=\"selected\">D</option>\n" \ + "<option value=\"E\">E</option>" \ "</select>", html end diff --git a/actionview/test/template/render_test.rb b/actionview/test/template/render_test.rb index 2651d6ff73..d189b2aa87 100644 --- a/actionview/test/template/render_test.rb +++ b/actionview/test/template/render_test.rb @@ -220,15 +220,15 @@ module RenderTestCases def test_render_partial_with_invalid_option_as e = assert_raises(ArgumentError) { @view.render(partial: "test/partial_only", as: "a-in") } - assert_equal "The value (a-in) of the option `as` is not a valid Ruby identifier; " + - "make sure it starts with lowercase letter, " + + assert_equal "The value (a-in) of the option `as` is not a valid Ruby identifier; " \ + "make sure it starts with lowercase letter, " \ "and is followed by any combination of letters, numbers and underscores.", e.message end def test_render_partial_with_hyphen_and_invalid_option_as e = assert_raises(ArgumentError) { @view.render(partial: "test/a-in", as: "a-in") } - assert_equal "The value (a-in) of the option `as` is not a valid Ruby identifier; " + - "make sure it starts with lowercase letter, " + + assert_equal "The value (a-in) of the option `as` is not a valid Ruby identifier; " \ + "make sure it starts with lowercase letter, " \ "and is followed by any combination of letters, numbers and underscores.", e.message end @@ -424,7 +424,7 @@ module RenderTestCases end CustomHandler = lambda do |template| - "@output_buffer = ''\n" + + "@output_buffer = ''\n" \ "@output_buffer << 'source: #{template.source.inspect}'\n" end diff --git a/actionview/test/template/url_helper_test.rb b/actionview/test/template/url_helper_test.rb index 95bea21c8f..09454b32cc 100644 --- a/actionview/test/template/url_helper_test.rb +++ b/actionview/test/template/url_helper_test.rb @@ -821,7 +821,7 @@ class TasksController < ActionController::Base private def render_default - render inline: "<%= link_to_unless_current('tasks', tasks_path) %>\n" + + render inline: "<%= link_to_unless_current('tasks', tasks_path) %>\n" \ "<%= link_to_unless_current('tasks', tasks_url) %>" end end diff --git a/activejob/lib/active_job/queue_adapter.rb b/activejob/lib/active_job/queue_adapter.rb index bcc555d33e..9dae80ffc2 100644 --- a/activejob/lib/active_job/queue_adapter.rb +++ b/activejob/lib/active_job/queue_adapter.rb @@ -1,4 +1,3 @@ -require "active_job/queue_adapters/inline_adapter" require "active_support/core_ext/string/inflections" module ActiveJob diff --git a/activemodel/lib/active_model/validator.rb b/activemodel/lib/active_model/validator.rb index 8212744170..98234e9b6b 100644 --- a/activemodel/lib/active_model/validator.rb +++ b/activemodel/lib/active_model/validator.rb @@ -141,8 +141,8 @@ module ActiveModel end # Performs validation on the supplied record. By default this will call - # +validates_each+ to determine validity therefore subclasses should - # override +validates_each+ with validation logic. + # +validate_each+ to determine validity therefore subclasses should + # override +validate_each+ with validation logic. def validate(record) attributes.each do |attribute| value = record.read_attribute_for_validation(attribute) diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 97af75546d..5bba673dee 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,12 @@ +* Add the touch option to ActiveRecord#increment! and decrement! + + *Hiroaki Izu* + +* Deprecate passing a class to the `class_name` because it eagerloads more classes than + necessary and potentially creates circular dependencies. + + *Kir Shatrov* + * Raise error when has_many through is defined before through association Fixes #26834 diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index f3e2189bcb..4606c91ffd 100644 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -1827,7 +1827,7 @@ module ActiveRecord builder = Builder::HasAndBelongsToMany.new name, self, options - join_model = builder.through_model + join_model = ActiveSupport::Deprecation.silence { builder.through_model } const_set join_model.name, join_model private_constant join_model.name @@ -1856,7 +1856,7 @@ module ActiveRecord hm_options[k] = options[k] if options.key? k end - has_many name, scope, hm_options, &extension + ActiveSupport::Deprecation.silence { has_many name, scope, hm_options, &extension } _reflections[name.to_s].parent_reflection = habtm_reflection end end diff --git a/activerecord/lib/active_record/associations/has_one_association.rb b/activerecord/lib/active_record/associations/has_one_association.rb index b624154def..8458253ff8 100644 --- a/activerecord/lib/active_record/associations/has_one_association.rb +++ b/activerecord/lib/active_record/associations/has_one_association.rb @@ -85,7 +85,7 @@ module ActiveRecord if target.persisted? && owner.persisted? && !target.save set_owner_attributes(target) - raise RecordNotSaved, "Failed to remove the existing associated #{reflection.name}. " + + raise RecordNotSaved, "Failed to remove the existing associated #{reflection.name}. " \ "The record failed to save after its foreign key was set to nil." end end diff --git a/activerecord/lib/active_record/associations/join_dependency.rb b/activerecord/lib/active_record/associations/join_dependency.rb index 4cd1e64c3d..a79eb03acc 100644 --- a/activerecord/lib/active_record/associations/join_dependency.rb +++ b/activerecord/lib/active_record/associations/join_dependency.rb @@ -32,7 +32,7 @@ module ActiveRecord @alias_cache[node][column] end - class Table < Struct.new(:node, :columns) # :nodoc: + Table = Struct.new(:node, :columns) do # :nodoc: def table Arel::Nodes::TableAlias.new node.table, node.aliased_table_name end diff --git a/activerecord/lib/active_record/coders/yaml_column.rb b/activerecord/lib/active_record/coders/yaml_column.rb index 3a04a10fc9..4b06987f08 100644 --- a/activerecord/lib/active_record/coders/yaml_column.rb +++ b/activerecord/lib/active_record/coders/yaml_column.rb @@ -38,11 +38,9 @@ module ActiveRecord private def check_arity_of_constructor - begin - load(nil) - rescue ArgumentError - raise ArgumentError, "Cannot serialize #{object_class}. Classes passed to `serialize` must have a 0 argument constructor." - end + load(nil) + rescue ArgumentError + raise ArgumentError, "Cannot serialize #{object_class}. Classes passed to `serialize` must have a 0 argument constructor." end end end diff --git a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb index 5ec2fc073e..ce4721c99d 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb @@ -967,7 +967,7 @@ module ActiveRecord end def pool_from_any_process_for(spec_name) - owner_to_pool = @owner_to_pool.values.find { |v| v[spec_name] } + owner_to_pool = @owner_to_pool.values.reverse.find { |v| v[spec_name] } owner_to_pool && owner_to_pool[spec_name] end end diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb index 9b324c090b..b518ef760b 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb @@ -3,29 +3,25 @@ module ActiveRecord # Abstract representation of an index definition on a table. Instances of # this type are typically created and returned by methods in database # adapters. e.g. ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter#indexes - class IndexDefinition < Struct.new(:table, :name, :unique, :columns, :lengths, :orders, :where, :type, :using, :comment) #:nodoc: - end + IndexDefinition = Struct.new(:table, :name, :unique, :columns, :lengths, :orders, :where, :type, :using, :comment) #:nodoc: # Abstract representation of a column definition. Instances of this type # are typically created by methods in TableDefinition, and added to the # +columns+ attribute of said TableDefinition object, in order to be used # for generating a number of table creation or table changing SQL statements. - class ColumnDefinition < Struct.new(:name, :type, :limit, :precision, :scale, :default, :null, :first, :after, :auto_increment, :primary_key, :collation, :sql_type, :comment) #:nodoc: + ColumnDefinition = Struct.new(:name, :type, :limit, :precision, :scale, :default, :null, :first, :after, :auto_increment, :primary_key, :collation, :sql_type, :comment) do #:nodoc: def primary_key? primary_key || type.to_sym == :primary_key end end - class AddColumnDefinition < Struct.new(:column) # :nodoc: - end + AddColumnDefinition = Struct.new(:column) # :nodoc: - class ChangeColumnDefinition < Struct.new(:column, :name) #:nodoc: - end + ChangeColumnDefinition = Struct.new(:column, :name) #:nodoc: - class PrimaryKeyDefinition < Struct.new(:name) # :nodoc: - end + PrimaryKeyDefinition = Struct.new(:name) # :nodoc: - class ForeignKeyDefinition < Struct.new(:from_table, :to_table, :options) #:nodoc: + ForeignKeyDefinition = Struct.new(:from_table, :to_table, :options) do #:nodoc: def name options[:name] end diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb index 4046b3829d..cf2269bf12 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb @@ -176,7 +176,7 @@ module ActiveRecord if @owner == Thread.current msg << "it is already leased by the current thread." else - msg << "it is already in use by a different thread: #{@owner}. " << + msg << "it is already in use by a different thread: #{@owner}. " \ "Current thread: #{Thread.current}." end raise ActiveRecordError, msg @@ -194,8 +194,8 @@ module ActiveRecord def expire if in_use? if @owner != Thread.current - raise ActiveRecordError, "Cannot expire connection, " << - "it is owned by a different thread: #{@owner}. " << + raise ActiveRecordError, "Cannot expire connection, " \ + "it is owned by a different thread: #{@owner}. " \ "Current thread: #{Thread.current}." end diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb index 4d30bdf196..0028dc0edb 100644 --- a/activerecord/lib/active_record/core.rb +++ b/activerecord/lib/active_record/core.rb @@ -308,7 +308,7 @@ module ActiveRecord relation = Relation.create(self, arel_table, predicate_builder) if finder_needs_type_condition? && !ignore_default_scope? - relation.where(type_condition).create_with(inheritance_column.to_sym => sti_name) + relation.where(type_condition).create_with(inheritance_column.to_s => sti_name) else relation end diff --git a/activerecord/lib/active_record/log_subscriber.rb b/activerecord/lib/active_record/log_subscriber.rb index 4b8d8d9105..ea101946f4 100644 --- a/activerecord/lib/active_record/log_subscriber.rb +++ b/activerecord/lib/active_record/log_subscriber.rb @@ -81,7 +81,7 @@ module ActiveRecord RED when /transaction\s*\Z/i CYAN - else + else MAGENTA end end diff --git a/activerecord/lib/active_record/migration.rb b/activerecord/lib/active_record/migration.rb index 6e5f5fa2a7..31c2397bc9 100644 --- a/activerecord/lib/active_record/migration.rb +++ b/activerecord/lib/active_record/migration.rb @@ -692,7 +692,7 @@ module ActiveRecord connection.respond_to?(:reverting) && connection.reverting end - class ReversibleBlockHelper < Struct.new(:reverting) # :nodoc: + ReversibleBlockHelper = Struct.new(:reverting) do # :nodoc: def up yield unless reverting end @@ -938,7 +938,7 @@ module ActiveRecord # MigrationProxy is used to defer loading of the actual migration classes # until they are needed - class MigrationProxy < Struct.new(:name, :version, :filename, :scope) + MigrationProxy = Struct.new(:name, :version, :filename, :scope) do def initialize(name, version, filename, scope) super @migration = nil diff --git a/activerecord/lib/active_record/migration/compatibility.rb b/activerecord/lib/active_record/migration/compatibility.rb index 2904634eb7..a5d8893634 100644 --- a/activerecord/lib/active_record/migration/compatibility.rb +++ b/activerecord/lib/active_record/migration/compatibility.rb @@ -16,7 +16,7 @@ module ActiveRecord class V5_0 < V5_1 def create_table(table_name, options = {}) if adapter_name == "PostgreSQL" - if options[:id] == :uuid && !options[:default] + if options[:id] == :uuid && !options.key?(:default) options[:default] = "uuid_generate_v4()" end end diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb index 19fe9632ca..4cd867faae 100644 --- a/activerecord/lib/active_record/persistence.rb +++ b/activerecord/lib/active_record/persistence.rb @@ -341,11 +341,13 @@ module ActiveRecord # Wrapper around #increment that writes the update to the database. # Only +attribute+ is updated; the record itself is not saved. # This means that any other modified attributes will still be dirty. - # Validations and callbacks are skipped. Returns +self+. - def increment!(attribute, by = 1) + # Validations and callbacks are skipped. Supports the `touch` option from + # +update_counters+, see that for more. + # Returns +self+. + def increment!(attribute, by = 1, touch: nil) increment(attribute, by) change = public_send(attribute) - (attribute_in_database(attribute.to_s) || 0) - self.class.update_counters(id, attribute => change) + self.class.update_counters(id, attribute => change, touch: touch) clear_attribute_change(attribute) # eww self end @@ -360,9 +362,11 @@ module ActiveRecord # Wrapper around #decrement that writes the update to the database. # Only +attribute+ is updated; the record itself is not saved. # This means that any other modified attributes will still be dirty. - # Validations and callbacks are skipped. Returns +self+. - def decrement!(attribute, by = 1) - increment!(attribute, -by) + # Validations and callbacks are skipped. Supports the `touch` option from + # +update_counters+, see that for more. + # Returns +self+. + def decrement!(attribute, by = 1, touch: nil) + increment!(attribute, -by, touch: touch) end # Assigns to +attribute+ the boolean opposite of <tt>attribute?</tt>. So diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb index 72f1ac4896..2c8c4b6297 100644 --- a/activerecord/lib/active_record/reflection.rb +++ b/activerecord/lib/active_record/reflection.rb @@ -321,7 +321,7 @@ module ActiveRecord end end - # Holds all the meta-data about an aggregation as it was specified in the + # Holds all the metadata about an aggregation as it was specified in the # Active Record class. class AggregateReflection < MacroReflection #:nodoc: def mapping @@ -330,7 +330,7 @@ module ActiveRecord end end - # Holds all the meta-data about an association as it was specified in the + # Holds all the metadata about an association as it was specified in the # Active Record class. class AssociationReflection < MacroReflection #:nodoc: # Returns the target association's class. @@ -364,6 +364,17 @@ module ActiveRecord @constructable = calculate_constructable(macro, options) @association_scope_cache = {} @scope_lock = Mutex.new + + if options[:class_name] && options[:class_name].class == Class + ActiveSupport::Deprecation.warn(<<-MSG.squish) + Passing a class to the `class_name` is deprecated and will raise + an ArgumentError in Rails 5.2. It eagerloads more classes than + necessary and potentially creates circular dependencies. + + Please pass the class name as a string: + `#{macro} :#{name}, class_name: '#{options[:class_name]}'` + MSG + end end def association_scope_cache(conn, owner) @@ -698,7 +709,7 @@ module ActiveRecord end end - # Holds all the meta-data about a :through association as it was specified + # Holds all the metadata about a :through association as it was specified # in the Active Record class. class ThroughReflection < AbstractReflection #:nodoc: attr_reader :delegate_reflection diff --git a/activerecord/lib/active_record/tasks/database_tasks.rb b/activerecord/lib/active_record/tasks/database_tasks.rb index bdb5184599..82604a915f 100644 --- a/activerecord/lib/active_record/tasks/database_tasks.rb +++ b/activerecord/lib/active_record/tasks/database_tasks.rb @@ -267,8 +267,8 @@ module ActiveRecord if seed_loader seed_loader.load_seed else - raise "You tried to load seed data, but no seed loader is specified. Please specify seed " + - "loader with ActiveRecord::Tasks::DatabaseTasks.seed_loader = your_seed_loader\n" + + raise "You tried to load seed data, but no seed loader is specified. Please specify seed " \ + "loader with ActiveRecord::Tasks::DatabaseTasks.seed_loader = your_seed_loader\n" \ "Seed loader should respond to load_seed method" end end diff --git a/activerecord/test/cases/adapters/mysql2/connection_test.rb b/activerecord/test/cases/adapters/mysql2/connection_test.rb index c1de2218e2..bae283a048 100644 --- a/activerecord/test/cases/adapters/mysql2/connection_test.rb +++ b/activerecord/test/cases/adapters/mysql2/connection_test.rb @@ -66,9 +66,10 @@ class Mysql2ConnectionTest < ActiveRecord::Mysql2TestCase def test_execute_after_disconnect @connection.disconnect! - assert_raise(ActiveRecord::StatementInvalid) do + error = assert_raise(ActiveRecord::StatementInvalid) do @connection.execute("SELECT 1") end + assert_kind_of Mysql2::Error, error.cause end def test_quote_after_disconnect diff --git a/activerecord/test/cases/adapters/postgresql/connection_test.rb b/activerecord/test/cases/adapters/postgresql/connection_test.rb index 075301d6d5..3cbd4ca212 100644 --- a/activerecord/test/cases/adapters/postgresql/connection_test.rb +++ b/activerecord/test/cases/adapters/postgresql/connection_test.rb @@ -156,7 +156,7 @@ module ActiveRecord secondary_connection.query("select pg_terminate_backend(#{original_connection_pid.first.first})") ActiveRecord::Base.connection_pool.checkin(secondary_connection) elsif ARTest.config["with_manual_interventions"] - puts "Kill the connection now (e.g. by restarting the PostgreSQL " + + puts "Kill the connection now (e.g. by restarting the PostgreSQL " \ 'server with the "-m fast" option) and then press enter.' $stdin.gets else @@ -175,7 +175,7 @@ module ActiveRecord new_connection_pid = @connection.query("select pg_backend_pid()") assert_not_equal original_connection_pid, new_connection_pid, - "umm -- looks like you didn't break the connection, because we're still " + + "umm -- looks like you didn't break the connection, because we're still " \ "successfully querying with the same connection pid." # Repair all fixture connections so other tests won't break. diff --git a/activerecord/test/cases/adapters/postgresql/uuid_test.rb b/activerecord/test/cases/adapters/postgresql/uuid_test.rb index f34d50e25c..4655cd1d20 100644 --- a/activerecord/test/cases/adapters/postgresql/uuid_test.rb +++ b/activerecord/test/cases/adapters/postgresql/uuid_test.rb @@ -234,25 +234,23 @@ class PostgresqlUUIDGenerationTest < ActiveRecord::PostgreSQLTestCase end end - if ActiveRecord::Base.connection.supports_pgcrypto_uuid? - def test_schema_dumper_for_uuid_primary_key_default_in_legacy_migration - @verbose_was = ActiveRecord::Migration.verbose - ActiveRecord::Migration.verbose = false - - migration = Class.new(ActiveRecord::Migration[4.2]) do - def version; 101 end - def migrate(x) - create_table("pg_uuids_4", id: :uuid) - end - end.new - ActiveRecord::Migrator.new(:up, [migration]).migrate - - schema = dump_table_schema "pg_uuids_4" - assert_match(/\bcreate_table "pg_uuids_4", id: :uuid, default: -> { "uuid_generate_v4\(\)" }/, schema) - ensure - drop_table "pg_uuids_4" - ActiveRecord::Migration.verbose = @verbose_was - end + def test_schema_dumper_for_uuid_primary_key_default_in_legacy_migration + @verbose_was = ActiveRecord::Migration.verbose + ActiveRecord::Migration.verbose = false + + migration = Class.new(ActiveRecord::Migration[5.0]) do + def version; 101 end + def migrate(x) + create_table("pg_uuids_4", id: :uuid) + end + end.new + ActiveRecord::Migrator.new(:up, [migration]).migrate + + schema = dump_table_schema "pg_uuids_4" + assert_match(/\bcreate_table "pg_uuids_4", id: :uuid, default: -> { "uuid_generate_v4\(\)" }/, schema) + ensure + drop_table "pg_uuids_4" + ActiveRecord::Migration.verbose = @verbose_was end end end @@ -285,6 +283,25 @@ class PostgresqlUUIDTestNilDefault < ActiveRecord::PostgreSQLTestCase schema = dump_table_schema "pg_uuids" assert_match(/\bcreate_table "pg_uuids", id: :uuid, default: nil/, schema) end + + def test_schema_dumper_for_uuid_primary_key_with_default_nil_in_legacy_migration + @verbose_was = ActiveRecord::Migration.verbose + ActiveRecord::Migration.verbose = false + + migration = Class.new(ActiveRecord::Migration[5.0]) do + def version; 101 end + def migrate(x) + create_table("pg_uuids_4", id: :uuid, default: nil) + end + end.new + ActiveRecord::Migrator.new(:up, [migration]).migrate + + schema = dump_table_schema "pg_uuids_4" + assert_match(/\bcreate_table "pg_uuids_4", id: :uuid, default: nil/, schema) + ensure + drop_table "pg_uuids_4" + ActiveRecord::Migration.verbose = @verbose_was + end end end diff --git a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb index 54fb61d6a5..efd2124679 100644 --- a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb @@ -86,8 +86,10 @@ class DeveloperWithSymbolClassName < Developer has_and_belongs_to_many :projects, class_name: :ProjectWithSymbolsForKeys end -class DeveloperWithConstantClassName < Developer - has_and_belongs_to_many :projects, class_name: ProjectWithSymbolsForKeys +ActiveSupport::Deprecation.silence do + class DeveloperWithConstantClassName < Developer + has_and_belongs_to_many :projects, class_name: ProjectWithSymbolsForKeys + end end class DeveloperWithExtendOption < Developer diff --git a/activerecord/test/cases/associations/has_one_associations_test.rb b/activerecord/test/cases/associations/has_one_associations_test.rb index aa910ba409..fc1e61124c 100644 --- a/activerecord/test/cases/associations/has_one_associations_test.rb +++ b/activerecord/test/cases/associations/has_one_associations_test.rb @@ -476,7 +476,7 @@ class HasOneAssociationsTest < ActiveRecord::TestCase assert_equal ships(:black_pearl), pirate.ship assert_equal pirate.id, pirate.ship.pirate_id - assert_equal "Failed to remove the existing associated ship. " + + assert_equal "Failed to remove the existing associated ship. " \ "The record failed to save after its foreign key was set to nil.", error.message end diff --git a/activerecord/test/cases/attribute_methods/read_test.rb b/activerecord/test/cases/attribute_methods/read_test.rb index 978dd93fa4..1fc63a49d4 100644 --- a/activerecord/test/cases/attribute_methods/read_test.rb +++ b/activerecord/test/cases/attribute_methods/read_test.rb @@ -3,7 +3,7 @@ require "cases/helper" module ActiveRecord module AttributeMethods class ReadTest < ActiveRecord::TestCase - class FakeColumn < Struct.new(:name) + FakeColumn = Struct.new(:name) do def type; :integer; end end diff --git a/activerecord/test/cases/connection_adapters/connection_handler_test.rb b/activerecord/test/cases/connection_adapters/connection_handler_test.rb index 2c33bf22ab..4f2392042b 100644 --- a/activerecord/test/cases/connection_adapters/connection_handler_test.rb +++ b/activerecord/test/cases/connection_adapters/connection_handler_test.rb @@ -89,6 +89,41 @@ module ActiveRecord rd.close end + def test_pool_from_any_process_for_uses_most_recent_spec + skip unless current_adapter?(:SQLite3Adapter) + + file = Tempfile.new "lol.sqlite3" + + rd, wr = IO.pipe + rd.binmode + wr.binmode + + pid = fork do + ActiveRecord::Base.configurations["arunit"]["database"] = file.path + ActiveRecord::Base.establish_connection(:arunit) + + pid2 = fork do + wr.write ActiveRecord::Base.connection_config[:database] + wr.close + end + + Process.waitpid pid2 + end + + Process.waitpid pid + + wr.close + + assert_equal file.path, rd.read + + rd.close + ensure + if file + file.close + file.unlink + end + end + def test_a_class_using_custom_pool_and_switching_back_to_primary klass2 = Class.new(Base) { def self.name; "klass2"; end } diff --git a/activerecord/test/cases/connection_pool_test.rb b/activerecord/test/cases/connection_pool_test.rb index 42600e53fd..9f7280634e 100644 --- a/activerecord/test/cases/connection_pool_test.rb +++ b/activerecord/test/cases/connection_pool_test.rb @@ -341,14 +341,18 @@ module ActiveRecord end end + class ConnectionTestModel < ActiveRecord::Base + end + def test_connection_notification_is_called payloads = [] subscription = ActiveSupport::Notifications.subscribe("!connection.active_record") do |name, started, finished, unique_id, payload| payloads << payload end - ActiveRecord::Base.establish_connection :arunit + ConnectionTestModel.establish_connection :arunit + assert_equal [:config, :connection_id, :spec_name], payloads[0].keys.sort - assert_equal "primary", payloads[0][:spec_name] + assert_equal "ActiveRecord::ConnectionAdapters::ConnectionPoolTest::ConnectionTestModel", payloads[0][:spec_name] ensure ActiveSupport::Notifications.unsubscribe(subscription) if subscription end @@ -395,7 +399,7 @@ module ActiveRecord all_threads_in_new_connection.wait end rescue Timeout::Error - flunk "pool unable to establish connections concurrently or implementation has " << + flunk "pool unable to establish connections concurrently or implementation has " \ "changed, this test then needs to patch a different :new_connection method" ensure # clean up the threads diff --git a/activerecord/test/cases/nested_attributes_with_callbacks_test.rb b/activerecord/test/cases/nested_attributes_with_callbacks_test.rb index 350a966d40..b9d2acbed2 100644 --- a/activerecord/test/cases/nested_attributes_with_callbacks_test.rb +++ b/activerecord/test/cases/nested_attributes_with_callbacks_test.rb @@ -120,14 +120,14 @@ class NestedAttributesWithCallbacksTest < ActiveRecord::TestCase assert_assignment_affects_records_in_target(:birds_with_add) end - test("Assignment updates records in target when not loaded" + + test("Assignment updates records in target when not loaded" \ " and callback loads target") do assert_not @pirate.birds_with_add_load.loaded? @pirate.birds_with_add_load_attributes = update_new_and_destroy_bird_attributes assert_assignment_affects_records_in_target(:birds_with_add_load) end - test("Assignment updates records in target when loaded" + + test("Assignment updates records in target when loaded" \ " and callback loads target") do @pirate.birds_with_add_load.load_target @pirate.birds_with_add_load_attributes = update_new_and_destroy_bird_attributes diff --git a/activerecord/test/cases/persistence_test.rb b/activerecord/test/cases/persistence_test.rb index 3f1da82cb4..5b7e2fd008 100644 --- a/activerecord/test/cases/persistence_test.rb +++ b/activerecord/test/cases/persistence_test.rb @@ -139,6 +139,14 @@ class PersistenceTest < ActiveRecord::TestCase assert_equal initial_credit + 2, a1.reload.credit_limit end + def test_increment_updates_timestamps + topic = topics(:first) + topic.update_columns(updated_at: 5.minutes.ago) + previous_updated_at = topic.updated_at + topic.increment!(:replies_count, touch: true) + assert_operator previous_updated_at, :<, topic.reload.updated_at + end + def test_destroy_all conditions = "author_name = 'Mary'" topics_by_mary = Topic.all.merge!(where: conditions, order: "id").to_a @@ -230,6 +238,14 @@ class PersistenceTest < ActiveRecord::TestCase assert_equal 41, accounts(:signals37, :reload).credit_limit end + def test_decrement_updates_timestamps + topic = topics(:first) + topic.update_columns(updated_at: 5.minutes.ago) + previous_updated_at = topic.updated_at + topic.decrement!(:replies_count, touch: true) + assert_operator previous_updated_at, :<, topic.reload.updated_at + end + def test_create topic = Topic.new topic.title = "New Topic" diff --git a/activerecord/test/cases/query_cache_test.rb b/activerecord/test/cases/query_cache_test.rb index 324c2f4388..93a67d0738 100644 --- a/activerecord/test/cases/query_cache_test.rb +++ b/activerecord/test/cases/query_cache_test.rb @@ -50,32 +50,36 @@ class QueryCacheTest < ActiveRecord::TestCase assert_cache :off end - def test_query_cache_across_threads - ActiveRecord::Base.connection_pool.connections.each do |conn| - assert_cache :off, conn - end + private def with_temporary_connection_pool + old_pool = ActiveRecord::Base.connection_handler.retrieve_connection_pool(ActiveRecord::Base.connection_specification_name) + new_pool = ActiveRecord::ConnectionAdapters::ConnectionPool.new ActiveRecord::Base.connection_pool.spec + ActiveRecord::Base.connection_handler.send(:owner_to_pool)["primary"] = new_pool - assert !ActiveRecord::Base.connection.nil? - assert_cache :off - - middleware { - assert_cache :clean - - Task.find 1 - assert_cache :dirty - - thread_1_connection = ActiveRecord::Base.connection - ActiveRecord::Base.clear_active_connections! - assert_cache :off, thread_1_connection + yield + ensure + ActiveRecord::Base.connection_handler.send(:owner_to_pool)["primary"] = old_pool + end - started = Concurrent::Event.new - checked = Concurrent::Event.new + def test_query_cache_across_threads + with_temporary_connection_pool do + begin + if in_memory_db? + # Separate connections to an in-memory database create an entirely new database, + # with an empty schema etc, so we just stub out this schema on the fly. + ActiveRecord::Base.connection_pool.with_connection do |connection| + connection.create_table :tasks do |t| + t.datetime :starting + t.datetime :ending + end + end + ActiveRecord::FixtureSet.create_fixtures(self.class.fixture_path, ["tasks"], {}, ActiveRecord::Base) + end - thread_2_connection = nil - thread = Thread.new { - thread_2_connection = ActiveRecord::Base.connection + ActiveRecord::Base.connection_pool.connections.each do |conn| + assert_cache :off, conn + end - assert_equal thread_2_connection, thread_1_connection + assert !ActiveRecord::Base.connection.nil? assert_cache :off middleware { @@ -84,29 +88,51 @@ class QueryCacheTest < ActiveRecord::TestCase Task.find 1 assert_cache :dirty - started.set - checked.wait - + thread_1_connection = ActiveRecord::Base.connection ActiveRecord::Base.clear_active_connections! - }.call({}) - } + assert_cache :off, thread_1_connection + + started = Concurrent::Event.new + checked = Concurrent::Event.new - started.wait + thread_2_connection = nil + thread = Thread.new { + thread_2_connection = ActiveRecord::Base.connection - thread_1_connection = ActiveRecord::Base.connection - assert_not_equal thread_1_connection, thread_2_connection - assert_cache :dirty, thread_2_connection - checked.set - thread.join + assert_equal thread_2_connection, thread_1_connection + assert_cache :off - assert_cache :off, thread_2_connection - }.call({}) + middleware { + assert_cache :clean - ActiveRecord::Base.connection_pool.connections.each do |conn| - assert_cache :off, conn + Task.find 1 + assert_cache :dirty + + started.set + checked.wait + + ActiveRecord::Base.clear_active_connections! + }.call({}) + } + + started.wait + + thread_1_connection = ActiveRecord::Base.connection + assert_not_equal thread_1_connection, thread_2_connection + assert_cache :dirty, thread_2_connection + checked.set + thread.join + + assert_cache :off, thread_2_connection + }.call({}) + + ActiveRecord::Base.connection_pool.connections.each do |conn| + assert_cache :off, conn + end + ensure + ActiveRecord::Base.clear_all_connections! + end end - ensure - ActiveRecord::Base.clear_all_connections! end def test_middleware_delegates @@ -349,37 +375,44 @@ class QueryCacheTest < ActiveRecord::TestCase end def test_query_cache_does_not_establish_connection_if_unconnected - ActiveRecord::Base.clear_active_connections! - refute ActiveRecord::Base.connection_handler.active_connections? # sanity check + with_temporary_connection_pool do + ActiveRecord::Base.clear_active_connections! + refute ActiveRecord::Base.connection_handler.active_connections? # sanity check - middleware { - refute ActiveRecord::Base.connection_handler.active_connections?, "QueryCache forced ActiveRecord::Base to establish a connection in setup" - }.call({}) + middleware { + refute ActiveRecord::Base.connection_handler.active_connections?, "QueryCache forced ActiveRecord::Base to establish a connection in setup" + }.call({}) - refute ActiveRecord::Base.connection_handler.active_connections?, "QueryCache forced ActiveRecord::Base to establish a connection in cleanup" + refute ActiveRecord::Base.connection_handler.active_connections?, "QueryCache forced ActiveRecord::Base to establish a connection in cleanup" + end end def test_query_cache_is_enabled_on_connections_established_after_middleware_runs - ActiveRecord::Base.clear_active_connections! - refute ActiveRecord::Base.connection_handler.active_connections? # sanity check + with_temporary_connection_pool do + ActiveRecord::Base.clear_active_connections! + refute ActiveRecord::Base.connection_handler.active_connections? # sanity check - middleware { - assert ActiveRecord::Base.connection.query_cache_enabled, "QueryCache did not get lazily enabled" - }.call({}) + middleware { + assert ActiveRecord::Base.connection.query_cache_enabled, "QueryCache did not get lazily enabled" + }.call({}) + end end def test_query_caching_is_local_to_the_current_thread - ActiveRecord::Base.clear_active_connections! + with_temporary_connection_pool do + ActiveRecord::Base.clear_active_connections! - middleware { - assert ActiveRecord::Base.connection_pool.query_cache_enabled - assert ActiveRecord::Base.connection.query_cache_enabled + middleware { + assert ActiveRecord::Base.connection_pool.query_cache_enabled + assert ActiveRecord::Base.connection.query_cache_enabled - Thread.new { - refute ActiveRecord::Base.connection_pool.query_cache_enabled - refute ActiveRecord::Base.connection.query_cache_enabled - }.join - }.call({}) + Thread.new { + refute ActiveRecord::Base.connection_pool.query_cache_enabled + refute ActiveRecord::Base.connection.query_cache_enabled + }.join + }.call({}) + + end end private diff --git a/activerecord/test/cases/reflection_test.rb b/activerecord/test/cases/reflection_test.rb index 0ef51272b9..2444eccab1 100644 --- a/activerecord/test/cases/reflection_test.rb +++ b/activerecord/test/cases/reflection_test.rb @@ -404,6 +404,12 @@ class ReflectionTest < ActiveRecord::TestCase assert_equal Client, Firm.reflect_on_association(:unsorted_clients_with_symbol).klass end + def test_class_for_class_name + assert_deprecated do + assert_predicate ActiveRecord::Reflection.create(:has_many, :clients, nil, { class_name: Client }, Firm), :validate? + end + end + def test_join_table category = Struct.new(:table_name, :pluralize_table_names).new("categories", true) product = Struct.new(:table_name, :pluralize_table_names).new("products", true) diff --git a/activerecord/test/cases/relation/mutation_test.rb b/activerecord/test/cases/relation/mutation_test.rb index de15eb9187..4f92f71a09 100644 --- a/activerecord/test/cases/relation/mutation_test.rb +++ b/activerecord/test/cases/relation/mutation_test.rb @@ -3,7 +3,7 @@ require "models/post" module ActiveRecord class RelationMutationTest < ActiveRecord::TestCase - class FakeKlass < Struct.new(:table_name, :name) + FakeKlass = Struct.new(:table_name, :name) do extend ActiveRecord::Delegation::DelegateCache inherited self diff --git a/activerecord/test/cases/relation_test.rb b/activerecord/test/cases/relation_test.rb index d5af0cc9a5..1241bb54a4 100644 --- a/activerecord/test/cases/relation_test.rb +++ b/activerecord/test/cases/relation_test.rb @@ -8,7 +8,7 @@ module ActiveRecord class RelationTest < ActiveRecord::TestCase fixtures :posts, :comments, :authors - class FakeKlass < Struct.new(:table_name, :name) + FakeKlass = Struct.new(:table_name, :name) do extend ActiveRecord::Delegation::DelegateCache inherited self diff --git a/activerecord/test/cases/tasks/database_tasks_test.rb b/activerecord/test/cases/tasks/database_tasks_test.rb index f7c53b5801..5653fd83fd 100644 --- a/activerecord/test/cases/tasks/database_tasks_test.rb +++ b/activerecord/test/cases/tasks/database_tasks_test.rb @@ -100,6 +100,8 @@ module ActiveRecord @configurations = { "development" => { "database" => "my-db" } } ActiveRecord::Base.stubs(:configurations).returns(@configurations) + # To refrain from connecting to a newly created empty DB in sqlite3_mem tests + ActiveRecord::Base.connection_handler.stubs(:establish_connection) end def test_ignores_configurations_without_databases diff --git a/activerecord/test/models/user.rb b/activerecord/test/models/user.rb index 47649e0a77..c099c57e37 100644 --- a/activerecord/test/models/user.rb +++ b/activerecord/test/models/user.rb @@ -5,7 +5,7 @@ class User < ActiveRecord::Base has_secure_token :auth_token has_and_belongs_to_many :jobs_pool, - class_name: Job, + class_name: "Job", join_table: "jobs_pool" end diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md index 873a39dbf6..0bb6b2466c 100644 --- a/activesupport/CHANGELOG.md +++ b/activesupport/CHANGELOG.md @@ -1,3 +1,33 @@ +* Fixed bugs that `StringInquirer#respond_to_missing?` and + `ArrayInquirer#respond_to_missing?` do not fallback to `super`. + + *Akira Matsuda* + +* Fix inconsistent results when parsing large durations and constructing durations from code + + ActiveSupport::Duration.parse('P3Y') == 3.years # It should be true + + Duration parsing made independent from any moment of time: + Fixed length in seconds is assigned to each duration part during parsing. + + Changed duration of months and years in seconds to more accurate and logical: + + 1. The value of 365.2425 days in Gregorian year is more accurate + as it accounts for every 400th non-leap year. + + 2. Month's length is bound to year's duration, which makes + sensible comparisons like `12.months == 1.year` to be `true` + and nonsensical ones like `30.days == 1.month` to be `false`. + + Calculations on times and dates with durations shouldn't be affected as + duration's numeric value isn't used in calculations, only parts are used. + + Methods on `Numeric` like `2.days` now use these predefined durations + to avoid duplicating of duration constants through the codebase and + eliminate creation of intermediate durations. + + *Andrey Novikov, Andrew White* + * Change return value of `Rational#duplicable?`, `ComplexClass#duplicable?` to false. diff --git a/activesupport/lib/active_support/array_inquirer.rb b/activesupport/lib/active_support/array_inquirer.rb index 85122e39b2..befa1746c6 100644 --- a/activesupport/lib/active_support/array_inquirer.rb +++ b/activesupport/lib/active_support/array_inquirer.rb @@ -20,7 +20,7 @@ module ActiveSupport # variants.any?(:phone, :tablet) # => true # variants.any?('phone', 'desktop') # => true # variants.any?(:desktop, :watch) # => false - def any?(*candidates, &block) + def any?(*candidates) if candidates.none? super else @@ -32,7 +32,7 @@ module ActiveSupport private def respond_to_missing?(name, include_private = false) - name[-1] == "?" + (name[-1] == "?") || super end def method_missing(name, *args) diff --git a/activesupport/lib/active_support/core_ext/integer/time.rb b/activesupport/lib/active_support/core_ext/integer/time.rb index 4a64872392..74baae3639 100644 --- a/activesupport/lib/active_support/core_ext/integer/time.rb +++ b/activesupport/lib/active_support/core_ext/integer/time.rb @@ -18,12 +18,12 @@ class Integer # # equivalent to Time.now.advance(months: 4, years: 5) # (4.months + 5.years).from_now def months - ActiveSupport::Duration.new(self * 30.days, [[:months, self]]) + ActiveSupport::Duration.months(self) end alias :month :months def years - ActiveSupport::Duration.new(self * 365.25.days.to_i, [[:years, self]]) + ActiveSupport::Duration.years(self) end alias :year :years end diff --git a/activesupport/lib/active_support/core_ext/numeric/time.rb b/activesupport/lib/active_support/core_ext/numeric/time.rb index 809dfd4e07..2e6c70d418 100644 --- a/activesupport/lib/active_support/core_ext/numeric/time.rb +++ b/activesupport/lib/active_support/core_ext/numeric/time.rb @@ -19,7 +19,7 @@ class Numeric # # equivalent to Time.current.advance(months: 4, years: 5) # (4.months + 5.years).from_now def seconds - ActiveSupport::Duration.new(self, [[:seconds, self]]) + ActiveSupport::Duration.seconds(self) end alias :second :seconds @@ -27,7 +27,7 @@ class Numeric # # 2.minutes # => 2 minutes def minutes - ActiveSupport::Duration.new(self * 60, [[:minutes, self]]) + ActiveSupport::Duration.minutes(self) end alias :minute :minutes @@ -35,7 +35,7 @@ class Numeric # # 2.hours # => 2 hours def hours - ActiveSupport::Duration.new(self * 3600, [[:hours, self]]) + ActiveSupport::Duration.hours(self) end alias :hour :hours @@ -43,7 +43,7 @@ class Numeric # # 2.days # => 2 days def days - ActiveSupport::Duration.new(self * 24.hours, [[:days, self]]) + ActiveSupport::Duration.days(self) end alias :day :days @@ -51,7 +51,7 @@ class Numeric # # 2.weeks # => 2 weeks def weeks - ActiveSupport::Duration.new(self * 7.days, [[:weeks, self]]) + ActiveSupport::Duration.weeks(self) end alias :week :weeks @@ -59,7 +59,7 @@ class Numeric # # 2.fortnights # => 4 weeks def fortnights - ActiveSupport::Duration.new(self * 2.weeks, [[:weeks, self * 2]]) + ActiveSupport::Duration.weeks(self * 2) end alias :fortnight :fortnights diff --git a/activesupport/lib/active_support/duration.rb b/activesupport/lib/active_support/duration.rb index c9e8c8fdc4..003f6203ef 100644 --- a/activesupport/lib/active_support/duration.rb +++ b/activesupport/lib/active_support/duration.rb @@ -7,13 +7,82 @@ module ActiveSupport # # 1.month.ago # equivalent to Time.now.advance(months: -1) class Duration - EPOCH = ::Time.utc(2000) + SECONDS_PER_MINUTE = 60 + SECONDS_PER_HOUR = 3600 + SECONDS_PER_DAY = 86400 + SECONDS_PER_WEEK = 604800 + SECONDS_PER_MONTH = 2629746 # 1/12 of a gregorian year + SECONDS_PER_YEAR = 31556952 # length of a gregorian year (365.2425 days) + + PARTS_IN_SECONDS = { + seconds: 1, + minutes: SECONDS_PER_MINUTE, + hours: SECONDS_PER_HOUR, + days: SECONDS_PER_DAY, + weeks: SECONDS_PER_WEEK, + months: SECONDS_PER_MONTH, + years: SECONDS_PER_YEAR + }.freeze attr_accessor :value, :parts autoload :ISO8601Parser, "active_support/duration/iso8601_parser" autoload :ISO8601Serializer, "active_support/duration/iso8601_serializer" + class << self + # Creates a new Duration from string formatted according to ISO 8601 Duration. + # + # See {ISO 8601}[http://en.wikipedia.org/wiki/ISO_8601#Durations] for more information. + # This method allows negative parts to be present in pattern. + # If invalid string is provided, it will raise +ActiveSupport::Duration::ISO8601Parser::ParsingError+. + def parse(iso8601duration) + parts = ISO8601Parser.new(iso8601duration).parse! + new(calculate_total_seconds(parts), parts) + end + + def ===(other) #:nodoc: + other.is_a?(Duration) + rescue ::NoMethodError + false + end + + def seconds(value) #:nodoc: + new(value, [[:seconds, value]]) + end + + def minutes(value) #:nodoc: + new(value * SECONDS_PER_MINUTE, [[:minutes, value]]) + end + + def hours(value) #:nodoc: + new(value * SECONDS_PER_HOUR, [[:hours, value]]) + end + + def days(value) #:nodoc: + new(value * SECONDS_PER_DAY, [[:days, value]]) + end + + def weeks(value) #:nodoc: + new(value * SECONDS_PER_WEEK, [[:weeks, value]]) + end + + def months(value) #:nodoc: + new(value * SECONDS_PER_MONTH, [[:months, value]]) + end + + def years(value) #:nodoc: + new(value * SECONDS_PER_YEAR, [[:years, value]]) + end + + private + + def calculate_total_seconds(parts) + parts.inject(0) do |total, (part, value)| + total + value * PARTS_IN_SECONDS[part] + end + end + end + def initialize(value, parts) #:nodoc: @value, @parts = value, parts.to_h @parts.default = 0 @@ -78,14 +147,14 @@ module ActiveSupport # 1.day.to_i # => 86400 # # Note that this conversion makes some assumptions about the - # duration of some periods, e.g. months are always 30 days - # and years are 365.25 days: + # duration of some periods, e.g. months are always 1/12 of year + # and years are 365.2425 days: # - # # equivalent to 30.days.to_i - # 1.month.to_i # => 2592000 + # # equivalent to (1.year / 12).to_i + # 1.month.to_i # => 2629746 # - # # equivalent to 365.25.days.to_i - # 1.year.to_i # => 31557600 + # # equivalent to 365.2425.days.to_i + # 1.year.to_i # => 31556952 # # In such cases, Ruby's core # Date[http://ruby-doc.org/stdlib/libdoc/date/rdoc/Date.html] and @@ -105,12 +174,6 @@ module ActiveSupport @value.hash end - def self.===(other) #:nodoc: - other.is_a?(Duration) - rescue ::NoMethodError - false - end - # Calculates a new Time or Date that is as far in the future # as this Duration represents. def since(time = ::Time.current) @@ -141,16 +204,6 @@ module ActiveSupport @value.respond_to?(method, include_private) end - # Creates a new Duration from string formatted according to ISO 8601 Duration. - # - # See {ISO 8601}[http://en.wikipedia.org/wiki/ISO_8601#Durations] for more information. - # This method allows negative parts to be present in pattern. - # If invalid string is provided, it will raise +ActiveSupport::Duration::ISO8601Parser::ParsingError+. - def self.parse(iso8601duration) - parts = ISO8601Parser.new(iso8601duration).parse! - new(EPOCH.advance(parts) - EPOCH, parts) - end - # Build ISO 8601 Duration string for this duration. # The +precision+ parameter can be used to limit seconds' precision of duration. def iso8601(precision: nil) diff --git a/activesupport/lib/active_support/execution_wrapper.rb b/activesupport/lib/active_support/execution_wrapper.rb index 3384d12d5b..ca88e7876b 100644 --- a/activesupport/lib/active_support/execution_wrapper.rb +++ b/activesupport/lib/active_support/execution_wrapper.rb @@ -19,14 +19,14 @@ module ActiveSupport set_callback(:complete, *args, &block) end - class RunHook < Struct.new(:hook) # :nodoc: + RunHook = Struct.new(:hook) do # :nodoc: def before(target) hook_state = target.send(:hook_state) hook_state[hook] = hook.run end end - class CompleteHook < Struct.new(:hook) # :nodoc: + CompleteHook = Struct.new(:hook) do # :nodoc: def before(target) hook_state = target.send(:hook_state) if hook_state.key?(hook) diff --git a/activesupport/lib/active_support/string_inquirer.rb b/activesupport/lib/active_support/string_inquirer.rb index 09e1cbb28d..90eac89c9e 100644 --- a/activesupport/lib/active_support/string_inquirer.rb +++ b/activesupport/lib/active_support/string_inquirer.rb @@ -18,7 +18,7 @@ module ActiveSupport private def respond_to_missing?(method_name, include_private = false) - method_name[-1] == "?" + (method_name[-1] == "?") || super end def method_missing(method_name, *arguments) diff --git a/activesupport/lib/active_support/testing/time_helpers.rb b/activesupport/lib/active_support/testing/time_helpers.rb index e2f008b4b7..07c9be0604 100644 --- a/activesupport/lib/active_support/testing/time_helpers.rb +++ b/activesupport/lib/active_support/testing/time_helpers.rb @@ -10,7 +10,7 @@ module ActiveSupport @stubs = Concurrent::Map.new { |h, k| h[k] = {} } end - def stub_object(object, method_name, return_value) + def stub_object(object, method_name, &block) if stub = stubbing(object, method_name) unstub_object(stub) end @@ -20,7 +20,7 @@ module ActiveSupport @stubs[object.object_id][method_name] = Stub.new(object, method_name, new_name) object.singleton_class.send :alias_method, new_name, method_name - object.define_singleton_method(method_name) { return_value } + object.define_singleton_method(method_name, &block) end def unstub_all! @@ -134,9 +134,9 @@ module ActiveSupport now = date_or_time.to_time.change(usec: 0) end - simple_stubs.stub_object(Time, :now, now) - simple_stubs.stub_object(Date, :today, now.to_date) - simple_stubs.stub_object(DateTime, :now, now.to_datetime) + simple_stubs.stub_object(Time, :now) { at(now.to_i) } + simple_stubs.stub_object(Date, :today) { jd(now.to_date.jd) } + simple_stubs.stub_object(DateTime, :now) { jd(now.to_date.jd, now.hour, now.min, now.sec, Rational(now.utc_offset, 86400)) } if block_given? begin diff --git a/activesupport/test/abstract_unit.rb b/activesupport/test/abstract_unit.rb index 4e564591b4..6b9daf0fe2 100644 --- a/activesupport/test/abstract_unit.rb +++ b/activesupport/test/abstract_unit.rb @@ -3,8 +3,8 @@ ORIG_ARGV = ARGV.dup require "active_support/core_ext/kernel/reporting" silence_warnings do - Encoding.default_internal = "UTF-8" - Encoding.default_external = "UTF-8" + Encoding.default_internal = Encoding::UTF_8 + Encoding.default_external = Encoding::UTF_8 end require "active_support/testing/autorun" diff --git a/activesupport/test/array_inquirer_test.rb b/activesupport/test/array_inquirer_test.rb index 4d3f5b001c..5b2bc82905 100644 --- a/activesupport/test/array_inquirer_test.rb +++ b/activesupport/test/array_inquirer_test.rb @@ -38,4 +38,24 @@ class ArrayInquirerTest < ActiveSupport::TestCase assert_instance_of ActiveSupport::ArrayInquirer, result assert_equal @array_inquirer, result end + + def test_respond_to_fallback_to_array_respond_to + Array.class_eval do + def respond_to_missing?(name, include_private = false) + (name == :foo) || super + end + end + arr = ActiveSupport::ArrayInquirer.new([:x]) + + assert_respond_to arr, :can_you_hear_me? + assert_respond_to arr, :foo + assert_not_respond_to arr, :nope + ensure + Array.class_eval do + undef_method :respond_to_missing? + def respond_to_missing?(name, include_private = false) + super + end + end + end end diff --git a/activesupport/test/core_ext/duration_test.rb b/activesupport/test/core_ext/duration_test.rb index fc0dd41d0e..6a275d1d5b 100644 --- a/activesupport/test/core_ext/duration_test.rb +++ b/activesupport/test/core_ext/duration_test.rb @@ -237,6 +237,29 @@ class DurationTest < ActiveSupport::TestCase assert_equal(1, (61 <=> 1.minute)) end + def test_twelve_months_equals_one_year + assert_equal 12.months, 1.year + end + + def test_thirty_days_does_not_equal_one_month + assert_not_equal 30.days, 1.month + end + + def test_adding_one_month_maintains_day_of_month + (1..11).each do |month| + [1, 14, 28].each do |day| + assert_equal Date.civil(2016, month + 1, day), Date.civil(2016, month, day) + 1.month + end + end + + assert_equal Date.civil(2017, 1, 1), Date.civil(2016, 12, 1) + 1.month + assert_equal Date.civil(2017, 1, 14), Date.civil(2016, 12, 14) + 1.month + assert_equal Date.civil(2017, 1, 28), Date.civil(2016, 12, 28) + 1.month + + assert_equal Date.civil(2015, 2, 28), Date.civil(2015, 1, 31) + 1.month + assert_equal Date.civil(2016, 2, 29), Date.civil(2016, 1, 31) + 1.month + end + # ISO8601 string examples are taken from ISO8601 gem at https://github.com/arnau/ISO8601/blob/b93d466840/spec/iso8601/duration_spec.rb # published under the conditions of MIT license at https://github.com/arnau/ISO8601/blob/b93d466840/LICENSE # @@ -345,6 +368,21 @@ class DurationTest < ActiveSupport::TestCase end end + def test_iso8601_parsing_equivalence_with_numeric_extensions_over_long_periods + with_env_tz eastern_time_zone do + with_tz_default "Eastern Time (US & Canada)" do + assert_equal 3.months, ActiveSupport::Duration.parse("P3M") + assert_equal 3.months.to_i, ActiveSupport::Duration.parse("P3M").to_i + assert_equal 10.months, ActiveSupport::Duration.parse("P10M") + assert_equal 10.months.to_i, ActiveSupport::Duration.parse("P10M").to_i + assert_equal 3.years, ActiveSupport::Duration.parse("P3Y") + assert_equal 3.years.to_i, ActiveSupport::Duration.parse("P3Y").to_i + assert_equal 10.years, ActiveSupport::Duration.parse("P10Y") + assert_equal 10.years.to_i, ActiveSupport::Duration.parse("P10Y").to_i + end + end + end + def test_adding_durations_do_not_hold_prior_states time = Time.parse("Nov 29, 2016") # If the implementation adds and subtracts 3 months, the diff --git a/activesupport/test/core_ext/module_test.rb b/activesupport/test/core_ext/module_test.rb index a4515d1956..5906e5d3d2 100644 --- a/activesupport/test/core_ext/module_test.rb +++ b/activesupport/test/core_ext/module_test.rb @@ -24,7 +24,7 @@ Somewhere = Struct.new(:street, :city) do attr_accessor :name end -class Someone < Struct.new(:name, :place) +Someone = Struct.new(:name, :place) do delegate :street, :city, :to_f, to: :place delegate :name=, to: :place, prefix: true delegate :upcase, to: "place.city" @@ -35,10 +35,10 @@ class Someone < Struct.new(:name, :place) "some_table" end - FAILED_DELEGATE_LINE = __LINE__ + 1 + self::FAILED_DELEGATE_LINE = __LINE__ + 1 delegate :foo, to: :place - FAILED_DELEGATE_LINE_2 = __LINE__ + 1 + self::FAILED_DELEGATE_LINE_2 = __LINE__ + 1 delegate :bar, to: :place, allow_nil: true private diff --git a/activesupport/test/core_ext/numeric_ext_test.rb b/activesupport/test/core_ext/numeric_ext_test.rb index 5361b7b708..5f86bf97c8 100644 --- a/activesupport/test/core_ext/numeric_ext_test.rb +++ b/activesupport/test/core_ext/numeric_ext_test.rb @@ -12,7 +12,7 @@ class NumericExtTimeAndDateTimeTest < ActiveSupport::TestCase 10.minutes => 600, 1.hour + 15.minutes => 4500, 2.days + 4.hours + 30.minutes => 189000, - 5.years + 1.month + 1.fortnight => 161589600 + 5.years + 1.month + 1.fortnight => 161624106 } end @@ -61,10 +61,10 @@ class NumericExtTimeAndDateTimeTest < ActiveSupport::TestCase end def test_duration_after_conversion_is_no_longer_accurate - assert_equal 30.days.to_i.seconds.since(@now), 1.month.to_i.seconds.since(@now) - assert_equal 365.25.days.to_f.seconds.since(@now), 1.year.to_f.seconds.since(@now) - assert_equal 30.days.to_i.seconds.since(@dtnow), 1.month.to_i.seconds.since(@dtnow) - assert_equal 365.25.days.to_f.seconds.since(@dtnow), 1.year.to_f.seconds.since(@dtnow) + assert_equal (1.year / 12).to_i.seconds.since(@now), 1.month.to_i.seconds.since(@now) + assert_equal 365.2425.days.to_f.seconds.since(@now), 1.year.to_f.seconds.since(@now) + assert_equal (1.year / 12).to_i.seconds.since(@dtnow), 1.month.to_i.seconds.since(@dtnow) + assert_equal 365.2425.days.to_f.seconds.since(@dtnow), 1.year.to_f.seconds.since(@dtnow) end def test_add_one_year_to_leap_day diff --git a/activesupport/test/core_ext/string_ext_test.rb b/activesupport/test/core_ext/string_ext_test.rb index 00685cd952..5d90fa2509 100644 --- a/activesupport/test/core_ext/string_ext_test.rb +++ b/activesupport/test/core_ext/string_ext_test.rb @@ -222,7 +222,7 @@ class StringInflectionsTest < ActiveSupport::TestCase original = %{\u205f\u3000 A string surrounded by various unicode spaces, with tabs(\t\t), newlines(\n\n), unicode nextlines(\u0085\u0085) and many spaces( ). \u00a0\u2007} - expected = "A string surrounded by various unicode spaces, " + + expected = "A string surrounded by various unicode spaces, " \ "with tabs( ), newlines( ), unicode nextlines( ) and many spaces( )." # Make sure squish returns what we expect: diff --git a/activesupport/test/json/encoding_test_cases.rb b/activesupport/test/json/encoding_test_cases.rb index 8eac246937..b2f0cf3048 100644 --- a/activesupport/test/json/encoding_test_cases.rb +++ b/activesupport/test/json/encoding_test_cases.rb @@ -23,7 +23,7 @@ module JSONTest end end - class MyStruct < Struct.new(:name, :value) + MyStruct = Struct.new(:name, :value) do def initialize(*) @unused = "unused instance variable" super diff --git a/activesupport/test/string_inquirer_test.rb b/activesupport/test/string_inquirer_test.rb index d41e4d6800..69d01fe26d 100644 --- a/activesupport/test/string_inquirer_test.rb +++ b/activesupport/test/string_inquirer_test.rb @@ -20,4 +20,25 @@ class StringInquirerTest < ActiveSupport::TestCase def test_respond_to assert_respond_to @string_inquirer, :development? end + + def test_respond_to_fallback_to_string_respond_to + String.class_eval do + def respond_to_missing?(name, include_private = false) + (name == :bar) || super + end + end + str = ActiveSupport::StringInquirer.new("hello") + + assert_respond_to str, :are_you_ready? + assert_respond_to str, :bar + assert_not_respond_to str, :nope + + ensure + String.class_eval do + undef_method :respond_to_missing? + def respond_to_missing?(name, include_private = false) + (name == :bar) || super + end + end + end end diff --git a/activesupport/test/time_travel_test.rb b/activesupport/test/time_travel_test.rb index c68be329bc..cfc6447360 100644 --- a/activesupport/test/time_travel_test.rb +++ b/activesupport/test/time_travel_test.rb @@ -3,6 +3,10 @@ require "active_support/core_ext/date_time" require "active_support/core_ext/numeric/time" class TimeTravelTest < ActiveSupport::TestCase + class TimeSubclass < ::Time; end + class DateSubclass < ::Date; end + class DateTimeSubclass < ::DateTime; end + def test_time_helper_travel Time.stub(:now, Time.now) do begin @@ -142,4 +146,19 @@ class TimeTravelTest < ActiveSupport::TestCase end end end + + def test_time_helper_travel_with_time_subclass + assert_equal TimeSubclass, TimeSubclass.now.class + assert_equal DateSubclass, DateSubclass.today.class + assert_equal DateTimeSubclass, DateTimeSubclass.now.class + + travel 1.day do + assert_equal TimeSubclass, TimeSubclass.now.class + assert_equal DateSubclass, DateSubclass.today.class + assert_equal DateTimeSubclass, DateTimeSubclass.now.class + assert_equal Time.now.to_s, TimeSubclass.now.to_s + assert_equal Date.today.to_s, DateSubclass.today.to_s + assert_equal DateTime.now.to_s, DateTimeSubclass.now.to_s + end + end end diff --git a/guides/source/5_0_release_notes.md b/guides/source/5_0_release_notes.md index 39753cbd6f..24fb0ca6e1 100644 --- a/guides/source/5_0_release_notes.md +++ b/guides/source/5_0_release_notes.md @@ -499,6 +499,9 @@ Please refer to the [Changelog][action-view] for detailed changes. `datetime-local`. ([Pull Request](https://github.com/rails/rails/pull/25469)) +* Allow blocks while rendering with the `render partial:` helper. + ([Pull Request](https://github.com/rails/rails/pull/17974)) + Action Mailer ------------- diff --git a/guides/source/debugging_rails_applications.md b/guides/source/debugging_rails_applications.md index df3003a6a8..ba0cdbf3af 100644 --- a/guides/source/debugging_rails_applications.md +++ b/guides/source/debugging_rails_applications.md @@ -683,7 +683,7 @@ Ruby instruction to be executed -- in this case, Active Support's `week` method. 51: # 52: # 2.weeks # => 14 days 53: def weeks -=> 54: ActiveSupport::Duration.new(self * 7.days, [[:days, self * 7]]) +=> 54: ActiveSupport::Duration.weeks(self) 55: end 56: alias :week :weeks 57: diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index f96432c89f..1a6aed7ce4 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -72,7 +72,7 @@ module Rails # on one of the applications to create a copy of the application which shares # the configuration. # - # If you decide to define rake tasks, runners, or initializers in an + # If you decide to define Rake tasks, runners, or initializers in an # application other than +Rails.application+, then you must run them manually. class Application < Engine autoload :Bootstrap, "rails/application/bootstrap" @@ -265,8 +265,8 @@ module Rails end end - # If you try to define a set of rake tasks on the instance, these will get - # passed up to the rake tasks defined on the application's class. + # If you try to define a set of Rake tasks on the instance, these will get + # passed up to the Rake tasks defined on the application's class. def rake_tasks(&block) self.class.rake_tasks(&block) end @@ -511,7 +511,7 @@ module Rails def validate_secret_key_config! #:nodoc: if secrets.secret_key_base.blank? - ActiveSupport::Deprecation.warn "You didn't set `secret_key_base`. " + + ActiveSupport::Deprecation.warn "You didn't set `secret_key_base`. " \ "Read the upgrade documentation to learn more about this new config option." if secrets.secret_token.blank? diff --git a/railties/lib/rails/application/bootstrap.rb b/railties/lib/rails/application/bootstrap.rb index 11da271501..6102af3fff 100644 --- a/railties/lib/rails/application/bootstrap.rb +++ b/railties/lib/rails/application/bootstrap.rb @@ -48,8 +48,8 @@ INFO logger = ActiveSupport::TaggedLogging.new(ActiveSupport::Logger.new(STDERR)) logger.level = ActiveSupport::Logger::WARN logger.warn( - "Rails Error: Unable to access log file. Please ensure that #{path} exists and is writable " + - "(ie, make it writable for user and group: chmod 0664 #{path}). " + + "Rails Error: Unable to access log file. Please ensure that #{path} exists and is writable " \ + "(ie, make it writable for user and group: chmod 0664 #{path}). " \ "The log level has been raised to WARN and the output directed to STDERR until the problem is fixed." ) logger diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb index 0226c0ffe5..b0d33f87a3 100644 --- a/railties/lib/rails/application/configuration.rb +++ b/railties/lib/rails/application/configuration.rb @@ -3,8 +3,6 @@ require "active_support/file_update_checker" require "rails/engine/configuration" require "rails/source_annotation_extractor" -require "active_support/deprecation" - module Rails class Application class Configuration < ::Rails::Engine::Configuration @@ -22,7 +20,7 @@ module Rails def initialize(*) super - self.encoding = "utf-8" + self.encoding = Encoding::UTF_8 @allow_concurrency = nil @consider_all_requests_local = false @filter_parameters = [] diff --git a/railties/lib/rails/command.rb b/railties/lib/rails/command.rb index ddb953543f..9012ceb274 100644 --- a/railties/lib/rails/command.rb +++ b/railties/lib/rails/command.rb @@ -37,7 +37,7 @@ module Rails end end - # Rails finds namespaces similar to thor, it only adds one rule: + # Rails finds namespaces similar to Thor, it only adds one rule: # # Command names must end with "_command.rb". This is required because Rails # looks in load paths and loads the command just before it's going to be used. diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb index 12b4f06c27..13af6051ce 100644 --- a/railties/lib/rails/engine.rb +++ b/railties/lib/rails/engine.rb @@ -109,7 +109,7 @@ module Rails # # == Endpoint # - # An engine can also be a rack application. It can be useful if you have a rack application that + # An engine can also be a Rack application. It can be useful if you have a Rack application that # you would like to wrap with +Engine+ and provide with some of the +Engine+'s features. # # To do that, use the +endpoint+ method: @@ -128,7 +128,7 @@ module Rails # # == Middleware stack # - # As an engine can now be a rack endpoint, it can also have a middleware + # As an engine can now be a Rack endpoint, it can also have a middleware # stack. The usage is exactly the same as in <tt>Application</tt>: # # module MyEngine @@ -499,7 +499,7 @@ module Rails paths["app/helpers"].existent end - # Returns the underlying rack application for this engine. + # Returns the underlying Rack application for this engine. def app @app || @app_build_lock.synchronize { @app ||= begin @@ -549,7 +549,7 @@ module Rails load(seed_file) if seed_file end - # Add configured load paths to ruby load paths and remove duplicates. + # Add configured load paths to Ruby's load path, and remove duplicate entries. initializer :set_load_path, before: :bootstrap_hook do _all_load_paths.reverse_each do |path| $LOAD_PATH.unshift(path) if File.directory?(path) diff --git a/railties/lib/rails/generators.rb b/railties/lib/rails/generators.rb index e1980a42ad..99bda728ee 100644 --- a/railties/lib/rails/generators.rb +++ b/railties/lib/rails/generators.rb @@ -218,7 +218,7 @@ module Rails [[ "rails", rails ]] + groups.sort.to_a end - # Rails finds namespaces similar to thor, it only adds one rule: + # Rails finds namespaces similar to Thor, it only adds one rule: # # Generators names must end with "_generator.rb". This is required because Rails # looks in load paths and loads the generator just before it's going to be used. diff --git a/railties/lib/rails/generators/actions/create_migration.rb b/railties/lib/rails/generators/actions/create_migration.rb index f677e545e5..d06609e91e 100644 --- a/railties/lib/rails/generators/actions/create_migration.rb +++ b/railties/lib/rails/generators/actions/create_migration.rb @@ -54,8 +54,8 @@ module Rails say_status :skip, :yellow else say_status :conflict, :red - raise Error, "Another migration is already named #{migration_file_name}: " + - "#{existing_migration}. Use --force to replace this migration " + + raise Error, "Another migration is already named #{migration_file_name}: " \ + "#{existing_migration}. Use --force to replace this migration " \ "or --skip to ignore conflicted file." end end diff --git a/railties/lib/rails/generators/base.rb b/railties/lib/rails/generators/base.rb index ba031d7b5d..a650c52626 100644 --- a/railties/lib/rails/generators/base.rb +++ b/railties/lib/rails/generators/base.rb @@ -256,8 +256,8 @@ module Rails last = extract_last_module(nesting) if last && last.const_defined?(last_name.camelize, false) - raise Error, "The name '#{class_name}' is either already used in your application " << - "or reserved by Ruby on Rails. Please choose an alternative and run " << + raise Error, "The name '#{class_name}' is either already used in your application " \ + "or reserved by Ruby on Rails. Please choose an alternative and run " \ "this generator again." end end diff --git a/railties/lib/rails/generators/rails/plugin/plugin_generator.rb b/railties/lib/rails/generators/rails/plugin/plugin_generator.rb index 4cf4f8cd9a..22604d4d9d 100644 --- a/railties/lib/rails/generators/rails/plugin/plugin_generator.rb +++ b/railties/lib/rails/generators/rails/plugin/plugin_generator.rb @@ -186,7 +186,7 @@ task default: :test desc: "Skip gemspec file" class_option :skip_gemfile_entry, type: :boolean, default: false, - desc: "If creating plugin in application's directory " + + desc: "If creating plugin in application's directory " \ "skip adding entry to Gemfile" class_option :api, type: :boolean, default: false, @@ -415,7 +415,6 @@ task default: :test require 'rake/testtask' Rake::TestTask.new(:test) do |t| - t.libs << 'lib' t.libs << 'test' t.pattern = 'test/**/*_test.rb' t.verbose = false diff --git a/railties/lib/rails/info.rb b/railties/lib/rails/info.rb index 5d4acd6f6b..fc064dac32 100644 --- a/railties/lib/rails/info.rb +++ b/railties/lib/rails/info.rb @@ -1,9 +1,9 @@ require "cgi" module Rails - # This module helps build the runtime properties used to display in the - # Rails::InfoController responses. Including the active Rails version, Ruby - # version, Rack version, and so on. + # This module helps build the runtime properties that are displayed in + # Rails::InfoController responses. These include the active Rails version, + # Ruby version, Rack version, and so on. module Info mattr_accessor :properties class << (@@properties = []) diff --git a/railties/lib/rails/paths.rb b/railties/lib/rails/paths.rb index 10925de8b2..af3be10a31 100644 --- a/railties/lib/rails/paths.rb +++ b/railties/lib/rails/paths.rb @@ -2,12 +2,12 @@ module Rails module Paths # This object is an extended hash that behaves as root of the <tt>Rails::Paths</tt> system. # It allows you to collect information about how you want to structure your application - # paths by a Hash like API. It requires you to give a physical path on initialization. + # paths through a Hash-like API. It requires you to give a physical path on initialization. # # root = Root.new "/rails" # root.add "app/controllers", eager_load: true # - # The command above creates a new root object and adds "app/controllers" as a path. + # The above command creates a new root object and adds "app/controllers" as a path. # This means we can get a <tt>Rails::Paths::Path</tt> object back like below: # # path = root["app/controllers"] diff --git a/railties/lib/rails/source_annotation_extractor.rb b/railties/lib/rails/source_annotation_extractor.rb index 3a48c4c496..e9088c44ce 100644 --- a/railties/lib/rails/source_annotation_extractor.rb +++ b/railties/lib/rails/source_annotation_extractor.rb @@ -13,7 +13,7 @@ # start with the tag optionally followed by a colon. Everything up to the end # of the line (or closing ERB comment tag) is considered to be their text. class SourceAnnotationExtractor - class Annotation < Struct.new(:line, :tag, :text) + Annotation = Struct.new(:line, :tag, :text) do def self.directories @@directories ||= %w(app config db lib test) + (ENV["SOURCE_ANNOTATION_DIRECTORIES"] || "").split(",") end diff --git a/railties/lib/rails/tasks/framework.rake b/railties/lib/rails/tasks/framework.rake index d42d001b1a..f5586b53f0 100644 --- a/railties/lib/rails/tasks/framework.rake +++ b/railties/lib/rails/tasks/framework.rake @@ -1,5 +1,3 @@ -require "active_support/deprecation" - namespace :app do desc "Update configs and some other initially generated files (or use just update:configs or update:bin)" task update: [ "update:configs", "update:bin", "update:upgrade_guide_info" ] diff --git a/railties/lib/rails/tasks/routes.rake b/railties/lib/rails/tasks/routes.rake index 04daaf4a83..215fb2ceb5 100644 --- a/railties/lib/rails/tasks/routes.rake +++ b/railties/lib/rails/tasks/routes.rake @@ -1,5 +1,3 @@ -require "active_support/deprecation" -require "active_support/core_ext/string/strip" # for strip_heredoc require "optparse" desc "Print out all defined routes in match order, with names. Target specific controller with -c option, or grep routes using -g option" diff --git a/railties/test/rack_logger_test.rb b/railties/test/rack_logger_test.rb index 7dd91a2465..33b4bc6a3a 100644 --- a/railties/test/rack_logger_test.rb +++ b/railties/test/rack_logger_test.rb @@ -20,7 +20,7 @@ module Rails def development?; false; end end - class Subscriber < Struct.new(:starts, :finishes) + Subscriber = Struct.new(:starts, :finishes) do def initialize(starts = [], finishes = []) super end |