diff options
Diffstat (limited to 'actionview')
102 files changed, 1050 insertions, 852 deletions
diff --git a/actionview/CHANGELOG.md b/actionview/CHANGELOG.md index f2ae74454a..5bc93fcb5b 100644 --- a/actionview/CHANGELOG.md +++ b/actionview/CHANGELOG.md @@ -1,197 +1,29 @@ -* Remove the option `encode_special_chars` misnomer from `strip_tags` +* Add `srcset` option to `image_tag` helper. - As of rails-html-sanitizer v1.0.3 sanitizer will ignore the - `encode_special_chars` option. Fixes #28060. + *Roberto Miranda* - *Andrew Hood* +* Fix issues with scopes and engine on `current_page?` method. -## Rails 5.1.0.beta1 (February 23, 2017) ## + Fixes #29401. -* Change the ERB handler from Erubis to Erubi. + *Nikita Savrov* - Erubi is an Erubis fork that's svelte, simple, and currently maintained. - Plus it supports `--enable-frozen-string-literal` in Ruby 2.3+. +* Generate field ids in `collection_check_boxes` and `collection_radio_buttons`. - Compatibility: Drops support for `<%===` tags for debug output. - These were an unused, undocumented side effect of the Erubis - implementation. + This makes sure that the labels are linked up with the fields. - Deprecation: The Erubis handler will be removed in Rails 5.2, for the - handful of folks using it directly. - - *Jeremy Evans* - -* 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* - -* Return correct object name in form helper method after `fields_for`. - - Fixes #26931. + Fixes #29014. *Yuji Yaginuma* -* Use `ActionView::Resolver.caching?` (`config.action_view.cache_template_loading`) - to enable template recompilation. - - Before it was enabled by `consider_all_requests_local`, which caused - recompilation in tests. - - *Max Melentiev* - -* Add `form_with` to unify `form_tag` and `form_for` usage. - - Used like `form_tag` (where just the open tag is output): - - ```erb - <%= form_with scope: :post, url: super_special_posts_path %> - ``` - - Used like `form_for`: - - ```erb - <%= form_with model: @post do |form| %> - <%= form.text_field :title %> - <% end %> - ``` - - *Kasper Timm Hansen*, *Marek Kirejczyk* - -* Add `fields` form helper method. - - ```erb - <%= fields :comment, model: @comment do |fields| %> - <%= fields.text_field :title %> - <% end %> - ``` - - Can also be used within form helpers such as `form_with`. - - *Kasper Timm Hansen* - -* Removed deprecated `#original_exception` in `ActionView::Template::Error`. - - *Rafael Mendonça França* - -* Render now accepts any keys for locals, including reserved keywords. - - Only locals with valid variable names get set directly. Others - will still be available in `local_assigns`. - - Example of render with reserved keywords: - - ```erb - <%= render "example", class: "text-center", message: "Hello world!" %> - - <!-- _example.html.erb: --> - <%= tag.div class: local_assigns[:class] do %> - <p><%= message %></p> - <% end %> - ``` - - *Peter Schilling*, *Matthew Draper* - -* Show cache hits and misses when rendering partials. - - Partials using the `cache` helper will show whether a render hit or missed - the cache: - - ``` - Rendered messages/_message.html.erb in 1.2 ms [cache hit] - Rendered recordings/threads/_thread.html.erb in 1.5 ms [cache miss] - ``` - - This removes the need for the old fragment cache logging: - - ``` - Read fragment views/v1/2914079/v1/2914079/recordings/70182313-20160225015037000000/d0bdf2974e1ef6d31685c3b392ad0b74 (0.6ms) - Rendered messages/_message.html.erb in 1.2 ms [cache hit] - Write fragment views/v1/2914079/v1/2914079/recordings/70182313-20160225015037000000/3b4e249ac9d168c617e32e84b99218b5 (1.1ms) - Rendered recordings/threads/_thread.html.erb in 1.5 ms [cache miss] - ``` - - Though that full output can be reenabled with - `config.action_controller.enable_fragment_cache_logging = true`. - - *Stan Lo* - -* Changed partial rendering with a collection to allow collections which - implement `to_a`. - - Extracting the collection option had an optimization to avoid unnecessary - queries of ActiveRecord Relations by calling `#to_ary` on the given - collection. Instances of `Enumerator` or `Enumerable` are valid - collections, but they do not implement `#to_ary`. By changing this to - `#to_a`, they will now be extracted and rendered as expected. - - *Steven Harman* - -* New syntax for tag helpers. Avoid positional parameters and support HTML5 by default. - Example usage of tag helpers before: - - ```ruby - tag(:br, nil, true) - content_tag(:div, content_tag(:p, "Hello world!"), class: "strong") - - <%= content_tag :div, class: "strong" do -%> - Hello world! - <% end -%> - ``` - - Example usage of tag helpers after: - - ```ruby - tag.br - tag.div tag.p("Hello world!"), class: "strong" - - <%= tag.div class: "strong" do %> - Hello world! - <% end %> - ``` - - *Marek Kirejczyk*, *Kasper Timm Hansen* - -* Change `datetime_field` and `datetime_field_tag` to generate `datetime-local` fields. - - As a new specification of the HTML 5 the text field type `datetime` will no longer exist - and it is recommended to use `datetime-local`. - Ref: https://html.spec.whatwg.org/multipage/forms.html#local-date-and-time-state-(type=datetime-local) - - *Herminio Torres* - -* Raw template handler (which is also the default template handler in Rails 5) now outputs - HTML-safe strings. - - In Rails 5 the default template handler was changed to the raw template handler. Because - the ERB template handler escaped strings by default this broke some applications that - expected plain JS or HTML files to be rendered unescaped. This fixes the issue caused - by changing the default handler by changing the Raw template handler to output HTML-safe - strings. - - *Eileen M. Uchitelle* - -* `select_tag`'s `include_blank` option for generation for blank option tag, now adds an empty space label, - when the value as well as content for option tag are empty, so that we conform with html specification. - Ref: https://www.w3.org/TR/html5/forms.html#the-option-element. - - Generation of option before: +* Add `:json` type to `auto_discovery_link_tag` to support [JSON Feeds](https://jsonfeed.org/version/1) - ```html - <option value=""></option> - ``` + *Mike Gunderloy* - Generation of option after: +* Update `distance_of_time_in_words` helper to display better error messages + for bad input. - ```html - <option value="" label=" "></option> - ``` + *Jay Hayes* - *Vipul A M* -Please check [5-0-stable](https://github.com/rails/rails/blob/5-0-stable/actionview/CHANGELOG.md) for previous changes. +Please check [5-1-stable](https://github.com/rails/rails/blob/5-1-stable/actionview/CHANGELOG.md) for previous changes. diff --git a/actionview/Rakefile b/actionview/Rakefile index 00ab92129d..0fc38e8db4 100644 --- a/actionview/Rakefile +++ b/actionview/Rakefile @@ -1,10 +1,11 @@ require "rake/testtask" require "fileutils" +require "open3" desc "Default Task" task default: :test -task package: "assets:compile" +task package: %w( assets:compile assets:verify ) # Run the unit tests @@ -84,12 +85,50 @@ namespace :assets do desc "Compile Action View assets" task :compile do require "blade" + require "sprockets" + require "sprockets/export" Blade.build end + + desc "Verify compiled Action View assets" + task :verify do + file = "lib/assets/compiled/rails-ujs.js" + pathname = Pathname.new("#{__dir__}/#{file}") + + print "[verify] #{file} exists " + if pathname.exist? + puts "[OK]" + else + $stderr.puts "[FAIL]" + fail + end + + print "[verify] #{file} is a UMD module " + if pathname.read =~ /module\.exports.*define\.amd/m + puts "[OK]" + else + $stderr.puts "[FAIL]" + fail + end + + print "[verify] #{__dir__} can be required as a module " + js = <<-JS + window = { Event: class {} } + class Element {} + require('#{__dir__}') + JS + _, stderr, status = Open3.capture3("node", "--print", js) + if status.success? + puts "[OK]" + else + $stderr.puts "[FAIL]\n#{stderr}" + fail + end + end end task :lines do - load File.expand_path("..", File.dirname(__FILE__)) + "/tools/line_statistics" + load File.join(File.expand_path("..", __dir__), "/tools/line_statistics") files = FileList["lib/**/*.rb"] CodeTools::LineStatistics.new(files).print_loc end diff --git a/actionview/actionview.gemspec b/actionview/actionview.gemspec index cfaa5007a1..48e79c53ca 100644 --- a/actionview/actionview.gemspec +++ b/actionview/actionview.gemspec @@ -1,4 +1,4 @@ -version = File.read(File.expand_path("../../RAILS_VERSION", __FILE__)).strip +version = File.read(File.expand_path("../RAILS_VERSION", __dir__)).strip Gem::Specification.new do |s| s.platform = Gem::Platform::RUBY @@ -19,6 +19,11 @@ Gem::Specification.new do |s| s.require_path = "lib" s.requirements << "none" + s.metadata = { + "source_code_uri" => "https://github.com/rails/rails/tree/v#{version}/actionview", + "changelog_uri" => "https://github.com/rails/rails/blob/v#{version}/actionview/CHANGELOG.md" + } + s.add_dependency "activesupport", version s.add_dependency "builder", "~> 3.1" diff --git a/actionview/app/assets/javascripts/README.md b/actionview/app/assets/javascripts/README.md index 92f3e8a3b3..f321b9f720 100644 --- a/actionview/app/assets/javascripts/README.md +++ b/actionview/app/assets/javascripts/README.md @@ -30,16 +30,27 @@ Run `yarn add rails-ujs` to install the rails-ujs package. Usage ------------ -Require `rails-ujs` into your application.js manifest. +Require `rails-ujs` in your application.js manifest. ```javascript //= require rails-ujs ``` +Usage with yarn +------------ + +When using with the Webpacker gem or your preferred JavaScript bundler, just +add the following to your main JS file and compile. + +```javascript +import Rails from 'rails-ujs'; +Rails.start() +``` + How to run tests ------------ -Run `bundle exec rake ujs:server` first, and then run the web tests by visiting [[http://localhost:4567]] in your browser. +Run `bundle exec rake ujs:server` first, and then run the web tests by visiting http://localhost:4567 in your browser. ## License rails-ujs is released under the [MIT License](MIT-LICENSE). diff --git a/actionview/app/assets/javascripts/config.coffee b/actionview/app/assets/javascripts/config.coffee deleted file mode 100644 index a93325e903..0000000000 --- a/actionview/app/assets/javascripts/config.coffee +++ /dev/null @@ -1,34 +0,0 @@ -#= export Rails - -@Rails = - # Link elements bound by rails-ujs - linkClickSelector: 'a[data-confirm], a[data-method], a[data-remote]:not([disabled]), a[data-disable-with], a[data-disable]' - - # Button elements bound by rails-ujs - buttonClickSelector: - selector: 'button[data-remote]:not([form]), button[data-confirm]:not([form])' - exclude: 'form button' - - # Select elements bound by rails-ujs - inputChangeSelector: 'select[data-remote], input[data-remote], textarea[data-remote]' - - # Form elements bound by rails-ujs - formSubmitSelector: 'form' - - # Form input elements bound by rails-ujs - formInputClickSelector: 'form input[type=submit], form input[type=image], form button[type=submit], form button:not([type]), input[type=submit][form], input[type=image][form], button[type=submit][form], button[form]:not([type])' - - # Form input elements disabled during form submission - formDisableSelector: 'input[data-disable-with]:enabled, button[data-disable-with]:enabled, textarea[data-disable-with]:enabled, input[data-disable]:enabled, button[data-disable]:enabled, textarea[data-disable]:enabled' - - # Form input elements re-enabled after form submission - formEnableSelector: 'input[data-disable-with]:disabled, button[data-disable-with]:disabled, textarea[data-disable-with]:disabled, input[data-disable]:disabled, button[data-disable]:disabled, textarea[data-disable]:disabled' - - # Form file input elements - fileInputSelector: 'input[name][type=file]:not([disabled])' - - # Link onClick disable selector with possible reenable after remote submission - linkDisableSelector: 'a[data-disable-with], a[data-disable]' - - # Button onClick disable selector with possible reenable after remote submission - buttonDisableSelector: 'button[data-remote][data-disable-with], button[data-remote][data-disable]' diff --git a/actionview/app/assets/javascripts/rails-ujs.coffee b/actionview/app/assets/javascripts/rails-ujs.coffee index df889ce067..bd6e9bb881 100644 --- a/actionview/app/assets/javascripts/rails-ujs.coffee +++ b/actionview/app/assets/javascripts/rails-ujs.coffee @@ -1,75 +1,39 @@ -# -# Unobtrusive JavaScript -# https://github.com/rails/rails-ujs -# -# Released under the MIT license -# -#= require ./config -#= require_tree ./utils -#= require_tree ./features +#= require ./rails-ujs/BANNER +#= export Rails +#= require_self +#= require_tree ./rails-ujs/utils +#= require_tree ./rails-ujs/features +#= require ./rails-ujs/start -{ - fire, delegate - getData, $ - refreshCSRFTokens, CSRFProtection - enableElement, disableElement - handleConfirm - handleRemote, formSubmitButtonClick, handleMetaClick - handleMethod -} = Rails +@Rails = + # Link elements bound by rails-ujs + linkClickSelector: 'a[data-confirm], a[data-method], a[data-remote]:not([disabled]), a[data-disable-with], a[data-disable]' -# For backward compatibility -if jQuery? and not jQuery.rails - jQuery.rails = Rails - jQuery.ajaxPrefilter (options, originalOptions, xhr) -> - CSRFProtection(xhr) unless options.crossDomain + # Button elements bound by rails-ujs + buttonClickSelector: + selector: 'button[data-remote]:not([form]), button[data-confirm]:not([form])' + exclude: 'form button' -Rails.start = -> - # Cut down on the number of issues from people inadvertently including - # rails-ujs twice by detecting and raising an error when it happens. - throw new Error('rails-ujs has already been loaded!') if window._rails_loaded + # Select elements bound by rails-ujs + inputChangeSelector: 'select[data-remote], input[data-remote], textarea[data-remote]' - # This event works the same as the load event, except that it fires every - # time the page is loaded. - # See https://github.com/rails/jquery-ujs/issues/357 - # See https://developer.mozilla.org/en-US/docs/Using_Firefox_1.5_caching - window.addEventListener 'pageshow', -> - $(Rails.formEnableSelector).forEach (el) -> - enableElement(el) if getData(el, 'ujs:disabled') - $(Rails.linkDisableSelector).forEach (el) -> - enableElement(el) if getData(el, 'ujs:disabled') + # Form elements bound by rails-ujs + formSubmitSelector: 'form' - delegate document, Rails.linkDisableSelector, 'ajax:complete', enableElement - delegate document, Rails.linkDisableSelector, 'ajax:stopped', enableElement - delegate document, Rails.buttonDisableSelector, 'ajax:complete', enableElement - delegate document, Rails.buttonDisableSelector, 'ajax:stopped', enableElement + # Form input elements bound by rails-ujs + formInputClickSelector: 'form input[type=submit], form input[type=image], form button[type=submit], form button:not([type]), input[type=submit][form], input[type=image][form], button[type=submit][form], button[form]:not([type])' - delegate document, Rails.linkClickSelector, 'click', handleConfirm - delegate document, Rails.linkClickSelector, 'click', handleMetaClick - delegate document, Rails.linkClickSelector, 'click', disableElement - delegate document, Rails.linkClickSelector, 'click', handleRemote - delegate document, Rails.linkClickSelector, 'click', handleMethod + # Form input elements disabled during form submission + formDisableSelector: 'input[data-disable-with]:enabled, button[data-disable-with]:enabled, textarea[data-disable-with]:enabled, input[data-disable]:enabled, button[data-disable]:enabled, textarea[data-disable]:enabled' - delegate document, Rails.buttonClickSelector, 'click', handleConfirm - delegate document, Rails.buttonClickSelector, 'click', disableElement - delegate document, Rails.buttonClickSelector, 'click', handleRemote + # Form input elements re-enabled after form submission + formEnableSelector: 'input[data-disable-with]:disabled, button[data-disable-with]:disabled, textarea[data-disable-with]:disabled, input[data-disable]:disabled, button[data-disable]:disabled, textarea[data-disable]:disabled' - delegate document, Rails.inputChangeSelector, 'change', handleConfirm - delegate document, Rails.inputChangeSelector, 'change', handleRemote + # Form file input elements + fileInputSelector: 'input[name][type=file]:not([disabled])' - delegate document, Rails.formSubmitSelector, 'submit', handleConfirm - delegate document, Rails.formSubmitSelector, 'submit', handleRemote - # Normal mode submit - # Slight timeout so that the submit button gets properly serialized - delegate document, Rails.formSubmitSelector, 'submit', (e) -> setTimeout((-> disableElement(e)), 13) - delegate document, Rails.formSubmitSelector, 'ajax:send', disableElement - delegate document, Rails.formSubmitSelector, 'ajax:complete', enableElement + # Link onClick disable selector with possible reenable after remote submission + linkDisableSelector: 'a[data-disable-with], a[data-disable]' - delegate document, Rails.formInputClickSelector, 'click', handleConfirm - delegate document, Rails.formInputClickSelector, 'click', formSubmitButtonClick - - document.addEventListener('DOMContentLoaded', refreshCSRFTokens) - window._rails_loaded = true - -if window.Rails is Rails and fire(document, 'rails:attachBindings') - Rails.start() + # Button onClick disable selector with possible reenable after remote submission + buttonDisableSelector: 'button[data-remote][data-disable-with], button[data-remote][data-disable]' diff --git a/actionview/app/assets/javascripts/rails-ujs/BANNER.js b/actionview/app/assets/javascripts/rails-ujs/BANNER.js new file mode 100644 index 0000000000..47ecd66003 --- /dev/null +++ b/actionview/app/assets/javascripts/rails-ujs/BANNER.js @@ -0,0 +1,5 @@ +/* +Unobtrusive JavaScript +https://github.com/rails/rails/blob/master/actionview/app/assets/javascripts +Released under the MIT license + */ diff --git a/actionview/app/assets/javascripts/features/confirm.coffee b/actionview/app/assets/javascripts/rails-ujs/features/confirm.coffee index 72b5aaa218..72b5aaa218 100644 --- a/actionview/app/assets/javascripts/features/confirm.coffee +++ b/actionview/app/assets/javascripts/rails-ujs/features/confirm.coffee diff --git a/actionview/app/assets/javascripts/features/disable.coffee b/actionview/app/assets/javascripts/rails-ujs/features/disable.coffee index e8cce7da40..90aa3bdf0e 100644 --- a/actionview/app/assets/javascripts/features/disable.coffee +++ b/actionview/app/assets/javascripts/rails-ujs/features/disable.coffee @@ -2,6 +2,10 @@ { matches, getData, setData, stopEverything, formElements } = Rails +Rails.handleDisabledElement = (e) -> + element = this + stopEverything(e) if element.disabled + # Unified function to enable an element (link, button and form) Rails.enableElement = (e) -> element = if e instanceof Event then e.target else e diff --git a/actionview/app/assets/javascripts/features/method.coffee b/actionview/app/assets/javascripts/rails-ujs/features/method.coffee index d04d9414dd..d04d9414dd 100644 --- a/actionview/app/assets/javascripts/features/method.coffee +++ b/actionview/app/assets/javascripts/rails-ujs/features/method.coffee diff --git a/actionview/app/assets/javascripts/features/remote.coffee b/actionview/app/assets/javascripts/rails-ujs/features/remote.coffee index 852587042c..852587042c 100644 --- a/actionview/app/assets/javascripts/features/remote.coffee +++ b/actionview/app/assets/javascripts/rails-ujs/features/remote.coffee diff --git a/actionview/app/assets/javascripts/rails-ujs/start.coffee b/actionview/app/assets/javascripts/rails-ujs/start.coffee new file mode 100644 index 0000000000..55595ac96f --- /dev/null +++ b/actionview/app/assets/javascripts/rails-ujs/start.coffee @@ -0,0 +1,70 @@ +{ + fire, delegate + getData, $ + refreshCSRFTokens, CSRFProtection + enableElement, disableElement, handleDisabledElement + handleConfirm + handleRemote, formSubmitButtonClick, handleMetaClick + handleMethod +} = Rails + +# For backward compatibility +if jQuery? and jQuery.ajax? and not jQuery.rails + jQuery.rails = Rails + jQuery.ajaxPrefilter (options, originalOptions, xhr) -> + CSRFProtection(xhr) unless options.crossDomain + +Rails.start = -> + # Cut down on the number of issues from people inadvertently including + # rails-ujs twice by detecting and raising an error when it happens. + throw new Error('rails-ujs has already been loaded!') if window._rails_loaded + + # This event works the same as the load event, except that it fires every + # time the page is loaded. + # See https://github.com/rails/jquery-ujs/issues/357 + # See https://developer.mozilla.org/en-US/docs/Using_Firefox_1.5_caching + window.addEventListener 'pageshow', -> + $(Rails.formEnableSelector).forEach (el) -> + enableElement(el) if getData(el, 'ujs:disabled') + $(Rails.linkDisableSelector).forEach (el) -> + enableElement(el) if getData(el, 'ujs:disabled') + + delegate document, Rails.linkDisableSelector, 'ajax:complete', enableElement + delegate document, Rails.linkDisableSelector, 'ajax:stopped', enableElement + delegate document, Rails.buttonDisableSelector, 'ajax:complete', enableElement + delegate document, Rails.buttonDisableSelector, 'ajax:stopped', enableElement + + delegate document, Rails.linkClickSelector, 'click', handleDisabledElement + delegate document, Rails.linkClickSelector, 'click', handleConfirm + delegate document, Rails.linkClickSelector, 'click', handleMetaClick + delegate document, Rails.linkClickSelector, 'click', disableElement + delegate document, Rails.linkClickSelector, 'click', handleRemote + delegate document, Rails.linkClickSelector, 'click', handleMethod + + delegate document, Rails.buttonClickSelector, 'click', handleDisabledElement + delegate document, Rails.buttonClickSelector, 'click', handleConfirm + delegate document, Rails.buttonClickSelector, 'click', disableElement + delegate document, Rails.buttonClickSelector, 'click', handleRemote + + delegate document, Rails.inputChangeSelector, 'change', handleDisabledElement + delegate document, Rails.inputChangeSelector, 'change', handleConfirm + delegate document, Rails.inputChangeSelector, 'change', handleRemote + + delegate document, Rails.formSubmitSelector, 'submit', handleDisabledElement + delegate document, Rails.formSubmitSelector, 'submit', handleConfirm + delegate document, Rails.formSubmitSelector, 'submit', handleRemote + # Normal mode submit + # Slight timeout so that the submit button gets properly serialized + delegate document, Rails.formSubmitSelector, 'submit', (e) -> setTimeout((-> disableElement(e)), 13) + delegate document, Rails.formSubmitSelector, 'ajax:send', disableElement + delegate document, Rails.formSubmitSelector, 'ajax:complete', enableElement + + delegate document, Rails.formInputClickSelector, 'click', handleDisabledElement + delegate document, Rails.formInputClickSelector, 'click', handleConfirm + delegate document, Rails.formInputClickSelector, 'click', formSubmitButtonClick + + document.addEventListener('DOMContentLoaded', refreshCSRFTokens) + window._rails_loaded = true + +if window.Rails is Rails and fire(document, 'rails:attachBindings') + Rails.start() diff --git a/actionview/app/assets/javascripts/utils/ajax.coffee b/actionview/app/assets/javascripts/rails-ujs/utils/ajax.coffee index 9af515beda..a653d3af3d 100644 --- a/actionview/app/assets/javascripts/utils/ajax.coffee +++ b/actionview/app/assets/javascripts/rails-ujs/utils/ajax.coffee @@ -14,7 +14,7 @@ AcceptHeaders = Rails.ajax = (options) -> options = prepareOptions(options) xhr = createXHR options, -> - response = processResponse(xhr.response, xhr.getResponseHeader('Content-Type')) + response = processResponse(xhr.response ? xhr.responseText, xhr.getResponseHeader('Content-Type')) if xhr.status // 100 == 2 options.success?(response, xhr.statusText, xhr) else @@ -29,6 +29,7 @@ Rails.ajax = (options) -> fire(document, 'ajaxStop') # to be compatible with jQuery.ajax prepareOptions = (options) -> + options.url = options.url or location.href options.type = options.type.toUpperCase() # append data to url if it's a GET request if options.type is 'GET' and options.data @@ -63,10 +64,10 @@ processResponse = (response, type) -> if typeof response is 'string' and typeof type is 'string' if type.match(/\bjson\b/) try response = JSON.parse(response) - else if type.match(/\bjavascript\b/) + else if type.match(/\b(?:java|ecma)script\b/) script = document.createElement('script') - script.innerHTML = response - document.body.appendChild(script) + script.text = response + document.head.appendChild(script).parentNode.removeChild(script) else if type.match(/\b(xml|html|svg)\b/) parser = new DOMParser() type = type.replace(/;.+/, '') # remove something like ';charset=utf-8' diff --git a/actionview/app/assets/javascripts/utils/csrf.coffee b/actionview/app/assets/javascripts/rails-ujs/utils/csrf.coffee index 4eb5ebb414..4eb5ebb414 100644 --- a/actionview/app/assets/javascripts/utils/csrf.coffee +++ b/actionview/app/assets/javascripts/rails-ujs/utils/csrf.coffee diff --git a/actionview/app/assets/javascripts/utils/dom.coffee b/actionview/app/assets/javascripts/rails-ujs/utils/dom.coffee index 6bef618147..6bef618147 100644 --- a/actionview/app/assets/javascripts/utils/dom.coffee +++ b/actionview/app/assets/javascripts/rails-ujs/utils/dom.coffee diff --git a/actionview/app/assets/javascripts/utils/event.coffee b/actionview/app/assets/javascripts/rails-ujs/utils/event.coffee index 8d3ff007ea..8d3ff007ea 100644 --- a/actionview/app/assets/javascripts/utils/event.coffee +++ b/actionview/app/assets/javascripts/rails-ujs/utils/event.coffee diff --git a/actionview/app/assets/javascripts/utils/form.coffee b/actionview/app/assets/javascripts/rails-ujs/utils/form.coffee index 5fa337b518..5fa337b518 100644 --- a/actionview/app/assets/javascripts/utils/form.coffee +++ b/actionview/app/assets/javascripts/rails-ujs/utils/form.coffee diff --git a/actionview/bin/test b/actionview/bin/test index a7beb14b27..470ce93f10 100755 --- a/actionview/bin/test +++ b/actionview/bin/test @@ -1,4 +1,4 @@ #!/usr/bin/env ruby COMPONENT_ROOT = File.expand_path("..", __dir__) -require File.expand_path("../tools/test", COMPONENT_ROOT) +require_relative "../../tools/test" diff --git a/actionview/lib/action_view.rb b/actionview/lib/action_view.rb index ca586f1d52..53a83d48f6 100644 --- a/actionview/lib/action_view.rb +++ b/actionview/lib/action_view.rb @@ -23,7 +23,7 @@ require "active_support" require "active_support/rails" -require "action_view/version" +require_relative "action_view/version" module ActionView extend ActiveSupport::Autoload @@ -92,5 +92,5 @@ end require "active_support/core_ext/string/output_safety" ActiveSupport.on_load(:i18n) do - I18n.load_path << "#{File.dirname(__FILE__)}/action_view/locale/en.yml" + I18n.load_path << File.expand_path("action_view/locale/en.yml", __dir__) end diff --git a/actionview/lib/action_view/base.rb b/actionview/lib/action_view/base.rb index 5387174467..969d300bc1 100644 --- a/actionview/lib/action_view/base.rb +++ b/actionview/lib/action_view/base.rb @@ -1,11 +1,11 @@ require "active_support/core_ext/module/attr_internal" require "active_support/core_ext/module/attribute_accessors" require "active_support/ordered_options" -require "action_view/log_subscriber" -require "action_view/helpers" -require "action_view/context" -require "action_view/template" -require "action_view/lookup_context" +require_relative "log_subscriber" +require_relative "helpers" +require_relative "context" +require_relative "template" +require_relative "lookup_context" module ActionView #:nodoc: # = Action View Base @@ -140,30 +140,25 @@ module ActionView #:nodoc: include Helpers, ::ERB::Util, Context # Specify the proc used to decorate input tags that refer to attributes with errors. - cattr_accessor :field_error_proc - @@field_error_proc = Proc.new { |html_tag, instance| "<div class=\"field_with_errors\">#{html_tag}</div>".html_safe } + cattr_accessor :field_error_proc, default: Proc.new { |html_tag, instance| "<div class=\"field_with_errors\">#{html_tag}</div>".html_safe } # How to complete the streaming when an exception occurs. # This is our best guess: first try to close the attribute, then the tag. - cattr_accessor :streaming_completion_on_exception - @@streaming_completion_on_exception = %("><script>window.location = "/500.html"</script></html>) + cattr_accessor :streaming_completion_on_exception, default: %("><script>window.location = "/500.html"</script></html>) # Specify whether rendering within namespaced controllers should prefix # the partial paths for ActiveModel objects with the namespace. # (e.g., an Admin::PostsController would render @post using /admin/posts/_post.erb) - cattr_accessor :prefix_partial_path_with_controller_namespace - @@prefix_partial_path_with_controller_namespace = true + cattr_accessor :prefix_partial_path_with_controller_namespace, default: true # Specify default_formats that can be rendered. cattr_accessor :default_formats # Specify whether an error should be raised for missing translations - cattr_accessor :raise_on_missing_translations - @@raise_on_missing_translations = false + cattr_accessor :raise_on_missing_translations, default: false # Specify whether submit_tag should automatically disable on click - cattr_accessor :automatically_disable_submit_tag - @@automatically_disable_submit_tag = true + cattr_accessor :automatically_disable_submit_tag, default: true class_attribute :_routes class_attribute :logger @@ -207,6 +202,7 @@ module ActionView #:nodoc: @view_renderer = ActionView::Renderer.new(lookup_context) end + @cache_hit = {} assign(assigns) assign_controller(controller) _prepare_context diff --git a/actionview/lib/action_view/dependency_tracker.rb b/actionview/lib/action_view/dependency_tracker.rb index 451eeec9d6..ee438f9311 100644 --- a/actionview/lib/action_view/dependency_tracker.rb +++ b/actionview/lib/action_view/dependency_tracker.rb @@ -1,5 +1,5 @@ require "concurrent/map" -require "action_view/path_set" +require_relative "path_set" module ActionView class DependencyTracker # :nodoc: diff --git a/actionview/lib/action_view/digestor.rb b/actionview/lib/action_view/digestor.rb index 0658d8601d..00ff36c879 100644 --- a/actionview/lib/action_view/digestor.rb +++ b/actionview/lib/action_view/digestor.rb @@ -1,5 +1,5 @@ require "concurrent/map" -require "action_view/dependency_tracker" +require_relative "dependency_tracker" require "monitor" module ActionView @@ -62,8 +62,10 @@ module ActionView node end else - logger.error " '#{name}' file doesn't exist, so no dependencies" - logger.error " Couldn't find template for digesting: #{name}" + unless name.include?("#") # Dynamic template partial names can never be tracked + logger.error " Couldn't find template for digesting: #{name}" + end + seen[name] ||= Missing.new(name, logical_name, nil) end end diff --git a/actionview/lib/action_view/gem_version.rb b/actionview/lib/action_view/gem_version.rb index 662a85f191..92e21d7a4f 100644 --- a/actionview/lib/action_view/gem_version.rb +++ b/actionview/lib/action_view/gem_version.rb @@ -6,9 +6,9 @@ module ActionView module VERSION MAJOR = 5 - MINOR = 1 + MINOR = 2 TINY = 0 - PRE = "beta1" + PRE = "alpha" STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".") end diff --git a/actionview/lib/action_view/helpers/asset_tag_helper.rb b/actionview/lib/action_view/helpers/asset_tag_helper.rb index 750f96f29e..cc8690e7bc 100644 --- a/actionview/lib/action_view/helpers/asset_tag_helper.rb +++ b/actionview/lib/action_view/helpers/asset_tag_helper.rb @@ -1,7 +1,7 @@ require "active_support/core_ext/array/extract_options" require "active_support/core_ext/hash/keys" -require "action_view/helpers/asset_url_helper" -require "action_view/helpers/tag_helper" +require_relative "asset_url_helper" +require_relative "tag_helper" module ActionView # = Action View Asset Tag Helpers @@ -122,9 +122,9 @@ module ActionView end # Returns a link tag that browsers and feed readers can use to auto-detect - # an RSS or Atom feed. The +type+ can either be <tt>:rss</tt> (default) or - # <tt>:atom</tt>. Control the link options in url_for format using the - # +url_options+. You can modify the LINK tag itself in +tag_options+. + # an RSS, Atom, or JSON feed. The +type+ can be <tt>:rss</tt> (default), + # <tt>:atom</tt>, or <tt>:json</tt>. Control the link options in url_for format + # using the +url_options+. You can modify the LINK tag itself in +tag_options+. # # ==== Options # @@ -138,6 +138,8 @@ module ActionView # # => <link rel="alternate" type="application/rss+xml" title="RSS" href="http://www.currenthost.com/controller/action" /> # auto_discovery_link_tag(:atom) # # => <link rel="alternate" type="application/atom+xml" title="ATOM" href="http://www.currenthost.com/controller/action" /> + # auto_discovery_link_tag(:json) + # # => <link rel="alternate" type="application/json" title="JSON" href="http://www.currenthost.com/controller/action" /> # auto_discovery_link_tag(:rss, {action: "feed"}) # # => <link rel="alternate" type="application/rss+xml" title="RSS" href="http://www.currenthost.com/controller/feed" /> # auto_discovery_link_tag(:rss, {action: "feed"}, {title: "My RSS"}) @@ -147,8 +149,8 @@ module ActionView # auto_discovery_link_tag(:rss, "http://www.example.com/feed.rss", {title: "Example RSS"}) # # => <link rel="alternate" type="application/rss+xml" title="Example RSS" href="http://www.example.com/feed.rss" /> def auto_discovery_link_tag(type = :rss, url_options = {}, tag_options = {}) - if !(type == :rss || type == :atom) && tag_options[:type].blank? - raise ArgumentError.new("You should pass :type tag_option key explicitly, because you have passed #{type} type other than :rss or :atom.") + if !(type == :rss || type == :atom || type == :json) && tag_options[:type].blank? + raise ArgumentError.new("You should pass :type tag_option key explicitly, because you have passed #{type} type other than :rss, :atom, or :json.") end tag( @@ -201,13 +203,15 @@ module ActionView # ==== Options # # You can add HTML attributes using the +options+. The +options+ supports - # two additional keys for convenience and conformance: + # additional keys for convenience and conformance: # # * <tt>:alt</tt> - If no alt text is given, the file name part of the # +source+ is used (capitalized and without the extension) # * <tt>:size</tt> - Supplied as "{Width}x{Height}" or "{Number}", so "30x45" becomes # width="30" and height="45", and "50" becomes width="50" and height="50". # <tt>:size</tt> will be ignored if the value is not in the correct format. + # * <tt>:srcset</tt> - If supplied as a hash or array of <tt>[source, descriptor]</tt> + # pairs, each image path will be expanded before the list is formatted as a string. # # ==== Examples # @@ -225,16 +229,28 @@ module ActionView # # => <img alt="Icon" class="menu_icon" src="/icons/icon.gif" /> # image_tag("/icons/icon.gif", data: { title: 'Rails Application' }) # # => <img data-title="Rails Application" src="/icons/icon.gif" /> + # image_tag("icon.png", srcset: { "icon_2x.png" => "2x", "icon_4x.png" => "4x" }) + # # => <img src="/assets/icon.png" srcset="/assets/icon_2x.png 2x, /assets/icon_4x.png 4x"> + # image_tag("pic.jpg", srcset: [["pic_1024.jpg", "1024w"], ["pic_1980.jpg", "1980w"]], sizes: "100vw") + # # => <img src="/assets/pic.jpg" srcset="/assets/pic_1024.jpg 1024w, /assets/pic_1980.jpg 1980w" sizes="100vw"> def image_tag(source, options = {}) options = options.symbolize_keys check_for_image_tag_errors(options) + skip_pipeline = options.delete(:skip_pipeline) - src = options[:src] = path_to_image(source, skip_pipeline: options.delete(:skip_pipeline)) + src = options[:src] = path_to_image(source, skip_pipeline: skip_pipeline) unless src.start_with?("cid:") || src.start_with?("data:") || src.blank? options[:alt] = options.fetch(:alt) { image_alt(src) } end + if options[:srcset] && !options[:srcset].is_a?(String) + options[:srcset] = options[:srcset].map do |src_path, size| + src_path = path_to_image(src_path, skip_pipeline: skip_pipeline) + "#{src_path} #{size}" + end.join(", ") + end + options[:width], options[:height] = extract_dimensions(options.delete(:size)) if options[:size] tag("img", options) end diff --git a/actionview/lib/action_view/helpers/cache_helper.rb b/actionview/lib/action_view/helpers/cache_helper.rb index 15ab7e304f..b7c7324f31 100644 --- a/actionview/lib/action_view/helpers/cache_helper.rb +++ b/actionview/lib/action_view/helpers/cache_helper.rb @@ -8,10 +8,9 @@ module ActionView # fragments, and so on. This method takes a block that contains # the content you wish to cache. # - # The best way to use this is by doing key-based cache expiration - # on top of a cache store like Memcached that'll automatically - # kick out old entries. For more on key-based expiration, see: - # http://signalvnoise.com/posts/3113-how-key-based-cache-expiration-works + # The best way to use this is by doing recyclable key-based cache expiration + # on top of a cache store like Memcached or Redis that'll automatically + # kick out old entries. # # When using this method, you list the cache dependency as the name of the cache, like so: # @@ -23,10 +22,14 @@ module ActionView # This approach will assume that when a new topic is added, you'll touch # the project. The cache key generated from this call will be something like: # - # views/projects/123-20120806214154/7a1156131a6928cb0026877f8b749ac9 - # ^class ^id ^updated_at ^template tree digest + # views/template/action.html.erb:7a1156131a6928cb0026877f8b749ac9/projects/123 + # ^template path ^template tree digest ^class ^id # - # The cache is thus automatically bumped whenever the project updated_at is touched. + # This cache key is stable, but it's combined with a cache version derived from the project + # record. When the project updated_at is touched, the #cache_version changes, even + # if the key stays stable. This means that unlike a traditional key-based cache expiration + # approach, you won't be generating cache trash, unused keys, simply because the dependent + # record is updated. # # If your template cache depends on multiple sources (try to avoid this to keep things simple), # you can name all these dependencies as part of an array: @@ -211,16 +214,19 @@ module ActionView end end - attr_reader :cache_hit # :nodoc: - private def fragment_name_with_digest(name, virtual_path) virtual_path ||= @virtual_path + if virtual_path name = controller.url_for(name).split("://").last if name.is_a?(Hash) - digest = Digestor.digest name: virtual_path, finder: lookup_context, dependencies: view_cache_dependencies - [ name, digest ] + + if digest = Digestor.digest(name: virtual_path, finder: lookup_context, dependencies: view_cache_dependencies).presence + [ "#{virtual_path}:#{digest}", name ] + else + [ virtual_path, name ] + end else name end @@ -228,10 +234,10 @@ module ActionView def fragment_for(name = {}, options = nil, &block) if content = read_fragment_for(name, options) - @cache_hit = true + @view_renderer.cache_hits[@virtual_path] = :hit if defined?(@view_renderer) content else - @cache_hit = false + @view_renderer.cache_hits[@virtual_path] = :miss if defined?(@view_renderer) write_fragment_for(name, options, &block) end end diff --git a/actionview/lib/action_view/helpers/date_helper.rb b/actionview/lib/action_view/helpers/date_helper.rb index 09dc6ef6bd..3fbed44f7e 100644 --- a/actionview/lib/action_view/helpers/date_helper.rb +++ b/actionview/lib/action_view/helpers/date_helper.rb @@ -1,5 +1,5 @@ require "date" -require "action_view/helpers/tag_helper" +require_relative "tag_helper" require "active_support/core_ext/array/extract_options" require "active_support/core_ext/date/conversions" require "active_support/core_ext/hash/slice" @@ -95,8 +95,8 @@ module ActionView scope: :'datetime.distance_in_words' }.merge!(options) - from_time = from_time.to_time if from_time.respond_to?(:to_time) - to_time = to_time.to_time if to_time.respond_to?(:to_time) + from_time = normalize_distance_of_time_argument_to_time(from_time) + to_time = normalize_distance_of_time_argument_to_time(to_time) from_time, to_time = to_time, from_time if from_time > to_time distance_in_minutes = ((to_time - from_time) / 60.0).round distance_in_seconds = (to_time - from_time).round @@ -130,22 +130,18 @@ module ActionView # 60 days up to 365 days when 86400...525600 then locale.t :x_months, count: (distance_in_minutes.to_f / 43200.0).round else - if from_time.acts_like?(:time) && to_time.acts_like?(:time) - fyear = from_time.year - fyear += 1 if from_time.month >= 3 - tyear = to_time.year - tyear -= 1 if to_time.month < 3 - leap_years = (fyear > tyear) ? 0 : (fyear..tyear).count { |x| Date.leap?(x) } - minute_offset_for_leap_year = leap_years * 1440 - # Discount the leap year days when calculating year distance. - # e.g. if there are 20 leap year days between 2 dates having the same day - # and month then the based on 365 days calculation - # the distance in years will come out to over 80 years when in written - # English it would read better as about 80 years. - minutes_with_offset = distance_in_minutes - minute_offset_for_leap_year - else - minutes_with_offset = distance_in_minutes - end + from_year = from_time.year + from_year += 1 if from_time.month >= 3 + to_year = to_time.year + to_year -= 1 if to_time.month < 3 + leap_years = (from_year > to_year) ? 0 : (from_year..to_year).count { |x| Date.leap?(x) } + minute_offset_for_leap_year = leap_years * 1440 + # Discount the leap year days when calculating year distance. + # e.g. if there are 20 leap year days between 2 dates having the same day + # and month then the based on 365 days calculation + # the distance in years will come out to over 80 years when in written + # English it would read better as about 80 years. + minutes_with_offset = distance_in_minutes - minute_offset_for_leap_year remainder = (minutes_with_offset % MINUTES_IN_YEAR) distance_in_years = (minutes_with_offset.div MINUTES_IN_YEAR) if remainder < MINUTES_IN_QUARTER_YEAR @@ -687,6 +683,18 @@ module ActionView content_tag("time".freeze, content, options.reverse_merge(datetime: datetime), &block) end + + private + + def normalize_distance_of_time_argument_to_time(value) + if value.is_a?(Numeric) + Time.at(value) + elsif value.respond_to?(:to_time) + value.to_time + else + raise ArgumentError, "#{value.inspect} can't be converted to a Time value" + end + end end class DateTimeSelector #:nodoc: @@ -999,7 +1007,7 @@ module ActionView select_options[:disabled] = "disabled" if @options[:disabled] select_options[:class] = css_class_attribute(type, select_options[:class], @options[:with_css_classes]) if @options[:with_css_classes] - select_html = "\n" + select_html = "\n".dup select_html << content_tag("option".freeze, "", value: "") + "\n" if @options[:include_blank] select_html << prompt_option_tag(type, @options[:prompt]) + "\n" if @options[:prompt] select_html << select_options_as_html @@ -1081,7 +1089,7 @@ module ActionView # Given an ordering of datetime components, create the selection HTML # and join them with their appropriate separators. def build_selects_from_types(order) - select = "" + select = "".dup first_visible = order.find { |type| !@options[:"discard_#{type}"] } order.reverse_each do |type| separator = separator(type) unless type == first_visible # don't add before first visible field diff --git a/actionview/lib/action_view/helpers/form_helper.rb b/actionview/lib/action_view/helpers/form_helper.rb index 26a625e4fe..6b36c2272a 100644 --- a/actionview/lib/action_view/helpers/form_helper.rb +++ b/actionview/lib/action_view/helpers/form_helper.rb @@ -1,10 +1,10 @@ require "cgi" -require "action_view/helpers/date_helper" -require "action_view/helpers/tag_helper" -require "action_view/helpers/form_tag_helper" -require "action_view/helpers/active_model_helper" -require "action_view/model_naming" -require "action_view/record_identifier" +require_relative "date_helper" +require_relative "tag_helper" +require_relative "form_tag_helper" +require_relative "active_model_helper" +require_relative "../model_naming" +require_relative "../record_identifier" require "active_support/core_ext/module/attribute_accessors" require "active_support/core_ext/hash/slice" require "active_support/core_ext/string/output_safety" @@ -201,9 +201,9 @@ module ActionView # <%= f.submit %> # <% end %> # - # This also works for the methods in FormOptionHelper and DateHelper that + # This also works for the methods in FormOptionsHelper and DateHelper that # are designed to work with an object as base, like - # FormOptionHelper#collection_select and DateHelper#datetime_select. + # FormOptionsHelper#collection_select and DateHelper#datetime_select. # # === #form_for with a model object # @@ -416,13 +416,13 @@ module ActionView # # To set an authenticity token you need to pass an <tt>:authenticity_token</tt> parameter # - # <%= form_for @invoice, url: external_url, authenticity_token: 'external_token' do |f| + # <%= form_for @invoice, url: external_url, authenticity_token: 'external_token' do |f| %> # ... # <% end %> # # If you don't want to an authenticity token field be rendered at all just pass <tt>false</tt>: # - # <%= form_for @invoice, url: external_url, authenticity_token: false do |f| + # <%= form_for @invoice, url: external_url, authenticity_token: false do |f| %> # ... # <% end %> def form_for(record, options = {}, &block) @@ -474,6 +474,8 @@ module ActionView end private :apply_form_for_options! + mattr_accessor :form_with_generates_remote_forms, default: true + # Creates a form tag based on mixing URLs, scopes, or models. # # # Using just a URL: @@ -632,9 +634,9 @@ module ActionView # <%= form.submit %> # <% end %> # - # Same goes for the methods in FormOptionHelper and DateHelper designed + # Same goes for the methods in FormOptionsHelper and DateHelper designed # to work with an object as a base, like - # FormOptionHelper#collection_select and DateHelper#datetime_select. + # FormOptionsHelper#collection_select and DateHelper#datetime_select. # # === Setting the method # @@ -791,9 +793,9 @@ module ActionView # _class_ of the model object, e.g. if <tt>@person.permission</tt>, is # of class +Permission+, the field will still be named <tt>permission[admin]</tt>. # - # Note: This also works for the methods in FormOptionHelper and + # Note: This also works for the methods in FormOptionsHelper and # DateHelper that are designed to work with an object as base, like - # FormOptionHelper#collection_select and DateHelper#datetime_select. + # FormOptionsHelper#collection_select and DateHelper#datetime_select. # # === Nested Attributes Examples # @@ -1033,9 +1035,9 @@ module ActionView # <%= check_box_tag "comment[all_caps]", "1", @comment.commenter.hulk_mode? %> # <% end %> # - # Same goes for the methods in FormOptionHelper and DateHelper designed + # Same goes for the methods in FormOptionsHelper and DateHelper designed # to work with an object as a base, like - # FormOptionHelper#collection_select and DateHelper#datetime_select. + # FormOptionsHelper#collection_select and DateHelper#datetime_select. def fields(scope = nil, model: nil, **options, &block) options[:allow_method_names_outside_object] = true options[:skip_default_ids] = true @@ -1503,7 +1505,7 @@ module ActionView end private - def html_options_for_form_with(url_for_options = nil, model = nil, html: {}, local: false, + def html_options_for_form_with(url_for_options = nil, model = nil, html: {}, local: !form_with_generates_remote_forms, skip_enforcing_utf8: false, **options) html_options = options.slice(:id, :class, :multipart, :method, :data).merge(html) html_options[:method] ||= :patch if model.respond_to?(:persisted?) && model.persisted? @@ -1517,12 +1519,14 @@ module ActionView html_options[:"accept-charset"] = "UTF-8" html_options[:"data-remote"] = true unless local - if !local && !embed_authenticity_token_in_remote_forms && - html_options[:authenticity_token].blank? - # The authenticity token is taken from the meta tag in this case - html_options[:authenticity_token] = false - elsif html_options[:authenticity_token] == true - # Include the default authenticity_token, which is only generated when its set to nil, + html_options[:authenticity_token] = options.delete(:authenticity_token) + + if !local && html_options[:authenticity_token].blank? + html_options[:authenticity_token] = embed_authenticity_token_in_remote_forms + end + + if html_options[:authenticity_token] == true + # Include the default authenticity_token, which is only generated when it's set to nil, # but we needed the true value to override the default of no authenticity_token on data-remote. html_options[:authenticity_token] = nil end @@ -1602,14 +1606,15 @@ module ActionView include ModelNaming # The methods which wrap a form helper call. - class_attribute :field_helpers - self.field_helpers = [:fields_for, :fields, :label, :text_field, :password_field, - :hidden_field, :file_field, :text_area, :check_box, - :radio_button, :color_field, :search_field, - :telephone_field, :phone_field, :date_field, - :time_field, :datetime_field, :datetime_local_field, - :month_field, :week_field, :url_field, :email_field, - :number_field, :range_field] + class_attribute :field_helpers, default: [ + :fields_for, :fields, :label, :text_field, :password_field, + :hidden_field, :file_field, :text_area, :check_box, + :radio_button, :color_field, :search_field, + :telephone_field, :phone_field, :date_field, + :time_field, :datetime_field, :datetime_local_field, + :month_field, :week_field, :url_field, :email_field, + :number_field, :range_field + ] attr_accessor :object_name, :object, :options @@ -1724,9 +1729,9 @@ module ActionView # _class_ of the model object, e.g. if <tt>@person.permission</tt>, is # of class +Permission+, the field will still be named <tt>permission[admin]</tt>. # - # Note: This also works for the methods in FormOptionHelper and + # Note: This also works for the methods in FormOptionsHelper and # DateHelper that are designed to work with an object as base, like - # FormOptionHelper#collection_select and DateHelper#datetime_select. + # FormOptionsHelper#collection_select and DateHelper#datetime_select. # # === Nested Attributes Examples # @@ -2313,8 +2318,6 @@ module ActionView end ActiveSupport.on_load(:action_view) do - cattr_accessor(:default_form_builder, instance_writer: false, instance_reader: false) do - ::ActionView::Helpers::FormBuilder - end + cattr_accessor :default_form_builder, instance_writer: false, instance_reader: false, default: ::ActionView::Helpers::FormBuilder end end diff --git a/actionview/lib/action_view/helpers/form_options_helper.rb b/actionview/lib/action_view/helpers/form_options_helper.rb index 07d4310a4e..0de3800a51 100644 --- a/actionview/lib/action_view/helpers/form_options_helper.rb +++ b/actionview/lib/action_view/helpers/form_options_helper.rb @@ -1,6 +1,6 @@ require "cgi" require "erb" -require "action_view/helpers/form_helper" +require_relative "form_helper" require "active_support/core_ext/string/output_safety" require "active_support/core_ext/array/extract_options" require "active_support/core_ext/array/wrap" diff --git a/actionview/lib/action_view/helpers/form_tag_helper.rb b/actionview/lib/action_view/helpers/form_tag_helper.rb index ffc64e7118..c8c6632781 100644 --- a/actionview/lib/action_view/helpers/form_tag_helper.rb +++ b/actionview/lib/action_view/helpers/form_tag_helper.rb @@ -1,5 +1,5 @@ require "cgi" -require "action_view/helpers/tag_helper" +require_relative "tag_helper" require "active_support/core_ext/string/output_safety" require "active_support/core_ext/module/attribute_accessors" @@ -18,7 +18,7 @@ module ActionView include TextHelper mattr_accessor :embed_authenticity_token_in_remote_forms - self.embed_authenticity_token_in_remote_forms = false + self.embed_authenticity_token_in_remote_forms = nil # Starts a form tag that points the action to a url configured with <tt>url_for_options</tt> just like # ActionController::Base#url_for. The method for the form defaults to POST. diff --git a/actionview/lib/action_view/helpers/javascript_helper.rb b/actionview/lib/action_view/helpers/javascript_helper.rb index 22e1e74ad6..8806492572 100644 --- a/actionview/lib/action_view/helpers/javascript_helper.rb +++ b/actionview/lib/action_view/helpers/javascript_helper.rb @@ -1,4 +1,4 @@ -require "action_view/helpers/tag_helper" +require_relative "tag_helper" module ActionView module Helpers @@ -13,8 +13,8 @@ module ActionView "'" => "\\'" } - JS_ESCAPE_MAP["\342\200\250".force_encoding(Encoding::UTF_8).encode!] = "
" - JS_ESCAPE_MAP["\342\200\251".force_encoding(Encoding::UTF_8).encode!] = "
" + JS_ESCAPE_MAP["\342\200\250".dup.force_encoding(Encoding::UTF_8).encode!] = "
" + JS_ESCAPE_MAP["\342\200\251".dup.force_encoding(Encoding::UTF_8).encode!] = "
" # Escapes carriage returns and single and double quotes for JavaScript segments. # diff --git a/actionview/lib/action_view/helpers/tags/check_box.rb b/actionview/lib/action_view/helpers/tags/check_box.rb index 02f87fc89f..b9b988325d 100644 --- a/actionview/lib/action_view/helpers/tags/check_box.rb +++ b/actionview/lib/action_view/helpers/tags/check_box.rb @@ -1,4 +1,4 @@ -require "action_view/helpers/tags/checkable" +require_relative "checkable" module ActionView module Helpers diff --git a/actionview/lib/action_view/helpers/tags/collection_check_boxes.rb b/actionview/lib/action_view/helpers/tags/collection_check_boxes.rb index 7252d4f2d9..ef37c1c342 100644 --- a/actionview/lib/action_view/helpers/tags/collection_check_boxes.rb +++ b/actionview/lib/action_view/helpers/tags/collection_check_boxes.rb @@ -1,4 +1,4 @@ -require "action_view/helpers/tags/collection_helpers" +require_relative "collection_helpers" module ActionView module Helpers @@ -10,6 +10,7 @@ module ActionView def check_box(extra_html_options = {}) html_options = extra_html_options.merge(@input_html_options) html_options[:multiple] = true + html_options[:skip_default_ids] = false @template_object.check_box(@object_name, @method_name, html_options, @value, nil) end end diff --git a/actionview/lib/action_view/helpers/tags/collection_radio_buttons.rb b/actionview/lib/action_view/helpers/tags/collection_radio_buttons.rb index a5f72af9ff..c7d28905d0 100644 --- a/actionview/lib/action_view/helpers/tags/collection_radio_buttons.rb +++ b/actionview/lib/action_view/helpers/tags/collection_radio_buttons.rb @@ -1,4 +1,4 @@ -require "action_view/helpers/tags/collection_helpers" +require_relative "collection_helpers" module ActionView module Helpers @@ -9,6 +9,7 @@ module ActionView class RadioButtonBuilder < Builder # :nodoc: def radio_button(extra_html_options = {}) html_options = extra_html_options.merge(@input_html_options) + html_options[:skip_default_ids] = false @template_object.radio_button(@object_name, @method_name, @value, html_options) end end diff --git a/actionview/lib/action_view/helpers/tags/radio_button.rb b/actionview/lib/action_view/helpers/tags/radio_button.rb index 43dbd32083..782263ac5b 100644 --- a/actionview/lib/action_view/helpers/tags/radio_button.rb +++ b/actionview/lib/action_view/helpers/tags/radio_button.rb @@ -1,4 +1,4 @@ -require "action_view/helpers/tags/checkable" +require_relative "checkable" module ActionView module Helpers diff --git a/actionview/lib/action_view/helpers/tags/select.rb b/actionview/lib/action_view/helpers/tags/select.rb index 667c7e945a..380f7a8c4e 100644 --- a/actionview/lib/action_view/helpers/tags/select.rb +++ b/actionview/lib/action_view/helpers/tags/select.rb @@ -6,7 +6,7 @@ module ActionView @choices = block_given? ? template_object.capture { yield || "" } : choices @choices = @choices.to_a if @choices.is_a?(Range) - @html_options = html_options + @html_options = html_options.except(:skip_default_ids, :allow_method_names_outside_object) super(object_name, method_name, template_object, options) end @@ -33,7 +33,7 @@ module ActionView # [nil, []] # { nil => [] } def grouped_choices? - !@choices.empty? && @choices.first.respond_to?(:last) && Array === @choices.first.last + !@choices.blank? && @choices.first.respond_to?(:last) && Array === @choices.first.last end end end diff --git a/actionview/lib/action_view/helpers/tags/text_area.rb b/actionview/lib/action_view/helpers/tags/text_area.rb index 31e3a9e9b1..1058fdf55f 100644 --- a/actionview/lib/action_view/helpers/tags/text_area.rb +++ b/actionview/lib/action_view/helpers/tags/text_area.rb @@ -1,4 +1,4 @@ -require "action_view/helpers/tags/placeholderable" +require_relative "placeholderable" module ActionView module Helpers diff --git a/actionview/lib/action_view/helpers/tags/text_field.rb b/actionview/lib/action_view/helpers/tags/text_field.rb index 613cade7b3..1d55105587 100644 --- a/actionview/lib/action_view/helpers/tags/text_field.rb +++ b/actionview/lib/action_view/helpers/tags/text_field.rb @@ -1,4 +1,4 @@ -require "action_view/helpers/tags/placeholderable" +require_relative "placeholderable" module ActionView module Helpers diff --git a/actionview/lib/action_view/helpers/translation_helper.rb b/actionview/lib/action_view/helpers/translation_helper.rb index 47ed41a129..b10cfadaed 100644 --- a/actionview/lib/action_view/helpers/translation_helper.rb +++ b/actionview/lib/action_view/helpers/translation_helper.rb @@ -1,4 +1,4 @@ -require "action_view/helpers/tag_helper" +require_relative "tag_helper" require "active_support/core_ext/string/access" require "i18n/exceptions" @@ -11,8 +11,7 @@ module ActionView include TagHelper included do - mattr_accessor :debug_missing_translation - self.debug_missing_translation = true + mattr_accessor :debug_missing_translation, default: true end # Delegates to <tt>I18n#translate</tt> but also performs three additional @@ -96,7 +95,7 @@ module ActionView raise e if raise_error keys = I18n.normalize_keys(e.locale, e.key, e.options[:scope]) - title = "translation missing: #{keys.join('.')}" + title = "translation missing: #{keys.join('.')}".dup interpolations = options.except(:default, :scope) if interpolations.any? diff --git a/actionview/lib/action_view/helpers/url_helper.rb b/actionview/lib/action_view/helpers/url_helper.rb index a306903c60..644e1e4391 100644 --- a/actionview/lib/action_view/helpers/url_helper.rb +++ b/actionview/lib/action_view/helpers/url_helper.rb @@ -1,4 +1,4 @@ -require "action_view/helpers/javascript_helper" +require_relative "javascript_helper" require "active_support/core_ext/array/access" require "active_support/core_ext/hash/keys" require "active_support/core_ext/string/output_safety" @@ -542,7 +542,7 @@ module ActionView return false unless request.get? || request.head? - check_parameters ||= !options.is_a?(String) && options.try(:delete, :check_parameters) + check_parameters ||= options.is_a?(Hash) && options.delete(:check_parameters) url_string = URI.parser.unescape(url_for(options)).force_encoding(Encoding::BINARY) # We ignore any extra parameters in the request_uri if the @@ -552,7 +552,10 @@ module ActionView request_uri = url_string.index("?") || check_parameters ? request.fullpath : request.path request_uri = URI.parser.unescape(request_uri).force_encoding(Encoding::BINARY) - url_string.chomp!("/") if url_string.start_with?("/") && url_string != "/" + if url_string.start_with?("/") && url_string != "/" + url_string.chomp!("/") + request_uri.chomp!("/") + end if %r{^\w+://}.match?(url_string) url_string == "#{request.protocol}#{request.host_with_port}#{request_uri}" @@ -621,11 +624,6 @@ module ActionView # # => [{name: 'country[name]', value: 'Denmark'}] def to_form_params(attribute, namespace = nil) attribute = if attribute.respond_to?(:permitted?) - unless attribute.permitted? - raise ArgumentError, "Attempting to generate a buttom from non-sanitized request parameters!" \ - " Whitelist and sanitize passed parameters to be secure." - end - attribute.to_h else attribute diff --git a/actionview/lib/action_view/layouts.rb b/actionview/lib/action_view/layouts.rb index 81feb90486..b62fde30e8 100644 --- a/actionview/lib/action_view/layouts.rb +++ b/actionview/lib/action_view/layouts.rb @@ -1,4 +1,4 @@ -require "action_view/rendering" +require_relative "rendering" require "active_support/core_ext/module/remove_method" module ActionView @@ -204,9 +204,9 @@ module ActionView include ActionView::Rendering included do - class_attribute :_layout, :_layout_conditions, instance_accessor: false - self._layout = nil - self._layout_conditions = {} + class_attribute :_layout, instance_accessor: false + class_attribute :_layout_conditions, instance_accessor: false, default: {} + _write_layout_method end diff --git a/actionview/lib/action_view/log_subscriber.rb b/actionview/lib/action_view/log_subscriber.rb index d03e1a51b8..d4ac77e10f 100644 --- a/actionview/lib/action_view/log_subscriber.rb +++ b/actionview/lib/action_view/log_subscriber.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "active_support/log_subscriber" module ActionView @@ -14,7 +16,7 @@ module ActionView def render_template(event) info do - message = " Rendered #{from_rails_root(event.payload[:identifier])}" + message = " Rendered #{from_rails_root(event.payload[:identifier])}".dup message << " within #{from_rails_root(event.payload[:layout])}" if event.payload[:layout] message << " (#{event.duration.round(1)}ms)" end @@ -22,10 +24,10 @@ module ActionView def render_partial(event) info do - message = " Rendered #{from_rails_root(event.payload[:identifier])}" + message = " Rendered #{from_rails_root(event.payload[:identifier])}".dup message << " within #{from_rails_root(event.payload[:layout])}" if event.payload[:layout] message << " (#{event.duration.round(1)}ms)" - message << " #{cache_message(event.payload)}" if event.payload.key?(:cache_hit) + message << " #{cache_message(event.payload)}" unless event.payload[:cache_hit].nil? message end end @@ -73,16 +75,17 @@ module ActionView end def cache_message(payload) # :doc: - if payload[:cache_hit] + case payload[:cache_hit] + when :hit "[cache hit]" - else + when :miss "[cache miss]" end end def log_rendering_start(payload) info do - message = " Rendering #{from_rails_root(payload[:identifier])}" + message = " Rendering #{from_rails_root(payload[:identifier])}".dup message << " within #{from_rails_root(payload[:layout])}" if payload[:layout] message end diff --git a/actionview/lib/action_view/lookup_context.rb b/actionview/lib/action_view/lookup_context.rb index f385a7cd04..ce5493c01b 100644 --- a/actionview/lib/action_view/lookup_context.rb +++ b/actionview/lib/action_view/lookup_context.rb @@ -1,7 +1,7 @@ require "concurrent/map" require "active_support/core_ext/module/remove_method" require "active_support/core_ext/module/attribute_accessors" -require "action_view/template/resolver" +require_relative "template/resolver" module ActionView # = Action View Lookup Context @@ -14,11 +14,9 @@ module ActionView class LookupContext #:nodoc: attr_accessor :prefixes, :rendered_format - mattr_accessor :fallbacks - @@fallbacks = FallbackFileSystemResolver.instances + mattr_accessor :fallbacks, default: FallbackFileSystemResolver.instances - mattr_accessor :registered_details - self.registered_details = [] + mattr_accessor :registered_details, default: [] def self.register_detail(name, &block) registered_details << name diff --git a/actionview/lib/action_view/railtie.rb b/actionview/lib/action_view/railtie.rb index d344d98f4b..61678933e9 100644 --- a/actionview/lib/action_view/railtie.rb +++ b/actionview/lib/action_view/railtie.rb @@ -5,7 +5,7 @@ module ActionView # = Action View Railtie class Railtie < Rails::Engine # :nodoc: config.action_view = ActiveSupport::OrderedOptions.new - config.action_view.embed_authenticity_token_in_remote_forms = false + config.action_view.embed_authenticity_token_in_remote_forms = nil config.action_view.debug_missing_translation = true config.eager_load_namespaces << ActionView @@ -17,6 +17,15 @@ module ActionView end end + initializer "action_view.form_with_generates_remote_forms" do |app| + ActiveSupport.on_load(:action_view) do + form_with_generates_remote_forms = app.config.action_view.delete(:form_with_generates_remote_forms) + unless form_with_generates_remote_forms.nil? + ActionView::Helpers::FormHelper.form_with_generates_remote_forms = form_with_generates_remote_forms + end + end + end + initializer "action_view.logger" do ActiveSupport.on_load(:action_view) { self.logger ||= Rails.logger } end diff --git a/actionview/lib/action_view/record_identifier.rb b/actionview/lib/action_view/record_identifier.rb index 48bea315a9..6805513347 100644 --- a/actionview/lib/action_view/record_identifier.rb +++ b/actionview/lib/action_view/record_identifier.rb @@ -1,5 +1,5 @@ require "active_support/core_ext/module" -require "action_view/model_naming" +require_relative "model_naming" module ActionView # RecordIdentifier encapsulates methods used by various ActionView helpers diff --git a/actionview/lib/action_view/renderer/partial_renderer.rb b/actionview/lib/action_view/renderer/partial_renderer.rb index 647b15ea94..77f5084686 100644 --- a/actionview/lib/action_view/renderer/partial_renderer.rb +++ b/actionview/lib/action_view/renderer/partial_renderer.rb @@ -1,5 +1,5 @@ require "concurrent/map" -require "action_view/renderer/partial_renderer/collection_caching" +require_relative "partial_renderer/collection_caching" module ActionView class PartialIteration @@ -344,7 +344,7 @@ module ActionView end content = layout.render(view, locals) { content } if layout - payload[:cache_hit] = view.cache_hit + payload[:cache_hit] = view.view_renderer.cache_hits[@template.virtual_path] content end end diff --git a/actionview/lib/action_view/renderer/partial_renderer/collection_caching.rb b/actionview/lib/action_view/renderer/partial_renderer/collection_caching.rb index 1fbe209200..32663fb80d 100644 --- a/actionview/lib/action_view/renderer/partial_renderer/collection_caching.rb +++ b/actionview/lib/action_view/renderer/partial_renderer/collection_caching.rb @@ -5,7 +5,7 @@ module ActionView included do # Fallback cache store if Action View is used without Rails. # Otherwise overridden in Railtie to use Rails.cache. - mattr_accessor(:collection_cache) { ActiveSupport::Cache::MemoryStore.new } + mattr_accessor :collection_cache, default: ActiveSupport::Cache::MemoryStore.new end private @@ -38,7 +38,7 @@ module ActionView end def expanded_cache_key(key) - key = @view.fragment_cache_key(@view.cache_fragment_name(key, virtual_path: @template.virtual_path)) + key = @view.combined_fragment_cache_key(@view.cache_fragment_name(key, virtual_path: @template.virtual_path)) key.frozen? ? key.dup : key # #read_multi & #write may require mutability, Dalli 2.6.0. end diff --git a/actionview/lib/action_view/renderer/renderer.rb b/actionview/lib/action_view/renderer/renderer.rb index 2a3b89aebf..bcdeb85d30 100644 --- a/actionview/lib/action_view/renderer/renderer.rb +++ b/actionview/lib/action_view/renderer/renderer.rb @@ -46,5 +46,9 @@ module ActionView def render_partial(context, options, &block) #:nodoc: PartialRenderer.new(@lookup_context).render(context, options, block) end + + def cache_hits # :nodoc: + @cache_hits ||= {} + end end end diff --git a/actionview/lib/action_view/rendering.rb b/actionview/lib/action_view/rendering.rb index cf18562c45..9bee76a1f7 100644 --- a/actionview/lib/action_view/rendering.rb +++ b/actionview/lib/action_view/rendering.rb @@ -1,4 +1,4 @@ -require "action_view/view_paths" +require_relative "view_paths" module ActionView # This is a class to fix I18n global state. Whenever you provide I18n.locale during a request, diff --git a/actionview/lib/action_view/template.rb b/actionview/lib/action_view/template.rb index b0e2f1e54e..e53c8356af 100644 --- a/actionview/lib/action_view/template.rb +++ b/actionview/lib/action_view/template.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "active_support/core_ext/object/try" require "active_support/core_ext/kernel/singleton_class" require "thread" @@ -282,7 +284,7 @@ module ActionView # Make sure that the resulting String to be eval'd is in the # encoding of the code - source = <<-end_src + source = <<-end_src.dup def #{method_name}(local_assigns, output_buffer) _old_virtual_path, @virtual_path = @virtual_path, #{@virtual_path.inspect};_old_output_buffer = @output_buffer;#{locals_code};#{code} ensure @@ -329,12 +331,12 @@ module ActionView 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}];" } + locals.each_with_object("".dup) { |key, code| code << "#{key} = #{key} = local_assigns[:#{key}];" } end def method_name @method_name ||= begin - m = "_#{identifier_method_name}__#{@identifier.hash}_#{__id__}" + m = "_#{identifier_method_name}__#{@identifier.hash}_#{__id__}".dup m.tr!("-".freeze, "_".freeze) m end diff --git a/actionview/lib/action_view/template/handlers/builder.rb b/actionview/lib/action_view/template/handlers/builder.rb index e99b921cb7..67ad78133d 100644 --- a/actionview/lib/action_view/template/handlers/builder.rb +++ b/actionview/lib/action_view/template/handlers/builder.rb @@ -1,9 +1,7 @@ module ActionView module Template::Handlers class Builder - # Default format used by Builder. - class_attribute :default_format - self.default_format = :xml + class_attribute :default_format, default: :xml def call(template) require_engine @@ -14,7 +12,6 @@ module ActionView end private - def require_engine # :doc: @required ||= begin require "builder" diff --git a/actionview/lib/action_view/template/handlers/erb.rb b/actionview/lib/action_view/template/handlers/erb.rb index 58c7fd1a88..48c2e22a89 100644 --- a/actionview/lib/action_view/template/handlers/erb.rb +++ b/actionview/lib/action_view/template/handlers/erb.rb @@ -9,16 +9,13 @@ module ActionView # Specify trim mode for the ERB compiler. Defaults to '-'. # See ERB documentation for suitable values. - class_attribute :erb_trim_mode - self.erb_trim_mode = "-" + class_attribute :erb_trim_mode, default: "-" # Default implementation used. - class_attribute :erb_implementation - self.erb_implementation = Erubi + class_attribute :erb_implementation, default: Erubi # Do not escape templates of these mime types. - class_attribute :escape_whitelist - self.escape_whitelist = ["text/plain"] + class_attribute :escape_whitelist, default: ["text/plain"] ENCODING_TAG = Regexp.new("\\A(<%#{ENCODING_FLAG}-?%>)[ \\t]*") diff --git a/actionview/lib/action_view/template/resolver.rb b/actionview/lib/action_view/template/resolver.rb index d3905b5f23..0ccf398d9a 100644 --- a/actionview/lib/action_view/template/resolver.rb +++ b/actionview/lib/action_view/template/resolver.rb @@ -1,7 +1,7 @@ require "pathname" require "active_support/core_ext/class" require "active_support/core_ext/module/attribute_accessors" -require "action_view/template" +require_relative "../template" require "thread" require "concurrent/map" @@ -14,7 +14,7 @@ module ActionView alias_method :partial?, :partial def self.build(name, prefix, partial) - virtual = "" + virtual = "".dup virtual << "#{prefix}/" unless prefix.empty? virtual << (partial ? "_#{name}" : name) new name, prefix, partial, virtual @@ -125,8 +125,7 @@ module ActionView end end - cattr_accessor :caching - self.caching = true + cattr_accessor :caching, default: true class << self alias :caching? :caching diff --git a/actionview/lib/action_view/test_case.rb b/actionview/lib/action_view/test_case.rb index ae4fec4337..424a86ba3e 100644 --- a/actionview/lib/action_view/test_case.rb +++ b/actionview/lib/action_view/test_case.rb @@ -71,7 +71,7 @@ module ActionView def helper_method(*methods) # Almost a duplicate from ActionController::Helpers methods.flatten.each do |method| - _helpers.module_eval <<-end_eval + _helpers.module_eval <<-end_eval, __FILE__, __LINE__ + 1 def #{method}(*args, &block) # def current_user(*args, &block) _test_case.send(%(#{method}), *args, &block) # _test_case.send(%(current_user), *args, &block) end # end @@ -104,7 +104,7 @@ module ActionView # empty string ensures buffer has UTF-8 encoding as # new without arguments returns ASCII-8BIT encoded buffer like String#new @output_buffer = ActiveSupport::SafeBuffer.new "" - @rendered = "" + @rendered = "".dup make_test_case_available_to_view! say_no_to_protect_against_forgery! diff --git a/actionview/lib/action_view/testing/resolvers.rb b/actionview/lib/action_view/testing/resolvers.rb index 3188526b63..5e853311e6 100644 --- a/actionview/lib/action_view/testing/resolvers.rb +++ b/actionview/lib/action_view/testing/resolvers.rb @@ -1,4 +1,4 @@ -require "action_view/template/resolver" +require_relative "../template/resolver" module ActionView #:nodoc: # Use FixtureResolver in your tests to simulate the presence of files on the @@ -20,7 +20,7 @@ module ActionView #:nodoc: private def query(path, exts, _, _) - query = "" + query = "".dup EXTENSIONS.each_key do |ext| query << "(" << exts[ext].map { |e| e && Regexp.escape(".#{e}") }.join("|") << "|)" end diff --git a/actionview/lib/action_view/view_paths.rb b/actionview/lib/action_view/view_paths.rb index f0fe6831fa..938f0fc17f 100644 --- a/actionview/lib/action_view/view_paths.rb +++ b/actionview/lib/action_view/view_paths.rb @@ -3,9 +3,7 @@ module ActionView extend ActiveSupport::Concern included do - class_attribute :_view_paths - self._view_paths = ActionView::PathSet.new - _view_paths.freeze + class_attribute :_view_paths, default: ActionView::PathSet.new.freeze end delegate :template_exists?, :any_templates?, :view_paths, :formats, :formats=, diff --git a/actionview/package.json b/actionview/package.json index a1da13315e..85f4ddacbe 100644 --- a/actionview/package.json +++ b/actionview/package.json @@ -1,6 +1,6 @@ { "name": "rails-ujs", - "version": "5.1.0-beta1", + "version": "5.2.0-alpha", "description": "Ruby on Rails unobtrusive scripting adapter", "main": "lib/assets/compiled/rails-ujs.js", "files": [ @@ -11,7 +11,7 @@ }, "scripts": { "build": "bundle exec blade build", - "test": "echo \"See the README: https://github.com/rails/rails-ujs#how-to-run-tests\" && exit 1", + "test": "echo \"See the README: https://github.com/rails/rails/blob/master/actionview/app/assets/javascripts#how-to-run-tests\" && exit 1", "lint": "coffeelint app/assets/javascripts && eslint test/public/test" }, "repository": { diff --git a/actionview/test/abstract_unit.rb b/actionview/test/abstract_unit.rb index dde66a7ba0..a7d706c5e1 100644 --- a/actionview/test/abstract_unit.rb +++ b/actionview/test/abstract_unit.rb @@ -1,8 +1,8 @@ -$:.unshift(File.dirname(__FILE__) + "/lib") -$:.unshift(File.dirname(__FILE__) + "/fixtures/helpers") -$:.unshift(File.dirname(__FILE__) + "/fixtures/alternate_helpers") +$:.unshift File.expand_path("lib", __dir__) +$:.unshift File.expand_path("fixtures/helpers", __dir__) +$:.unshift File.expand_path("fixtures/alternate_helpers", __dir__) -ENV["TMPDIR"] = File.join(File.dirname(__FILE__), "tmp") +ENV["TMPDIR"] = File.expand_path("tmp", __dir__) require "active_support/core_ext/kernel/reporting" @@ -47,7 +47,7 @@ I18n.backend.store_translations "da", {} I18n.backend.store_translations "pt-BR", {} ORIGINAL_LOCALES = I18n.available_locales.map(&:to_s).sort -FIXTURE_LOAD_PATH = File.join(File.dirname(__FILE__), "fixtures") +FIXTURE_LOAD_PATH = File.expand_path("fixtures", __dir__) module RenderERBUtils def view @@ -133,7 +133,7 @@ class BasicController def config @config ||= ActiveSupport::InheritableOptions.new(ActionController::Base.config).tap do |config| # VIEW TODO: View tests should not require a controller - public_dir = File.expand_path("../fixtures/public", __FILE__) + public_dir = File.expand_path("fixtures/public", __dir__) config.assets_dir = public_dir config.javascripts_dir = "#{public_dir}/javascripts" config.stylesheets_dir = "#{public_dir}/stylesheets" @@ -196,7 +196,7 @@ class ActionDispatch::IntegrationTest < ActiveSupport::TestCase end def with_autoload_path(path) - path = File.join(File.dirname(__FILE__), "fixtures", path) + path = File.join(File.expand_path("fixtures", __dir__), path) if ActiveSupport::Dependencies.autoload_paths.include?(path) yield else diff --git a/actionview/test/actionpack/abstract/abstract_controller_test.rb b/actionview/test/actionpack/abstract/abstract_controller_test.rb index a2cd3deb58..8f65a61493 100644 --- a/actionview/test/actionpack/abstract/abstract_controller_test.rb +++ b/actionview/test/actionpack/abstract/abstract_controller_test.rb @@ -42,7 +42,7 @@ module AbstractController super end - append_view_path File.expand_path(File.join(File.dirname(__FILE__), "views")) + append_view_path File.expand_path("views", __dir__) end class Me2 < RenderingController @@ -152,7 +152,7 @@ module AbstractController class OverridingLocalPrefixes < AbstractController::Base include AbstractController::Rendering include ActionView::Rendering - append_view_path File.expand_path(File.join(File.dirname(__FILE__), "views")) + append_view_path File.expand_path("views", __dir__) def index render diff --git a/actionview/test/actionpack/abstract/helper_test.rb b/actionview/test/actionpack/abstract/helper_test.rb index 83237518d7..13922e4485 100644 --- a/actionview/test/actionpack/abstract/helper_test.rb +++ b/actionview/test/actionpack/abstract/helper_test.rb @@ -1,6 +1,6 @@ require "abstract_unit" -ActionController::Base.helpers_path = File.expand_path("../../../fixtures/helpers", __FILE__) +ActionController::Base.helpers_path = File.expand_path("../../fixtures/helpers", __dir__) module AbstractController module Testing @@ -51,7 +51,7 @@ module AbstractController class AbstractInvalidHelpers < AbstractHelpers include ActionController::Helpers - path = File.expand_path("../../../fixtures/helpers_missing", __FILE__) + path = File.expand_path("../../fixtures/helpers_missing", __dir__) $:.unshift(path) self.helpers_path = path end diff --git a/actionview/test/actionpack/controller/capture_test.rb b/actionview/test/actionpack/controller/capture_test.rb index f0ae609845..cc3a23c60c 100644 --- a/actionview/test/actionpack/controller/capture_test.rb +++ b/actionview/test/actionpack/controller/capture_test.rb @@ -2,7 +2,7 @@ require "abstract_unit" require "active_support/logger" class CaptureController < ActionController::Base - self.view_paths = [ File.dirname(__FILE__) + "/../../fixtures/actionpack" ] + self.view_paths = [ File.expand_path("../../fixtures/actionpack", __dir__) ] def self.controller_name; "test"; end def self.controller_path; "test"; end diff --git a/actionview/test/actionpack/controller/layout_test.rb b/actionview/test/actionpack/controller/layout_test.rb index b79835ff34..b3e0329f57 100644 --- a/actionview/test/actionpack/controller/layout_test.rb +++ b/actionview/test/actionpack/controller/layout_test.rb @@ -5,7 +5,7 @@ require "active_support/core_ext/array/extract_options" # method has access to the view_paths array when looking for a layout to automatically assign. old_load_paths = ActionController::Base.view_paths -ActionController::Base.view_paths = [ File.dirname(__FILE__) + "/../../fixtures/actionpack/layout_tests/" ] +ActionController::Base.view_paths = [ File.expand_path("../../fixtures/actionpack/layout_tests", __dir__) ] class LayoutTest < ActionController::Base def self.controller_path; "views" end @@ -96,7 +96,7 @@ class StreamingLayoutController < LayoutTest end class AbsolutePathLayoutController < LayoutTest - layout File.expand_path(File.expand_path(__FILE__) + "/../../../fixtures/actionpack/layout_tests/layouts/layout_test") + layout File.expand_path("../../fixtures/actionpack/layout_tests/layouts/layout_test", __dir__) end class HasOwnLayoutController < LayoutTest @@ -117,7 +117,7 @@ end class PrependsViewPathController < LayoutTest def hello - prepend_view_path File.dirname(__FILE__) + "/../../fixtures/actionpack/layout_tests/alt/" + prepend_view_path File.expand_path("../../fixtures/actionpack/layout_tests/alt", __dir__) render layout: "alt" end end diff --git a/actionview/test/actionpack/controller/render_test.rb b/actionview/test/actionpack/controller/render_test.rb index 51ec8899b1..6528169312 100644 --- a/actionview/test/actionpack/controller/render_test.rb +++ b/actionview/test/actionpack/controller/render_test.rb @@ -56,7 +56,7 @@ class TestController < ApplicationController end def hello_world_file - render file: File.expand_path("../../../fixtures/actionpack/hello", __FILE__), formats: [:html] + render file: File.expand_path("../../fixtures/actionpack/hello", __dir__), formats: [:html] end # :ported: @@ -125,7 +125,7 @@ class TestController < ApplicationController # :ported: def render_file_with_instance_variables @secret = "in the sauce" - path = File.join(File.dirname(__FILE__), "../../fixtures/test/render_file_with_ivar") + path = File.expand_path("../../fixtures/test/render_file_with_ivar", __dir__) render file: path end @@ -142,21 +142,21 @@ class TestController < ApplicationController def render_file_using_pathname @secret = "in the sauce" - render file: Pathname.new(File.dirname(__FILE__)).join("..", "..", "fixtures", "test", "dot.directory", "render_file_with_ivar") + render file: Pathname.new(__dir__).join("..", "..", "fixtures", "test", "dot.directory", "render_file_with_ivar") end def render_file_from_template @secret = "in the sauce" - @path = File.expand_path(File.join(File.dirname(__FILE__), "../../fixtures/test/render_file_with_ivar")) + @path = File.expand_path("../../fixtures/test/render_file_with_ivar", __dir__) end def render_file_with_locals - path = File.join(File.dirname(__FILE__), "../../fixtures/test/render_file_with_locals") + path = File.expand_path("../../fixtures/test/render_file_with_locals", __dir__) render file: path, locals: { secret: "in the sauce" } end def render_file_as_string_with_locals - path = File.expand_path(File.join(File.dirname(__FILE__), "../../fixtures/test/render_file_with_locals")) + path = File.expand_path("../../fixtures/test/render_file_with_locals", __dir__) render file: path, locals: { secret: "in the sauce" } end diff --git a/actionview/test/active_record_unit.rb b/actionview/test/active_record_unit.rb index 7f94b7ebb4..901c0e2b3e 100644 --- a/actionview/test/active_record_unit.rb +++ b/actionview/test/active_record_unit.rb @@ -13,7 +13,7 @@ end # Try to grab AR unless defined?(ActiveRecord) && defined?(FixtureSet) begin - PATH_TO_AR = "#{File.dirname(__FILE__)}/../../activerecord/lib" + PATH_TO_AR = File.expand_path("../../activerecord/lib", __dir__) raise LoadError, "#{PATH_TO_AR} doesn't exist" unless File.directory?(PATH_TO_AR) $LOAD_PATH.unshift PATH_TO_AR require "active_record" @@ -58,13 +58,13 @@ class ActiveRecordTestConnector # Load actionpack sqlite3 tables def load_schema - File.read(File.dirname(__FILE__) + "/fixtures/db_definitions/sqlite.sql").split(";").each do |sql| + File.read(File.expand_path("fixtures/db_definitions/sqlite.sql", __dir__)).split(";").each do |sql| ActiveRecord::Base.connection.execute(sql) unless sql.blank? end end def require_fixture_models - Dir.glob(File.dirname(__FILE__) + "/fixtures/*.rb").each { |f| require f } + Dir.glob(File.expand_path("fixtures/*.rb", __dir__)).each { |f| require f } end end end diff --git a/actionview/test/activerecord/controller_runtime_test.rb b/actionview/test/activerecord/controller_runtime_test.rb index 590559f592..1cec5072c0 100644 --- a/actionview/test/activerecord/controller_runtime_test.rb +++ b/actionview/test/activerecord/controller_runtime_test.rb @@ -67,7 +67,7 @@ class ControllerRuntimeLogSubscriberTest < ActionController::TestCase wait assert_equal 2, @logger.logged(:info).size - assert_match(/\(Views: [\d.]+ms \| ActiveRecord: 0.0ms\)/, @logger.logged(:info)[1]) + assert_match(/\(Views: [\d.]+ms \| ActiveRecord: 0\.0ms\)/, @logger.logged(:info)[1]) end def test_log_with_active_record_when_post diff --git a/actionview/test/activerecord/form_helper_activerecord_test.rb b/actionview/test/activerecord/form_helper_activerecord_test.rb index 3b314588c7..9949c3fde0 100644 --- a/actionview/test/activerecord/form_helper_activerecord_test.rb +++ b/actionview/test/activerecord/form_helper_activerecord_test.rb @@ -55,7 +55,7 @@ class FormHelperActiveRecordTest < ActionView::TestCase private def hidden_fields(method = nil) - txt = %{<input name="utf8" type="hidden" value="✓" />} + txt = %{<input name="utf8" type="hidden" value="✓" />}.dup if method && !%w(get post).include?(method.to_s) txt << %{<input name="_method" type="hidden" value="#{method}" />} @@ -65,7 +65,7 @@ class FormHelperActiveRecordTest < ActionView::TestCase end def form_text(action = "/", id = nil, html_class = nil, remote = nil, multipart = nil, method = nil) - txt = %{<form accept-charset="UTF-8" action="#{action}"} + txt = %{<form accept-charset="UTF-8" action="#{action}"}.dup txt << %{ enctype="multipart/form-data"} if multipart txt << %{ data-remote="true"} if remote txt << %{ class="#{html_class}"} if html_class diff --git a/actionview/test/activerecord/polymorphic_routes_test.rb b/actionview/test/activerecord/polymorphic_routes_test.rb index e99c769dc2..b2e0fb08c4 100644 --- a/actionview/test/activerecord/polymorphic_routes_test.rb +++ b/actionview/test/activerecord/polymorphic_routes_test.rb @@ -730,3 +730,49 @@ class PolymorphicPathRoutesTest < PolymorphicRoutesTest assert_equal url.sub(/http:\/\/#{host}/, ""), url_for(args) end end + +class DirectRoutesTest < ActionView::TestCase + class Linkable + attr_reader :id + + def self.name + super.demodulize + end + + def initialize(id) + @id = id + end + + def linkable_type + self.class.name.underscore + end + end + + class Category < Linkable; end + class Collection < Linkable; end + class Product < Linkable; end + + Routes = ActionDispatch::Routing::RouteSet.new + Routes.draw do + resources :categories, :collections, :products + direct(:linkable) { |linkable| [:"#{linkable.linkable_type}", { id: linkable.id }] } + end + + include Routes.url_helpers + + def setup + @category = Category.new("1") + @collection = Collection.new("2") + @product = Product.new("3") + end + + def test_direct_routes + assert_equal "/categories/1", linkable_path(@category) + assert_equal "/collections/2", linkable_path(@collection) + assert_equal "/products/3", linkable_path(@product) + + assert_equal "http://test.host/categories/1", linkable_url(@category) + assert_equal "http://test.host/collections/2", linkable_url(@collection) + assert_equal "http://test.host/products/3", linkable_url(@product) + end +end diff --git a/actionview/test/activerecord/relation_cache_test.rb b/actionview/test/activerecord/relation_cache_test.rb index 43f7242ee9..d12c426586 100644 --- a/actionview/test/activerecord/relation_cache_test.rb +++ b/actionview/test/activerecord/relation_cache_test.rb @@ -4,13 +4,17 @@ class RelationCacheTest < ActionView::TestCase tests ActionView::Helpers::CacheHelper def setup - @virtual_path = "path" + view_paths = ActionController::Base.view_paths + lookup_context = ActionView::LookupContext.new(view_paths, {}, ["test"]) + @view_renderer = ActionView::Renderer.new(lookup_context) + @virtual_path = "path" + controller.cache_store = ActiveSupport::Cache::MemoryStore.new end def test_cache_relation_other cache(Project.all) { concat("Hello World") } - assert_equal "Hello World", controller.cache_store.read("views/projects-#{Project.count}/") + assert_equal "Hello World", controller.cache_store.read("views/path/projects-#{Project.count}") end def view_cache_dependencies; end diff --git a/actionview/test/fixtures/actionpack/layouts/builder.builder b/actionview/test/fixtures/actionpack/layouts/builder.builder index 7c7d4b2dd1..c55488edd0 100644 --- a/actionview/test/fixtures/actionpack/layouts/builder.builder +++ b/actionview/test/fixtures/actionpack/layouts/builder.builder @@ -1,3 +1,3 @@ xml.wrapper do xml << yield -end
\ No newline at end of file +end diff --git a/actionview/test/fixtures/actionpack/test/_hello.builder b/actionview/test/fixtures/actionpack/test/_hello.builder index ef52f632d1..fc72df16d0 100644 --- a/actionview/test/fixtures/actionpack/test/_hello.builder +++ b/actionview/test/fixtures/actionpack/test/_hello.builder @@ -1 +1 @@ -xm.hello
\ No newline at end of file +xm.hello diff --git a/actionview/test/fixtures/actionpack/test/formatted_xml_erb.builder b/actionview/test/fixtures/actionpack/test/formatted_xml_erb.builder index 14fd3549fb..f98aaa34a5 100644 --- a/actionview/test/fixtures/actionpack/test/formatted_xml_erb.builder +++ b/actionview/test/fixtures/actionpack/test/formatted_xml_erb.builder @@ -1 +1 @@ -xml.test 'failed'
\ No newline at end of file +xml.test "failed" diff --git a/actionview/test/fixtures/actionpack/test/hello.builder b/actionview/test/fixtures/actionpack/test/hello.builder index a471553941..b8ab17ad5b 100644 --- a/actionview/test/fixtures/actionpack/test/hello.builder +++ b/actionview/test/fixtures/actionpack/test/hello.builder @@ -1,4 +1,4 @@ xml.html do xml.p "Hello #{@name}" - xml << render(:file => "test/greeting") -end
\ No newline at end of file + xml << render(file: "test/greeting") +end diff --git a/actionview/test/fixtures/actionpack/test/hello_world_container.builder b/actionview/test/fixtures/actionpack/test/hello_world_container.builder index e48d75c405..24032ab5e0 100644 --- a/actionview/test/fixtures/actionpack/test/hello_world_container.builder +++ b/actionview/test/fixtures/actionpack/test/hello_world_container.builder @@ -1,3 +1,3 @@ xml.test do - render :partial => 'hello', :locals => { :xm => xml } -end
\ No newline at end of file + render partial: "hello", locals: { xm: xml } +end diff --git a/actionview/test/fixtures/actionpack/test/hello_xml_world.builder b/actionview/test/fixtures/actionpack/test/hello_xml_world.builder index e7081b89fe..d16bb6b5cb 100644 --- a/actionview/test/fixtures/actionpack/test/hello_xml_world.builder +++ b/actionview/test/fixtures/actionpack/test/hello_xml_world.builder @@ -8,4 +8,4 @@ xml.html do xml.p "monks" xml.p "wiseguys" end -end
\ No newline at end of file +end diff --git a/actionview/test/fixtures/actionpack/test/non_erb_block_content_for.builder b/actionview/test/fixtures/actionpack/test/non_erb_block_content_for.builder index d539a425a4..cd65da751b 100644 --- a/actionview/test/fixtures/actionpack/test/non_erb_block_content_for.builder +++ b/actionview/test/fixtures/actionpack/test/non_erb_block_content_for.builder @@ -1,4 +1,4 @@ content_for :title do - 'Putting stuff in the title!' + "Putting stuff in the title!" end xml << "Great stuff!" diff --git a/actionview/test/fixtures/comments/empty.html+grid.erb b/actionview/test/fixtures/comments/empty.html+grid.erb new file mode 100644 index 0000000000..dc3fa32a81 --- /dev/null +++ b/actionview/test/fixtures/comments/empty.html+grid.erb @@ -0,0 +1 @@ +<h1>No Comment</h1> diff --git a/actionview/test/fixtures/comments/empty.html.builder b/actionview/test/fixtures/comments/empty.html.builder index 2b0c7207a3..12d6fdd9a5 100644 --- a/actionview/test/fixtures/comments/empty.html.builder +++ b/actionview/test/fixtures/comments/empty.html.builder @@ -1 +1 @@ -xml.h1 'No Comment'
\ No newline at end of file +xml.h1 "No Comment" diff --git a/actionview/test/fixtures/ruby_template.ruby b/actionview/test/fixtures/ruby_template.ruby index 5097bce47c..93334610a8 100644 --- a/actionview/test/fixtures/ruby_template.ruby +++ b/actionview/test/fixtures/ruby_template.ruby @@ -1,2 +1,2 @@ -body = "" +body = "".dup body << ["Hello", "from", "Ruby", "code"].join(" ") diff --git a/actionview/test/fixtures/test/_cached_nested_cached_customer.erb b/actionview/test/fixtures/test/_cached_nested_cached_customer.erb new file mode 100644 index 0000000000..01bf025cd3 --- /dev/null +++ b/actionview/test/fixtures/test/_cached_nested_cached_customer.erb @@ -0,0 +1,3 @@ +<% cache cached_customer do %> + <%= render partial: "test/cached_customer", locals: { cached_customer: cached_customer } %> +<% end %> diff --git a/actionview/test/fixtures/test/_nested_cached_customer.erb b/actionview/test/fixtures/test/_nested_cached_customer.erb new file mode 100644 index 0000000000..f43adc94c9 --- /dev/null +++ b/actionview/test/fixtures/test/_nested_cached_customer.erb @@ -0,0 +1 @@ +<%= render partial: "test/cached_customer", locals: { cached_customer: cached_customer } %> diff --git a/actionview/test/fixtures/test/_partial_with_variants.html+grid.erb b/actionview/test/fixtures/test/_partial_with_variants.html+grid.erb new file mode 100644 index 0000000000..225363c8c3 --- /dev/null +++ b/actionview/test/fixtures/test/_partial_with_variants.html+grid.erb @@ -0,0 +1 @@ +<h1>Partial with variants</h1> diff --git a/actionview/test/fixtures/test/hello.builder b/actionview/test/fixtures/test/hello.builder index a471553941..b8ab17ad5b 100644 --- a/actionview/test/fixtures/test/hello.builder +++ b/actionview/test/fixtures/test/hello.builder @@ -1,4 +1,4 @@ xml.html do xml.p "Hello #{@name}" - xml << render(:file => "test/greeting") -end
\ No newline at end of file + xml << render(file: "test/greeting") +end diff --git a/actionview/test/template/asset_tag_helper_test.rb b/actionview/test/template/asset_tag_helper_test.rb index 07a6452cc1..d1190b1bd7 100644 --- a/actionview/test/template/asset_tag_helper_test.rb +++ b/actionview/test/template/asset_tag_helper_test.rb @@ -53,6 +53,7 @@ class AssetTagHelperTest < ActionView::TestCase %(auto_discovery_link_tag) => %(<link href="http://www.example.com" rel="alternate" title="RSS" type="application/rss+xml" />), %(auto_discovery_link_tag(:rss)) => %(<link href="http://www.example.com" rel="alternate" title="RSS" type="application/rss+xml" />), %(auto_discovery_link_tag(:atom)) => %(<link href="http://www.example.com" rel="alternate" title="ATOM" type="application/atom+xml" />), + %(auto_discovery_link_tag(:json)) => %(<link href="http://www.example.com" rel="alternate" title="JSON" type="application/json" />), %(auto_discovery_link_tag(:rss, :action => "feed")) => %(<link href="http://www.example.com" rel="alternate" title="RSS" type="application/rss+xml" />), %(auto_discovery_link_tag(:rss, "http://localhost/feed")) => %(<link href="http://localhost/feed" rel="alternate" title="RSS" type="application/rss+xml" />), %(auto_discovery_link_tag(:rss, "//localhost/feed")) => %(<link href="//localhost/feed" rel="alternate" title="RSS" type="application/rss+xml" />), @@ -196,7 +197,10 @@ class AssetTagHelperTest < ActionView::TestCase %(image_tag("mouse.png", :alt => nil)) => %(<img src="/images/mouse.png" />), %(image_tag("data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==", :alt => nil)) => %(<img src="data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" />), %(image_tag("")) => %(<img src="" />), - %(image_tag("gold.png", data: { title: 'Rails Application' })) => %(<img data-title="Rails Application" src="/images/gold.png" alt="Gold" />) + %(image_tag("gold.png", data: { title: 'Rails Application' })) => %(<img data-title="Rails Application" src="/images/gold.png" alt="Gold" />), + %(image_tag("rss.gif", srcset: "/assets/pic_640.jpg 640w, /assets/pic_1024.jpg 1024w")) => %(<img srcset="/assets/pic_640.jpg 640w, /assets/pic_1024.jpg 1024w" src="/images/rss.gif" alt="Rss" />), + %(image_tag("rss.gif", srcset: { "pic_640.jpg" => "640w", "pic_1024.jpg" => "1024w" })) => %(<img srcset="/images/pic_640.jpg 640w, /images/pic_1024.jpg 1024w" src="/images/rss.gif" alt="Rss" />), + %(image_tag("rss.gif", srcset: [["pic_640.jpg", "640w"], ["pic_1024.jpg", "1024w"]])) => %(<img srcset="/images/pic_640.jpg 640w, /images/pic_1024.jpg 1024w" src="/images/rss.gif" alt="Rss" />) } FaviconLinkToTag = { @@ -709,13 +713,13 @@ class AssetTagHelperNonVhostTest < ActionView::TestCase def test_should_wildcard_asset_host @controller.config.asset_host = "http://a%d.example.com" - assert_match(%r(http://a[0123].example.com), compute_asset_host("foo")) + assert_match(%r(http://a[0123]\.example\.com), compute_asset_host("foo")) end def test_should_wildcard_asset_host_between_zero_and_four @controller.config.asset_host = "http://a%d.example.com" - assert_match(%r(http://a[0123].example.com/collaboration/hieraki/images/xml.png), image_path("xml.png")) - assert_match(%r(http://a[0123].example.com/collaboration/hieraki/images/xml.png), image_url("xml.png")) + assert_match(%r(http://a[0123]\.example\.com/collaboration/hieraki/images/xml\.png), image_path("xml.png")) + assert_match(%r(http://a[0123]\.example\.com/collaboration/hieraki/images/xml\.png), image_url("xml.png")) end def test_asset_host_without_protocol_should_be_protocol_relative diff --git a/actionview/test/template/atom_feed_helper_test.rb b/actionview/test/template/atom_feed_helper_test.rb index 1245a1a966..7fa5e042fb 100644 --- a/actionview/test/template/atom_feed_helper_test.rb +++ b/actionview/test/template/atom_feed_helper_test.rb @@ -194,7 +194,7 @@ class ScrollsController < ActionController::Base FEEDS["provide_builder"] = <<-'EOT' # we pass in the new_xml to the helper so it doesn't # call anything on the original builder - new_xml = Builder::XmlMarkup.new(:target=>'') + new_xml = Builder::XmlMarkup.new(:target=>''.dup) atom_feed(:xml => new_xml) do |feed| feed.title("My great blog!") feed.updated(@scrolls.first.created_at) @@ -301,8 +301,8 @@ class AtomFeedTest < ActionController::TestCase with_restful_routing(:scrolls) do get :index, params: { id: "feed_with_atomPub_namespace" } assert_match %r{xml:lang="en-US"}, @response.body - assert_match %r{xmlns="http://www.w3.org/2005/Atom"}, @response.body - assert_match %r{xmlns:app="http://www.w3.org/2007/app"}, @response.body + assert_match %r{xmlns="http://www\.w3\.org/2005/Atom"}, @response.body + assert_match %r{xmlns:app="http://www\.w3\.org/2007/app"}, @response.body end end @@ -319,7 +319,7 @@ class AtomFeedTest < ActionController::TestCase with_restful_routing(:scrolls) do get :index, params: { id: "feed_with_xml_processing_instructions" } assert_match %r{<\?xml-stylesheet [^\?]*type="text/css"}, @response.body - assert_match %r{<\?xml-stylesheet [^\?]*href="t.css"}, @response.body + assert_match %r{<\?xml-stylesheet [^\?]*href="t\.css"}, @response.body end end @@ -334,7 +334,7 @@ class AtomFeedTest < ActionController::TestCase def test_feed_xhtml with_restful_routing(:scrolls) do get :index, params: { id: "feed_with_xhtml_content" } - assert_match %r{xmlns="http://www.w3.org/1999/xhtml"}, @response.body + assert_match %r{xmlns="http://www\.w3\.org/1999/xhtml"}, @response.body assert_select "summary", text: /Something Boring/ assert_select "summary", text: /after 2/ end diff --git a/actionview/test/template/date_helper_test.rb b/actionview/test/template/date_helper_test.rb index d257147e1f..b9b8194e69 100644 --- a/actionview/test/template/date_helper_test.rb +++ b/actionview/test/template/date_helper_test.rb @@ -128,11 +128,29 @@ class DateHelperTest < ActionView::TestCase assert_distance_of_time_in_words(from) end - def test_distance_in_words_with_mathn_required - # test we avoid Integer#/ (redefined by mathn) - silence_warnings { require "mathn" } + def test_distance_in_words_with_nil_input + assert_raises(ArgumentError) { distance_of_time_in_words(nil) } + assert_raises(ArgumentError) { distance_of_time_in_words(0, nil) } + end + + def test_distance_in_words_with_mixed_argument_types + assert_equal "1 minute", distance_of_time_in_words(0, Time.at(60)) + assert_equal "10 minutes", distance_of_time_in_words(Time.at(600), 0) + end + + def test_distance_in_words_doesnt_use_the_quotient_operator + rubinius_skip "Date is written in Ruby and relies on Fixnum#/" + jruby_skip "Date is written in Ruby and relies on Fixnum#/" + + klass = RUBY_VERSION > "2.4" ? Integer : Fixnum + + # Make sure that we avoid {Integer,Fixnum}#/ (redefined by mathn) + klass.send :private, :/ + from = Time.utc(2004, 6, 6, 21, 45, 0) assert_distance_of_time_in_words(from) + ensure + klass.send :public, :/ end def test_time_ago_in_words_passes_include_seconds @@ -196,7 +214,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_day - expected = %(<select id="date_day" name="date[day]">\n) + expected = %(<select id="date_day" name="date[day]">\n).dup expected << %(<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16" selected="selected">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n) expected << "</select>\n" @@ -205,7 +223,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_day_with_blank - expected = %(<select id="date_day" name="date[day]">\n) + expected = %(<select id="date_day" name="date[day]">\n).dup expected << %(<option value=""></option>\n<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16" selected="selected">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n) expected << "</select>\n" @@ -214,7 +232,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_day_nil_with_blank - expected = %(<select id="date_day" name="date[day]">\n) + expected = %(<select id="date_day" name="date[day]">\n).dup expected << %(<option value=""></option>\n<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n) expected << "</select>\n" @@ -222,7 +240,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_day_with_two_digit_numbers - expected = %(<select id="date_day" name="date[day]">\n) + expected = %(<select id="date_day" name="date[day]">\n).dup expected << %(<option value="1">01</option>\n<option selected="selected" value="2">02</option>\n<option value="3">03</option>\n<option value="4">04</option>\n<option value="5">05</option>\n<option value="6">06</option>\n<option value="7">07</option>\n<option value="8">08</option>\n<option value="9">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n) expected << "</select>\n" @@ -231,7 +249,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_day_with_html_options - expected = %(<select id="date_day" name="date[day]" class="selector">\n) + expected = %(<select id="date_day" name="date[day]" class="selector">\n).dup expected << %(<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16" selected="selected">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n) expected << "</select>\n" @@ -240,7 +258,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_day_with_default_prompt - expected = %(<select id="date_day" name="date[day]">\n) + expected = %(<select id="date_day" name="date[day]">\n).dup expected << %(<option value="">Day</option>\n<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16" selected="selected">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n) expected << "</select>\n" @@ -248,7 +266,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_day_with_custom_prompt - expected = %(<select id="date_day" name="date[day]">\n) + expected = %(<select id="date_day" name="date[day]">\n).dup expected << %(<option value="">Choose day</option>\n<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16" selected="selected">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n) expected << "</select>\n" @@ -256,7 +274,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_day_with_generic_with_css_classes - expected = %(<select id="date_day" name="date[day]" class="day">\n) + expected = %(<select id="date_day" name="date[day]" class="day">\n).dup expected << %(<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16" selected="selected">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n) expected << "</select>\n" @@ -264,7 +282,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_day_with_custom_with_css_classes - expected = %(<select id="date_day" name="date[day]" class="my-day">\n) + expected = %(<select id="date_day" name="date[day]" class="my-day">\n).dup expected << %(<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16" selected="selected">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n) expected << "</select>\n" @@ -272,7 +290,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_month - expected = %(<select id="date_month" name="date[month]">\n) + expected = %(<select id="date_month" name="date[month]">\n).dup expected << %(<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option value="6">June</option>\n<option value="7">July</option>\n<option value="8" selected="selected">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n) expected << "</select>\n" @@ -281,7 +299,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_month_with_two_digit_numbers - expected = %(<select id="date_month" name="date[month]">\n) + expected = %(<select id="date_month" name="date[month]">\n).dup expected << %(<option value="1">01</option>\n<option value="2">02</option>\n<option value="3">03</option>\n<option value="4">04</option>\n<option value="5">05</option>\n<option value="6">06</option>\n<option value="7">07</option>\n<option value="8" selected="selected">08</option>\n<option value="9">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n) expected << "</select>\n" @@ -290,7 +308,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_month_with_disabled - expected = %(<select id="date_month" name="date[month]" disabled="disabled">\n) + expected = %(<select id="date_month" name="date[month]" disabled="disabled">\n).dup expected << %(<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option value="6">June</option>\n<option value="7">July</option>\n<option value="8" selected="selected">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n) expected << "</select>\n" @@ -299,7 +317,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_month_with_field_name_override - expected = %(<select id="date_mois" name="date[mois]">\n) + expected = %(<select id="date_mois" name="date[mois]">\n).dup expected << %(<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option value="6">June</option>\n<option value="7">July</option>\n<option value="8" selected="selected">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n) expected << "</select>\n" @@ -308,7 +326,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_month_with_blank - expected = %(<select id="date_month" name="date[month]">\n) + expected = %(<select id="date_month" name="date[month]">\n).dup expected << %(<option value=""></option>\n<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option value="6">June</option>\n<option value="7">July</option>\n<option value="8" selected="selected">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n) expected << "</select>\n" @@ -317,7 +335,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_month_nil_with_blank - expected = %(<select id="date_month" name="date[month]">\n) + expected = %(<select id="date_month" name="date[month]">\n).dup expected << %(<option value=""></option>\n<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option value="6">June</option>\n<option value="7">July</option>\n<option value="8">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n) expected << "</select>\n" @@ -325,7 +343,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_month_with_numbers - expected = %(<select id="date_month" name="date[month]">\n) + expected = %(<select id="date_month" name="date[month]">\n).dup expected << %(<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8" selected="selected">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n) expected << "</select>\n" @@ -334,7 +352,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_month_with_numbers_and_names - expected = %(<select id="date_month" name="date[month]">\n) + expected = %(<select id="date_month" name="date[month]">\n).dup expected << %(<option value="1">1 - January</option>\n<option value="2">2 - February</option>\n<option value="3">3 - March</option>\n<option value="4">4 - April</option>\n<option value="5">5 - May</option>\n<option value="6">6 - June</option>\n<option value="7">7 - July</option>\n<option value="8" selected="selected">8 - August</option>\n<option value="9">9 - September</option>\n<option value="10">10 - October</option>\n<option value="11">11 - November</option>\n<option value="12">12 - December</option>\n) expected << "</select>\n" @@ -343,7 +361,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_month_with_format_string - expected = %(<select id="date_month" name="date[month]">\n) + expected = %(<select id="date_month" name="date[month]">\n).dup expected << %(<option value="1">January (01)</option>\n<option value="2">February (02)</option>\n<option value="3">March (03)</option>\n<option value="4">April (04)</option>\n<option value="5">May (05)</option>\n<option value="6">June (06)</option>\n<option value="7">July (07)</option>\n<option value="8" selected="selected">August (08)</option>\n<option value="9">September (09)</option>\n<option value="10">October (10)</option>\n<option value="11">November (11)</option>\n<option value="12">December (12)</option>\n) expected << "</select>\n" @@ -353,7 +371,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_month_with_numbers_and_names_with_abbv - expected = %(<select id="date_month" name="date[month]">\n) + expected = %(<select id="date_month" name="date[month]">\n).dup expected << %(<option value="1">1 - Jan</option>\n<option value="2">2 - Feb</option>\n<option value="3">3 - Mar</option>\n<option value="4">4 - Apr</option>\n<option value="5">5 - May</option>\n<option value="6">6 - Jun</option>\n<option value="7">7 - Jul</option>\n<option value="8" selected="selected">8 - Aug</option>\n<option value="9">9 - Sep</option>\n<option value="10">10 - Oct</option>\n<option value="11">11 - Nov</option>\n<option value="12">12 - Dec</option>\n) expected << "</select>\n" @@ -362,7 +380,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_month_with_abbv - expected = %(<select id="date_month" name="date[month]">\n) + expected = %(<select id="date_month" name="date[month]">\n).dup expected << %(<option value="1">Jan</option>\n<option value="2">Feb</option>\n<option value="3">Mar</option>\n<option value="4">Apr</option>\n<option value="5">May</option>\n<option value="6">Jun</option>\n<option value="7">Jul</option>\n<option value="8" selected="selected">Aug</option>\n<option value="9">Sep</option>\n<option value="10">Oct</option>\n<option value="11">Nov</option>\n<option value="12">Dec</option>\n) expected << "</select>\n" @@ -373,7 +391,7 @@ class DateHelperTest < ActionView::TestCase def test_select_month_with_custom_names month_names = %w(nil Januar Februar Marts April Maj Juni Juli August September Oktober November December) - expected = %(<select id="date_month" name="date[month]">\n) + expected = %(<select id="date_month" name="date[month]">\n).dup 1.upto(12) { |month| expected << %(<option value="#{month}"#{' selected="selected"' if month == 8}>#{month_names[month]}</option>\n) } expected << "</select>\n" @@ -384,7 +402,7 @@ class DateHelperTest < ActionView::TestCase def test_select_month_with_zero_indexed_custom_names month_names = %w(Januar Februar Marts April Maj Juni Juli August September Oktober November December) - expected = %(<select id="date_month" name="date[month]">\n) + expected = %(<select id="date_month" name="date[month]">\n).dup 1.upto(12) { |month| expected << %(<option value="#{month}"#{' selected="selected"' if month == 8}>#{month_names[month - 1]}</option>\n) } expected << "</select>\n" @@ -401,7 +419,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_month_with_html_options - expected = %(<select id="date_month" name="date[month]" class="selector" accesskey="M">\n) + expected = %(<select id="date_month" name="date[month]" class="selector" accesskey="M">\n).dup expected << %(<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option value="6">June</option>\n<option value="7">July</option>\n<option value="8" selected="selected">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n) expected << "</select>\n" @@ -409,7 +427,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_month_with_default_prompt - expected = %(<select id="date_month" name="date[month]">\n) + expected = %(<select id="date_month" name="date[month]">\n).dup expected << %(<option value="">Month</option>\n<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option value="6">June</option>\n<option value="7">July</option>\n<option value="8" selected="selected">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n) expected << "</select>\n" @@ -417,7 +435,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_month_with_custom_prompt - expected = %(<select id="date_month" name="date[month]">\n) + expected = %(<select id="date_month" name="date[month]">\n).dup expected << %(<option value="">Choose month</option>\n<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option value="6">June</option>\n<option value="7">July</option>\n<option value="8" selected="selected">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n) expected << "</select>\n" @@ -425,7 +443,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_month_with_generic_with_css_classes - expected = %(<select id="date_month" name="date[month]" class="month">\n) + expected = %(<select id="date_month" name="date[month]" class="month">\n).dup expected << %(<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option value="6">June</option>\n<option value="7">July</option>\n<option value="8" selected="selected">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n) expected << "</select>\n" @@ -433,7 +451,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_month_with_custom_with_css_classes - expected = %(<select id="date_month" name="date[month]" class="my-month">\n) + expected = %(<select id="date_month" name="date[month]" class="my-month">\n).dup expected << %(<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option value="6">June</option>\n<option value="7">July</option>\n<option value="8" selected="selected">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n) expected << "</select>\n" @@ -441,7 +459,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_year - expected = %(<select id="date_year" name="date[year]">\n) + expected = %(<select id="date_year" name="date[year]">\n).dup expected << %(<option value="2003" selected="selected">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n) expected << "</select>\n" @@ -450,7 +468,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_year_with_disabled - expected = %(<select id="date_year" name="date[year]" disabled="disabled">\n) + expected = %(<select id="date_year" name="date[year]" disabled="disabled">\n).dup expected << %(<option value="2003" selected="selected">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n) expected << "</select>\n" @@ -459,7 +477,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_year_with_field_name_override - expected = %(<select id="date_annee" name="date[annee]">\n) + expected = %(<select id="date_annee" name="date[annee]">\n).dup expected << %(<option value="2003" selected="selected">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n) expected << "</select>\n" @@ -468,7 +486,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_year_with_type_discarding - expected = %(<select id="date_year" name="date_year">\n) + expected = %(<select id="date_year" name="date_year">\n).dup expected << %(<option value="2003" selected="selected">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n) expected << "</select>\n" @@ -479,7 +497,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_year_descending - expected = %(<select id="date_year" name="date[year]">\n) + expected = %(<select id="date_year" name="date[year]">\n).dup expected << %(<option value="2005" selected="selected">2005</option>\n<option value="2004">2004</option>\n<option value="2003">2003</option>\n) expected << "</select>\n" @@ -496,7 +514,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_year_with_html_options - expected = %(<select id="date_year" name="date[year]" class="selector" accesskey="M">\n) + expected = %(<select id="date_year" name="date[year]" class="selector" accesskey="M">\n).dup expected << %(<option value="2003" selected="selected">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n) expected << "</select>\n" @@ -504,7 +522,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_year_with_default_prompt - expected = %(<select id="date_year" name="date[year]">\n) + expected = %(<select id="date_year" name="date[year]">\n).dup expected << %(<option value="">Year</option>\n<option value="2003">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n) expected << "</select>\n" @@ -512,7 +530,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_year_with_custom_prompt - expected = %(<select id="date_year" name="date[year]">\n) + expected = %(<select id="date_year" name="date[year]">\n).dup expected << %(<option value="">Choose year</option>\n<option value="2003">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n) expected << "</select>\n" @@ -520,7 +538,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_year_with_generic_with_css_classes - expected = %(<select id="date_year" name="date[year]" class="year">\n) + expected = %(<select id="date_year" name="date[year]" class="year">\n).dup expected << %(<option value="2003">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n) expected << "</select>\n" @@ -528,7 +546,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_year_with_custom_with_css_classes - expected = %(<select id="date_year" name="date[year]" class="my-year">\n) + expected = %(<select id="date_year" name="date[year]" class="my-year">\n).dup expected << %(<option value="2003">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n) expected << "</select>\n" @@ -536,14 +554,14 @@ class DateHelperTest < ActionView::TestCase end def test_select_year_with_position - expected = %(<select id="date_year_1i" name="date[year(1i)]">\n) + expected = %(<select id="date_year_1i" name="date[year(1i)]">\n).dup expected << %(<option value="2003">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n) expected << "</select>\n" assert_dom_equal expected, select_year(Date.current, include_position: true, start_year: 2003, end_year: 2005) end def test_select_hour - expected = %(<select id="date_hour" name="date[hour]">\n) + expected = %(<select id="date_hour" name="date[hour]">\n).dup expected << %(<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08" selected="selected">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n) expected << "</select>\n" @@ -551,7 +569,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_hour_with_ampm - expected = %(<select id="date_hour" name="date[hour]">\n) + expected = %(<select id="date_hour" name="date[hour]">\n).dup expected << %(<option value="00">12 AM</option>\n<option value="01">01 AM</option>\n<option value="02">02 AM</option>\n<option value="03">03 AM</option>\n<option value="04">04 AM</option>\n<option value="05">05 AM</option>\n<option value="06">06 AM</option>\n<option value="07">07 AM</option>\n<option value="08" selected="selected">08 AM</option>\n<option value="09">09 AM</option>\n<option value="10">10 AM</option>\n<option value="11">11 AM</option>\n<option value="12">12 PM</option>\n<option value="13">01 PM</option>\n<option value="14">02 PM</option>\n<option value="15">03 PM</option>\n<option value="16">04 PM</option>\n<option value="17">05 PM</option>\n<option value="18">06 PM</option>\n<option value="19">07 PM</option>\n<option value="20">08 PM</option>\n<option value="21">09 PM</option>\n<option value="22">10 PM</option>\n<option value="23">11 PM</option>\n) expected << "</select>\n" @@ -559,7 +577,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_hour_with_disabled - expected = %(<select id="date_hour" name="date[hour]" disabled="disabled">\n) + expected = %(<select id="date_hour" name="date[hour]" disabled="disabled">\n).dup expected << %(<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08" selected="selected">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n) expected << "</select>\n" @@ -567,7 +585,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_hour_with_field_name_override - expected = %(<select id="date_heure" name="date[heure]">\n) + expected = %(<select id="date_heure" name="date[heure]">\n).dup expected << %(<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08" selected="selected">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n) expected << "</select>\n" @@ -575,7 +593,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_hour_with_blank - expected = %(<select id="date_hour" name="date[hour]">\n) + expected = %(<select id="date_hour" name="date[hour]">\n).dup expected << %(<option value=""></option>\n<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08" selected="selected">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n) expected << "</select>\n" @@ -583,7 +601,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_hour_nil_with_blank - expected = %(<select id="date_hour" name="date[hour]">\n) + expected = %(<select id="date_hour" name="date[hour]">\n).dup expected << %(<option value=""></option>\n<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n) expected << "</select>\n" @@ -591,7 +609,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_hour_with_html_options - expected = %(<select id="date_hour" name="date[hour]" class="selector" accesskey="M">\n) + expected = %(<select id="date_hour" name="date[hour]" class="selector" accesskey="M">\n).dup expected << %(<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08" selected="selected">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n) expected << "</select>\n" @@ -599,7 +617,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_hour_with_default_prompt - expected = %(<select id="date_hour" name="date[hour]">\n) + expected = %(<select id="date_hour" name="date[hour]">\n).dup expected << %(<option value="">Hour</option>\n<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08" selected="selected">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n) expected << "</select>\n" @@ -607,7 +625,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_hour_with_custom_prompt - expected = %(<select id="date_hour" name="date[hour]">\n) + expected = %(<select id="date_hour" name="date[hour]">\n).dup expected << %(<option value="">Choose hour</option>\n<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08" selected="selected">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n) expected << "</select>\n" @@ -615,7 +633,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_hour_with_generic_with_css_classes - expected = %(<select id="date_hour" name="date[hour]" class="hour">\n) + expected = %(<select id="date_hour" name="date[hour]" class="hour">\n).dup expected << %(<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08" selected="selected">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n) expected << "</select>\n" @@ -623,7 +641,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_hour_with_custom_with_css_classes - expected = %(<select id="date_hour" name="date[hour]" class="my-hour">\n) + expected = %(<select id="date_hour" name="date[hour]" class="my-hour">\n).dup expected << %(<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08" selected="selected">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n) expected << "</select>\n" @@ -631,7 +649,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_minute - expected = %(<select id="date_minute" name="date[minute]">\n) + expected = %(<select id="date_minute" name="date[minute]">\n).dup expected << %(<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04" selected="selected">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n) expected << "</select>\n" @@ -639,7 +657,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_minute_with_disabled - expected = %(<select id="date_minute" name="date[minute]" disabled="disabled">\n) + expected = %(<select id="date_minute" name="date[minute]" disabled="disabled">\n).dup expected << %(<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04" selected="selected">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n) expected << "</select>\n" @@ -647,7 +665,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_minute_with_field_name_override - expected = %(<select id="date_minuto" name="date[minuto]">\n) + expected = %(<select id="date_minuto" name="date[minuto]">\n).dup expected << %(<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04" selected="selected">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n) expected << "</select>\n" @@ -655,7 +673,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_minute_with_blank - expected = %(<select id="date_minute" name="date[minute]">\n) + expected = %(<select id="date_minute" name="date[minute]">\n).dup expected << %(<option value=""></option>\n<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04" selected="selected">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n) expected << "</select>\n" @@ -663,7 +681,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_minute_with_blank_and_step - expected = %(<select id="date_minute" name="date[minute]">\n) + expected = %(<select id="date_minute" name="date[minute]">\n).dup expected << %(<option value=""></option>\n<option value="00">00</option>\n<option value="15">15</option>\n<option value="30">30</option>\n<option value="45">45</option>\n) expected << "</select>\n" @@ -671,7 +689,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_minute_nil_with_blank - expected = %(<select id="date_minute" name="date[minute]">\n) + expected = %(<select id="date_minute" name="date[minute]">\n).dup expected << %(<option value=""></option>\n<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n) expected << "</select>\n" @@ -679,7 +697,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_minute_nil_with_blank_and_step - expected = %(<select id="date_minute" name="date[minute]">\n) + expected = %(<select id="date_minute" name="date[minute]">\n).dup expected << %(<option value=""></option>\n<option value="00">00</option>\n<option value="15">15</option>\n<option value="30">30</option>\n<option value="45">45</option>\n) expected << "</select>\n" @@ -695,7 +713,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_minute_with_html_options - expected = %(<select id="date_minute" name="date[minute]" class="selector" accesskey="M">\n) + expected = %(<select id="date_minute" name="date[minute]" class="selector" accesskey="M">\n).dup expected << %(<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04" selected="selected">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n) expected << "</select>\n" @@ -703,7 +721,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_minute_with_default_prompt - expected = %(<select id="date_minute" name="date[minute]">\n) + expected = %(<select id="date_minute" name="date[minute]">\n).dup expected << %(<option value="">Minute</option>\n<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04" selected="selected">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n) expected << "</select>\n" @@ -711,7 +729,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_minute_with_custom_prompt - expected = %(<select id="date_minute" name="date[minute]">\n) + expected = %(<select id="date_minute" name="date[minute]">\n).dup expected << %(<option value="">Choose minute</option>\n<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04" selected="selected">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n) expected << "</select>\n" @@ -719,7 +737,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_minute_with_generic_with_css_classes - expected = %(<select id="date_minute" name="date[minute]" class="minute">\n) + expected = %(<select id="date_minute" name="date[minute]" class="minute">\n).dup expected << %(<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04" selected="selected">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n) expected << "</select>\n" @@ -727,7 +745,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_minute_with_custom_with_css_classes - expected = %(<select id="date_minute" name="date[minute]" class="my-minute">\n) + expected = %(<select id="date_minute" name="date[minute]" class="my-minute">\n).dup expected << %(<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04" selected="selected">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n) expected << "</select>\n" @@ -735,7 +753,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_second - expected = %(<select id="date_second" name="date[second]">\n) + expected = %(<select id="date_second" name="date[second]">\n).dup expected << %(<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18" selected="selected">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n) expected << "</select>\n" @@ -743,7 +761,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_second_with_disabled - expected = %(<select id="date_second" name="date[second]" disabled="disabled">\n) + expected = %(<select id="date_second" name="date[second]" disabled="disabled">\n).dup expected << %(<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18" selected="selected">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n) expected << "</select>\n" @@ -751,7 +769,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_second_with_field_name_override - expected = %(<select id="date_segundo" name="date[segundo]">\n) + expected = %(<select id="date_segundo" name="date[segundo]">\n).dup expected << %(<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18" selected="selected">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n) expected << "</select>\n" @@ -759,7 +777,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_second_with_blank - expected = %(<select id="date_second" name="date[second]">\n) + expected = %(<select id="date_second" name="date[second]">\n).dup expected << %(<option value=""></option>\n<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18" selected="selected">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n) expected << "</select>\n" @@ -767,7 +785,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_second_nil_with_blank - expected = %(<select id="date_second" name="date[second]">\n) + expected = %(<select id="date_second" name="date[second]">\n).dup expected << %(<option value=""></option>\n<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n) expected << "</select>\n" @@ -775,7 +793,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_second_with_html_options - expected = %(<select id="date_second" name="date[second]" class="selector" accesskey="M">\n) + expected = %(<select id="date_second" name="date[second]" class="selector" accesskey="M">\n).dup expected << %(<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18" selected="selected">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n) expected << "</select>\n" @@ -783,7 +801,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_second_with_default_prompt - expected = %(<select id="date_second" name="date[second]">\n) + expected = %(<select id="date_second" name="date[second]">\n).dup expected << %(<option value="">Seconds</option>\n<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18" selected="selected">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n) expected << "</select>\n" @@ -791,7 +809,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_second_with_custom_prompt - expected = %(<select id="date_second" name="date[second]">\n) + expected = %(<select id="date_second" name="date[second]">\n).dup expected << %(<option value="">Choose seconds</option>\n<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18" selected="selected">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n) expected << "</select>\n" @@ -799,7 +817,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_second_with_generic_with_css_classes - expected = %(<select id="date_second" name="date[second]" class="second">\n) + expected = %(<select id="date_second" name="date[second]" class="second">\n).dup expected << %(<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18" selected="selected">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n) expected << "</select>\n" @@ -807,7 +825,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_second_with_custom_with_css_classes - expected = %(<select id="date_second" name="date[second]" class="my-second">\n) + expected = %(<select id="date_second" name="date[second]" class="my-second">\n).dup expected << %(<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18" selected="selected">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n) expected << "</select>\n" @@ -815,7 +833,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_date - expected = %(<select id="date_first_year" name="date[first][year]">\n) + expected = %(<select id="date_first_year" name="date[first][year]">\n).dup expected << %(<option value="2003" selected="selected">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n) expected << "</select>\n" @@ -840,7 +858,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_date_with_order - expected = %(<select id="date_first_month" name="date[first][month]">\n) + expected = %(<select id="date_first_month" name="date[first][month]">\n).dup expected << %(<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option value="6">June</option>\n<option value="7">July</option>\n<option value="8" selected="selected">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n) expected << "</select>\n" @@ -857,7 +875,7 @@ class DateHelperTest < ActionView::TestCase def test_select_date_with_incomplete_order # Since the order is incomplete nothing will be shown - expected = %(<input id="date_first_year" name="date[first][year]" type="hidden" value="2003" />\n) + expected = %(<input id="date_first_year" name="date[first][year]" type="hidden" value="2003" />\n).dup expected << %(<input id="date_first_month" name="date[first][month]" type="hidden" value="8" />\n) expected << %(<input id="date_first_day" name="date[first][day]" type="hidden" value="1" />\n) @@ -865,7 +883,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_date_with_disabled - expected = %(<select id="date_first_year" name="date[first][year]" disabled="disabled">\n) + expected = %(<select id="date_first_year" name="date[first][year]" disabled="disabled">\n).dup expected << %(<option value="2003" selected="selected">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n) expected << "</select>\n" @@ -881,7 +899,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_date_with_no_start_year - expected = %(<select id="date_first_year" name="date[first][year]">\n) + expected = %(<select id="date_first_year" name="date[first][year]">\n).dup (Date.today.year - 5).upto(Date.today.year + 1) do |y| if y == Date.today.year expected << %(<option value="#{y}" selected="selected">#{y}</option>\n) @@ -905,7 +923,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_date_with_no_end_year - expected = %(<select id="date_first_year" name="date[first][year]">\n) + expected = %(<select id="date_first_year" name="date[first][year]">\n).dup 2003.upto(2008) do |y| if y == 2003 expected << %(<option value="#{y}" selected="selected">#{y}</option>\n) @@ -929,7 +947,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_date_with_no_start_or_end_year - expected = %(<select id="date_first_year" name="date[first][year]">\n) + expected = %(<select id="date_first_year" name="date[first][year]">\n).dup (Date.today.year - 5).upto(Date.today.year + 5) do |y| if y == Date.today.year expected << %(<option value="#{y}" selected="selected">#{y}</option>\n) @@ -953,7 +971,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_date_with_zero_value - expected = %(<select id="date_first_year" name="date[first][year]">\n) + expected = %(<select id="date_first_year" name="date[first][year]">\n).dup expected << %(<option value="2003">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n) expected << "</select>\n" @@ -969,7 +987,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_date_with_zero_value_and_no_start_year - expected = %(<select id="date_first_year" name="date[first][year]">\n) + expected = %(<select id="date_first_year" name="date[first][year]">\n).dup (Date.today.year - 5).upto(Date.today.year + 1) { |y| expected << %(<option value="#{y}">#{y}</option>\n) } expected << "</select>\n" @@ -985,7 +1003,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_date_with_zero_value_and_no_end_year - expected = %(<select id="date_first_year" name="date[first][year]">\n) + expected = %(<select id="date_first_year" name="date[first][year]">\n).dup last_year = Time.now.year + 5 2003.upto(last_year) { |y| expected << %(<option value="#{y}">#{y}</option>\n) } expected << "</select>\n" @@ -1002,7 +1020,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_date_with_zero_value_and_no_start_and_end_year - expected = %(<select id="date_first_year" name="date[first][year]">\n) + expected = %(<select id="date_first_year" name="date[first][year]">\n).dup (Date.today.year - 5).upto(Date.today.year + 5) { |y| expected << %(<option value="#{y}">#{y}</option>\n) } expected << "</select>\n" @@ -1018,7 +1036,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_date_with_nil_value_and_no_start_and_end_year - expected = %(<select id="date_first_year" name="date[first][year]">\n) + expected = %(<select id="date_first_year" name="date[first][year]">\n).dup (Date.today.year - 5).upto(Date.today.year + 5) { |y| expected << %(<option value="#{y}">#{y}</option>\n) } expected << "</select>\n" @@ -1034,7 +1052,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_date_with_html_options - expected = %(<select id="date_first_year" name="date[first][year]" class="selector">\n) + expected = %(<select id="date_first_year" name="date[first][year]" class="selector">\n).dup expected << %(<option value="2003" selected="selected">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n) expected << "</select>\n" @@ -1050,7 +1068,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_date_with_separator - expected = %(<select id="date_first_year" name="date[first][year]">\n) + expected = %(<select id="date_first_year" name="date[first][year]">\n).dup expected << %(<option value="2003" selected="selected">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n) expected << "</select>\n" @@ -1070,7 +1088,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_date_with_separator_and_discard_day - expected = %(<select id="date_first_year" name="date[first][year]">\n) + expected = %(<select id="date_first_year" name="date[first][year]">\n).dup expected << %(<option value="2003" selected="selected">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n) expected << "</select>\n" @@ -1086,7 +1104,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_date_with_separator_discard_month_and_day - expected = %(<select id="date_first_year" name="date[first][year]">\n) + expected = %(<select id="date_first_year" name="date[first][year]">\n).dup expected << %(<option value="2003" selected="selected">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n) expected << "</select>\n" @@ -1097,7 +1115,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_date_with_hidden - expected = %(<input id="date_first_year" name="date[first][year]" type="hidden" value="2003"/>\n) + expected = %(<input id="date_first_year" name="date[first][year]" type="hidden" value="2003"/>\n).dup expected << %(<input id="date_first_month" name="date[first][month]" type="hidden" value="8" />\n) expected << %(<input id="date_first_day" name="date[first][day]" type="hidden" value="16" />\n) @@ -1106,7 +1124,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_date_with_css_classes_option - expected = %(<select id="date_first_year" name="date[first][year]" class="year">\n) + expected = %(<select id="date_first_year" name="date[first][year]" class="year">\n).dup expected << %(<option value="2003" selected="selected">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n) expected << "</select>\n" @@ -1122,7 +1140,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_date_with_custom_with_css_classes - expected = %(<select id="date_year" name="date[year]" class="my-year">\n) + expected = %(<select id="date_year" name="date[year]" class="my-year">\n).dup expected << %(<option value="2003" selected="selected">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n) expected << "</select>\n" @@ -1138,7 +1156,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_date_with_css_classes_option_and_html_class_option - expected = %(<select id="date_first_year" name="date[first][year]" class="datetime optional year">\n) + expected = %(<select id="date_first_year" name="date[first][year]" class="datetime optional year">\n).dup expected << %(<option value="2003" selected="selected">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n) expected << "</select>\n" @@ -1154,7 +1172,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_date_with_custom_with_css_classes_and_html_class_option - expected = %(<select id="date_year" name="date[year]" class="date optional my-year">\n) + expected = %(<select id="date_year" name="date[year]" class="date optional my-year">\n).dup expected << %(<option value="2003" selected="selected">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n) expected << "</select>\n" @@ -1170,7 +1188,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_date_with_partial_with_css_classes_and_html_class_option - expected = %(<select id="date_year" name="date[year]" class="date optional">\n) + expected = %(<select id="date_year" name="date[year]" class="date optional">\n).dup expected << %(<option value="2003" selected="selected">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n) expected << "</select>\n" @@ -1186,7 +1204,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_date_with_html_class_option - expected = %(<select id="date_year" name="date[year]" class="date optional custom-grid">\n) + expected = %(<select id="date_year" name="date[year]" class="date optional custom-grid">\n).dup expected << %(<option value="2003" selected="selected">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n) expected << "</select>\n" @@ -1202,7 +1220,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_datetime - expected = %(<select id="date_first_year" name="date[first][year]">\n) + expected = %(<select id="date_first_year" name="date[first][year]">\n).dup expected << %(<option value="2003" selected="selected">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n) expected << "</select>\n" @@ -1230,7 +1248,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_datetime_with_ampm - expected = %(<select id="date_first_year" name="date[first][year]">\n) + expected = %(<select id="date_first_year" name="date[first][year]">\n).dup expected << %(<option value="2003" selected="selected">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n) expected << "</select>\n" @@ -1258,7 +1276,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_datetime_with_separators - expected = %(<select id="date_first_year" name="date[first][year]">\n) + expected = %(<select id="date_first_year" name="date[first][year]">\n).dup expected << %(<option value="2003" selected="selected">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n) expected << "</select>\n" @@ -1286,7 +1304,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_datetime_with_nil_value_and_no_start_and_end_year - expected = %(<select id="date_first_year" name="date[first][year]">\n) + expected = %(<select id="date_first_year" name="date[first][year]">\n).dup (Date.today.year - 5).upto(Date.today.year + 5) { |y| expected << %(<option value="#{y}">#{y}</option>\n) } expected << "</select>\n" @@ -1314,7 +1332,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_datetime_with_html_options - expected = %(<select id="date_first_year" name="date[first][year]" class="selector">\n) + expected = %(<select id="date_first_year" name="date[first][year]" class="selector">\n).dup expected << %(<option value="2003" selected="selected">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n) expected << "</select>\n" @@ -1342,7 +1360,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_datetime_with_all_separators - expected = %(<select id="date_first_year" name="date[first][year]" class="selector">\n) + expected = %(<select id="date_first_year" name="date[first][year]" class="selector">\n).dup expected << %(<option value="2003" selected="selected">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n) expected << "</select>\n" @@ -1378,7 +1396,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_datetime_with_default_prompt - expected = %(<select id="date_first_year" name="date[first][year]">\n) + expected = %(<select id="date_first_year" name="date[first][year]">\n).dup expected << %(<option value="">Year</option>\n<option value="2003" selected="selected">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n) expected << "</select>\n" @@ -1407,7 +1425,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_datetime_with_custom_prompt - expected = %(<select id="date_first_year" name="date[first][year]">\n) + expected = %(<select id="date_first_year" name="date[first][year]">\n).dup expected << %(<option value="">Choose year</option>\n<option value="2003" selected="selected">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n) expected << "</select>\n" @@ -1436,7 +1454,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_datetime_with_generic_with_css_classes - expected = %(<select id="date_year" name="date[year]" class="year">\n) + expected = %(<select id="date_year" name="date[year]" class="year">\n).dup expected << %(<option value="2003" selected="selected">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n) expected << "</select>\n" @@ -1464,7 +1482,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_datetime_with_custom_with_css_classes - expected = %(<select id="date_year" name="date[year]" class="my-year">\n) + expected = %(<select id="date_year" name="date[year]" class="my-year">\n).dup expected << %(<option value="2003" selected="selected">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n) expected << "</select>\n" @@ -1492,7 +1510,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_datetime_with_custom_hours - expected = %(<select id="date_first_year" name="date[first][year]">\n) + expected = %(<select id="date_first_year" name="date[first][year]">\n).dup expected << %(<option value="">Choose year</option>\n<option value="2003" selected="selected">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n) expected << "</select>\n" @@ -1521,7 +1539,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_datetime_with_hidden - expected = %(<input id="date_first_year" name="date[first][year]" type="hidden" value="2003" />\n) + expected = %(<input id="date_first_year" name="date[first][year]" type="hidden" value="2003" />\n).dup expected << %(<input id="date_first_month" name="date[first][month]" type="hidden" value="8" />\n) expected << %(<input id="date_first_day" name="date[first][day]" type="hidden" value="16" />\n) expected << %(<input id="date_first_hour" name="date[first][hour]" type="hidden" value="8" />\n) @@ -1533,7 +1551,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_time - expected = %(<input name="date[year]" id="date_year" value="2003" type="hidden" />\n) + expected = %(<input name="date[year]" id="date_year" value="2003" type="hidden" />\n).dup expected << %(<input name="date[month]" id="date_month" value="8" type="hidden" />\n) expected << %(<input name="date[day]" id="date_day" value="16" type="hidden" />\n) @@ -1552,7 +1570,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_time_with_ampm - expected = %(<input name="date[year]" id="date_year" value="2003" type="hidden" />\n) + expected = %(<input name="date[year]" id="date_year" value="2003" type="hidden" />\n).dup expected << %(<input name="date[month]" id="date_month" value="8" type="hidden" />\n) expected << %(<input name="date[day]" id="date_day" value="16" type="hidden" />\n) @@ -1570,7 +1588,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_time_with_separator - expected = %(<input name="date[year]" id="date_year" value="2003" type="hidden" />\n) + expected = %(<input name="date[year]" id="date_year" value="2003" type="hidden" />\n).dup expected << %(<input name="date[month]" id="date_month" value="8" type="hidden" />\n) expected << %(<input name="date[day]" id="date_day" value="16" type="hidden" />\n) expected << %(<select id="date_hour" name="date[hour]">\n) @@ -1588,7 +1606,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_time_with_seconds - expected = %(<input name="date[year]" id="date_year" value="2003" type="hidden" />\n) + expected = %(<input name="date[year]" id="date_year" value="2003" type="hidden" />\n).dup expected << %(<input name="date[month]" id="date_month" value="8" type="hidden" />\n) expected << %(<input name="date[day]" id="date_day" value="16" type="hidden" />\n) @@ -1612,7 +1630,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_time_with_seconds_and_separator - expected = %(<input name="date[year]" id="date_year" value="2003" type="hidden" />\n) + expected = %(<input name="date[year]" id="date_year" value="2003" type="hidden" />\n).dup expected << %(<input name="date[month]" id="date_month" value="8" type="hidden" />\n) expected << %(<input name="date[day]" id="date_day" value="16" type="hidden" />\n) @@ -1636,7 +1654,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_time_with_html_options - expected = %(<input name="date[year]" id="date_year" value="2003" type="hidden" />\n) + expected = %(<input name="date[year]" id="date_year" value="2003" type="hidden" />\n).dup expected << %(<input name="date[month]" id="date_month" value="8" type="hidden" />\n) expected << %(<input name="date[day]" id="date_day" value="16" type="hidden" />\n) @@ -1659,7 +1677,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_time_with_default_prompt - expected = %(<input name="date[year]" id="date_year" value="2003" type="hidden" />\n) + expected = %(<input name="date[year]" id="date_year" value="2003" type="hidden" />\n).dup expected << %(<input name="date[month]" id="date_month" value="8" type="hidden" />\n) expected << %(<input name="date[day]" id="date_day" value="16" type="hidden" />\n) @@ -1683,7 +1701,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_time_with_custom_prompt - expected = %(<input name="date[year]" id="date_year" value="2003" type="hidden" />\n) + expected = %(<input name="date[year]" id="date_year" value="2003" type="hidden" />\n).dup expected << %(<input name="date[month]" id="date_month" value="8" type="hidden" />\n) expected << %(<input name="date[day]" id="date_day" value="16" type="hidden" />\n) @@ -1708,7 +1726,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_time_with_generic_with_css_classes - expected = %(<input name="date[year]" id="date_year" value="2003" type="hidden" />\n) + expected = %(<input name="date[year]" id="date_year" value="2003" type="hidden" />\n).dup expected << %(<input name="date[month]" id="date_month" value="8" type="hidden" />\n) expected << %(<input name="date[day]" id="date_day" value="16" type="hidden" />\n) @@ -1732,7 +1750,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_time_with_custom_with_css_classes - expected = %(<input name="date[year]" id="date_year" value="2003" type="hidden" />\n) + expected = %(<input name="date[year]" id="date_year" value="2003" type="hidden" />\n).dup expected << %(<input name="date[month]" id="date_month" value="8" type="hidden" />\n) expected << %(<input name="date[day]" id="date_day" value="16" type="hidden" />\n) @@ -1756,7 +1774,7 @@ class DateHelperTest < ActionView::TestCase end def test_select_time_with_hidden - expected = %(<input id="date_first_year" name="date[first][year]" type="hidden" value="2003" />\n) + expected = %(<input id="date_first_year" name="date[first][year]" type="hidden" value="2003" />\n).dup expected << %(<input id="date_first_month" name="date[first][month]" type="hidden" value="8" />\n) expected << %(<input id="date_first_day" name="date[first][day]" type="hidden" value="16" />\n) expected << %(<input id="date_first_hour" name="date[first][hour]" type="hidden" value="8" />\n) @@ -1770,7 +1788,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Date.new(2004, 6, 15) - expected = %{<select id="post_written_on_1i" name="post[written_on(1i)]">\n} + expected = %{<select id="post_written_on_1i" name="post[written_on(1i)]">\n}.dup expected << %{<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option value="2004" selected="selected">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n} expected << "</select>\n" @@ -1790,7 +1808,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Date.new(2004, 6, 15) - expected = %{<select id="post_written_on_1i" name="post[written_on(1i)]">\n} + expected = %{<select id="post_written_on_1i" name="post[written_on(1i)]">\n}.dup expected << %{<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option selected="selected" value="2004">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n} expected << "</select>\n" @@ -1810,7 +1828,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Date.new(2004, 6, 15) - expected = %{<select id="post_written_on_1i" name="post[written_on(1i)]">\n} + expected = %{<select id="post_written_on_1i" name="post[written_on(1i)]">\n}.dup expected << %{<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option selected="selected" value="2004">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n} expected << "</select>\n" @@ -1848,7 +1866,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Date.new(2004, 6, 15) - expected = "<input type=\"hidden\" id=\"post_written_on_3i\" name=\"post[written_on(3i)]\" value=\"1\" />\n" + expected = "<input type=\"hidden\" id=\"post_written_on_3i\" name=\"post[written_on(3i)]\" value=\"1\" />\n".dup expected << %{<select id="post_written_on_2i" name="post[written_on(2i)]">\n} expected << %{<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option value="6" selected="selected">June</option>\n<option value="7">July</option>\n<option value="8">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n} @@ -1865,7 +1883,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Date.new(2004, 2, 29) - expected = "<input type=\"hidden\" id=\"post_written_on_2i\" name=\"post[written_on(2i)]\" value=\"2\" />\n" + expected = "<input type=\"hidden\" id=\"post_written_on_2i\" name=\"post[written_on(2i)]\" value=\"2\" />\n".dup expected << "<input type=\"hidden\" id=\"post_written_on_3i\" name=\"post[written_on(3i)]\" value=\"1\" />\n" expected << %{<select id="post_written_on_1i" name="post[written_on(1i)]">\n} @@ -1879,7 +1897,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Date.new(2004, 6, 15) - expected = "<input type=\"hidden\" id=\"post_written_on_3i\" name=\"post[written_on(3i)]\" value=\"1\" />\n" + expected = "<input type=\"hidden\" id=\"post_written_on_3i\" name=\"post[written_on(3i)]\" value=\"1\" />\n".dup expected << %{<select id="post_written_on_2i" name="post[written_on(2i)]">\n} expected << %{<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option value="6" selected="selected">June</option>\n<option value="7">July</option>\n<option value="8">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n} @@ -1898,7 +1916,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Date.new(2004, 6, 15) - expected = "<input type=\"hidden\" id=\"post_written_on_3i\" disabled=\"disabled\" name=\"post[written_on(3i)]\" value=\"1\" />\n" + expected = "<input type=\"hidden\" id=\"post_written_on_3i\" disabled=\"disabled\" name=\"post[written_on(3i)]\" value=\"1\" />\n".dup expected << %{<select id="post_written_on_2i" disabled="disabled" name="post[written_on(2i)]">\n} expected << %{<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option value="6" selected="selected">June</option>\n<option value="7">July</option>\n<option value="8">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n} @@ -1919,7 +1937,7 @@ class DateHelperTest < ActionView::TestCase concat f.date_select(:written_on) end - expected = %{<select id="post_written_on_1i" name="post[written_on(1i)]">\n<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option selected="selected" value="2004">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n</select>\n} + expected = %{<select id="post_written_on_1i" name="post[written_on(1i)]">\n<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option selected="selected" value="2004">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n</select>\n}.dup expected << %{<select id="post_written_on_2i" name="post[written_on(2i)]">\n<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option selected="selected" value="6">June</option>\n<option value="7">July</option>\n<option value="8">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n</select>\n} expected << %{<select id="post_written_on_3i" name="post[written_on(3i)]">\n<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option selected="selected" value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n</select>\n} @@ -1935,7 +1953,7 @@ class DateHelperTest < ActionView::TestCase concat f.date_select(:written_on) end - expected = %{<select id="post_#{id}_written_on_1i" name="post[#{id}][written_on(1i)]">\n<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option selected="selected" value="2004">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n</select>\n} + expected = %{<select id="post_#{id}_written_on_1i" name="post[#{id}][written_on(1i)]">\n<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option selected="selected" value="2004">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n</select>\n}.dup expected << %{<select id="post_#{id}_written_on_2i" name="post[#{id}][written_on(2i)]">\n<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option selected="selected" value="6">June</option>\n<option value="7">July</option>\n<option value="8">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n</select>\n} expected << %{<select id="post_#{id}_written_on_3i" name="post[#{id}][written_on(3i)]">\n<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option selected="selected" value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n</select>\n} @@ -1951,7 +1969,7 @@ class DateHelperTest < ActionView::TestCase concat f.date_select(:written_on) end - expected = %{<select id="post_#{id}_written_on_1i" name="post[#{id}][written_on(1i)]">\n<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option selected="selected" value="2004">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n</select>\n} + expected = %{<select id="post_#{id}_written_on_1i" name="post[#{id}][written_on(1i)]">\n<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option selected="selected" value="2004">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n</select>\n}.dup expected << %{<select id="post_#{id}_written_on_2i" name="post[#{id}][written_on(2i)]">\n<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option selected="selected" value="6">June</option>\n<option value="7">July</option>\n<option value="8">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n</select>\n} expected << %{<select id="post_#{id}_written_on_3i" name="post[#{id}][written_on(3i)]">\n<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option selected="selected" value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n</select>\n} @@ -1963,7 +1981,7 @@ class DateHelperTest < ActionView::TestCase @post.written_on = Date.new(2004, 6, 15) id = 456 - expected = %{<select id="post_456_written_on_1i" name="post[#{id}][written_on(1i)]">\n} + expected = %{<select id="post_456_written_on_1i" name="post[#{id}][written_on(1i)]">\n}.dup expected << %{<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option value="2004" selected="selected">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n} expected << "</select>\n" @@ -1983,7 +2001,7 @@ class DateHelperTest < ActionView::TestCase @post.written_on = Date.new(2004, 6, 15) id = 123 - expected = %{<select id="post_123_written_on_1i" name="post[#{id}][written_on(1i)]">\n} + expected = %{<select id="post_123_written_on_1i" name="post[#{id}][written_on(1i)]">\n}.dup expected << %{<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option value="2004" selected="selected">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n} expected << "</select>\n" @@ -2002,7 +2020,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Date.new(2004, 6, 15) - expected = %{<select id="post_written_on_3i" name="post[written_on(3i)]">\n} + expected = %{<select id="post_written_on_3i" name="post[written_on(3i)]">\n}.dup 1.upto(31) { |i| expected << %(<option value="#{i}"#{' selected="selected"' if i == 15}>#{i}</option>\n) } expected << "</select>\n" @@ -2022,7 +2040,7 @@ class DateHelperTest < ActionView::TestCase start_year = Time.now.year - 5 end_year = Time.now.year + 5 - expected = %{<select id="post_written_on_1i" name="post[written_on(1i)]">\n} + expected = %{<select id="post_written_on_1i" name="post[written_on(1i)]">\n}.dup start_year.upto(end_year) { |i| expected << %(<option value="#{i}"#{' selected="selected"' if i == Time.now.year}>#{i}</option>\n) } expected << "</select>\n" @@ -2042,7 +2060,7 @@ class DateHelperTest < ActionView::TestCase start_year = Time.now.year - 5 end_year = Time.now.year + 5 - expected = %{<select id="post_written_on_1i" name="post[written_on(1i)]">\n} + expected = %{<select id="post_written_on_1i" name="post[written_on(1i)]">\n}.dup expected << "<option value=\"\"></option>\n" start_year.upto(end_year) { |i| expected << %(<option value="#{i}">#{i}</option>\n) } expected << "</select>\n" @@ -2086,7 +2104,7 @@ class DateHelperTest < ActionView::TestCase start_year = Time.now.year - 5 end_year = Time.now.year + 5 - expected = %{<select id="post_written_on_1i" name="post[written_on(1i)]">\n} + expected = %{<select id="post_written_on_1i" name="post[written_on(1i)]">\n}.dup expected << "<option value=\"\"></option>\n" start_year.upto(end_year) { |i| expected << %(<option value="#{i}">#{i}</option>\n) } expected << "</select>\n" @@ -2118,7 +2136,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Date.new(2004, 6, 15) - expected = %{<select id="post_written_on_1i" name="post[written_on(1i)]">\n} + expected = %{<select id="post_written_on_1i" name="post[written_on(1i)]">\n}.dup expected << %{<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option value="2004" selected="selected">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n} expected << "</select>\n" @@ -2137,7 +2155,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Date.new(2004, 6, 15) - expected = %{<select id="post_written_on_1i" name="post[written_on(1i)]" class="selector">\n} + expected = %{<select id="post_written_on_1i" name="post[written_on(1i)]" class="selector">\n}.dup expected << %{<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option value="2004" selected="selected">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n} expected << "</select>\n" @@ -2161,7 +2179,7 @@ class DateHelperTest < ActionView::TestCase concat f.date_select(:written_on, {}, class: "selector") end - expected = %{<select id="post_written_on_1i" name="post[written_on(1i)]" class="selector">\n} + expected = %{<select id="post_written_on_1i" name="post[written_on(1i)]" class="selector">\n}.dup expected << %{<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option value="2004" selected="selected">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n} expected << "</select>\n" @@ -2181,7 +2199,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Date.new(2004, 6, 15) - expected = %{<select id="post_written_on_1i" name="post[written_on(1i)]">\n} + expected = %{<select id="post_written_on_1i" name="post[written_on(1i)]">\n}.dup expected << %{<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option value="2004" selected="selected">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n} expected << "</select>\n" @@ -2205,7 +2223,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Date.new(2004, 6, 15) - expected = %{<select id="post_written_on_3i" name="post[written_on(3i)]">\n} + expected = %{<select id="post_written_on_3i" name="post[written_on(3i)]">\n}.dup expected << %{<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15" selected="selected">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n} expected << "</select>\n" @@ -2228,7 +2246,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Date.new(2004, 6, 15) - expected = %{<select id="post_written_on_3i" name="post[written_on(3i)]">\n} + expected = %{<select id="post_written_on_3i" name="post[written_on(3i)]">\n}.dup expected << %{<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15" selected="selected">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n} expected << "</select>\n" @@ -2246,7 +2264,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Date.new(2004, 6, 15) - expected = %{<select id="post_written_on_1i" name="post[written_on(1i)]">\n} + expected = %{<select id="post_written_on_1i" name="post[written_on(1i)]">\n}.dup expected << %{<option value="">Year</option>\n<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option value="2004" selected="selected">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n} expected << "</select>\n" @@ -2266,7 +2284,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Date.new(2004, 6, 15) - expected = %{<select id="post_written_on_1i" name="post[written_on(1i)]">\n} + expected = %{<select id="post_written_on_1i" name="post[written_on(1i)]">\n}.dup expected << %{<option value="">Choose year</option>\n<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option value="2004" selected="selected">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n} expected << "</select>\n" @@ -2286,7 +2304,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Date.new(2004, 6, 15) - expected = %{<select id="post_written_on_1i" name="post[written_on(1i)]" class="year">\n} + expected = %{<select id="post_written_on_1i" name="post[written_on(1i)]" class="year">\n}.dup expected << %{<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option value="2004" selected="selected">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n} expected << "</select>\n" @@ -2306,7 +2324,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Date.new(2004, 6, 15) - expected = %{<select id="post_written_on_1i" name="post[written_on(1i)]" class="my-year">\n} + expected = %{<select id="post_written_on_1i" name="post[written_on(1i)]" class="my-year">\n}.dup expected << %{<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option value="2004" selected="selected">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n} expected << "</select>\n" @@ -2326,7 +2344,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Time.local(2004, 6, 15, 15, 16, 35) - expected = %{<input type="hidden" id="post_written_on_1i" name="post[written_on(1i)]" value="2004" />\n} + expected = %{<input type="hidden" id="post_written_on_1i" name="post[written_on(1i)]" value="2004" />\n}.dup expected << %{<input type="hidden" id="post_written_on_2i" name="post[written_on(2i)]" value="6" />\n} expected << %{<input type="hidden" id="post_written_on_3i" name="post[written_on(3i)]" value="15" />\n} @@ -2345,7 +2363,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Time.local(2004, 6, 15, 15, 16, 35) - expected = %{<input type="hidden" id="post_written_on_1i" name="post[written_on(1i)]" value="2004" />\n} + expected = %{<input type="hidden" id="post_written_on_1i" name="post[written_on(1i)]" value="2004" />\n}.dup expected << %{<input type="hidden" id="post_written_on_2i" name="post[written_on(2i)]" value="6" />\n} expected << %{<input type="hidden" id="post_written_on_3i" name="post[written_on(3i)]" value="15" />\n} @@ -2364,7 +2382,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Time.local(2004, 6, 15, 15, 16, 35) - expected = %{<input type="hidden" id="post_written_on_1i" name="post[written_on(1i)]" value="1" />\n} + expected = %{<input type="hidden" id="post_written_on_1i" name="post[written_on(1i)]" value="1" />\n}.dup expected << %{<input type="hidden" id="post_written_on_2i" name="post[written_on(2i)]" value="1" />\n} expected << %{<input type="hidden" id="post_written_on_3i" name="post[written_on(3i)]" value="1" />\n} @@ -2383,7 +2401,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Time.local(2004, 6, 15, 15, 16, 35) - expected = %(<select id="post_written_on_4i" name="post[written_on(4i)]">\n) + expected = %(<select id="post_written_on_4i" name="post[written_on(4i)]">\n).dup 0.upto(23) { |i| expected << %(<option value="#{sprintf("%02d", i)}"#{' selected="selected"' if i == 15}>#{sprintf("%02d", i)}</option>\n) } expected << "</select>\n" expected << " : " @@ -2398,7 +2416,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Time.local(2004, 6, 15, 15, 16, 35) - expected = %{<input type="hidden" id="post_written_on_1i" name="post[written_on(1i)]" value="2004" />\n} + expected = %{<input type="hidden" id="post_written_on_1i" name="post[written_on(1i)]" value="2004" />\n}.dup expected << %{<input type="hidden" id="post_written_on_2i" name="post[written_on(2i)]" value="6" />\n} expected << %{<input type="hidden" id="post_written_on_3i" name="post[written_on(3i)]" value="15" />\n} @@ -2421,7 +2439,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Time.local(2004, 6, 15, 15, 16, 35) - expected = %{<input type="hidden" id="post_written_on_1i" name="post[written_on(1i)]" value="2004" />\n} + expected = %{<input type="hidden" id="post_written_on_1i" name="post[written_on(1i)]" value="2004" />\n}.dup expected << %{<input type="hidden" id="post_written_on_2i" name="post[written_on(2i)]" value="6" />\n} expected << %{<input type="hidden" id="post_written_on_3i" name="post[written_on(3i)]" value="15" />\n} @@ -2444,7 +2462,7 @@ class DateHelperTest < ActionView::TestCase concat f.time_select(:written_on, {}, class: "selector") end - expected = %{<input type="hidden" id="post_written_on_1i" name="post[written_on(1i)]" value="2004" />\n} + expected = %{<input type="hidden" id="post_written_on_1i" name="post[written_on(1i)]" value="2004" />\n}.dup expected << %{<input type="hidden" id="post_written_on_2i" name="post[written_on(2i)]" value="6" />\n} expected << %{<input type="hidden" id="post_written_on_3i" name="post[written_on(3i)]" value="15" />\n} @@ -2463,7 +2481,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Time.local(2004, 6, 15, 15, 16, 35) - expected = %{<input type="hidden" id="post_written_on_1i" name="post[written_on(1i)]" value="2004" />\n} + expected = %{<input type="hidden" id="post_written_on_1i" name="post[written_on(1i)]" value="2004" />\n}.dup expected << %{<input type="hidden" id="post_written_on_2i" name="post[written_on(2i)]" value="6" />\n} expected << %{<input type="hidden" id="post_written_on_3i" name="post[written_on(3i)]" value="15" />\n} @@ -2490,7 +2508,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Time.local(2004, 6, 15, 15, 16, 35) - expected = %{<input type="hidden" id="post_written_on_1i" name="post[written_on(1i)]" value="2004" />\n} + expected = %{<input type="hidden" id="post_written_on_1i" name="post[written_on(1i)]" value="2004" />\n}.dup expected << %{<input type="hidden" id="post_written_on_2i" name="post[written_on(2i)]" value="6" />\n} expected << %{<input type="hidden" id="post_written_on_3i" name="post[written_on(3i)]" value="15" />\n} @@ -2511,7 +2529,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Time.local(2004, 6, 15, 15, 16, 35) - expected = %{<input type="hidden" id="post_written_on_1i" name="post[written_on(1i)]" value="2004" />\n} + expected = %{<input type="hidden" id="post_written_on_1i" name="post[written_on(1i)]" value="2004" />\n}.dup expected << %{<input type="hidden" id="post_written_on_2i" name="post[written_on(2i)]" value="6" />\n} expected << %{<input type="hidden" id="post_written_on_3i" name="post[written_on(3i)]" value="15" />\n} @@ -2532,7 +2550,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Time.local(2004, 6, 15, 15, 16, 35) - expected = %{<input type="hidden" id="post_written_on_1i" name="post[written_on(1i)]" value="2004" />\n} + expected = %{<input type="hidden" id="post_written_on_1i" name="post[written_on(1i)]" value="2004" />\n}.dup expected << %{<input type="hidden" id="post_written_on_2i" name="post[written_on(2i)]" value="6" />\n} expected << %{<input type="hidden" id="post_written_on_3i" name="post[written_on(3i)]" value="15" />\n} @@ -2553,7 +2571,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Time.local(2004, 6, 15, 15, 16, 35) - expected = %{<input type="hidden" id="post_written_on_1i" name="post[written_on(1i)]" value="2004" />\n} + expected = %{<input type="hidden" id="post_written_on_1i" name="post[written_on(1i)]" value="2004" />\n}.dup expected << %{<input type="hidden" id="post_written_on_2i" name="post[written_on(2i)]" value="6" />\n} expected << %{<input type="hidden" id="post_written_on_3i" name="post[written_on(3i)]" value="15" />\n} @@ -2574,7 +2592,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Time.local(2004, 6, 15, 15, 16, 35) - expected = %{<input type="hidden" id="post_written_on_1i" disabled="disabled" name="post[written_on(1i)]" value="2004" />\n} + expected = %{<input type="hidden" id="post_written_on_1i" disabled="disabled" name="post[written_on(1i)]" value="2004" />\n}.dup expected << %{<input type="hidden" id="post_written_on_2i" disabled="disabled" name="post[written_on(2i)]" value="6" />\n} expected << %{<input type="hidden" id="post_written_on_3i" disabled="disabled" name="post[written_on(3i)]" value="15" />\n} @@ -2593,7 +2611,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.updated_at = Time.local(2004, 6, 15, 16, 35) - expected = %{<select id="post_updated_at_1i" name="post[updated_at(1i)]">\n} + expected = %{<select id="post_updated_at_1i" name="post[updated_at(1i)]">\n}.dup expected << %{<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option value="2004" selected="selected">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n} expected << "</select>\n" @@ -2622,7 +2640,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.updated_at = Time.local(2004, 6, 15, 16, 35) - expected = %{<select id="post_updated_at_1i" name="post[updated_at(1i)]">\n} + expected = %{<select id="post_updated_at_1i" name="post[updated_at(1i)]">\n}.dup expected << %{<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option value="2004" selected="selected">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n} expected << "</select>\n" @@ -2688,7 +2706,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new - expected = %{<select id="post_updated_at_1i" name="post[updated_at(1i)]">\n} + expected = %{<select id="post_updated_at_1i" name="post[updated_at(1i)]">\n}.dup expected << %{<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option value="2004" selected="selected">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n} expected << "</select>\n" @@ -2723,7 +2741,7 @@ class DateHelperTest < ActionView::TestCase concat f.datetime_select(:updated_at, {}, class: "selector") end - expected = %{<select id="post_updated_at_1i" name="post[updated_at(1i)]" class="selector">\n<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option selected="selected" value="2004">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n</select>\n} + expected = %{<select id="post_updated_at_1i" name="post[updated_at(1i)]" class="selector">\n<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option selected="selected" value="2004">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n</select>\n}.dup expected << %{<select id="post_updated_at_2i" name="post[updated_at(2i)]" class="selector">\n<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option selected="selected" value="6">June</option>\n<option value="7">July</option>\n<option value="8">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n</select>\n} expected << %{<select id="post_updated_at_3i" name="post[updated_at(3i)]" class="selector">\n<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option selected="selected" value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n</select>\n} expected << %{ — <select id="post_updated_at_4i" name="post[updated_at(4i)]" class="selector">\n<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option selected="selected" value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n</select>\n} @@ -2736,7 +2754,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.updated_at = Time.local(2004, 6, 15, 15, 16, 35) - expected = %{<select id="post_updated_at_1i" name="post[updated_at(1i)]">\n} + expected = %{<select id="post_updated_at_1i" name="post[updated_at(1i)]">\n}.dup expected << %{<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option value="2004" selected="selected">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n} expected << "</select>\n" @@ -2789,7 +2807,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.updated_at = nil - expected = %{<select id="post_updated_at_1i" name="post[updated_at(1i)]">\n} + expected = %{<select id="post_updated_at_1i" name="post[updated_at(1i)]">\n}.dup expected << %{<option value="">Year</option>\n<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n} expected << "</select>\n" @@ -2818,7 +2836,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.updated_at = nil - expected = %{<select id="post_updated_at_1i" name="post[updated_at(1i)]">\n} + expected = %{<select id="post_updated_at_1i" name="post[updated_at(1i)]">\n}.dup expected << %{<option value="">Choose year</option>\n<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n} expected << "</select>\n" @@ -2847,7 +2865,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Time.local(2004, 6, 15, 15, 16, 35) - expected = %{<select id="post_written_on_1i" name="post[written_on(1i)]" class="year">\n} + expected = %{<select id="post_written_on_1i" name="post[written_on(1i)]" class="year">\n}.dup expected << %{<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option value="2004" selected="selected">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n} expected << "</select>\n" @@ -2876,7 +2894,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Time.local(2004, 6, 15, 15, 16, 35) - expected = %{<select id="post_written_on_1i" name="post[written_on(1i)]" class="my-year">\n} + expected = %{<select id="post_written_on_1i" name="post[written_on(1i)]" class="my-year">\n}.dup expected << %{<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option value="2004" selected="selected">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n} expected << "</select>\n" @@ -2902,7 +2920,7 @@ class DateHelperTest < ActionView::TestCase end def test_date_select_with_zero_value_and_no_start_year - expected = %(<select id="date_first_year" name="date[first][year]">\n) + expected = %(<select id="date_first_year" name="date[first][year]">\n).dup (Date.today.year - 5).upto(Date.today.year + 1) { |y| expected << %(<option value="#{y}">#{y}</option>\n) } expected << "</select>\n" @@ -2918,7 +2936,7 @@ class DateHelperTest < ActionView::TestCase end def test_date_select_with_zero_value_and_no_end_year - expected = %(<select id="date_first_year" name="date[first][year]">\n) + expected = %(<select id="date_first_year" name="date[first][year]">\n).dup last_year = Time.now.year + 5 2003.upto(last_year) { |y| expected << %(<option value="#{y}">#{y}</option>\n) } expected << "</select>\n" @@ -2935,7 +2953,7 @@ class DateHelperTest < ActionView::TestCase end def test_date_select_with_zero_value_and_no_start_and_end_year - expected = %(<select id="date_first_year" name="date[first][year]">\n) + expected = %(<select id="date_first_year" name="date[first][year]">\n).dup (Date.today.year - 5).upto(Date.today.year + 5) { |y| expected << %(<option value="#{y}">#{y}</option>\n) } expected << "</select>\n" @@ -2951,7 +2969,7 @@ class DateHelperTest < ActionView::TestCase end def test_date_select_with_nil_value_and_no_start_and_end_year - expected = %(<select id="date_first_year" name="date[first][year]">\n) + expected = %(<select id="date_first_year" name="date[first][year]">\n).dup (Date.today.year - 5).upto(Date.today.year + 5) { |y| expected << %(<option value="#{y}">#{y}</option>\n) } expected << "</select>\n" @@ -2967,7 +2985,7 @@ class DateHelperTest < ActionView::TestCase end def test_datetime_select_with_nil_value_and_no_start_and_end_year - expected = %(<select id="date_first_year" name="date[first][year]">\n) + expected = %(<select id="date_first_year" name="date[first][year]">\n).dup (Date.today.year - 5).upto(Date.today.year + 5) { |y| expected << %(<option value="#{y}">#{y}</option>\n) } expected << "</select>\n" @@ -2999,7 +3017,7 @@ class DateHelperTest < ActionView::TestCase @post.updated_at = Time.local(2004, 6, 15, 16, 35) id = 456 - expected = %{<select id="post_456_updated_at_1i" name="post[#{id}][updated_at(1i)]">\n} + expected = %{<select id="post_456_updated_at_1i" name="post[#{id}][updated_at(1i)]">\n}.dup expected << %{<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option value="2004" selected="selected">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n} expected << "</select>\n" @@ -3033,7 +3051,7 @@ class DateHelperTest < ActionView::TestCase concat f.datetime_select(:updated_at) end - expected = %{<select id="post_456_updated_at_1i" name="post[#{id}][updated_at(1i)]">\n} + expected = %{<select id="post_456_updated_at_1i" name="post[#{id}][updated_at(1i)]">\n}.dup expected << %{<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option value="2004" selected="selected">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n} expected << "</select>\n" @@ -3063,7 +3081,7 @@ class DateHelperTest < ActionView::TestCase @post.updated_at = Time.local(2004, 6, 15, 16, 35) id = @post.id - expected = %{<select id="post_123_updated_at_1i" name="post[#{id}][updated_at(1i)]">\n} + expected = %{<select id="post_123_updated_at_1i" name="post[#{id}][updated_at(1i)]">\n}.dup expected << %{<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option value="2004" selected="selected">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n} expected << "</select>\n" @@ -3092,7 +3110,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.updated_at = Time.local(2004, 6, 15, 15, 16, 35) - expected = %{<select id="post_updated_at_1i" name="post[updated_at(1i)]">\n} + expected = %{<select id="post_updated_at_1i" name="post[updated_at(1i)]">\n}.dup 1999.upto(2009) { |i| expected << %(<option value="#{i}"#{' selected="selected"' if i == 2004}>#{i}</option>\n) } expected << "</select>\n" expected << %{<select id="post_updated_at_2i" name="post[updated_at(2i)]">\n} @@ -3123,7 +3141,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.updated_at = Time.local(2004, 6, 15, 15, 16, 35) - expected = %{<input type="hidden" id="post_updated_at_1i" name="post[updated_at(1i)]" value="2004" />\n} + expected = %{<input type="hidden" id="post_updated_at_1i" name="post[updated_at(1i)]" value="2004" />\n}.dup expected << %{<select id="post_updated_at_2i" name="post[updated_at(2i)]">\n} 1.upto(12) { |i| expected << %(<option value="#{i}"#{' selected="selected"' if i == 6}>#{Date::MONTHNAMES[i]}</option>\n) } expected << "</select>\n" @@ -3148,7 +3166,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.updated_at = Time.local(2004, 6, 15, 15, 16, 35) - expected = %{<select id="post_updated_at_1i" name="post[updated_at(1i)]">\n} + expected = %{<select id="post_updated_at_1i" name="post[updated_at(1i)]">\n}.dup 1999.upto(2009) { |i| expected << %(<option value="#{i}"#{' selected="selected"' if i == 2004}>#{i}</option>\n) } expected << "</select>\n" expected << %{<input type="hidden" id="post_updated_at_2i" name="post[updated_at(2i)]" value="6" />\n} @@ -3171,7 +3189,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.updated_at = Time.local(2004, 6, 15, 15, 16, 35) - expected = %{<input type="hidden" id="post_updated_at_1i" name="post[updated_at(1i)]" value="2004" />\n} + expected = %{<input type="hidden" id="post_updated_at_1i" name="post[updated_at(1i)]" value="2004" />\n}.dup expected << %{<input type="hidden" id="post_updated_at_2i" name="post[updated_at(2i)]" value="6" />\n} expected << %{<input type="hidden" id="post_updated_at_3i" name="post[updated_at(3i)]" value="1" />\n} @@ -3190,7 +3208,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.updated_at = Time.local(2004, 6, 15, 15, 16, 35) - expected = %{<input type="hidden" id="post_updated_at_1i" disabled="disabled" name="post[updated_at(1i)]" value="2004" />\n} + expected = %{<input type="hidden" id="post_updated_at_1i" disabled="disabled" name="post[updated_at(1i)]" value="2004" />\n}.dup expected << %{<input type="hidden" id="post_updated_at_2i" disabled="disabled" name="post[updated_at(2i)]" value="6" />\n} expected << %{<input type="hidden" id="post_updated_at_3i" disabled="disabled" name="post[updated_at(3i)]" value="1" />\n} @@ -3209,7 +3227,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.updated_at = Time.local(2004, 6, 15, 15, 16, 35) - expected = %{<select id="post_updated_at_1i" name="post[updated_at(1i)]">\n} + expected = %{<select id="post_updated_at_1i" name="post[updated_at(1i)]">\n}.dup 1999.upto(2009) { |i| expected << %(<option value="#{i}"#{' selected="selected"' if i == 2004}>#{i}</option>\n) } expected << "</select>\n" expected << %{<select id="post_updated_at_2i" name="post[updated_at(2i)]">\n} @@ -3226,7 +3244,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.updated_at = Time.local(2004, 6, 15, 15, 16, 35) - expected = %{<select id="post_updated_at_1i" name="post[updated_at(1i)]">\n} + expected = %{<select id="post_updated_at_1i" name="post[updated_at(1i)]">\n}.dup 1999.upto(2009) { |i| expected << %(<option value="#{i}"#{' selected="selected"' if i == 2004}>#{i}</option>\n) } expected << "</select>\n" expected << %{<select id="post_updated_at_2i" name="post[updated_at(2i)]">\n} @@ -3250,7 +3268,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.updated_at = Time.local(2004, 6, 15, 15, 16, 35) - expected = %{<select id="post_updated_at_1i" disabled="disabled" name="post[updated_at(1i)]">\n} + expected = %{<select id="post_updated_at_1i" disabled="disabled" name="post[updated_at(1i)]">\n}.dup 1999.upto(2009) { |i| expected << %(<option value="#{i}"#{' selected="selected"' if i == 2004}>#{i}</option>\n) } expected << "</select>\n" expected << %{<select id="post_updated_at_2i" disabled="disabled" name="post[updated_at(2i)]">\n} @@ -3274,7 +3292,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.updated_at = Time.local(2004, 6, 15, 15, 16, 35) - expected = %{<select id="post_updated_at_3i" name="post[updated_at(3i)]">\n} + expected = %{<select id="post_updated_at_3i" name="post[updated_at(3i)]">\n}.dup 1.upto(31) { |i| expected << %(<option value="#{i}"#{' selected="selected"' if i == 15}>#{i}</option>\n) } expected << "</select>\n" expected << %{<select id="post_updated_at_2i" name="post[updated_at(2i)]">\n} @@ -3301,7 +3319,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.updated_at = Time.local(2004, 6, 15, 15, 16, 35) - expected = %{<input type="hidden" id="post_updated_at_1i" name="post[updated_at(1i)]" value="2004" />\n} + expected = %{<input type="hidden" id="post_updated_at_1i" name="post[updated_at(1i)]" value="2004" />\n}.dup expected << %{<select id="post_updated_at_3i" name="post[updated_at(3i)]">\n} 1.upto(31) { |i| expected << %(<option value="#{i}"#{' selected="selected"' if i == 15}>#{i}</option>\n) } expected << "</select>\n" @@ -3326,7 +3344,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.updated_at = nil - expected = %{<select id="post_updated_at_1i" name="post[updated_at(1i)]">\n} + expected = %{<select id="post_updated_at_1i" name="post[updated_at(1i)]">\n}.dup 2001.upto(2011) { |i| expected << %(<option value="#{i}"#{' selected="selected"' if i == 2006}>#{i}</option>\n) } expected << "</select>\n" expected << %{<select id="post_updated_at_2i" name="post[updated_at(2i)]">\n} @@ -3353,7 +3371,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.updated_at = nil - expected = %{<select id="post_updated_at_1i" name="post[updated_at(1i)]">\n} + expected = %{<select id="post_updated_at_1i" name="post[updated_at(1i)]">\n}.dup expected << %(<option value=""></option>\n) (Time.now.year - 5).upto(Time.now.year + 5) { |i| expected << %(<option value="#{i}">#{i}</option>\n) } expected << "</select>\n" @@ -3373,7 +3391,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.updated_at = nil - expected = %{<select id="post_updated_at_1i" name="post[updated_at(1i)]">\n} + expected = %{<select id="post_updated_at_1i" name="post[updated_at(1i)]">\n}.dup (Time.now.year - 5).upto(Time.now.year + 5) { |i| expected << %(<option value="#{i}"#{' selected="selected"' if i == Time.now.year}>#{i}</option>\n) } expected << "</select>\n" expected << %{<select id="post_updated_at_2i" name="post[updated_at(2i)]">\n} @@ -3400,7 +3418,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.updated_at = Time.local(2004, 6, 15, 16, 35) - expected = %{<select id="post_updated_at_1i" name="post[updated_at(1i)]" class="selector">\n} + expected = %{<select id="post_updated_at_1i" name="post[updated_at(1i)]" class="selector">\n}.dup expected << %{<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option value="2004" selected="selected">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n} expected << "</select>\n" diff --git a/actionview/test/template/digestor_test.rb b/actionview/test/template/digestor_test.rb index a814cab686..de04f3f25d 100644 --- a/actionview/test/template/digestor_test.rb +++ b/actionview/test/template/digestor_test.rb @@ -14,7 +14,7 @@ class FixtureTemplate end class FixtureFinder < ActionView::LookupContext - FIXTURES_DIR = "#{File.dirname(__FILE__)}/../fixtures/digestor" + FIXTURES_DIR = File.expand_path("../fixtures/digestor", __dir__) def initialize(details = {}) super(ActionView::PathSet.new(["digestor", "digestor/api"]), details, []) @@ -122,13 +122,13 @@ class TemplateDigestorTest < ActionView::TestCase end def test_logging_of_missing_template_for_dependencies - assert_logged "'messages/something_missing' file doesn't exist, so no dependencies" do + assert_logged "Couldn't find template for digesting: messages/something_missing" do dependencies("messages/something_missing") end end def test_logging_of_missing_template_for_nested_dependencies - assert_logged "'messages/something_missing' file doesn't exist, so no dependencies" do + assert_logged "Couldn't find template for digesting: messages/something_missing" do nested_dependencies("messages/something_missing") end end diff --git a/actionview/test/template/form_helper/form_with_test.rb b/actionview/test/template/form_helper/form_with_test.rb index a4a2966ff9..c1a8181204 100644 --- a/actionview/test/template/form_helper/form_with_test.rb +++ b/actionview/test/template/form_helper/form_with_test.rb @@ -16,7 +16,7 @@ class FormWithActsLikeFormTagTest < FormWithTest method = options[:method] skip_enforcing_utf8 = options.fetch(:skip_enforcing_utf8, false) - "".tap do |txt| + "".dup.tap do |txt| unless skip_enforcing_utf8 txt << %{<input name="utf8" type="hidden" value="✓" />} end @@ -32,7 +32,7 @@ class FormWithActsLikeFormTagTest < FormWithTest method = method.to_s == "get" ? "get" : "post" - txt = %{<form accept-charset="UTF-8" action="#{action}"} + txt = %{<form accept-charset="UTF-8" action="#{action}"}.dup txt << %{ enctype="multipart/form-data"} if enctype txt << %{ data-remote="true"} unless local txt << %{ class="#{html_class}"} if html_class @@ -302,6 +302,7 @@ class FormWithActsLikeFormForTest < FormWithTest concat f.text_field(:title) concat f.text_area(:body) concat f.check_box(:secret) + concat f.select(:category, %w( animal economy sports )) concat f.submit("Create post") concat f.button("Create post") concat f.button { @@ -315,6 +316,7 @@ class FormWithActsLikeFormForTest < FormWithTest "<textarea name='post[body]'>\nBack to the hill and over it again!</textarea>" \ "<input name='post[secret]' type='hidden' value='0' />" \ "<input name='post[secret]' checked='checked' type='checkbox' value='1' />" \ + "<select name='post[category]'><option value='animal'>animal</option>\n<option value='economy'>economy</option>\n<option value='sports'>sports</option></select>" \ "<input name='commit' data-disable-with='Create post' type='submit' value='Create post' />" \ "<button name='button' type='submit'>Create post</button>" \ "<button name='button' type='submit'><span>Create post</span></button>" @@ -401,9 +403,9 @@ class FormWithActsLikeFormForTest < FormWithTest expected = whole_form("/posts") do "<input type='hidden' name='post[active]' value='' />" \ - "<input name='post[active]' type='radio' value='true' />" \ + "<input name='post[active]' type='radio' value='true' id='post_active_true' />" \ "<label for='post_active_true'>true</label>" \ - "<input checked='checked' name='post[active]' type='radio' value='false' />" \ + "<input checked='checked' name='post[active]' type='radio' value='false' id='post_active_false' />" \ "<label for='post_active_false'>false</label>" end @@ -424,10 +426,10 @@ class FormWithActsLikeFormForTest < FormWithTest 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' />" \ + "<input name='post[active]' type='radio' value='true' id='post_active_true' />" \ "true</label>" \ "<label for='post_active_false'>" \ - "<input checked='checked' name='post[active]' type='radio' value='false' />" \ + "<input checked='checked' name='post[active]' type='radio' value='false' id='post_active_false' />" \ "false</label>" end @@ -450,10 +452,10 @@ class FormWithActsLikeFormForTest < FormWithTest 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' />" \ + "<input name='post[active]' type='radio' value='true' id='post_active_true' />" \ "true</label>" \ "<label for='post_active_false'>" \ - "<input checked='checked' name='post[active]' type='radio' value='false' />" \ + "<input checked='checked' name='post[active]' type='radio' value='false' id='post_active_false' />" \ "false</label>" \ "<input name='post[id]' type='hidden' value='1' />" end @@ -471,9 +473,9 @@ class FormWithActsLikeFormForTest < FormWithTest expected = whole_form("/posts") do "<input type='hidden' name='post[1][active]' value='' />" \ - "<input name='post[1][active]' type='radio' value='true' />" \ + "<input name='post[1][active]' type='radio' value='true' id='post_1_active_true' />" \ "<label for='post_1_active_true'>true</label>" \ - "<input checked='checked' name='post[1][active]' type='radio' value='false' />" \ + "<input checked='checked' name='post[1][active]' type='radio' value='false' id='post_1_active_false' />" \ "<label for='post_1_active_false'>false</label>" end @@ -490,11 +492,11 @@ class FormWithActsLikeFormForTest < FormWithTest expected = whole_form("/posts") do "<input name='post[tag_ids][]' type='hidden' value='' />" \ - "<input checked='checked' name='post[tag_ids][]' type='checkbox' value='1' />" \ + "<input checked='checked' name='post[tag_ids][]' type='checkbox' value='1' id='post_tag_ids_1' />" \ "<label for='post_tag_ids_1'>Tag 1</label>" \ - "<input name='post[tag_ids][]' type='checkbox' value='2' />" \ + "<input name='post[tag_ids][]' type='checkbox' value='2' id='post_tag_ids_2' />" \ "<label for='post_tag_ids_2'>Tag 2</label>" \ - "<input checked='checked' name='post[tag_ids][]' type='checkbox' value='3' />" \ + "<input checked='checked' name='post[tag_ids][]' type='checkbox' value='3' id='post_tag_ids_3' />" \ "<label for='post_tag_ids_3'>Tag 3</label>" end @@ -515,13 +517,13 @@ class FormWithActsLikeFormForTest < FormWithTest 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' />" \ + "<input checked='checked' name='post[tag_ids][]' type='checkbox' value='1' id='post_tag_ids_1' />" \ "Tag 1</label>" \ "<label for='post_tag_ids_2'>" \ - "<input name='post[tag_ids][]' type='checkbox' value='2' />" \ + "<input name='post[tag_ids][]' type='checkbox' value='2' id='post_tag_ids_2' />" \ "Tag 2</label>" \ "<label for='post_tag_ids_3'>" \ - "<input checked='checked' name='post[tag_ids][]' type='checkbox' value='3' />" \ + "<input checked='checked' name='post[tag_ids][]' type='checkbox' value='3' id='post_tag_ids_3' />" \ "Tag 3</label>" end @@ -545,13 +547,13 @@ class FormWithActsLikeFormForTest < FormWithTest 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' />" \ + "<input checked='checked' name='post[tag_ids][]' type='checkbox' value='1' id='post_tag_ids_1' />" \ "Tag 1</label>" \ "<label for='post_tag_ids_2'>" \ - "<input name='post[tag_ids][]' type='checkbox' value='2' />" \ + "<input name='post[tag_ids][]' type='checkbox' value='2' id='post_tag_ids_2' />" \ "Tag 2</label>" \ "<label for='post_tag_ids_3'>" \ - "<input checked='checked' name='post[tag_ids][]' type='checkbox' value='3' />" \ + "<input checked='checked' name='post[tag_ids][]' type='checkbox' value='3' id='post_tag_ids_3' />" \ "Tag 3</label>" \ "<input name='post[id]' type='hidden' value='1' />" end @@ -570,7 +572,7 @@ class FormWithActsLikeFormForTest < FormWithTest 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 checked='checked' name='post[1][tag_ids][]' type='checkbox' value='1' id='post_1_tag_ids_1' />" \ "<label for='post_1_tag_ids_1'>Tag 1</label>" end @@ -729,6 +731,28 @@ class FormWithActsLikeFormForTest < FormWithTest assert_dom_equal expected, output_buffer end + def test_form_is_not_remote_by_default_if_form_with_generates_remote_forms_is_false + old_value = ActionView::Helpers::FormHelper.form_with_generates_remote_forms + ActionView::Helpers::FormHelper.form_with_generates_remote_forms = false + + form_with(model: @post, url: "/", id: "create-post", method: :patch) do |f| + concat f.text_field(:title) + concat f.text_area(:body) + concat f.check_box(:secret) + end + + expected = whole_form("/", "create-post", method: "patch", local: true) do + "<input name='post[title]' type='text' value='Hello World' />" \ + "<textarea name='post[body]'>\nBack to the hill and over it again!</textarea>" \ + "<input name='post[secret]' type='hidden' value='0' />" \ + "<input name='post[secret]' checked='checked' type='checkbox' value='1' />" + end + + assert_dom_equal expected, output_buffer + ensure + ActionView::Helpers::FormHelper.form_with_generates_remote_forms = old_value + end + def test_form_with_skip_enforcing_utf8_true form_with(scope: :post, skip_enforcing_utf8: true) do |f| concat f.text_field(:title) @@ -854,24 +878,6 @@ class FormWithActsLikeFormForTest < FormWithTest assert_dom_equal expected, output_buffer end - def test_form_with_with_namespace - skip "Do namespaces still make sense?" - form_for(@post, namespace: "namespace") do |f| - concat f.text_field(:title) - concat f.text_area(:body) - concat f.check_box(:secret) - 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[secret]' checked='checked' type='checkbox' value='1' />" - end - - assert_dom_equal expected, output_buffer - end - def test_submit_with_object_as_new_record_and_locale_strings with_locale :submit do @post.persisted = false @@ -1636,7 +1642,7 @@ class FormWithActsLikeFormForTest < FormWithTest expected = 0 @post.comments.each do |comment| f.fields(:comments, model: comment) { |cf| - assert_equal cf.index, expected + assert_equal expected, cf.index expected += 1 } end @@ -1650,7 +1656,7 @@ class FormWithActsLikeFormForTest < FormWithTest expected = 0 @post.comments.each do |comment| f.fields(:comments, model: comment) { |cf| - assert_equal cf.index, expected + assert_equal expected, cf.index expected += 1 } end @@ -1663,7 +1669,7 @@ class FormWithActsLikeFormForTest < FormWithTest form_with(model: @post) do |f| expected = 0 f.fields(:comments, model: @post.comments) { |cf| - assert_equal cf.index, expected + assert_equal expected, cf.index expected += 1 } end @@ -1674,7 +1680,7 @@ class FormWithActsLikeFormForTest < FormWithTest form_with(model: @post) do |f| f.fields(:comments, model: Comment.new(321), child_index: "abc") { |cf| - assert_equal cf.index, "abc" + assert_equal "abc", cf.index } end end @@ -2188,9 +2194,9 @@ class FormWithActsLikeFormForTest < FormWithTest method = options[:method] if options.fetch(:skip_enforcing_utf8, false) - txt = "" + txt = "".dup else - txt = %{<input name="utf8" type="hidden" value="✓" />} + txt = %{<input name="utf8" type="hidden" value="✓" />}.dup end if method && !%w(get post).include?(method.to_s) @@ -2201,7 +2207,7 @@ class FormWithActsLikeFormForTest < FormWithTest end def form_text(action = "/", id = nil, html_class = nil, local = nil, multipart = nil, method = nil) - txt = %{<form accept-charset="UTF-8" action="#{action}"} + txt = %{<form accept-charset="UTF-8" action="#{action}"}.dup txt << %{ enctype="multipart/form-data"} if multipart txt << %{ data-remote="true"} unless local txt << %{ class="#{html_class}"} if html_class diff --git a/actionview/test/template/form_helper_test.rb b/actionview/test/template/form_helper_test.rb index b3a180b28a..ec2e6b0959 100644 --- a/actionview/test/template/form_helper_test.rb +++ b/actionview/test/template/form_helper_test.rb @@ -1446,8 +1446,8 @@ class FormHelperTest < ActionView::TestCase check_box("post[]", "secret") ) assert_dom_equal( - %{<input checked="checked" id="post_#{pid}_title_hello_world" name="post[#{pid}][title]" type="radio" value="Hello World" />}, - radio_button("post[]", "title", "Hello World") + %{<input checked="checked" id="post_#{pid}_title_hello_world" name="post[#{pid}][title]" type="radio" value="Hello World" />}, + radio_button("post[]", "title", "Hello World") ) assert_dom_equal( %{<input id="post_#{pid}_title_goodbye_world" name="post[#{pid}][title]" type="radio" value="Goodbye World" />}, @@ -2893,7 +2893,7 @@ class FormHelperTest < ActionView::TestCase expected = 0 @post.comments.each do |comment| f.fields_for(:comments, comment) { |cf| - assert_equal cf.index, expected + assert_equal expected, cf.index expected += 1 } end @@ -2907,7 +2907,7 @@ class FormHelperTest < ActionView::TestCase expected = 0 @post.comments.each do |comment| f.fields_for(:comments, comment) { |cf| - assert_equal cf.index, expected + assert_equal expected, cf.index expected += 1 } end @@ -2920,7 +2920,7 @@ class FormHelperTest < ActionView::TestCase form_for(@post) do |f| expected = 0 f.fields_for(:comments, @post.comments) { |cf| - assert_equal cf.index, expected + assert_equal expected, cf.index expected += 1 } end @@ -2931,7 +2931,7 @@ class FormHelperTest < ActionView::TestCase form_for(@post) do |f| f.fields_for(:comments, Comment.new(321), child_index: "abc") { |cf| - assert_equal cf.index, "abc" + assert_equal "abc", cf.index } end end @@ -3446,9 +3446,9 @@ class FormHelperTest < ActionView::TestCase method = options[:method] if options.fetch(:enforce_utf8, true) - txt = %{<input name="utf8" type="hidden" value="✓" />} + txt = %{<input name="utf8" type="hidden" value="✓" />}.dup else - txt = "" + txt = "".dup end if method && !%w(get post).include?(method.to_s) @@ -3459,7 +3459,7 @@ class FormHelperTest < ActionView::TestCase end def form_text(action = "/", id = nil, html_class = nil, remote = nil, multipart = nil, method = nil) - txt = %{<form accept-charset="UTF-8" action="#{action}"} + txt = %{<form accept-charset="UTF-8" action="#{action}"}.dup txt << %{ enctype="multipart/form-data"} if multipart txt << %{ data-remote="true"} if remote txt << %{ class="#{html_class}"} if html_class diff --git a/actionview/test/template/form_options_helper_test.rb b/actionview/test/template/form_options_helper_test.rb index 258dcdb806..792481f432 100644 --- a/actionview/test/template/form_options_helper_test.rb +++ b/actionview/test/template/form_options_helper_test.rb @@ -6,6 +6,15 @@ class Map < Hash end end +class CustomEnumerable + include Enumerable + + def each + yield "one" + yield "two" + end +end + class FormOptionsHelperTest < ActionView::TestCase tests ActionView::Helpers::FormOptionsHelper @@ -260,8 +269,8 @@ class FormOptionsHelperTest < ActionView::TestCase def test_collection_options_with_preselected_value_as_string_and_option_value_is_integer albums = [ Album.new(1, "first", "rap"), Album.new(2, "second", "pop")] assert_dom_equal( - %(<option selected="selected" value="1">rap</option>\n<option value="2">pop</option>), - options_from_collection_for_select(albums, "id", "genre", selected: "1") + %(<option selected="selected" value="1">rap</option>\n<option value="2">pop</option>), + options_from_collection_for_select(albums, "id", "genre", selected: "1") ) end @@ -269,8 +278,8 @@ class FormOptionsHelperTest < ActionView::TestCase albums = [ Album.new("1", "first", "rap"), Album.new("2", "second", "pop")] assert_dom_equal( - %(<option selected="selected" value="1">rap</option>\n<option value="2">pop</option>), - options_from_collection_for_select(albums, "id", "genre", selected: 1) + %(<option selected="selected" value="1">rap</option>\n<option value="2">pop</option>), + options_from_collection_for_select(albums, "id", "genre", selected: 1) ) end @@ -278,8 +287,8 @@ class FormOptionsHelperTest < ActionView::TestCase albums = [ Album.new(1.0, "first", "rap"), Album.new(2.0, "second", "pop")] assert_dom_equal( - %(<option value="1.0">rap</option>\n<option value="2.0" selected="selected">pop</option>), - options_from_collection_for_select(albums, "id", "genre", selected: "2.0") + %(<option value="1.0">rap</option>\n<option value="2.0" selected="selected">pop</option>), + options_from_collection_for_select(albums, "id", "genre", selected: "2.0") ) end @@ -287,8 +296,8 @@ class FormOptionsHelperTest < ActionView::TestCase albums = [ Album.new(1.0, "first", "rap"), Album.new(2.0, "second", "pop")] assert_dom_equal( - %(<option value="1.0">rap</option>\n<option value="2.0">pop</option>), - options_from_collection_for_select(albums, "id", "genre", selected: nil) + %(<option value="1.0">rap</option>\n<option value="2.0">pop</option>), + options_from_collection_for_select(albums, "id", "genre", selected: nil) ) end @@ -296,8 +305,8 @@ class FormOptionsHelperTest < ActionView::TestCase albums = [ Album.new(1.0, "first", "rap"), Album.new(2.0, "second", "pop")] assert_dom_equal( - %(<option value="1.0">rap</option>\n<option value="2.0">pop</option>), - options_from_collection_for_select(albums, "id", "genre", disabled: nil) + %(<option value="1.0">rap</option>\n<option value="2.0">pop</option>), + options_from_collection_for_select(albums, "id", "genre", disabled: nil) ) end @@ -305,8 +314,8 @@ class FormOptionsHelperTest < ActionView::TestCase albums = [ Album.new(1.0, "first", "rap"), Album.new(2.0, "second", "pop")] assert_dom_equal( - %(<option disabled="disabled" value="1.0">rap</option>\n<option disabled="disabled" value="2.0">pop</option>), - options_from_collection_for_select(albums, "id", "genre", disabled: ["1.0", 2.0]) + %(<option disabled="disabled" value="1.0">rap</option>\n<option disabled="disabled" value="2.0">pop</option>), + options_from_collection_for_select(albums, "id", "genre", disabled: ["1.0", 2.0]) ) end @@ -314,8 +323,8 @@ class FormOptionsHelperTest < ActionView::TestCase albums = [ Album.new(1.0, "first", "rap"), Album.new(2.0, "second", "pop"), Album.new(3.0, "third", "country") ] assert_dom_equal( - %(<option value="1.0" selected="selected">rap</option>\n<option value="2.0">pop</option>\n<option value="3.0" selected="selected">country</option>), - options_from_collection_for_select(albums, "id", "genre", ["1.0", "3.0"]) + %(<option value="1.0" selected="selected">rap</option>\n<option value="2.0">pop</option>\n<option value="3.0" selected="selected">country</option>), + options_from_collection_for_select(albums, "id", "genre", ["1.0", "3.0"]) ) end @@ -362,15 +371,15 @@ class FormOptionsHelperTest < ActionView::TestCase def test_grouped_options_for_select_with_selected_and_prompt assert_dom_equal( - "<option value=\"\">Choose a product...</option><optgroup label=\"Hats\"><option value=\"Baseball Cap\">Baseball Cap</option>\n<option selected=\"selected\" value=\"Cowboy Hat\">Cowboy Hat</option></optgroup>", - grouped_options_for_select([["Hats", ["Baseball Cap", "Cowboy Hat"]]], "Cowboy Hat", prompt: "Choose a product...") + "<option value=\"\">Choose a product...</option><optgroup label=\"Hats\"><option value=\"Baseball Cap\">Baseball Cap</option>\n<option selected=\"selected\" value=\"Cowboy Hat\">Cowboy Hat</option></optgroup>", + grouped_options_for_select([["Hats", ["Baseball Cap", "Cowboy Hat"]]], "Cowboy Hat", prompt: "Choose a product...") ) end def test_grouped_options_for_select_with_selected_and_prompt_true assert_dom_equal( - "<option value=\"\">Please select</option><optgroup label=\"Hats\"><option value=\"Baseball Cap\">Baseball Cap</option>\n<option selected=\"selected\" value=\"Cowboy Hat\">Cowboy Hat</option></optgroup>", - grouped_options_for_select([["Hats", ["Baseball Cap", "Cowboy Hat"]]], "Cowboy Hat", prompt: true) + "<option value=\"\">Please select</option><optgroup label=\"Hats\"><option value=\"Baseball Cap\">Baseball Cap</option>\n<option selected=\"selected\" value=\"Cowboy Hat\">Cowboy Hat</option></optgroup>", + grouped_options_for_select([["Hats", ["Baseball Cap", "Cowboy Hat"]]], "Cowboy Hat", prompt: true) ) end @@ -386,8 +395,8 @@ class FormOptionsHelperTest < ActionView::TestCase def test_optgroups_with_with_options_with_hash assert_dom_equal( - "<optgroup label=\"North America\"><option value=\"United States\">United States</option>\n<option value=\"Canada\">Canada</option></optgroup><optgroup label=\"Europe\"><option value=\"Denmark\">Denmark</option>\n<option value=\"Germany\">Germany</option></optgroup>", - grouped_options_for_select("North America" => ["United States", "Canada"], "Europe" => ["Denmark", "Germany"]) + "<optgroup label=\"North America\"><option value=\"United States\">United States</option>\n<option value=\"Canada\">Canada</option></optgroup><optgroup label=\"Europe\"><option value=\"Denmark\">Denmark</option>\n<option value=\"Germany\">Germany</option></optgroup>", + grouped_options_for_select("North America" => ["United States", "Canada"], "Europe" => ["Denmark", "Germany"]) ) end @@ -750,8 +759,8 @@ class FormOptionsHelperTest < ActionView::TestCase @post = Post.new @post.category = "" assert_dom_equal( - "<select class=\"disabled\" disabled=\"disabled\" name=\"post[category]\" id=\"post_category\"><option value=\"\">Please select</option>\n<option value=\"\"></option>\n</select>", - select("post", "category", [], { prompt: true, include_blank: true }, class: "disabled", disabled: true) + "<select class=\"disabled\" disabled=\"disabled\" name=\"post[category]\" id=\"post_category\"><option value=\"\">Please select</option>\n<option value=\"\"></option>\n</select>", + select("post", "category", [], { prompt: true, include_blank: true }, class: "disabled", disabled: true) ) end @@ -904,6 +913,14 @@ class FormOptionsHelperTest < ActionView::TestCase ) end + def test_select_with_enumerable + @post = Post.new + assert_dom_equal( + "<select id=\"post_category\" name=\"post[category]\"><option value=\"one\">one</option>\n<option value=\"two\">two</option></select>", + select("post", "category", CustomEnumerable.new) + ) + end + def test_collection_select @post = Post.new @post.author_name = "Babe" diff --git a/actionview/test/template/form_tag_helper_test.rb b/actionview/test/template/form_tag_helper_test.rb index 084c540139..7ac15db9fe 100644 --- a/actionview/test/template/form_tag_helper_test.rb +++ b/actionview/test/template/form_tag_helper_test.rb @@ -14,7 +14,7 @@ class FormTagHelperTest < ActionView::TestCase method = options[:method] enforce_utf8 = options.fetch(:enforce_utf8, true) - "".tap do |txt| + "".dup.tap do |txt| if enforce_utf8 txt << %{<input name="utf8" type="hidden" value="✓" />} end @@ -30,7 +30,7 @@ class FormTagHelperTest < ActionView::TestCase method = method.to_s == "get" ? "get" : "post" - txt = %{<form accept-charset="UTF-8" action="#{action}"} + txt = %{<form accept-charset="UTF-8" action="#{action}"}.dup txt << %{ enctype="multipart/form-data"} if enctype txt << %{ data-remote="true"} if remote txt << %{ class="#{html_class}"} if html_class @@ -345,6 +345,12 @@ class FormTagHelperTest < ActionView::TestCase assert_dom_equal expected, actual end + def test_text_field_tag_with_ac_parameters + actual = text_field_tag "title", ActionController::Parameters.new(key: "value") + expected = %(<input id="title" name="title" type="text" value="{"key"=>"value"}" />) + assert_dom_equal expected, actual + end + def test_text_field_tag_size_string actual = text_field_tag "title", "Hello!", "size" => "75" expected = %(<input id="title" name="title" size="75" type="text" value="Hello!" />) diff --git a/actionview/test/template/javascript_helper_test.rb b/actionview/test/template/javascript_helper_test.rb index c7670b056b..67747a7a83 100644 --- a/actionview/test/template/javascript_helper_test.rb +++ b/actionview/test/template/javascript_helper_test.rb @@ -20,8 +20,8 @@ class JavaScriptHelperTest < ActionView::TestCase assert_equal %(This \\"thing\\" is really\\n netos\\'), escape_javascript(%(This "thing" is really\n netos')) assert_equal %(backslash\\\\test), escape_javascript(%(backslash\\test)) assert_equal %(dont <\\/close> tags), escape_javascript(%(dont </close> tags)) - assert_equal %(unicode 
 newline), escape_javascript(%(unicode \342\200\250 newline).force_encoding(Encoding::UTF_8).encode!) - assert_equal %(unicode 
 newline), escape_javascript(%(unicode \342\200\251 newline).force_encoding(Encoding::UTF_8).encode!) + assert_equal %(unicode 
 newline), escape_javascript(%(unicode \342\200\250 newline).dup.force_encoding(Encoding::UTF_8).encode!) + assert_equal %(unicode 
 newline), escape_javascript(%(unicode \342\200\251 newline).dup.force_encoding(Encoding::UTF_8).encode!) assert_equal %(dont <\\/close> tags), j(%(dont </close> tags)) end diff --git a/actionview/test/template/log_subscriber_test.rb b/actionview/test/template/log_subscriber_test.rb index 7f358add7e..4c9f84f277 100644 --- a/actionview/test/template/log_subscriber_test.rb +++ b/actionview/test/template/log_subscriber_test.rb @@ -8,11 +8,14 @@ class AVLogSubscriberTest < ActiveSupport::TestCase def setup super - view_paths = ActionController::Base.view_paths + + view_paths = ActionController::Base.view_paths lookup_context = ActionView::LookupContext.new(view_paths, {}, ["test"]) - renderer = ActionView::Renderer.new(lookup_context) - @view = ActionView::Base.new(renderer, {}) + renderer = ActionView::Renderer.new(lookup_context) + @view = ActionView::Base.new(renderer, {}) + ActionView::LogSubscriber.attach_to :action_view + unless Rails.respond_to?(:root) @defined_root = true def Rails.root; :defined_root; end # Minitest `stub` expects the method to be defined. @@ -21,7 +24,9 @@ class AVLogSubscriberTest < ActiveSupport::TestCase def teardown super + ActiveSupport::LogSubscriber.log_subscribers.clear + # We need to undef `root`, RenderTestCases don't want this to be defined Rails.instance_eval { undef :root } if @defined_root end @@ -39,7 +44,7 @@ class AVLogSubscriberTest < ActiveSupport::TestCase def set_view_cache_dependencies def @view.view_cache_dependencies; []; end - def @view.fragment_cache_key(*); "ahoy `controller` dependency"; end + def @view.combined_fragment_cache_key(*); "ahoy `controller` dependency"; end end def test_render_file_template @@ -103,9 +108,9 @@ class AVLogSubscriberTest < ActiveSupport::TestCase set_view_cache_dependencies set_cache_controller - @view.render(partial: "test/cached_customer", locals: { cached_customer: Customer.new("david") }) # Second render should hit cache. @view.render(partial: "test/cached_customer", locals: { cached_customer: Customer.new("david") }) + @view.render(partial: "test/cached_customer", locals: { cached_customer: Customer.new("david") }) wait assert_equal 2, @logger.logged(:info).size @@ -113,6 +118,46 @@ class AVLogSubscriberTest < ActiveSupport::TestCase end end + def test_render_uncached_outer_partial_with_inner_cached_partial_wont_mix_cache_hits_or_misses + Rails.stub(:root, File.expand_path(FIXTURE_LOAD_PATH)) do + set_view_cache_dependencies + set_cache_controller + + @view.render(partial: "test/nested_cached_customer", locals: { cached_customer: Customer.new("Stan") }) + wait + *, cached_inner, uncached_outer = @logger.logged(:info) + assert_match(/Rendered test\/_cached_customer\.erb (.*) \[cache miss\]/, cached_inner) + assert_match(/Rendered test\/_nested_cached_customer\.erb \(.*?ms\)$/, uncached_outer) + + # Second render hits the cache for the _cached_customer partial. Outer template's log shouldn't be affected. + @view.render(partial: "test/nested_cached_customer", locals: { cached_customer: Customer.new("Stan") }) + wait + *, cached_inner, uncached_outer = @logger.logged(:info) + assert_match(/Rendered test\/_cached_customer\.erb (.*) \[cache hit\]/, cached_inner) + assert_match(/Rendered test\/_nested_cached_customer\.erb \(.*?ms\)$/, uncached_outer) + end + end + + def test_render_cached_outer_partial_with_cached_inner_partial + Rails.stub(:root, File.expand_path(FIXTURE_LOAD_PATH)) do + set_view_cache_dependencies + set_cache_controller + + @view.render(partial: "test/cached_nested_cached_customer", locals: { cached_customer: Customer.new("Stan") }) + wait + *, cached_inner, cached_outer = @logger.logged(:info) + assert_match(/Rendered test\/_cached_customer\.erb (.*) \[cache miss\]/, cached_inner) + assert_match(/Rendered test\/_cached_nested_cached_customer\.erb (.*) \[cache miss\]/, cached_outer) + + # One render: inner partial skipped, because the outer has been cached. + assert_difference -> { @logger.logged(:info).size }, +1 do + @view.render(partial: "test/cached_nested_cached_customer", locals: { cached_customer: Customer.new("Stan") }) + wait + end + assert_match(/Rendered test\/_cached_nested_cached_customer\.erb (.*) \[cache hit\]/, @logger.logged(:info).last) + end + end + def test_render_partial_with_cache_hitted_and_missed Rails.stub(:root, File.expand_path(FIXTURE_LOAD_PATH)) do set_view_cache_dependencies diff --git a/actionview/test/template/render_test.rb b/actionview/test/template/render_test.rb index 412948719c..1fd8b4fe1a 100644 --- a/actionview/test/template/render_test.rb +++ b/actionview/test/template/render_test.rb @@ -10,8 +10,8 @@ module RenderTestCases @view = Class.new(ActionView::Base) do def view_cache_dependencies; end - def fragment_cache_key(key) - ActiveSupport::Cache.expand_cache_key(key, :views) + def combined_fragment_cache_key(key) + [ :views, key ] end end.new(paths, @assigns) @@ -27,7 +27,7 @@ module RenderTestCases def test_render_without_options e = assert_raises(ArgumentError) { @view.render() } - assert_match(/You invoked render but did not give any of (.+) option./, e.message) + assert_match(/You invoked render but did not give any of (.+) option\./, e.message) end def test_render_file @@ -83,6 +83,10 @@ module RenderTestCases assert_equal "<h1>Kein Kommentar</h1>", @view.render(template: "comments/empty", locale: [:de]) end + def test_render_template_with_variants + assert_equal "<h1>No Comment</h1>\n", @view.render(template: "comments/empty", variants: :grid) + end + def test_render_file_with_handlers assert_equal "<h1>No Comment</h1>\n", @view.render(file: "comments/empty", handlers: [:builder]) assert_equal "<h1>No Comment</h1>\n", @view.render(file: "comments/empty", handlers: :builder) @@ -134,7 +138,7 @@ module RenderTestCases end def test_render_file_with_full_path - template_path = File.join(File.dirname(__FILE__), "../fixtures/test/hello_world") + template_path = File.expand_path("../fixtures/test/hello_world", __dir__) assert_equal "Hello world!", @view.render(file: template_path) end @@ -156,7 +160,7 @@ module RenderTestCases end def test_render_outside_path - assert File.exist?(File.join(File.dirname(__FILE__), "../../test/abstract_unit.rb")) + assert File.exist?(File.expand_path("../../test/abstract_unit.rb", __dir__)) assert_raises ActionView::MissingTemplate do @view.render(template: "../\\../test/abstract_unit.rb") end @@ -170,6 +174,10 @@ module RenderTestCases assert_equal "partial html", @view.render(partial: "test/partial") end + def test_render_partial_with_variants + assert_equal "<h1>Partial with variants</h1>\n", @view.render(partial: "test/partial_with_variants", variants: :grid) + end + def test_render_partial_with_selected_format assert_equal "partial html", @view.render(partial: "test/partial", formats: :html) assert_equal "partial js", @view.render(partial: "test/partial", formats: [:js]) @@ -253,7 +261,7 @@ module RenderTestCases def test_render_sub_template_with_errors e = assert_raises(ActionView::Template::Error) { @view.render(template: "test/sub_template_raise") } assert_match %r!method.*doesnt_exist!, e.message - assert_match %r{Trace of template inclusion: .*test/sub_template_raise.html.erb}, e.sub_template_message + assert_match %r{Trace of template inclusion: .*test/sub_template_raise\.html\.erb}, e.sub_template_message assert_equal "1", e.line_number assert_equal File.expand_path("#{FIXTURE_LOAD_PATH}/test/_raise.html.erb"), e.file_name end @@ -431,7 +439,7 @@ module RenderTestCases end CustomHandler = lambda do |template| - "@output_buffer = ''\n" \ + "@output_buffer = ''.dup\n" \ "@output_buffer << 'source: #{template.source.inspect}'\n" end @@ -575,7 +583,7 @@ module RenderTestCases def test_render_with_passing_couple_extensions_to_one_register_template_handler_function_call ActionView::Template.register_template_handler :foo1, :foo2, CustomHandler - assert_equal @view.render(inline: "Hello, World!", type: :foo1), @view.render(inline: "Hello, World!", type: :foo2) + assert_equal @view.render(inline: "Hello, World!".dup, type: :foo1), @view.render(inline: "Hello, World!".dup, type: :foo2) ensure ActionView::Template.unregister_template_handler :foo1, :foo2 end @@ -710,6 +718,6 @@ class CachedCollectionViewRenderTest < ActiveSupport::TestCase private def cache_key(*names, virtual_path) digest = ActionView::Digestor.digest name: virtual_path, finder: @view.lookup_context, dependencies: [] - @view.fragment_cache_key([ *names, digest ]) + @view.combined_fragment_cache_key([ "#{virtual_path}:#{digest}", *names ]) end end diff --git a/actionview/test/template/resolver_patterns_test.rb b/actionview/test/template/resolver_patterns_test.rb index 43e3f21076..8e21f4b828 100644 --- a/actionview/test/template/resolver_patterns_test.rb +++ b/actionview/test/template/resolver_patterns_test.rb @@ -2,7 +2,7 @@ require "abstract_unit" class ResolverPatternsTest < ActiveSupport::TestCase def setup - path = File.expand_path("../../fixtures/", __FILE__) + path = File.expand_path("../fixtures", __dir__) pattern = ":prefix/{:formats/,}:action{.:formats,}{+:variants,}{.:handlers,}" @resolver = ActionView::FileSystemResolver.new(path, pattern) end diff --git a/actionview/test/template/sanitize_helper_test.rb b/actionview/test/template/sanitize_helper_test.rb index 11ed55456f..4d4ed3c35c 100644 --- a/actionview/test/template/sanitize_helper_test.rb +++ b/actionview/test/template/sanitize_helper_test.rb @@ -1,6 +1,6 @@ require "abstract_unit" -# The exhaustive tests are in test/controller/html/sanitizer_test.rb. +# The exhaustive tests are in the rails-html-sanitizer gem. # This tests that the helpers hook up correctly to the sanitizer classes. class SanitizeHelperTest < ActionView::TestCase tests ActionView::Helpers::SanitizeHelper diff --git a/actionview/test/template/streaming_render_test.rb b/actionview/test/template/streaming_render_test.rb index 6ce66a1275..41b9063417 100644 --- a/actionview/test/template/streaming_render_test.rb +++ b/actionview/test/template/streaming_render_test.rb @@ -17,7 +17,7 @@ class FiberedTest < ActiveSupport::TestCase def buffered_render(options) body = render_body(options) - string = "" + string = "".dup body.each do |piece| string << piece end diff --git a/actionview/test/template/template_test.rb b/actionview/test/template/template_test.rb index 9d31a98703..d3c08634bc 100644 --- a/actionview/test/template/template_test.rb +++ b/actionview/test/template/template_test.rb @@ -1,4 +1,5 @@ # encoding: US-ASCII + require "abstract_unit" require "logger" @@ -53,7 +54,7 @@ class TestERBTemplate < ActiveSupport::TestCase end def new_template(body = "<%= hello %>", details = { format: :html }) - ActionView::Template.new(body, "hello template", details.fetch(:handler) { ERBHandler }, { virtual_path: "hello" }.merge!(details)) + ActionView::Template.new(body.dup, "hello template", details.fetch(:handler) { ERBHandler }, { virtual_path: "hello" }.merge!(details)) end def render(locals = {}) diff --git a/actionview/test/template/text_helper_test.rb b/actionview/test/template/text_helper_test.rb index 251c98230f..21ee4cc8e5 100644 --- a/actionview/test/template/text_helper_test.rb +++ b/actionview/test/template/text_helper_test.rb @@ -11,7 +11,7 @@ class TextHelperTest < ActionView::TestCase end def test_concat - self.output_buffer = "foo" + self.output_buffer = "foo".dup assert_equal "foobar", concat("bar") assert_equal "foobar", output_buffer end @@ -104,8 +104,8 @@ class TextHelperTest < ActionView::TestCase end def test_truncate_multibyte - assert_equal "\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 ...".force_encoding(Encoding::UTF_8), - truncate("\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 \354\225\204\353\235\274\353\246\254\354\230\244".force_encoding(Encoding::UTF_8), length: 10) + assert_equal "\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 ...".dup.force_encoding(Encoding::UTF_8), + truncate("\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 \354\225\204\353\235\274\353\246\254\354\230\244".dup.force_encoding(Encoding::UTF_8), length: 10) end def test_truncate_does_not_modify_the_options_hash @@ -325,7 +325,7 @@ class TextHelperTest < ActionView::TestCase end def test_excerpt_with_utf8 - assert_equal("...\357\254\203ciency could not be...".force_encoding(Encoding::UTF_8), excerpt("That's why e\357\254\203ciency could not be helped".force_encoding(Encoding::UTF_8), "could", radius: 8)) + assert_equal("...\357\254\203ciency could not be...".dup.force_encoding(Encoding::UTF_8), excerpt("That's why e\357\254\203ciency could not be helped".dup.force_encoding(Encoding::UTF_8), "could", radius: 8)) end def test_excerpt_does_not_modify_the_options_hash diff --git a/actionview/test/template/url_helper_test.rb b/actionview/test/template/url_helper_test.rb index 09454b32cc..a087c5c0cd 100644 --- a/actionview/test/template/url_helper_test.rb +++ b/actionview/test/template/url_helper_test.rb @@ -7,8 +7,7 @@ class UrlHelperTest < ActiveSupport::TestCase # In those cases, we'll set up a simple mock attr_accessor :controller, :request - cattr_accessor :request_forgery - self.request_forgery = false + cattr_accessor :request_forgery, default: false routes = ActionDispatch::Routing::RouteSet.new routes.draw do @@ -16,6 +15,10 @@ class UrlHelperTest < ActiveSupport::TestCase get "/other" => "foo#other" get "/article/:id" => "foo#article", :as => :article get "/category/:category" => "foo#category" + + scope :engine do + get "/" => "foo#bar" + end end include ActionView::Helpers::UrlHelper @@ -231,7 +234,11 @@ class UrlHelperTest < ActiveSupport::TestCase end def to_h - { foo: :bar, baz: "quux" } + if permitted? + { foo: :bar, baz: "quux" } + else + raise ArgumentError + end end end @@ -505,6 +512,12 @@ class UrlHelperTest < ActiveSupport::TestCase assert !current_page?("http://www.example.com/", check_parameters: true) end + def test_current_page_considering_params_when_options_does_not_respond_to_to_hash + @request = request_for_url("/?order=desc&page=1") + + assert !current_page?(:back, check_parameters: false) + end + def test_current_page_with_params_that_match @request = request_for_url("/?order=desc&page=1") @@ -512,10 +525,10 @@ class UrlHelperTest < ActiveSupport::TestCase assert current_page?("http://www.example.com/?order=desc&page=1") end - def test_current_page_with_not_get_verb - @request = request_for_url("/events", method: :post) + def test_current_page_with_scope_that_match + @request = request_for_url("/engine/") - assert !current_page?("/events") + assert current_page?("/engine") end def test_current_page_with_escaped_params @@ -526,7 +539,7 @@ class UrlHelperTest < ActiveSupport::TestCase def test_current_page_with_escaped_params_with_different_encoding @request = request_for_url("/") - @request.stub(:path, "/category/administra%c3%a7%c3%a3o".force_encoding(Encoding::ASCII_8BIT)) do + @request.stub(:path, "/category/administra%c3%a7%c3%a3o".dup.force_encoding(Encoding::ASCII_8BIT)) do assert current_page?(controller: "foo", action: "category", category: "administração") assert current_page?("http://www.example.com/category/administra%c3%a7%c3%a3o") end @@ -544,6 +557,12 @@ class UrlHelperTest < ActiveSupport::TestCase assert current_page?("/posts/") end + def test_current_page_with_not_get_verb + @request = request_for_url("/events", method: :post) + + assert !current_page?("/events") + end + def test_link_unless_current @request = request_for_url("/") @@ -605,8 +624,8 @@ class UrlHelperTest < ActiveSupport::TestCase def test_mail_to_with_special_characters assert_dom_equal( - %{<a href="mailto:%23%21%24%25%26%27%2A%2B-%2F%3D%3F%5E_%60%7B%7D%7C%7E@example.org">#!$%&'*+-/=?^_`{}|~@example.org</a>}, - mail_to("#!$%&'*+-/=?^_`{}|~@example.org") + %{<a href="mailto:%23%21%24%25%26%27%2A%2B-%2F%3D%3F%5E_%60%7B%7D%7C@example.org">#!$%&'*+-/=?^_`{}|@example.org</a>}, + mail_to("#!$%&'*+-/=?^_`{}|@example.org") ) end @@ -672,13 +691,6 @@ class UrlHelperTest < ActiveSupport::TestCase def request_forgery_protection_token "form_token" end - - private - def sort_query_string_params(uri) - path, qs = uri.split("?") - qs = qs.split("&").sort.join("&") if qs - qs ? "#{path}?#{qs}" : path - end end class UrlHelperControllerTest < ActionController::TestCase @@ -876,6 +888,11 @@ class WorkshopsController < ActionController::Base @workshop = Workshop.new(params[:id]) render inline: "<%= url_for(@workshop) %>\n<%= link_to('Workshop', @workshop) %>" end + + def edit + @workshop = Workshop.new(params[:id]) + render inline: "<%= current_page?(@workshop) %>" + end end class SessionsController < ActionController::Base @@ -940,4 +957,11 @@ class PolymorphicControllerTest < ActionController::TestCase get :edit, params: { workshop_id: 1, id: 1, format: "json" } assert_equal %{/workshops/1/sessions/1.json\n<a href="/workshops/1/sessions/1.json">Session</a>}, @response.body end + + def test_current_page_when_options_does_not_respond_to_to_hash + @controller = WorkshopsController.new + + get :edit, params: { id: 1 } + assert_equal "false", @response.body + end end diff --git a/actionview/test/ujs/config.ru b/actionview/test/ujs/config.ru index 48b7a4b53a..213a41127a 100644 --- a/actionview/test/ujs/config.ru +++ b/actionview/test/ujs/config.ru @@ -1,4 +1,4 @@ -$LOAD_PATH.unshift File.expand_path("..", __FILE__) +$LOAD_PATH.unshift __dir__ require "server" run UJS::Server diff --git a/actionview/test/ujs/public/test/call-remote.js b/actionview/test/ujs/public/test/call-remote.js index dbeb8ad832..5932195363 100644 --- a/actionview/test/ujs/public/test/call-remote.js +++ b/actionview/test/ujs/public/test/call-remote.js @@ -100,6 +100,34 @@ asyncTest('JS code should be executed', 1, function() { submit() }) +asyncTest('ecmascript code should be executed', 1, function() { + buildForm({ method: 'post', 'data-type': 'script' }) + + $('form').append('<input type="text" name="content_type" value="application/ecmascript">') + $('form').append('<input type="text" name="content" value="ok(true, \'remote code should be run\')">') + + submit() +}) + +asyncTest('execution of JS code does not modify current DOM', 1, function() { + var docLength, newDocLength + function getDocLength() { + return document.documentElement.outerHTML.length + } + + buildForm({ method: 'post', 'data-type': 'script' }) + + $('form').append('<input type="text" name="content_type" value="text/javascript">') + $('form').append('<input type="text" name="content" value="\'remote code should be run\'">') + + docLength = getDocLength() + + submit(function() { + newDocLength = getDocLength() + ok(docLength === newDocLength, 'executed JS should not present in the document') + }) +}) + asyncTest('XML document should be parsed', 1, function() { buildForm({ method: 'post', 'data-type': 'html' }) diff --git a/actionview/test/ujs/public/test/data-confirm.js b/actionview/test/ujs/public/test/data-confirm.js index 28190c2250..229b9e1466 100644 --- a/actionview/test/ujs/public/test/data-confirm.js +++ b/actionview/test/ujs/public/test/data-confirm.js @@ -26,6 +26,13 @@ module('data-confirm', { 'data-confirm': 'Are you absolutely sure?' })) + $('#qunit-fixture').append($('<button />', { + type: 'submit', + form: 'confirm', + disabled: 'disabled', + 'data-confirm': 'Are you absolutely sure?' + })) + this.windowConfirm = window.confirm }, teardown: function() { @@ -286,3 +293,24 @@ asyncTest('clicking on the children of a link should also trigger a confirm', 6, .find('strong') .triggerNative('click') }) + +asyncTest('clicking on the children of a disabled button should not trigger a confirm.', 1, function() { + var message + // auto-decline: + window.confirm = function(msg) { message = msg; return false } + + $('button[data-confirm][disabled]') + .html("<strong>Click me</strong>") + .bindNative('confirm', function() { + App.assertCallbackNotInvoked('confirm') + }) + .find('strong') + .bindNative('click', function() { + App.assertCallbackInvoked('click') + }) + .triggerNative('click') + + setTimeout(function() { + start() + }, 50) +}) diff --git a/actionview/test/ujs/public/test/data-remote.js b/actionview/test/ujs/public/test/data-remote.js index b756add24e..161a92ac11 100644 --- a/actionview/test/ujs/public/test/data-remote.js +++ b/actionview/test/ujs/public/test/data-remote.js @@ -1,3 +1,17 @@ +(function() { + +function buildSelect(attrs) { + attrs = $.extend({ + 'name': 'user_data', 'data-remote': 'true', 'data-url': '/echo', 'data-params': 'data1=value1' + }, attrs) + + $('#qunit-fixture').append( + $('<select />', attrs) + .append($('<option />', {value: 'optionValue1', text: 'option1'})) + .append($('<option />', {value: 'optionValue2', text: 'option2'})) + ) +} + module('data-remote', { setup: function() { $('#qunit-fixture') @@ -135,17 +149,7 @@ asyncTest('clicking on a button with data-remote attribute', 5, function() { }) asyncTest('changing a select option with data-remote attribute', 5, function() { - $('form') - .append( - $('<select />', { - 'name': 'user_data', - 'data-remote': 'true', - 'data-params': 'data1=value1', - 'data-url': '/echo' - }) - .append($('<option />', {value: 'optionValue1', text: 'option1'})) - .append($('<option />', {value: 'optionValue2', text: 'option2'})) - ) + buildSelect() $('select[data-remote]') .bindNative('ajax:success', function(e, data, status, xhr) { @@ -350,17 +354,7 @@ asyncTest('submitting a form with falsy "data-remote" attribute', 0, function() }) asyncTest('changing a select option with falsy "data-remote" attribute', 0, function() { - $('form') - .append( - $('<select />', { - 'name': 'user_data', - 'data-remote': 'false', - 'data-params': 'data1=value1', - 'data-url': '/echo' - }) - .append($('<option />', {value: 'optionValue1', text: 'option1'})) - .append($('<option />', {value: 'optionValue2', text: 'option2'})) - ) + buildSelect({'data-remote': 'false'}) $('select[data-remote=false]:first') .bindNative('ajax:beforeSend', function() { @@ -413,3 +407,32 @@ asyncTest('form buttons should only be serialized when clicked', 4, function() { }) .find('[name=submit2]').triggerNative('click') }) + +asyncTest('changing a select option without "data-url" attribute still fires ajax request to current location', 1, function() { + var currentLocation, ajaxLocation + + buildSelect({'data-url': ''}); + + $('select[data-remote]') + .bindNative('ajax:beforeSend', function(e, xhr, settings) { + // Get current location (the same way jQuery does) + try { + currentLocation = location.href + } catch(err) { + currentLocation = document.createElement( 'a' ) + currentLocation.href = '' + currentLocation = currentLocation.href + } + + ajaxLocation = settings.url.replace(settings.data, '').replace(/&$/, '').replace(/\?$/, '') + equal(ajaxLocation, currentLocation, 'URL should be current page by default') + + return false + }) + .val('optionValue2') + .triggerNative('change') + + setTimeout(function() { start() }, 20) +}) + +})() |