diff options
Diffstat (limited to 'actionview/test')
93 files changed, 1389 insertions, 690 deletions
diff --git a/actionview/test/abstract_unit.rb b/actionview/test/abstract_unit.rb index a7d706c5e1..f20a66c2d2 100644 --- a/actionview/test/abstract_unit.rb +++ b/actionview/test/abstract_unit.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + $:.unshift File.expand_path("lib", __dir__) $:.unshift File.expand_path("fixtures/helpers", __dir__) $:.unshift File.expand_path("fixtures/alternate_helpers", __dir__) @@ -24,14 +26,6 @@ require "active_record" require "pp" # require 'pp' early to prevent hidden_methods from not picking up the pretty-print methods until too late -module Rails - class << self - def env - @_env ||= ActiveSupport::StringInquirer.new(ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "test") - end - end -end - ActiveSupport::Dependencies.hook! Thread.abort_on_exception = true @@ -108,12 +102,6 @@ module ActionDispatch end end -module ActiveSupport - class TestCase - include ActionDispatch::DrawOnce - end -end - class RoutedRackApp attr_reader :routes @@ -160,29 +148,6 @@ class ActionDispatch::IntegrationTest < ActiveSupport::TestCase self.app = build_app - # Stub Rails dispatcher so it does not get controller references and - # simply return the controller#action as Rack::Body. - class StubDispatcher < ::ActionDispatch::Routing::RouteSet::Dispatcher - private - def controller_reference(controller_param) - controller_param - end - - def dispatch(controller, action, env) - [200, { "Content-Type" => "text/html" }, ["#{controller}##{action}"]] - end - end - - def self.stub_controllers - old_dispatcher = ActionDispatch::Routing::RouteSet::Dispatcher - ActionDispatch::Routing::RouteSet.module_eval { remove_const :Dispatcher } - ActionDispatch::Routing::RouteSet.module_eval { const_set :Dispatcher, StubDispatcher } - yield ActionDispatch::Routing::RouteSet.new - ensure - ActionDispatch::Routing::RouteSet.module_eval { remove_const :Dispatcher } - ActionDispatch::Routing::RouteSet.module_eval { const_set :Dispatcher, old_dispatcher } - end - def with_routing(&block) temporary_routes = ActionDispatch::Routing::RouteSet.new old_app, self.class.app = self.class.app, self.class.build_app(temporary_routes) @@ -194,21 +159,6 @@ class ActionDispatch::IntegrationTest < ActiveSupport::TestCase self.class.app = old_app silence_warnings { Object.const_set(:SharedTestRoutes, old_routes) } end - - def with_autoload_path(path) - path = File.join(File.expand_path("fixtures", __dir__), path) - if ActiveSupport::Dependencies.autoload_paths.include?(path) - yield - else - begin - ActiveSupport::Dependencies.autoload_paths << path - yield - ensure - ActiveSupport::Dependencies.autoload_paths.reject! { |p| p == path } - ActiveSupport::Dependencies.clear - end - end - end end ActionView::RoutingUrlFor.include(ActionDispatch::Routing::UrlFor) @@ -272,6 +222,7 @@ module ActionDispatch end class ActiveSupport::TestCase + include ActionDispatch::DrawOnce include ActiveSupport::Testing::MethodCallAssertions # Skips the current run on Rubinius using Minitest::Assertions#skip diff --git a/actionview/test/actionpack/abstract/abstract_controller_test.rb b/actionview/test/actionpack/abstract/abstract_controller_test.rb index 8f65a61493..4d4e2b8ef2 100644 --- a/actionview/test/actionpack/abstract/abstract_controller_test.rb +++ b/actionview/test/actionpack/abstract/abstract_controller_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" require "set" @@ -189,10 +191,10 @@ module AbstractController private def self.layout(formats) - find_template(name.underscore, { formats: formats }, _prefixes: ["layouts"]) + find_template(name.underscore, { formats: formats }, { _prefixes: ["layouts"] }) rescue ActionView::MissingTemplate begin - find_template("application", { formats: formats }, _prefixes: ["layouts"]) + find_template("application", { formats: formats }, { _prefixes: ["layouts"] }) rescue ActionView::MissingTemplate end end @@ -234,7 +236,7 @@ module AbstractController end end - class RespondToActionController < AbstractController::Base; + class RespondToActionController < AbstractController::Base def index() self.response_body = "success" end def fail() self.response_body = "fail" end diff --git a/actionview/test/actionpack/abstract/helper_test.rb b/actionview/test/actionpack/abstract/helper_test.rb index 13922e4485..480ff60ba2 100644 --- a/actionview/test/actionpack/abstract/helper_test.rb +++ b/actionview/test/actionpack/abstract/helper_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" ActionController::Base.helpers_path = File.expand_path("../../fixtures/helpers", __dir__) diff --git a/actionview/test/actionpack/abstract/layouts_test.rb b/actionview/test/actionpack/abstract/layouts_test.rb index 4ece992597..1146e6f64b 100644 --- a/actionview/test/actionpack/abstract/layouts_test.rb +++ b/actionview/test/actionpack/abstract/layouts_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" module AbstractControllerTests diff --git a/actionview/test/actionpack/abstract/render_test.rb b/actionview/test/actionpack/abstract/render_test.rb index 8b0c54fb77..d863548a5c 100644 --- a/actionview/test/actionpack/abstract/render_test.rb +++ b/actionview/test/actionpack/abstract/render_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" module AbstractController diff --git a/actionview/test/actionpack/controller/capture_test.rb b/actionview/test/actionpack/controller/capture_test.rb index cc3a23c60c..09309e5b6d 100644 --- a/actionview/test/actionpack/controller/capture_test.rb +++ b/actionview/test/actionpack/controller/capture_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" require "active_support/logger" diff --git a/actionview/test/actionpack/controller/layout_test.rb b/actionview/test/actionpack/controller/layout_test.rb index b3e0329f57..ff66ff2a1a 100644 --- a/actionview/test/actionpack/controller/layout_test.rb +++ b/actionview/test/actionpack/controller/layout_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" require "active_support/core_ext/array/extract_options" diff --git a/actionview/test/actionpack/controller/render_test.rb b/actionview/test/actionpack/controller/render_test.rb index 6528169312..3e6b55a87e 100644 --- a/actionview/test/actionpack/controller/render_test.rb +++ b/actionview/test/actionpack/controller/render_test.rb @@ -1,13 +1,11 @@ +# frozen_string_literal: true + require "abstract_unit" require "active_model" require "controller/fake_models" -class ApplicationController < ActionController::Base - self.view_paths = File.join(FIXTURE_LOAD_PATH, "actionpack") -end - module Quiz - #Models + # Models Question = Struct.new(:name, :id) do extend ActiveModel::Naming include ActiveModel::Conversion @@ -18,7 +16,7 @@ module Quiz end # Controller - class QuestionsController < ApplicationController + class QuestionsController < ActionController::Base def new render partial: Quiz::Question.new("Namespaced Partial") end @@ -26,7 +24,7 @@ module Quiz end module Fun - class GamesController < ApplicationController + class GamesController < ActionController::Base def hello_world; end def nested_partial_with_form_builder @@ -35,7 +33,7 @@ module Fun end end -class TestController < ApplicationController +class TestController < ActionController::Base protect_from_forgery before_action :set_variable_for_layout @@ -487,6 +485,10 @@ class TestController < ApplicationController render partial: "customer", locals: { customer: Customer.new("david") } end + def partial_with_string_locals + render partial: "customer", locals: { "customer" => Customer.new("david") } + end + def partial_with_form_builder render partial: ActionView::Helpers::FormBuilder.new(:post, nil, view_context, {}) end @@ -638,10 +640,15 @@ class RenderTest < ActionController::TestCase ActionView::Base.logger = ActiveSupport::Logger.new(nil) @request.host = "www.nextangle.com" + + @old_view_paths = ActionController::Base.view_paths + ActionController::Base.view_paths = File.join(FIXTURE_LOAD_PATH, "actionpack") end def teardown ActionView::Base.logger = nil + + ActionController::Base.view_paths = @old_view_paths end # :ported: @@ -1167,6 +1174,11 @@ class RenderTest < ActionController::TestCase assert_equal "Hello: david", @response.body end + def test_partial_with_string_locals + get :partial_with_string_locals + assert_equal "Hello: david", @response.body + end + def test_partial_with_form_builder get :partial_with_form_builder assert_equal "<label for=\"post_title\">Title</label>\n", @response.body diff --git a/actionview/test/actionpack/controller/view_paths_test.rb b/actionview/test/actionpack/controller/view_paths_test.rb index 4c58b959a9..45c662f0ce 100644 --- a/actionview/test/actionpack/controller/view_paths_test.rb +++ b/actionview/test/actionpack/controller/view_paths_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" class ViewLoadPathsTest < ActionController::TestCase diff --git a/actionview/test/active_record_unit.rb b/actionview/test/active_record_unit.rb index 901c0e2b3e..7f48b515a0 100644 --- a/actionview/test/active_record_unit.rb +++ b/actionview/test/active_record_unit.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" # Define the essentials @@ -36,7 +38,7 @@ class ActiveRecordTestConnector end rescue Exception => e # errors from ActiveRecord setup $stderr.puts "\nSkipping ActiveRecord assertion tests: #{e}" - #$stderr.puts " #{e.backtrace.join("\n ")}\n" + # $stderr.puts " #{e.backtrace.join("\n ")}\n" self.able_to_connect = false end diff --git a/actionview/test/activerecord/controller_runtime_test.rb b/actionview/test/activerecord/controller_runtime_test.rb index 1cec5072c0..42b171ea07 100644 --- a/actionview/test/activerecord/controller_runtime_test.rb +++ b/actionview/test/activerecord/controller_runtime_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "active_record_unit" require "active_record/railties/controller_runtime" require "fixtures/project" diff --git a/actionview/test/activerecord/debug_helper_test.rb b/actionview/test/activerecord/debug_helper_test.rb index 06ae555a03..4be1023733 100644 --- a/actionview/test/activerecord/debug_helper_test.rb +++ b/actionview/test/activerecord/debug_helper_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "active_record_unit" require "nokogiri" diff --git a/actionview/test/activerecord/form_helper_activerecord_test.rb b/actionview/test/activerecord/form_helper_activerecord_test.rb index 9949c3fde0..1472ee8def 100644 --- a/actionview/test/activerecord/form_helper_activerecord_test.rb +++ b/actionview/test/activerecord/form_helper_activerecord_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "active_record_unit" require "fixtures/project" require "fixtures/developer" diff --git a/actionview/test/activerecord/multifetch_cache_test.rb b/actionview/test/activerecord/multifetch_cache_test.rb new file mode 100644 index 0000000000..12be069e69 --- /dev/null +++ b/actionview/test/activerecord/multifetch_cache_test.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +require "active_record_unit" +require "active_record/railties/collection_cache_association_loading" + +ActionView::PartialRenderer.prepend(ActiveRecord::Railties::CollectionCacheAssociationLoading) + +class MultifetchCacheTest < ActiveRecordTestCase + fixtures :topics, :replies + + def setup + view_paths = ActionController::Base.view_paths + + @view = Class.new(ActionView::Base) do + def view_cache_dependencies + [] + end + + def combined_fragment_cache_key(key) + [ :views, key ] + end + end.new(view_paths, {}) + end + + def test_only_preloading_for_records_that_miss_the_cache + @view.render partial: "test/partial", collection: [topics(:rails)], cached: true + + @topics = Topic.preload(:replies) + + @view.render partial: "test/partial", collection: @topics, cached: true + + assert_not @topics.detect { |topic| topic.id == topics(:rails).id }.replies.loaded? + assert @topics.detect { |topic| topic.id != topics(:rails).id }.replies.loaded? + end +end diff --git a/actionview/test/activerecord/polymorphic_routes_test.rb b/actionview/test/activerecord/polymorphic_routes_test.rb index b2e0fb08c4..4b931f793f 100644 --- a/actionview/test/activerecord/polymorphic_routes_test.rb +++ b/actionview/test/activerecord/polymorphic_routes_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "active_record_unit" require "fixtures/project" diff --git a/actionview/test/activerecord/relation_cache_test.rb b/actionview/test/activerecord/relation_cache_test.rb index d12c426586..bd0cd10eaf 100644 --- a/actionview/test/activerecord/relation_cache_test.rb +++ b/actionview/test/activerecord/relation_cache_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "active_record_unit" class RelationCacheTest < ActionView::TestCase diff --git a/actionview/test/activerecord/render_partial_with_record_identification_test.rb b/actionview/test/activerecord/render_partial_with_record_identification_test.rb index 60c3ab3045..3a698fa42e 100644 --- a/actionview/test/activerecord/render_partial_with_record_identification_test.rb +++ b/actionview/test/activerecord/render_partial_with_record_identification_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "active_record_unit" class RenderPartialWithRecordIdentificationController < ActionController::Base @@ -15,21 +17,11 @@ class RenderPartialWithRecordIdentificationController < ActionController::Base render partial: Reply.base end - def render_with_has_many_through_association - @developer = Developer.first - render partial: @developer.topics - end - def render_with_has_one_association @company = Company.find(1) render partial: @company.mascot end - def render_with_belongs_to_association - @reply = Reply.find(1) - render partial: @reply.topic - end - def render_with_record @developer = Developer.first render partial: @developer diff --git a/actionview/test/fixtures/company.rb b/actionview/test/fixtures/company.rb index 9f527acdd8..93afdd5472 100644 --- a/actionview/test/fixtures/company.rb +++ b/actionview/test/fixtures/company.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Company < ActiveRecord::Base has_one :mascot self.sequence_name = :companies_nonstd_seq diff --git a/actionview/test/fixtures/developer.rb b/actionview/test/fixtures/developer.rb index 1a686a33ce..cb7ee49eed 100644 --- a/actionview/test/fixtures/developer.rb +++ b/actionview/test/fixtures/developer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Developer < ActiveRecord::Base has_and_belongs_to_many :projects has_many :replies diff --git a/actionview/test/fixtures/digestor/comments/show.js.erb b/actionview/test/fixtures/digestor/comments/show.js.erb new file mode 100644 index 0000000000..38b37dfa2b --- /dev/null +++ b/actionview/test/fixtures/digestor/comments/show.js.erb @@ -0,0 +1 @@ +alert("<%=j render("comments/comment") %>") diff --git a/actionview/test/fixtures/helpers/abc_helper.rb b/actionview/test/fixtures/helpers/abc_helper.rb index cf2774bb5f..999b9b5c6e 100644 --- a/actionview/test/fixtures/helpers/abc_helper.rb +++ b/actionview/test/fixtures/helpers/abc_helper.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module AbcHelper def bare_a() end end diff --git a/actionview/test/fixtures/helpers/helpery_test_helper.rb b/actionview/test/fixtures/helpers/helpery_test_helper.rb index a4f2951efa..9836143848 100644 --- a/actionview/test/fixtures/helpers/helpery_test_helper.rb +++ b/actionview/test/fixtures/helpers/helpery_test_helper.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module HelperyTestHelper def helpery_test "Default" diff --git a/actionview/test/fixtures/helpers_missing/invalid_require_helper.rb b/actionview/test/fixtures/helpers_missing/invalid_require_helper.rb index 6ac6677daa..c77121046d 100644 --- a/actionview/test/fixtures/helpers_missing/invalid_require_helper.rb +++ b/actionview/test/fixtures/helpers_missing/invalid_require_helper.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "very_invalid_file_name" module InvalidRequireHelper diff --git a/actionview/test/fixtures/layouts/streaming_with_locale.erb b/actionview/test/fixtures/layouts/streaming_with_locale.erb new file mode 100644 index 0000000000..e1fdad2073 --- /dev/null +++ b/actionview/test/fixtures/layouts/streaming_with_locale.erb @@ -0,0 +1,2 @@ +layout.locale: <%= I18n.locale %> +<%= yield %> diff --git a/actionview/test/fixtures/mascot.rb b/actionview/test/fixtures/mascot.rb index 1c0bd7c8fd..26a2c7bbe1 100644 --- a/actionview/test/fixtures/mascot.rb +++ b/actionview/test/fixtures/mascot.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Mascot < ActiveRecord::Base belongs_to :company end diff --git a/actionview/test/fixtures/project.rb b/actionview/test/fixtures/project.rb index 404b12cbab..019ddb7aef 100644 --- a/actionview/test/fixtures/project.rb +++ b/actionview/test/fixtures/project.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Project < ActiveRecord::Base has_and_belongs_to_many :developers, -> { uniq } diff --git a/actionview/test/fixtures/public/.gitignore b/actionview/test/fixtures/public/.gitignore deleted file mode 100644 index 312e635ee6..0000000000 --- a/actionview/test/fixtures/public/.gitignore +++ /dev/null @@ -1 +0,0 @@ -absolute/* diff --git a/actionview/test/fixtures/reply.rb b/actionview/test/fixtures/reply.rb index 047522c55b..b2b662e1b5 100644 --- a/actionview/test/fixtures/reply.rb +++ b/actionview/test/fixtures/reply.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Reply < ActiveRecord::Base scope :base, -> { all } belongs_to :topic, -> { includes(:replies) } diff --git a/actionview/test/fixtures/test/streaming_with_locale.erb b/actionview/test/fixtures/test/streaming_with_locale.erb new file mode 100644 index 0000000000..b0f2b2f7e9 --- /dev/null +++ b/actionview/test/fixtures/test/streaming_with_locale.erb @@ -0,0 +1 @@ +view.locale: <%= I18n.locale %> diff --git a/actionview/test/fixtures/topic.rb b/actionview/test/fixtures/topic.rb index 48a3dfba88..ff194ce567 100644 --- a/actionview/test/fixtures/topic.rb +++ b/actionview/test/fixtures/topic.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Topic < ActiveRecord::Base has_many :replies, dependent: :destroy end diff --git a/actionview/test/lib/controller/fake_models.rb b/actionview/test/lib/controller/fake_models.rb index 5250101220..f8b7ddaecc 100644 --- a/actionview/test/lib/controller/fake_models.rb +++ b/actionview/test/lib/controller/fake_models.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "active_model" Customer = Struct.new(:name, :id) do diff --git a/actionview/test/template/active_model_helper_test.rb b/actionview/test/template/active_model_helper_test.rb index 6b63aa25a5..36afed6dd6 100644 --- a/actionview/test/template/active_model_helper_test.rb +++ b/actionview/test/template/active_model_helper_test.rb @@ -1,10 +1,12 @@ +# frozen_string_literal: true + require "abstract_unit" class ActiveModelHelperTest < ActionView::TestCase tests ActionView::Helpers::ActiveModelHelper silence_warnings do - Post = Struct.new(:author_name, :body, :updated_at) do + Post = Struct.new(:author_name, :body, :category, :published, :updated_at) do include ActiveModel::Conversion include ActiveModel::Validations @@ -20,10 +22,14 @@ class ActiveModelHelperTest < ActionView::TestCase @post = Post.new @post.errors[:author_name] << "can't be empty" @post.errors[:body] << "foo" + @post.errors[:category] << "must exist" + @post.errors[:published] << "must be accepted" @post.errors[:updated_at] << "bar" @post.author_name = "" @post.body = "Back to the hill and over it again!" + @post.category = "rails" + @post.published = false @post.updated_at = Date.new(2004, 6, 15) end @@ -54,6 +60,25 @@ class ActiveModelHelperTest < ActionView::TestCase assert_dom_equal(expected_dom, select("post", "author_name", [:a, :b], prompt: "Choose one...")) end + def test_select_grouped_options_with_errors + grouped_options = [ + ["A", [["A1"], ["A2"]]], + ["B", [["B1"], ["B2"]]], + ] + + assert_dom_equal( + %(<div class="field_with_errors"><select name="post[category]" id="post_category"><optgroup label="A"><option value="A1">A1</option>\n<option value="A2">A2</option></optgroup><optgroup label="B"><option value="B1">B1</option>\n<option value="B2">B2</option></optgroup></select></div>), + select("post", "category", grouped_options) + ) + end + + def test_collection_select_with_errors + assert_dom_equal( + %(<div class="field_with_errors"><select name="post[author_name]" id="post_author_name"><option value="a">a</option>\n<option value="b">b</option></select></div>), + collection_select("post", "author_name", [:a, :b], :to_s, :to_s) + ) + end + def test_date_select_with_errors assert_dom_equal( %(<div class="field_with_errors"><select id="post_updated_at_1i" name="post[updated_at(1i)]">\n<option selected="selected" value="2004">2004</option>\n<option value="2005">2005</option>\n</select>\n<input id="post_updated_at_2i" name="post[updated_at(2i)]" type="hidden" value="6" />\n<input id="post_updated_at_3i" name="post[updated_at(3i)]" type="hidden" value="1" />\n</div>), @@ -75,6 +100,55 @@ class ActiveModelHelperTest < ActionView::TestCase ) end + def test_label_with_errors + assert_dom_equal( + %(<div class="field_with_errors"><label for="post_body">Body</label></div>), + label("post", "body") + ) + end + + def test_check_box_with_errors + assert_dom_equal( + %(<input name="post[published]" type="hidden" value="0" /><div class="field_with_errors"><input type="checkbox" value="1" name="post[published]" id="post_published" /></div>), + check_box("post", "published") + ) + end + + def test_check_boxes_with_errors + assert_dom_equal( + %(<input name="post[published]" type="hidden" value="0" /><div class="field_with_errors"><input type="checkbox" value="1" name="post[published]" id="post_published" /></div><input name="post[published]" type="hidden" value="0" /><div class="field_with_errors"><input type="checkbox" value="1" name="post[published]" id="post_published" /></div>), + check_box("post", "published") + check_box("post", "published") + ) + end + + def test_radio_button_with_errors + assert_dom_equal( + %(<div class="field_with_errors"><input type="radio" value="rails" checked="checked" name="post[category]" id="post_category_rails" /></div>), + radio_button("post", "category", "rails") + ) + end + + def test_radio_buttons_with_errors + assert_dom_equal( + %(<div class="field_with_errors"><input type="radio" value="rails" checked="checked" name="post[category]" id="post_category_rails" /></div><div class="field_with_errors"><input type="radio" value="java" name="post[category]" id="post_category_java" /></div>), + radio_button("post", "category", "rails") + radio_button("post", "category", "java") + ) + end + + def test_collection_check_boxes_with_errors + assert_dom_equal( + %(<input type="hidden" name="post[category][]" value="" /><div class="field_with_errors"><input type="checkbox" value="ruby" name="post[category][]" id="post_category_ruby" /></div><label for="post_category_ruby">ruby</label><div class="field_with_errors"><input type="checkbox" value="java" name="post[category][]" id="post_category_java" /></div><label for="post_category_java">java</label>), + collection_check_boxes("post", "category", [:ruby, :java], :to_s, :to_s) + ) + end + + def test_collection_radio_buttons_with_errors + assert_dom_equal( + %(<input type="hidden" name="post[category]" value="" /><div class="field_with_errors"><input type="radio" value="ruby" name="post[category]" id="post_category_ruby" /></div><label for="post_category_ruby">ruby</label><div class="field_with_errors"><input type="radio" value="java" name="post[category]" id="post_category_java" /></div><label for="post_category_java">java</label>), + collection_radio_buttons("post", "category", [:ruby, :java], :to_s, :to_s) + ) + end + def test_hidden_field_does_not_render_errors assert_dom_equal( %(<input id="post_author_name" name="post[author_name]" type="hidden" value="" />), diff --git a/actionview/test/template/asset_tag_helper_test.rb b/actionview/test/template/asset_tag_helper_test.rb index d1190b1bd7..e68f03d1f4 100644 --- a/actionview/test/template/asset_tag_helper_test.rb +++ b/actionview/test/template/asset_tag_helper_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" require "active_support/ordered_options" @@ -17,6 +19,7 @@ class AssetTagHelperTest < ActionView::TestCase def ssl?() false end def host_with_port() "localhost" end def base_url() "http://www.example.com" end + def send_early_hints(links) end end.new @controller.request = @request @@ -26,6 +29,10 @@ class AssetTagHelperTest < ActionView::TestCase "http://www.example.com" end + def content_security_policy_nonce + "iyhD0Yc0W+c=" + end + AssetPathToTag = { %(asset_path("")) => %(), %(asset_path(" ")) => %(), @@ -181,26 +188,26 @@ class AssetTagHelperTest < ActionView::TestCase } ImageLinkToTag = { - %(image_tag("xml.png")) => %(<img alt="Xml" src="/images/xml.png" />), + %(image_tag("xml.png")) => %(<img src="/images/xml.png" />), %(image_tag("rss.gif", :alt => "rss syndication")) => %(<img alt="rss syndication" src="/images/rss.gif" />), - %(image_tag("gold.png", :size => "20")) => %(<img alt="Gold" height="20" src="/images/gold.png" width="20" />), - %(image_tag("gold.png", :size => 20)) => %(<img alt="Gold" height="20" src="/images/gold.png" width="20" />), - %(image_tag("gold.png", :size => "45x70")) => %(<img alt="Gold" height="70" src="/images/gold.png" width="45" />), - %(image_tag("gold.png", "size" => "45x70")) => %(<img alt="Gold" height="70" src="/images/gold.png" width="45" />), - %(image_tag("error.png", "size" => "45 x 70")) => %(<img alt="Error" src="/images/error.png" />), - %(image_tag("error.png", "size" => "x")) => %(<img alt="Error" src="/images/error.png" />), - %(image_tag("google.com.png")) => %(<img alt="Google.com" src="/images/google.com.png" />), - %(image_tag("slash..png")) => %(<img alt="Slash." src="/images/slash..png" />), - %(image_tag(".pdf.png")) => %(<img alt=".pdf" src="/images/.pdf.png" />), - %(image_tag("http://www.rubyonrails.com/images/rails.png")) => %(<img alt="Rails" src="http://www.rubyonrails.com/images/rails.png" />), - %(image_tag("//www.rubyonrails.com/images/rails.png")) => %(<img alt="Rails" src="//www.rubyonrails.com/images/rails.png" />), + %(image_tag("gold.png", :size => "20")) => %(<img height="20" src="/images/gold.png" width="20" />), + %(image_tag("gold.png", :size => 20)) => %(<img height="20" src="/images/gold.png" width="20" />), + %(image_tag("gold.png", :size => "45x70")) => %(<img height="70" src="/images/gold.png" width="45" />), + %(image_tag("gold.png", "size" => "45x70")) => %(<img height="70" src="/images/gold.png" width="45" />), + %(image_tag("error.png", "size" => "45 x 70")) => %(<img src="/images/error.png" />), + %(image_tag("error.png", "size" => "x")) => %(<img src="/images/error.png" />), + %(image_tag("google.com.png")) => %(<img src="/images/google.com.png" />), + %(image_tag("slash..png")) => %(<img src="/images/slash..png" />), + %(image_tag(".pdf.png")) => %(<img src="/images/.pdf.png" />), + %(image_tag("http://www.rubyonrails.com/images/rails.png")) => %(<img src="http://www.rubyonrails.com/images/rails.png" />), + %(image_tag("//www.rubyonrails.com/images/rails.png")) => %(<img src="//www.rubyonrails.com/images/rails.png" />), %(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("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" />) + %(image_tag("gold.png", data: { title: 'Rails Application' })) => %(<img data-title="Rails Application" src="/images/gold.png" />), + %(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" />), + %(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" />), + %(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" />) } FaviconLinkToTag = { @@ -211,6 +218,17 @@ class AssetTagHelperTest < ActionView::TestCase %(favicon_link_tag 'mb-icon.png', :rel => 'apple-touch-icon', :type => 'image/png') => %(<link href="/images/mb-icon.png" rel="apple-touch-icon" type="image/png" />) } + PreloadLinkToTag = { + %(preload_link_tag '/styles/custom_theme.css') => %(<link rel="preload" href="/styles/custom_theme.css" as="style" type="text/css" />), + %(preload_link_tag '/videos/video.webm') => %(<link rel="preload" href="/videos/video.webm" as="video" type="video/webm" />), + %(preload_link_tag '/posts.json', as: 'fetch') => %(<link rel="preload" href="/posts.json" as="fetch" type="application/json" />), + %(preload_link_tag '/users', as: 'fetch', type: 'application/json') => %(<link rel="preload" href="/users" as="fetch" type="application/json" />), + %(preload_link_tag '//example.com/map?callback=initMap', as: 'fetch', type: 'application/javascript') => %(<link rel="preload" href="//example.com/map?callback=initMap" as="fetch" type="application/javascript" />), + %(preload_link_tag '//example.com/font.woff2') => %(<link rel="preload" href="//example.com/font.woff2" as="font" type="font/woff2" crossorigin="anonymous"/>), + %(preload_link_tag '//example.com/font.woff2', crossorigin: 'use-credentials') => %(<link rel="preload" href="//example.com/font.woff2" as="font" type="font/woff2" crossorigin="use-credentials" />), + %(preload_link_tag '/media/audio.ogg', nopush: true) => %(<link rel="preload" href="/media/audio.ogg" as="audio" type="audio/ogg" />) + } + VideoPathToTag = { %(video_path("xml")) => %(/videos/xml), %(video_path("xml.ogg")) => %(/videos/xml.ogg), @@ -303,6 +321,24 @@ class AssetTagHelperTest < ActionView::TestCase %(font_path("font.ttf?123")) => %(/fonts/font.ttf?123) } + FontUrlToTag = { + %(font_url("font.eot")) => %(http://www.example.com/fonts/font.eot), + %(font_url("font.eot#iefix")) => %(http://www.example.com/fonts/font.eot#iefix), + %(font_url("font.woff")) => %(http://www.example.com/fonts/font.woff), + %(font_url("font.ttf")) => %(http://www.example.com/fonts/font.ttf), + %(font_url("font.ttf?123")) => %(http://www.example.com/fonts/font.ttf?123), + %(font_url("font.ttf", host: "http://assets.example.com")) => %(http://assets.example.com/fonts/font.ttf) + } + + UrlToFontToTag = { + %(url_to_font("font.eot")) => %(http://www.example.com/fonts/font.eot), + %(url_to_font("font.eot#iefix")) => %(http://www.example.com/fonts/font.eot#iefix), + %(url_to_font("font.woff")) => %(http://www.example.com/fonts/font.woff), + %(url_to_font("font.ttf")) => %(http://www.example.com/fonts/font.ttf), + %(url_to_font("font.ttf?123")) => %(http://www.example.com/fonts/font.ttf?123), + %(url_to_font("font.ttf", host: "http://assets.example.com")) => %(http://assets.example.com/fonts/font.ttf) + } + def test_autodiscovery_link_tag_with_unknown_type_but_not_pass_type_option_key assert_raise(ArgumentError) do auto_discovery_link_tag(:xml) @@ -375,7 +411,7 @@ class AssetTagHelperTest < ActionView::TestCase end def test_javascript_include_tag_is_html_safe - assert javascript_include_tag("prototype").html_safe? + assert_predicate javascript_include_tag("prototype"), :html_safe? end def test_javascript_include_tag_relative_protocol @@ -389,6 +425,10 @@ class AssetTagHelperTest < ActionView::TestCase assert_dom_equal %(<script src="//assets.example.com/javascripts/prototype.js"></script>), javascript_include_tag("prototype") end + def test_javascript_include_tag_nonce + assert_dom_equal %(<script src="/javascripts/bank.js" nonce="iyhD0Yc0W+c="></script>), javascript_include_tag("bank", nonce: true) + end + def test_stylesheet_path StylePathToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) } end @@ -419,9 +459,17 @@ class AssetTagHelperTest < ActionView::TestCase } end + def test_stylesheet_link_tag_without_request + @request = nil + assert_dom_equal( + %(<link rel="stylesheet" media="screen" href="/stylesheets/foo.css" />), + stylesheet_link_tag("foo.css") + ) + end + def test_stylesheet_link_tag_is_html_safe - assert stylesheet_link_tag("dir/file").html_safe? - assert stylesheet_link_tag("dir/other/file", "dir/file2").html_safe? + assert_predicate stylesheet_link_tag("dir/file"), :html_safe? + assert_predicate stylesheet_link_tag("dir/other/file", "dir/file2"), :html_safe? end def test_stylesheet_link_tag_escapes_options @@ -443,6 +491,11 @@ class AssetTagHelperTest < ActionView::TestCase assert_dom_equal %(<link href="//assets.example.com/stylesheets/wellington.css" media="screen" rel="stylesheet" />), stylesheet_link_tag("wellington") end + def test_javascript_include_tag_without_request + @request = nil + assert_dom_equal %(<script src="/javascripts/foo.js"></script>), javascript_include_tag("foo.js") + end + def test_image_path ImagePathToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) } end @@ -461,11 +514,21 @@ class AssetTagHelperTest < ActionView::TestCase def test_image_alt [nil, "/", "/foo/bar/", "foo/bar/"].each do |prefix| - assert_equal "Rails", image_alt("#{prefix}rails.png") - assert_equal "Rails", image_alt("#{prefix}rails-9c0a079bdd7701d7e729bd956823d153.png") - assert_equal "Rails", image_alt("#{prefix}rails-f56ef62bc41b040664e801a38f068082a75d506d9048307e8096737463503d0b.png") - assert_equal "Long file name with hyphens", image_alt("#{prefix}long-file-name-with-hyphens.png") - assert_equal "Long file name with underscores", image_alt("#{prefix}long_file_name_with_underscores.png") + assert_deprecated do + assert_equal "Rails", image_alt("#{prefix}rails.png") + end + assert_deprecated do + assert_equal "Rails", image_alt("#{prefix}rails-9c0a079bdd7701d7e729bd956823d153.png") + end + assert_deprecated do + assert_equal "Rails", image_alt("#{prefix}rails-f56ef62bc41b040664e801a38f068082a75d506d9048307e8096737463503d0b.png") + end + assert_deprecated do + assert_equal "Long file name with hyphens", image_alt("#{prefix}long-file-name-with-hyphens.png") + end + assert_deprecated do + assert_equal "Long file name with underscores", image_alt("#{prefix}long_file_name_with_underscores.png") + end end end @@ -491,6 +554,10 @@ class AssetTagHelperTest < ActionView::TestCase FaviconLinkToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) } end + def test_preload_link_tag + PreloadLinkToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) } + end + def test_video_path VideoPathToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) } end @@ -535,6 +602,14 @@ class AssetTagHelperTest < ActionView::TestCase FontPathToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) } end + def test_font_url + FontUrlToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) } + end + + def test_url_to_font_alias_for_font_url + UrlToFontToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) } + end + def test_video_audio_tag_does_not_modify_options options = { autoplay: true } video_tag("video", options) @@ -563,9 +638,6 @@ class AssetTagHelperTest < ActionView::TestCase def blank?; true; end def to_s; "no-image-yet.png"; end end - def test_image_tag_with_blank_placeholder - assert_equal '<img alt="" src="/images/no-image-yet.png" />', image_tag(PlaceholderImage.new, alt: "") - end def test_image_path_with_blank_placeholder assert_equal "/images/no-image-yet.png", image_path(PlaceholderImage.new) end @@ -618,7 +690,9 @@ class AssetTagHelperNonVhostTest < ActionView::TestCase @controller = BasicController.new @controller.config.relative_url_root = "/collaboration/hieraki" - @request = Struct.new(:protocol, :base_url).new("gopher://", "gopher://www.example.com") + @request = Struct.new(:protocol, :base_url) do + def send_early_hints(links); end + end.new("gopher://", "gopher://www.example.com") @controller.request = @request end @@ -740,6 +814,23 @@ class AssetTagHelperNonVhostTest < ActionView::TestCase end end +class AssetTagHelperWithoutRequestTest < ActionView::TestCase + tests ActionView::Helpers::AssetTagHelper + + undef :request + + def test_stylesheet_link_tag_without_request + assert_dom_equal( + %(<link rel="stylesheet" media="screen" href="/stylesheets/foo.css" />), + stylesheet_link_tag("foo.css") + ) + end + + def test_javascript_include_tag_without_request + assert_dom_equal %(<script src="/javascripts/foo.js"></script>), javascript_include_tag("foo.js") + end +end + class AssetUrlHelperControllerTest < ActionView::TestCase tests ActionView::Helpers::AssetUrlHelper diff --git a/actionview/test/template/atom_feed_helper_test.rb b/actionview/test/template/atom_feed_helper_test.rb index 7fa5e042fb..8e683cb48a 100644 --- a/actionview/test/template/atom_feed_helper_test.rb +++ b/actionview/test/template/atom_feed_helper_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" Scroll = Struct.new(:id, :to_param, :title, :body, :updated_at, :created_at) do @@ -255,7 +257,7 @@ class AtomFeedTest < ActionController::TestCase get :index, params: { id: "provide_builder" } # because we pass in the non-default builder, the content generated by the # helper should go 'nowhere'. Leaving the response body blank. - assert @response.body.blank? + assert_predicate @response.body, :blank? end end diff --git a/actionview/test/template/capture_helper_test.rb b/actionview/test/template/capture_helper_test.rb index 7f37523eeb..131e49327e 100644 --- a/actionview/test/template/capture_helper_test.rb +++ b/actionview/test/template/capture_helper_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" class CaptureHelperTest < ActionView::TestCase @@ -47,21 +49,21 @@ class CaptureHelperTest < ActionView::TestCase end def test_content_for_with_multiple_calls - assert ! content_for?(:title) + assert_not content_for?(:title) content_for :title, "foo" content_for :title, "bar" assert_equal "foobar", content_for(:title) end def test_content_for_with_multiple_calls_and_flush - assert ! content_for?(:title) + assert_not content_for?(:title) content_for :title, "foo" content_for :title, "bar", flush: true assert_equal "bar", content_for(:title) end def test_content_for_with_block - assert ! content_for?(:title) + assert_not content_for?(:title) content_for :title do output_buffer << "foo" output_buffer << "bar" @@ -71,7 +73,7 @@ class CaptureHelperTest < ActionView::TestCase end def test_content_for_with_block_and_multiple_calls_with_flush - assert ! content_for?(:title) + assert_not content_for?(:title) content_for :title do "foo" end @@ -82,7 +84,7 @@ class CaptureHelperTest < ActionView::TestCase end def test_content_for_with_block_and_multiple_calls_with_flush_nil_content - assert ! content_for?(:title) + assert_not content_for?(:title) content_for :title do "foo" end @@ -93,7 +95,7 @@ class CaptureHelperTest < ActionView::TestCase end def test_content_for_with_block_and_multiple_calls_without_flush - assert ! content_for?(:title) + assert_not content_for?(:title) content_for :title do "foo" end @@ -104,7 +106,7 @@ class CaptureHelperTest < ActionView::TestCase end def test_content_for_with_whitespace_block - assert ! content_for?(:title) + assert_not content_for?(:title) content_for :title, "foo" content_for :title do output_buffer << " \n " @@ -115,7 +117,7 @@ class CaptureHelperTest < ActionView::TestCase end def test_content_for_with_whitespace_block_and_flush - assert ! content_for?(:title) + assert_not content_for?(:title) content_for :title, "foo" content_for :title, flush: true do output_buffer << " \n " @@ -126,7 +128,7 @@ class CaptureHelperTest < ActionView::TestCase end def test_content_for_returns_nil_when_writing - assert ! content_for?(:title) + assert_not content_for?(:title) assert_nil content_for(:title, "foo") assert_nil content_for(:title) { output_buffer << "bar"; nil } assert_nil content_for(:title) { output_buffer << " \n "; nil } @@ -142,27 +144,27 @@ class CaptureHelperTest < ActionView::TestCase end def test_content_for_question_mark - assert ! content_for?(:title) + assert_not content_for?(:title) content_for :title, "title" assert content_for?(:title) - assert ! content_for?(:something_else) + assert_not content_for?(:something_else) end def test_content_for_should_be_html_safe_after_flush_empty - assert ! content_for?(:title) + assert_not content_for?(:title) content_for :title do content_tag(:p, "title") end - assert content_for(:title).html_safe? + assert_predicate content_for(:title), :html_safe? content_for :title, "", flush: true content_for(:title) do content_tag(:p, "title") end - assert content_for(:title).html_safe? + assert_predicate content_for(:title), :html_safe? end def test_provide - assert !content_for?(:title) + assert_not content_for?(:title) provide :title, "hi" assert content_for?(:title) assert_equal "hi", content_for(:title) diff --git a/actionview/test/template/compiled_templates_test.rb b/actionview/test/template/compiled_templates_test.rb index adb2be9be4..3cd6448e38 100644 --- a/actionview/test/template/compiled_templates_test.rb +++ b/actionview/test/template/compiled_templates_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" class CompiledTemplatesTest < ActiveSupport::TestCase diff --git a/actionview/test/template/controller_helper_test.rb b/actionview/test/template/controller_helper_test.rb index 8dd0cedb75..46d20c188c 100644 --- a/actionview/test/template/controller_helper_test.rb +++ b/actionview/test/template/controller_helper_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" class ControllerHelperTest < ActionView::TestCase @@ -18,4 +20,15 @@ class ControllerHelperTest < ActionView::TestCase assert_nil default_form_builder end + + def test_respond_to + @controller = OpenStruct.new + assign_controller(@controller) + assert_not respond_to?(:params) + assert respond_to?(:assign_controller) + + @controller.params = {} + assert respond_to?(:params) + assert respond_to?(:assign_controller) + end end diff --git a/actionview/test/template/date_helper_i18n_test.rb b/actionview/test/template/date_helper_i18n_test.rb index 207c8a683e..60303b4c91 100644 --- a/actionview/test/template/date_helper_i18n_test.rb +++ b/actionview/test/template/date_helper_i18n_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" class DateHelperDistanceOfTimeInWordsI18nTests < ActiveSupport::TestCase diff --git a/actionview/test/template/date_helper_test.rb b/actionview/test/template/date_helper_test.rb index b9b8194e69..4b4939d705 100644 --- a/actionview/test/template/date_helper_test.rb +++ b/actionview/test/template/date_helper_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" class DateHelperTest < ActionView::TestCase @@ -139,18 +141,16 @@ class DateHelperTest < ActionView::TestCase 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 + rubinius_skip "Date is written in Ruby and relies on Integer#/" + jruby_skip "Date is written in Ruby and relies on Integer#/" - # Make sure that we avoid {Integer,Fixnum}#/ (redefined by mathn) - klass.send :private, :/ + # Make sure that we avoid Integer#/ (redefined by mathn) + Integer.send :private, :/ from = Time.utc(2004, 6, 6, 21, 45, 0) assert_distance_of_time_in_words(from) ensure - klass.send :public, :/ + Integer.send :public, :/ end def test_time_ago_in_words_passes_include_seconds @@ -253,8 +253,8 @@ class DateHelperTest < ActionView::TestCase 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" - assert_dom_equal expected, select_day(Time.mktime(2003, 8, 16), {}, class: "selector") - assert_dom_equal expected, select_day(16, {}, class: "selector") + assert_dom_equal expected, select_day(Time.mktime(2003, 8, 16), {}, { class: "selector" }) + assert_dom_equal expected, select_day(16, {}, { class: "selector" }) end def test_select_day_with_default_prompt @@ -423,7 +423,7 @@ class DateHelperTest < ActionView::TestCase 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" - assert_dom_equal expected, select_month(Time.mktime(2003, 8, 16), {}, class: "selector", accesskey: "M") + assert_dom_equal expected, select_month(Time.mktime(2003, 8, 16), {}, { class: "selector", accesskey: "M" }) end def test_select_month_with_default_prompt @@ -518,7 +518,7 @@ class DateHelperTest < ActionView::TestCase expected << %(<option value="2003" selected="selected">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n) expected << "</select>\n" - assert_dom_equal expected, select_year(Time.mktime(2003, 8, 16), { start_year: 2003, end_year: 2005 }, class: "selector", accesskey: "M") + assert_dom_equal expected, select_year(Time.mktime(2003, 8, 16), { start_year: 2003, end_year: 2005 }, { class: "selector", accesskey: "M" }) end def test_select_year_with_default_prompt @@ -613,7 +613,7 @@ class DateHelperTest < ActionView::TestCase 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" - assert_dom_equal expected, select_hour(Time.mktime(2003, 8, 16, 8, 4, 18), {}, class: "selector", accesskey: "M") + assert_dom_equal expected, select_hour(Time.mktime(2003, 8, 16, 8, 4, 18), {}, { class: "selector", accesskey: "M" }) end def test_select_hour_with_default_prompt @@ -685,7 +685,7 @@ class DateHelperTest < ActionView::TestCase expected << %(<option value=""></option>\n<option value="00">00</option>\n<option value="15">15</option>\n<option value="30">30</option>\n<option value="45">45</option>\n) expected << "</select>\n" - assert_dom_equal expected, select_minute(Time.mktime(2003, 8, 16, 8, 4, 18), include_blank: true , minute_step: 15) + assert_dom_equal expected, select_minute(Time.mktime(2003, 8, 16, 8, 4, 18), include_blank: true, minute_step: 15) end def test_select_minute_nil_with_blank @@ -701,7 +701,7 @@ class DateHelperTest < ActionView::TestCase expected << %(<option value=""></option>\n<option value="00">00</option>\n<option value="15">15</option>\n<option value="30">30</option>\n<option value="45">45</option>\n) expected << "</select>\n" - assert_dom_equal expected, select_minute(nil, include_blank: true , minute_step: 15) + assert_dom_equal expected, select_minute(nil, include_blank: true, minute_step: 15) end def test_select_minute_with_hidden @@ -717,7 +717,7 @@ class DateHelperTest < ActionView::TestCase 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" - assert_dom_equal expected, select_minute(Time.mktime(2003, 8, 16, 8, 4, 18), {}, class: "selector", accesskey: "M") + assert_dom_equal expected, select_minute(Time.mktime(2003, 8, 16, 8, 4, 18), {}, { class: "selector", accesskey: "M" }) end def test_select_minute_with_default_prompt @@ -797,7 +797,7 @@ class DateHelperTest < ActionView::TestCase 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" - assert_dom_equal expected, select_second(Time.mktime(2003, 8, 16, 8, 4, 18), {}, class: "selector", accesskey: "M") + assert_dom_equal expected, select_second(Time.mktime(2003, 8, 16, 8, 4, 18), {}, { class: "selector", accesskey: "M" }) end def test_select_second_with_default_prompt @@ -1064,7 +1064,7 @@ class DateHelperTest < ActionView::TestCase 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" - assert_dom_equal expected, select_date(Time.mktime(2003, 8, 16), { start_year: 2003, end_year: 2005, prefix: "date[first]" }, class: "selector") + assert_dom_equal expected, select_date(Time.mktime(2003, 8, 16), { start_year: 2003, end_year: 2005, prefix: "date[first]" }, { class: "selector" }) end def test_select_date_with_separator @@ -1168,7 +1168,7 @@ class DateHelperTest < ActionView::TestCase 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" - assert_dom_equal expected, select_date(Time.mktime(2003, 8, 16), { start_year: 2003, end_year: 2005, prefix: "date[first]", with_css_classes: true }, class: "datetime optional") + assert_dom_equal expected, select_date(Time.mktime(2003, 8, 16), { start_year: 2003, end_year: 2005, prefix: "date[first]", with_css_classes: true }, { class: "datetime optional" }) end def test_select_date_with_custom_with_css_classes_and_html_class_option @@ -1184,7 +1184,7 @@ class DateHelperTest < ActionView::TestCase 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" - assert_dom_equal expected, select_date(Time.mktime(2003, 8, 16), { start_year: 2003, end_year: 2005, with_css_classes: { year: "my-year", month: "my-month", day: "my-day" } }, class: "date optional") + assert_dom_equal expected, select_date(Time.mktime(2003, 8, 16), { start_year: 2003, end_year: 2005, with_css_classes: { year: "my-year", month: "my-month", day: "my-day" } }, { class: "date optional" }) end def test_select_date_with_partial_with_css_classes_and_html_class_option @@ -1200,7 +1200,7 @@ class DateHelperTest < ActionView::TestCase 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" - assert_dom_equal expected, select_date(Time.mktime(2003, 8, 16), { start_year: 2003, end_year: 2005, with_css_classes: { month: "my-month custom-grid" } }, class: "date optional") + assert_dom_equal expected, select_date(Time.mktime(2003, 8, 16), { start_year: 2003, end_year: 2005, with_css_classes: { month: "my-month custom-grid" } }, { class: "date optional" }) end def test_select_date_with_html_class_option @@ -1216,7 +1216,7 @@ class DateHelperTest < ActionView::TestCase 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" - assert_dom_equal expected, select_date(Time.mktime(2003, 8, 16), { start_year: 2003, end_year: 2005 }, class: "date optional custom-grid") + assert_dom_equal expected, select_date(Time.mktime(2003, 8, 16), { start_year: 2003, end_year: 2005 }, { class: "date optional custom-grid" }) end def test_select_datetime @@ -1356,7 +1356,7 @@ class DateHelperTest < ActionView::TestCase 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" - assert_dom_equal expected, select_datetime(Time.mktime(2003, 8, 16, 8, 4, 18), { start_year: 2003, end_year: 2005, prefix: "date[first]" }, class: "selector") + assert_dom_equal expected, select_datetime(Time.mktime(2003, 8, 16, 8, 4, 18), { start_year: 2003, end_year: 2005, prefix: "date[first]" }, { class: "selector" }) end def test_select_datetime_with_all_separators @@ -1388,7 +1388,7 @@ class DateHelperTest < ActionView::TestCase 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" - assert_dom_equal expected, select_datetime(Time.mktime(2003, 8, 16, 8, 4, 18), { datetime_separator: "—", date_separator: "/", time_separator: ":", start_year: 2003, end_year: 2005, prefix: "date[first]" }, class: "selector") + assert_dom_equal expected, select_datetime(Time.mktime(2003, 8, 16, 8, 4, 18), { datetime_separator: "—", date_separator: "/", time_separator: ":", start_year: 2003, end_year: 2005, prefix: "date[first]" }, { class: "selector" }) end def test_select_datetime_should_work_with_date @@ -1668,8 +1668,8 @@ class DateHelperTest < ActionView::TestCase 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" - assert_dom_equal expected, select_time(Time.mktime(2003, 8, 16, 8, 4, 18), {}, class: "selector") - assert_dom_equal expected, select_time(Time.mktime(2003, 8, 16, 8, 4, 18), { include_seconds: false }, class: "selector") + assert_dom_equal expected, select_time(Time.mktime(2003, 8, 16, 8, 4, 18), {}, { class: "selector" }) + assert_dom_equal expected, select_time(Time.mktime(2003, 8, 16, 8, 4, 18), { include_seconds: false }, { class: "selector" }) end def test_select_time_should_work_with_date @@ -1926,7 +1926,7 @@ class DateHelperTest < ActionView::TestCase 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" - assert_dom_equal expected, date_select("post", "written_on", { order: [ :month, :year ] }, disabled: true) + assert_dom_equal expected, date_select("post", "written_on", { order: [ :month, :year ] }, { disabled: true }) end def test_date_select_within_fields_for @@ -2168,7 +2168,7 @@ class DateHelperTest < ActionView::TestCase expected << "</select>\n" - assert_dom_equal expected, date_select("post", "written_on", {}, class: "selector") + assert_dom_equal expected, date_select("post", "written_on", {}, { class: "selector" }) end def test_date_select_with_html_options_within_fields_for @@ -2176,7 +2176,7 @@ class DateHelperTest < ActionView::TestCase @post.written_on = Date.new(2004, 6, 15) output_buffer = fields_for :post, @post do |f| - concat f.date_select(:written_on, {}, class: "selector") + concat f.date_select(:written_on, {}, { class: "selector" }) end expected = %{<select id="post_written_on_1i" name="post[written_on(1i)]" class="selector">\n}.dup @@ -2451,7 +2451,7 @@ class DateHelperTest < ActionView::TestCase 0.upto(59) { |i| expected << %(<option value="#{sprintf("%02d", i)}"#{' selected="selected"' if i == 16}>#{sprintf("%02d", i)}</option>\n) } expected << "</select>\n" - assert_dom_equal expected, time_select("post", "written_on", {}, class: "selector") + assert_dom_equal expected, time_select("post", "written_on", {}, { class: "selector" }) end def test_time_select_with_html_options_within_fields_for @@ -2459,7 +2459,7 @@ class DateHelperTest < ActionView::TestCase @post.written_on = Time.local(2004, 6, 15, 15, 16, 35) output_buffer = fields_for :post, @post do |f| - concat f.time_select(:written_on, {}, class: "selector") + 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}.dup @@ -2604,7 +2604,7 @@ class DateHelperTest < ActionView::TestCase 0.upto(59) { |i| expected << %(<option value="#{sprintf("%02d", i)}"#{' selected="selected"' if i == 16}>#{sprintf("%02d", i)}</option>\n) } expected << "</select>\n" - assert_dom_equal expected, time_select("post", "written_on", {}, disabled: true) + assert_dom_equal expected, time_select("post", "written_on", {}, { disabled: true }) end def test_datetime_select @@ -2738,7 +2738,7 @@ class DateHelperTest < ActionView::TestCase @post.updated_at = Time.local(2004, 6, 15, 16, 35) output_buffer = fields_for :post, @post do |f| - concat f.datetime_select(:updated_at, {}, class: "selector") + 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}.dup @@ -3220,7 +3220,7 @@ class DateHelperTest < ActionView::TestCase 0.upto(59) { |i| expected << %(<option value="#{sprintf("%02d", i)}"#{' selected="selected"' if i == 16}>#{sprintf("%02d", i)}</option>\n) } expected << "</select>\n" - assert_dom_equal expected, datetime_select("post", "updated_at", { discard_year: true, discard_month: true }, disabled: true) + assert_dom_equal expected, datetime_select("post", "updated_at", { discard_year: true, discard_month: true }, { disabled: true }) end def test_datetime_select_discard_hour @@ -3440,7 +3440,7 @@ class DateHelperTest < ActionView::TestCase 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">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" selected="selected">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" - assert_dom_equal expected, datetime_select("post", "updated_at", {}, class: "selector") + assert_dom_equal expected, datetime_select("post", "updated_at", {}, { class: "selector" }) end def test_date_select_should_not_change_passed_options_hash @@ -3591,25 +3591,25 @@ class DateHelperTest < ActionView::TestCase end def test_select_html_safety - assert select_day(16).html_safe? - assert select_month(8).html_safe? - assert select_year(Time.mktime(2003, 8, 16, 8, 4, 18)).html_safe? - assert select_minute(Time.mktime(2003, 8, 16, 8, 4, 18)).html_safe? - assert select_second(Time.mktime(2003, 8, 16, 8, 4, 18)).html_safe? + assert_predicate select_day(16), :html_safe? + assert_predicate select_month(8), :html_safe? + assert_predicate select_year(Time.mktime(2003, 8, 16, 8, 4, 18)), :html_safe? + assert_predicate select_minute(Time.mktime(2003, 8, 16, 8, 4, 18)), :html_safe? + assert_predicate select_second(Time.mktime(2003, 8, 16, 8, 4, 18)), :html_safe? - assert select_minute(8, use_hidden: true).html_safe? - assert select_month(8, prompt: "Choose month").html_safe? + assert_predicate select_minute(8, use_hidden: true), :html_safe? + assert_predicate select_month(8, prompt: "Choose month"), :html_safe? - assert select_time(Time.mktime(2003, 8, 16, 8, 4, 18), {}, class: "selector").html_safe? - assert select_date(Time.mktime(2003, 8, 16), date_separator: " / ", start_year: 2003, end_year: 2005, prefix: "date[first]").html_safe? + assert_predicate select_time(Time.mktime(2003, 8, 16, 8, 4, 18), {}, { class: "selector" }), :html_safe? + assert_predicate select_date(Time.mktime(2003, 8, 16), date_separator: " / ", start_year: 2003, end_year: 2005, prefix: "date[first]"), :html_safe? end def test_object_select_html_safety @post = Post.new @post.written_on = Date.new(2004, 6, 15) - assert date_select("post", "written_on", default: Time.local(2006, 9, 19, 15, 16, 35), include_blank: true).html_safe? - assert time_select("post", "written_on", ignore_date: true).html_safe? + assert_predicate date_select("post", "written_on", default: Time.local(2006, 9, 19, 15, 16, 35), include_blank: true), :html_safe? + assert_predicate time_select("post", "written_on", ignore_date: true), :html_safe? end def test_time_tag_with_date diff --git a/actionview/test/template/dependency_tracker_test.rb b/actionview/test/template/dependency_tracker_test.rb index 89917035ff..ef7aeac039 100644 --- a/actionview/test/template/dependency_tracker_test.rb +++ b/actionview/test/template/dependency_tracker_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" require "action_view/dependency_tracker" diff --git a/actionview/test/template/digestor_test.rb b/actionview/test/template/digestor_test.rb index de04f3f25d..ddaa7febb3 100644 --- a/actionview/test/template/digestor_test.rb +++ b/actionview/test/template/digestor_test.rb @@ -1,18 +1,9 @@ +# frozen_string_literal: true + require "abstract_unit" require "fileutils" require "action_view/dependency_tracker" -class FixtureTemplate - attr_reader :source, :handler - - def initialize(template_path) - @source = File.read(template_path) - @handler = ActionView::Template.handler_for_extension(:erb) - rescue Errno::ENOENT - raise ActionView::MissingTemplate.new([], "", [], true, []) - end -end - class FixtureFinder < ActionView::LookupContext FIXTURES_DIR = File.expand_path("../fixtures/digestor", __dir__) @@ -169,6 +160,18 @@ class TemplateDigestorTest < ActionView::TestCase assert_equal [:html], tree_template_formats("messages/show").uniq end + def test_template_dependencies_with_fallback_from_js_to_html_format + finder.rendered_format = :js + assert_equal ["comments/comment"], dependencies("comments/show") + end + + def test_template_digest_with_fallback_from_js_to_html_format + finder.rendered_format = :js + assert_digest_difference("comments/show") do + change_template("comments/_comment") + end + end + def test_recursion_in_renders assert digest("level/recursion") # assert recursion is possible assert_not_nil digest("level/recursion") # assert digest is stored diff --git a/actionview/test/template/erb/deprecated_erubis_implementation_test.rb b/actionview/test/template/erb/deprecated_erubis_implementation_test.rb deleted file mode 100644 index aaf99f85c0..0000000000 --- a/actionview/test/template/erb/deprecated_erubis_implementation_test.rb +++ /dev/null @@ -1,13 +0,0 @@ -require "abstract_unit" - -module ERBTest - class DeprecatedErubisImplementationTest < ActionView::TestCase - test "Erubis implementation is deprecated" do - assert_deprecated "ActionView::Template::Handlers::Erubis is deprecated and will be removed from Rails 5.2. Switch to ActionView::Template::Handlers::ERB::Erubi instead." do - assert_equal "ActionView::Template::Handlers::ERB::Erubis", ActionView::Template::Handlers::Erubis.to_s - - assert_nothing_raised { Class.new(ActionView::Template::Handlers::Erubis) } - end - end - end -end diff --git a/actionview/test/template/erb/form_for_test.rb b/actionview/test/template/erb/form_for_test.rb index e722b40a9a..b6ecf003a5 100644 --- a/actionview/test/template/erb/form_for_test.rb +++ b/actionview/test/template/erb/form_for_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" require "template/erb/helper" diff --git a/actionview/test/template/erb/helper.rb b/actionview/test/template/erb/helper.rb index bc1eedc15f..57d6cb1be3 100644 --- a/actionview/test/template/erb/helper.rb +++ b/actionview/test/template/erb/helper.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module ERBTest class ViewContext include ActionView::Helpers::UrlHelper diff --git a/actionview/test/template/erb/tag_helper_test.rb b/actionview/test/template/erb/tag_helper_test.rb index 233f37c48a..24a7592950 100644 --- a/actionview/test/template/erb/tag_helper_test.rb +++ b/actionview/test/template/erb/tag_helper_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" require "template/erb/helper" diff --git a/actionview/test/template/erb_util_test.rb b/actionview/test/template/erb_util_test.rb index 4412ea37fa..bd702dbe94 100644 --- a/actionview/test/template/erb_util_test.rb +++ b/actionview/test/template/erb_util_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" require "active_support/json" @@ -68,24 +70,24 @@ class ErbUtilTest < ActiveSupport::TestCase def test_json_escape_returns_unsafe_strings_when_passed_unsafe_strings value = json_escape("asdf") - assert !value.html_safe? + assert_not_predicate value, :html_safe? end def test_json_escape_returns_safe_strings_when_passed_safe_strings value = json_escape("asdf".html_safe) - assert value.html_safe? + assert_predicate value, :html_safe? end def test_html_escape_is_html_safe escaped = h("<p>") assert_equal "<p>", escaped - assert escaped.html_safe? + assert_predicate escaped, :html_safe? end def test_html_escape_passes_html_escape_unmodified escaped = h("<p>".html_safe) assert_equal "<p>", escaped - assert escaped.html_safe? + assert_predicate escaped, :html_safe? end def test_rest_in_ascii @@ -102,11 +104,11 @@ class ErbUtilTest < ActiveSupport::TestCase def test_html_escape_once_returns_unsafe_strings_when_passed_unsafe_strings value = html_escape_once("1 < 2 & 3") - assert !value.html_safe? + assert_not_predicate value, :html_safe? end def test_html_escape_once_returns_safe_strings_when_passed_safe_strings value = html_escape_once("1 < 2 & 3".html_safe) - assert value.html_safe? + assert_predicate value, :html_safe? end end diff --git a/actionview/test/template/form_collections_helper_test.rb b/actionview/test/template/form_collections_helper_test.rb index 6160524eb3..6db55a1447 100644 --- a/actionview/test/template/form_collections_helper_test.rb +++ b/actionview/test/template/form_collections_helper_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" Category = Struct.new(:id, :name) @@ -37,6 +39,13 @@ class FormCollectionsHelperTest < ActionView::TestCase assert_select "label[for=user_active_no]", "No" end + test "collection radio generates labels for non-English values correctly" do + with_collection_radio_buttons :user, :title, ["Господин", "Госпожа"], :to_s, :to_s + + assert_select "input[type=radio]#user_title_господин" + assert_select "label[for=user_title_господин]", "Господин" + end + test "collection radio should sanitize collection values for labels correctly" do with_collection_radio_buttons :user, :name, ["$0.99", "$1.99"], :to_s, :to_s assert_select "label[for=user_name_099]", "$0.99" @@ -86,7 +95,7 @@ class FormCollectionsHelperTest < ActionView::TestCase test "collection radio accepts html options as input" do collection = [[1, true], [0, false]] - with_collection_radio_buttons :user, :active, collection, :last, :first, {}, class: "special-radio" + with_collection_radio_buttons :user, :active, collection, :last, :first, {}, { class: "special-radio" } assert_select "input[type=radio][value=true].special-radio#user_active_true" assert_select "input[type=radio][value=false].special-radio#user_active_false" @@ -206,7 +215,7 @@ class FormCollectionsHelperTest < ActionView::TestCase test "collection radio buttons generates a hidden field using the given :name in :html_options" do collection = [Category.new(1, "Category 1"), Category.new(2, "Category 2")] - with_collection_radio_buttons :user, :category_ids, collection, :id, :name, {}, name: "user[other_category_ids]" + with_collection_radio_buttons :user, :category_ids, collection, :id, :name, {}, { name: "user[other_category_ids]" } assert_select "input[type=hidden][name='user[other_category_ids]'][value='']", count: 1 end @@ -250,7 +259,7 @@ class FormCollectionsHelperTest < ActionView::TestCase test "collection check boxes generates a hidden field using the given :name in :html_options" do collection = [Category.new(1, "Category 1"), Category.new(2, "Category 2")] - with_collection_check_boxes :user, :category_ids, collection, :id, :name, {}, name: "user[other_category_ids][]" + with_collection_check_boxes :user, :category_ids, collection, :id, :name, {}, { name: "user[other_category_ids][]" } assert_select "input[type=hidden][name='user[other_category_ids][]'][value='']", count: 1 end @@ -297,6 +306,13 @@ class FormCollectionsHelperTest < ActionView::TestCase assert_select "label[for=user_name_199]", "$1.99" end + test "collection check boxes generates labels for non-English values correctly" do + with_collection_check_boxes :user, :title, ["Господин", "Госпожа"], :to_s, :to_s + + assert_select "input[type=checkbox]#user_title_господин" + assert_select "label[for=user_title_господин]", "Господин" + end + test "collection check boxes accepts html options as the last element of array" do collection = [[1, "Category 1", { class: "foo" }], [2, "Category 2", { class: "bar" }]] with_collection_check_boxes :user, :active, collection, :first, :second @@ -430,7 +446,7 @@ class FormCollectionsHelperTest < ActionView::TestCase test "collection check boxes accepts html options" do collection = [[1, "Category 1"], [2, "Category 2"]] - with_collection_check_boxes :user, :category_ids, collection, :first, :last, {}, class: "check" + with_collection_check_boxes :user, :category_ids, collection, :first, :last, {}, { class: "check" } assert_select 'input.check[type=checkbox][value="1"]' assert_select 'input.check[type=checkbox][value="2"]' diff --git a/actionview/test/template/form_helper/form_with_test.rb b/actionview/test/template/form_helper/form_with_test.rb index c1a8181204..6b65d740eb 100644 --- a/actionview/test/template/form_helper/form_with_test.rb +++ b/actionview/test/template/form_helper/form_with_test.rb @@ -1,8 +1,29 @@ +# frozen_string_literal: true + require "abstract_unit" require "controller/fake_models" class FormWithTest < ActionView::TestCase include RenderERBUtils + + setup do + @old_value = ActionView::Helpers::FormHelper.form_with_generates_ids + ActionView::Helpers::FormHelper.form_with_generates_ids = true + end + + teardown do + ActionView::Helpers::FormHelper.form_with_generates_ids = @old_value + end + + private + def with_default_enforce_utf8(value) + old_value = ActionView::Helpers::FormTagHelper.default_enforce_utf8 + ActionView::Helpers::FormTagHelper.default_enforce_utf8 = value + + yield + ensure + ActionView::Helpers::FormTagHelper.default_enforce_utf8 = old_value + end end class FormWithActsLikeFormTagTest < FormWithTest @@ -97,7 +118,25 @@ class FormWithActsLikeFormTagTest < FormWithTest actual = form_with(skip_enforcing_utf8: true) expected = whole_form("http://www.example.com", skip_enforcing_utf8: true) assert_dom_equal expected, actual - assert actual.html_safe? + assert_predicate actual, :html_safe? + end + + def test_form_with_default_enforce_utf8_false + with_default_enforce_utf8 false do + actual = form_with + expected = whole_form("http://www.example.com", skip_enforcing_utf8: true) + assert_dom_equal expected, actual + assert_predicate actual, :html_safe? + end + end + + def test_form_with_default_enforce_utf8_true + with_default_enforce_utf8 true do + actual = form_with + expected = whole_form("http://www.example.com", skip_enforcing_utf8: false) + assert_dom_equal expected, actual + assert_predicate actual, :html_safe? + end end def test_form_with_with_block_in_erb @@ -179,6 +218,9 @@ class FormWithActsLikeFormForTest < FormWithTest submit: "Save changes", another_post: { update: "Update your %{model}" + }, + "blog/post": { + update: "Update your %{model}" } } } @@ -216,7 +258,7 @@ class FormWithActsLikeFormForTest < FormWithTest @post = Post.new @comment = Comment.new - def @post.errors() + def @post.errors Class.new { def [](field); field == "author_name" ? ["can't be empty"] : [] end def empty?() false end @@ -312,17 +354,45 @@ class FormWithActsLikeFormForTest < FormWithTest expected = whole_form("/posts/123", "create-post", method: "patch") do "<label for='post_title'>The Title</label>" \ + "<input name='post[title]' type='text' value='Hello World' id='post_title' />" \ + "<textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea>" \ + "<input name='post[secret]' type='hidden' value='0' />" \ + "<input name='post[secret]' checked='checked' type='checkbox' value='1' id='post_secret' />" \ + "<select name='post[category]' id='post_category'><option value='animal'>animal</option>\n<option value='economy'>economy</option>\n<option value='sports'>sports</option></select>" \ + "<input name='commit' data-disable-with='Create post' type='submit' value='Create post' />" \ + "<button name='button' type='submit'>Create post</button>" \ + "<button name='button' type='submit'><span>Create post</span></button>" + end + + assert_dom_equal expected, output_buffer + end + + def test_form_with_not_outputting_ids + old_value = ActionView::Helpers::FormHelper.form_with_generates_ids + ActionView::Helpers::FormHelper.form_with_generates_ids = false + + form_with(model: @post, id: "create-post") do |f| + concat f.label(:title) { "The Title" } + concat f.text_field(:title) + concat f.text_area(:body) + concat f.check_box(:secret) + concat f.select(:category, %w( animal economy sports )) + concat f.submit("Create post") + end + + expected = whole_form("/posts/123", "create-post", method: "patch") do + "<label>The Title</label>" \ "<input name='post[title]' type='text' value='Hello World' />" \ "<textarea name='post[body]'>\nBack to the hill and over it again!</textarea>" \ "<input name='post[secret]' type='hidden' value='0' />" \ "<input name='post[secret]' checked='checked' type='checkbox' value='1' />" \ "<select name='post[category]'><option value='animal'>animal</option>\n<option value='economy'>economy</option>\n<option value='sports'>sports</option></select>" \ - "<input name='commit' data-disable-with='Create post' type='submit' value='Create post' />" \ - "<button name='button' type='submit'>Create post</button>" \ - "<button name='button' type='submit'><span>Create post</span></button>" + "<input name='commit' data-disable-with='Create post' type='submit' value='Create post' />" end assert_dom_equal expected, output_buffer + ensure + ActionView::Helpers::FormHelper.form_with_generates_ids = old_value end def test_form_with_only_url_on_create @@ -333,7 +403,7 @@ class FormWithActsLikeFormForTest < FormWithTest expected = whole_form("/posts") do '<label for="title">Label me</label>' \ - '<input type="text" name="title">' + '<input type="text" name="title" id="title">' end assert_dom_equal expected, output_buffer @@ -347,7 +417,7 @@ class FormWithActsLikeFormForTest < FormWithTest expected = whole_form("/posts/123") do '<label for="title">Label me</label>' \ - '<input type="text" name="title">' + '<input type="text" name="title" id="title">' end assert_dom_equal expected, output_buffer @@ -359,7 +429,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123") do - '<input type="text" name="no_model_to_back_this_badboy">' + '<input type="text" name="no_model_to_back_this_badboy" id="no_model_to_back_this_badboy" >' end assert_dom_equal expected, output_buffer @@ -371,7 +441,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: :patch) do - '<input type="text" name="post[this_dont_exist_on_post]">' + '<input type="text" name="post[this_dont_exist_on_post]" id="post_this_dont_exist_on_post" >' end assert_dom_equal expected, output_buffer @@ -389,8 +459,8 @@ class FormWithActsLikeFormForTest < FormWithTest end.new form_with(model: obj, scope: "other_name", url: "/", id: "edit-other-name") do |f| - assert_dom_equal '<input type="hidden" name="other_name[private_property]">', f.hidden_field(:private_property) - assert_dom_equal '<input type="hidden" name="other_name[protected_property]">', f.hidden_field(:protected_property) + assert_dom_equal '<input type="hidden" name="other_name[private_property]" id="other_name_private_property">', f.hidden_field(:private_property) + assert_dom_equal '<input type="hidden" name="other_name[protected_property]" id="other_name_protected_property">', f.hidden_field(:protected_property) end end @@ -457,7 +527,7 @@ class FormWithActsLikeFormForTest < FormWithTest "<label for='post_active_false'>" \ "<input checked='checked' name='post[active]' type='radio' value='false' id='post_active_false' />" \ "false</label>" \ - "<input name='post[id]' type='hidden' value='1' />" + "<input name='post[id]' type='hidden' value='1' id='post_id' />" end assert_dom_equal expected, output_buffer @@ -555,7 +625,7 @@ class FormWithActsLikeFormForTest < FormWithTest "<label for='post_tag_ids_3'>" \ "<input checked='checked' name='post[tag_ids][]' type='checkbox' value='3' id='post_tag_ids_3' />" \ "Tag 3</label>" \ - "<input name='post[id]' type='hidden' value='1' />" + "<input name='post[id]' type='hidden' value='1' id='post_id' />" end assert_dom_equal expected, output_buffer @@ -585,7 +655,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", "create-post", method: "patch", multipart: true) do - "<input name='post[file]' type='file' />" + "<input name='post[file]' type='file' id='post_file' />" end assert_dom_equal expected, output_buffer @@ -599,7 +669,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch", multipart: true) do - "<input name='post[comment][file]' type='file' />" + "<input name='post[comment][file]' type='file' id='post_comment_file'/>" end assert_dom_equal expected, output_buffer @@ -638,7 +708,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/44", method: "patch") do - "<input name='post[title]' type='text' value='And his name will be forty and four.' />" \ + "<input name='post[title]' type='text' value='And his name will be forty and four.' id='post_title' />" \ "<input name='commit' data-disable-with='Edit post' type='submit' value='Edit post' />" end @@ -656,10 +726,10 @@ class FormWithActsLikeFormForTest < FormWithTest expected = whole_form("/posts/123", "create-post", method: "patch") do "<label for='other_name_title' class='post_title'>Title</label>" \ - "<input name='other_name[title]' value='Hello World' type='text' />" \ - "<textarea name='other_name[body]'>\nBack to the hill and over it again!</textarea>" \ + "<input name='other_name[title]' value='Hello World' type='text' id='other_name_title' />" \ + "<textarea name='other_name[body]' id='other_name_body'>\nBack to the hill and over it again!</textarea>" \ "<input name='other_name[secret]' value='0' type='hidden' />" \ - "<input name='other_name[secret]' checked='checked' value='1' type='checkbox' />" \ + "<input name='other_name[secret]' checked='checked' value='1' type='checkbox' id='other_name_secret' />" \ "<input name='commit' value='Create post' data-disable-with='Create post' type='submit' />" end @@ -674,10 +744,10 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/", "create-post", method: "delete") do - "<input name='post[title]' type='text' value='Hello World' />" \ - "<textarea name='post[body]'>\nBack to the hill and over it again!</textarea>" \ + "<input name='post[title]' type='text' value='Hello World' id='post_title' />" \ + "<textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea>" \ "<input name='post[secret]' type='hidden' value='0' />" \ - "<input name='post[secret]' checked='checked' type='checkbox' value='1' />" + "<input name='post[secret]' checked='checked' type='checkbox' value='1' id='post_secret'/>" end assert_dom_equal expected, output_buffer @@ -691,10 +761,10 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/", "create-post", method: "delete") do - "<input name='post[title]' type='text' value='Hello World' />" \ - "<textarea name='post[body]'>\nBack to the hill and over it again!</textarea>" \ + "<input name='post[title]' type='text' value='Hello World' id='post_title' />" \ + "<textarea name='post[body]' id='post_body' >\nBack to the hill and over it again!</textarea>" \ "<input name='post[secret]' type='hidden' value='0' />" \ - "<input name='post[secret]' checked='checked' type='checkbox' value='1' />" + "<input name='post[secret]' checked='checked' type='checkbox' value='1' id='post_secret' />" end assert_dom_equal expected, output_buffer @@ -708,7 +778,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/search", "search-post", method: "get") do - "<input name='post[title]' type='search' />" + "<input name='post[title]' type='search' id='post_title' />" end assert_dom_equal expected, output_buffer @@ -722,10 +792,10 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/", "create-post", method: "patch") do - "<input name='post[title]' type='text' value='Hello World' />" \ - "<textarea name='post[body]'>\nBack to the hill and over it again!</textarea>" \ + "<input name='post[title]' type='text' value='Hello World' id='post_title' />" \ + "<textarea name='post[body]' id='post_body' >\nBack to the hill and over it again!</textarea>" \ "<input name='post[secret]' type='hidden' value='0' />" \ - "<input name='post[secret]' checked='checked' type='checkbox' value='1' />" + "<input name='post[secret]' checked='checked' type='checkbox' value='1' id='post_secret' />" end assert_dom_equal expected, output_buffer @@ -742,10 +812,10 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/", "create-post", method: "patch", local: true) do - "<input name='post[title]' type='text' value='Hello World' />" \ - "<textarea name='post[body]'>\nBack to the hill and over it again!</textarea>" \ + "<input name='post[title]' type='text' value='Hello World' id='post_title' />" \ + "<textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea>" \ "<input name='post[secret]' type='hidden' value='0' />" \ - "<input name='post[secret]' checked='checked' type='checkbox' value='1' />" + "<input name='post[secret]' checked='checked' type='checkbox' value='1' id='post_secret' />" end assert_dom_equal expected, output_buffer @@ -759,7 +829,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/", skip_enforcing_utf8: true) do - "<input name='post[title]' type='text' value='Hello World' />" + "<input name='post[title]' type='text' value='Hello World' id='post_title' />" end assert_dom_equal expected, output_buffer @@ -771,12 +841,40 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/", skip_enforcing_utf8: false) do - "<input name='post[title]' type='text' value='Hello World' />" + "<input name='post[title]' type='text' value='Hello World' id='post_title' />" end assert_dom_equal expected, output_buffer end + def test_form_with_default_enforce_utf8_true + with_default_enforce_utf8 true do + form_with(scope: :post) do |f| + concat f.text_field(:title) + end + + expected = whole_form("/", skip_enforcing_utf8: false) do + "<input name='post[title]' type='text' value='Hello World' id='post_title' />" + end + + assert_dom_equal expected, output_buffer + end + end + + def test_form_with_default_enforce_utf8_false + with_default_enforce_utf8 false do + form_with(scope: :post) do |f| + concat f.text_field(:title) + end + + expected = whole_form("/", skip_enforcing_utf8: true) do + "<input name='post[title]' type='text' value='Hello World' id='post_title' />" + end + + assert_dom_equal expected, output_buffer + end + end + def test_form_with_without_object form_with(scope: :post, id: "create-post") do |f| concat f.text_field(:title) @@ -785,10 +883,10 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/", "create-post") do - "<input name='post[title]' type='text' value='Hello World' />" \ - "<textarea name='post[body]'>\nBack to the hill and over it again!</textarea>" \ + "<input name='post[title]' type='text' value='Hello World' id='post_title' />" \ + "<textarea name='post[body]' id='post_body' >\nBack to the hill and over it again!</textarea>" \ "<input name='post[secret]' type='hidden' value='0' />" \ - "<input name='post[secret]' checked='checked' type='checkbox' value='1' />" + "<input name='post[secret]' checked='checked' type='checkbox' value='1' id='post_secret' />" end assert_dom_equal expected, output_buffer @@ -804,10 +902,10 @@ class FormWithActsLikeFormForTest < FormWithTest expected = whole_form("/posts/123", method: "patch") do "<label for='post_123_title'>Title</label>" \ - "<input name='post[123][title]' type='text' value='Hello World' />" \ - "<textarea name='post[123][body]'>\nBack to the hill and over it again!</textarea>" \ + "<input name='post[123][title]' type='text' value='Hello World' id='post_123_title' />" \ + "<textarea name='post[123][body]' id='post_123_body'>\nBack to the hill and over it again!</textarea>" \ "<input name='post[123][secret]' type='hidden' value='0' />" \ - "<input name='post[123][secret]' checked='checked' type='checkbox' value='1' />" + "<input name='post[123][secret]' checked='checked' type='checkbox' value='1' id='post_123_secret' />" end assert_dom_equal expected, output_buffer @@ -821,10 +919,10 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - "<input name='post[][title]' type='text' value='Hello World' />" \ - "<textarea name='post[][body]'>\nBack to the hill and over it again!</textarea>" \ + "<input name='post[][title]' type='text' value='Hello World' id='post__title' />" \ + "<textarea name='post[][body]' id='post__body' >\nBack to the hill and over it again!</textarea>" \ "<input name='post[][secret]' type='hidden' value='0' />" \ - "<input name='post[][secret]' checked='checked' type='checkbox' value='1' />" + "<input name='post[][secret]' checked='checked' type='checkbox' value='1' id='post__secret' />" end assert_dom_equal expected, output_buffer @@ -839,7 +937,7 @@ class FormWithActsLikeFormForTest < FormWithTest expected = whole_form("/posts/123", method: "patch") do "<div class='field_with_errors'><label for='post_author_name' class='label'>Author name</label></div>" \ - "<div class='field_with_errors'><input name='post[author_name]' type='text' value='' /></div>" \ + "<div class='field_with_errors'><input name='post[author_name]' type='text' value='' id='post_author_name' /></div>" \ "<input name='commit' data-disable-with='Create post' type='submit' value='Create post' />" end @@ -857,7 +955,7 @@ class FormWithActsLikeFormForTest < FormWithTest expected = whole_form("/posts/123", method: "patch") do "<div class='field_with_errors'><label for='post_author_name' class='label'>Author name</label></div>" \ - "<div class='field_with_errors'><input name='post[author_name]' type='text' value='' /></div>" \ + "<div class='field_with_errors'><input name='post[author_name]' type='text' value='' id='post_author_name' /></div>" \ "<input name='commit' data-disable-with='Create post' type='submit' value='Create post' />" end @@ -923,7 +1021,7 @@ class FormWithActsLikeFormForTest < FormWithTest end end - def test_submit_with_object_and_nested_lookup + def test_submit_with_object_which_is_overwritten_by_scope_option with_locale :submit do form_with(model: @post, scope: :another_post) do |f| concat f.submit @@ -937,6 +1035,21 @@ class FormWithActsLikeFormForTest < FormWithTest end end + def test_submit_with_object_which_is_namespaced + blog_post = Blog::Post.new("And his name will be forty and four.", 44) + with_locale :submit do + form_with(model: blog_post) do |f| + concat f.submit + end + + expected = whole_form("/posts/44", method: "patch") do + "<input name='commit' data-disable-with='Update your Post' type='submit' value='Update your Post' />" + end + + assert_dom_equal expected, output_buffer + end + end + def test_fields_with_attributes_not_on_model form_with(model: @post) do |f| concat f.fields(:comment) { |c| @@ -945,7 +1058,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: :patch) do - '<input type="text" name="post[comment][dont_exist_on_model]">' + '<input type="text" name="post[comment][dont_exist_on_model]" id="post_comment_dont_exist_on_model" >' end assert_dom_equal expected, output_buffer @@ -965,7 +1078,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form do - '<input name="posts[post][0][comment][1][dont_exist_on_model]" type="text">' + '<input name="posts[post][0][comment][1][dont_exist_on_model]" type="text" id="posts_post_0_comment_1_dont_exist_on_model" >' end assert_dom_equal expected, output_buffer @@ -980,7 +1093,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - "<input name='post[comment][body]' type='text' value='Hello World' />" + "<input name='post[comment][body]' type='text' value='Hello World' id='post_comment_body' />" end assert_dom_equal expected, output_buffer @@ -1000,7 +1113,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form do - "<input name='posts[post][0][comment][1][name]' type='text' value='comment #1' />" + "<input name='posts[post][0][comment][1][name]' type='text' value='comment #1' id='posts_post_0_comment_1_name' />" end assert_dom_equal expected, output_buffer @@ -1015,8 +1128,8 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - "<input name='post[123][title]' type='text' value='Hello World' />" \ - "<input name='post[123][comment][][name]' type='text' value='new comment' />" + "<input name='post[123][title]' type='text' value='Hello World' id='post_123_title' />" \ + "<input name='post[123][comment][][name]' type='text' value='new comment' id='post_123_comment__name' />" end assert_dom_equal expected, output_buffer @@ -1031,8 +1144,8 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - "<input name='post[1][title]' type='text' value='Hello World' />" \ - "<input name='post[1][comment][1][name]' type='text' value='new comment' />" + "<input name='post[1][title]' type='text' value='Hello World' id='post_1_title' />" \ + "<input name='post[1][comment][1][name]' type='text' value='new comment' id='post_1_comment_1_name' />" end assert_dom_equal expected, output_buffer @@ -1046,7 +1159,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - "<input name='post[1][comment][title]' type='text' value='Hello World' />" + "<input name='post[1][comment][title]' type='text' value='Hello World' id='post_1_comment_title' />" end assert_dom_equal expected, output_buffer @@ -1060,7 +1173,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - "<input name='post[1][comment][5][title]' type='text' value='Hello World' />" + "<input name='post[1][comment][5][title]' type='text' value='Hello World' id='post_1_comment_5_title' />" end assert_dom_equal expected, output_buffer @@ -1074,7 +1187,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - "<input name='post[123][comment][title]' type='text' value='Hello World' />" + "<input name='post[123][comment][title]' type='text' value='Hello World' id='post_123_comment_title' />" end assert_dom_equal expected, output_buffer @@ -1088,7 +1201,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - "<input name='post[comment][5][title]' type='radio' value='hello' />" + "<input name='post[comment][5][title]' type='radio' value='hello' id='post_comment_5_title_hello' />" end assert_dom_equal expected, output_buffer @@ -1102,7 +1215,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - "<input name='post[123][comment][123][title]' type='text' value='Hello World' />" + "<input name='post[123][comment][123][title]' type='text' value='Hello World' id='post_123_comment_123_title' />" end assert_dom_equal expected, output_buffer @@ -1122,9 +1235,9 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - "<input name='post[123][comment][5][title]' type='text' value='Hello World' />" + "<input name='post[123][comment][5][title]' type='text' value='Hello World' id='post_123_comment_5_title' />" end + whole_form("/posts/123", method: "patch") do - "<input name='post[1][comment][123][title]' type='text' value='Hello World' />" + "<input name='post[1][comment][123][title]' type='text' value='Hello World' id='post_1_comment_123_title' />" end assert_dom_equal expected, output_buffer @@ -1141,8 +1254,8 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[title]" type="text" value="Hello World" />' \ - '<input name="post[author_attributes][name]" type="text" value="new author" />' + '<input name="post[title]" type="text" value="Hello World" id="post_title" />' \ + '<input name="post[author_attributes][name]" type="text" value="new author" id="post_author_attributes_name" />' end assert_dom_equal expected, output_buffer @@ -1168,9 +1281,9 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[title]" type="text" value="Hello World" />' \ - '<input name="post[author_attributes][name]" type="text" value="author #321" />' \ - '<input name="post[author_attributes][id]" type="hidden" value="321" />' + '<input name="post[title]" type="text" value="Hello World" id="post_title" />' \ + '<input name="post[author_attributes][name]" type="text" value="author #321" id="post_author_attributes_name" />' \ + '<input name="post[author_attributes][id]" type="hidden" value="321" id="post_author_attributes_id" />' end assert_dom_equal expected, output_buffer @@ -1187,9 +1300,9 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[title]" type="text" value="Hello World" />' \ - '<input name="post[author_attributes][name]" type="text" value="author #321" />' \ - '<input name="post[author_attributes][id]" type="hidden" value="321" />' + '<input name="post[title]" type="text" value="Hello World" id="post_title" />' \ + '<input name="post[author_attributes][name]" type="text" value="author #321" id="post_author_attributes_name" />' \ + '<input name="post[author_attributes][id]" type="hidden" value="321" id="post_author_attributes_id" />' end assert_dom_equal expected, output_buffer @@ -1206,8 +1319,8 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[title]" type="text" value="Hello World" />' \ - '<input name="post[author_attributes][name]" type="text" value="author #321" />' + '<input name="post[title]" type="text" value="Hello World" id="post_title" />' \ + '<input name="post[author_attributes][name]" type="text" value="author #321" id="post_author_attributes_name" />' end assert_dom_equal expected, output_buffer @@ -1224,8 +1337,8 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[title]" type="text" value="Hello World" />' \ - '<input name="post[author_attributes][name]" type="text" value="author #321" />' + '<input name="post[title]" type="text" value="Hello World" id="post_title" />' \ + '<input name="post[author_attributes][name]" type="text" value="author #321" id="post_author_attributes_name" />' end assert_dom_equal expected, output_buffer @@ -1242,9 +1355,9 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[title]" type="text" value="Hello World" />' \ - '<input name="post[author_attributes][name]" type="text" value="author #321" />' \ - '<input name="post[author_attributes][id]" type="hidden" value="321" />' + '<input name="post[title]" type="text" value="Hello World" id="post_title" />' \ + '<input name="post[author_attributes][name]" type="text" value="author #321" id="post_author_attributes_name" />' \ + '<input name="post[author_attributes][id]" type="hidden" value="321" id="post_author_attributes_id" />' end assert_dom_equal expected, output_buffer @@ -1262,9 +1375,9 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[title]" type="text" value="Hello World" />' \ - '<input name="post[author_attributes][id]" type="hidden" value="321" />' \ - '<input name="post[author_attributes][name]" type="text" value="author #321" />' + '<input name="post[title]" type="text" value="Hello World" id="post_title" />' \ + '<input name="post[author_attributes][id]" type="hidden" value="321" id="post_author_attributes_id" />' \ + '<input name="post[author_attributes][name]" type="text" value="author #321" id="post_author_attributes_name" />' end assert_dom_equal expected, output_buffer @@ -1283,11 +1396,11 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[title]" type="text" value="Hello World" />' \ - '<input name="post[comments_attributes][0][name]" type="text" value="comment #1" />' \ - '<input name="post[comments_attributes][0][id]" type="hidden" value="1" />' \ - '<input name="post[comments_attributes][1][name]" type="text" value="comment #2" />' \ - '<input name="post[comments_attributes][1][id]" type="hidden" value="2" />' + '<input name="post[title]" type="text" value="Hello World" id="post_title" />' \ + '<input name="post[comments_attributes][0][name]" type="text" value="comment #1" id="post_comments_attributes_0_name" />' \ + '<input name="post[comments_attributes][0][id]" type="hidden" value="1" id="post_comments_attributes_0_id" />' \ + '<input name="post[comments_attributes][1][name]" type="text" value="comment #2" id="post_comments_attributes_1_name" />' \ + '<input name="post[comments_attributes][1][id]" type="hidden" value="2" id="post_comments_attributes_1_id" />' end assert_dom_equal expected, output_buffer @@ -1310,11 +1423,11 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[title]" type="text" value="Hello World" />' \ - '<input name="post[author_attributes][name]" type="text" value="author #321" />' \ - '<input name="post[author_attributes][id]" type="hidden" value="321" />' \ - '<input name="post[comments_attributes][0][name]" type="text" value="comment #1" />' \ - '<input name="post[comments_attributes][1][name]" type="text" value="comment #2" />' + '<input name="post[title]" type="text" value="Hello World" id="post_title" />' \ + '<input name="post[author_attributes][name]" type="text" value="author #321" id="post_author_attributes_name" />' \ + '<input name="post[author_attributes][id]" type="hidden" value="321" id="post_author_attributes_id" />' \ + '<input name="post[comments_attributes][0][name]" type="text" value="comment #1" id="post_comments_attributes_0_name" />' \ + '<input name="post[comments_attributes][1][name]" type="text" value="comment #2" id="post_comments_attributes_1_name" />' end assert_dom_equal expected, output_buffer @@ -1337,10 +1450,10 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[title]" type="text" value="Hello World" />' \ - '<input name="post[author_attributes][name]" type="text" value="author #321" />' \ - '<input name="post[comments_attributes][0][name]" type="text" value="comment #1" />' \ - '<input name="post[comments_attributes][1][name]" type="text" value="comment #2" />' + '<input name="post[title]" type="text" value="Hello World" id="post_title" />' \ + '<input name="post[author_attributes][name]" type="text" value="author #321" id="post_author_attributes_name" />' \ + '<input name="post[comments_attributes][0][name]" type="text" value="comment #1" id="post_comments_attributes_0_name" />' \ + '<input name="post[comments_attributes][1][name]" type="text" value="comment #2" id="post_comments_attributes_1_name" />' end assert_dom_equal expected, output_buffer @@ -1363,11 +1476,11 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[title]" type="text" value="Hello World" />' \ - '<input name="post[author_attributes][name]" type="text" value="author #321" />' \ - '<input name="post[author_attributes][id]" type="hidden" value="321" />' \ - '<input name="post[comments_attributes][0][name]" type="text" value="comment #1" />' \ - '<input name="post[comments_attributes][1][name]" type="text" value="comment #2" />' + '<input name="post[title]" type="text" value="Hello World" id="post_title" />' \ + '<input name="post[author_attributes][name]" type="text" value="author #321" id="post_author_attributes_name" />' \ + '<input name="post[author_attributes][id]" type="hidden" value="321" id="post_author_attributes_id" />' \ + '<input name="post[comments_attributes][0][name]" type="text" value="comment #1" id="post_comments_attributes_0_name" />' \ + '<input name="post[comments_attributes][1][name]" type="text" value="comment #2" id="post_comments_attributes_1_name" />' end assert_dom_equal expected, output_buffer @@ -1386,11 +1499,11 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[title]" type="text" value="Hello World" />' \ - '<input name="post[comments_attributes][0][name]" type="text" value="comment #1" />' \ - '<input name="post[comments_attributes][0][id]" type="hidden" value="1" />' \ - '<input name="post[comments_attributes][1][name]" type="text" value="comment #2" />' \ - '<input name="post[comments_attributes][1][id]" type="hidden" value="2" />' + '<input name="post[title]" type="text" value="Hello World" id="post_title" />' \ + '<input name="post[comments_attributes][0][name]" type="text" value="comment #1" id="post_comments_attributes_0_name" />' \ + '<input name="post[comments_attributes][0][id]" type="hidden" value="1" id="post_comments_attributes_0_id" />' \ + '<input name="post[comments_attributes][1][name]" type="text" value="comment #2" id="post_comments_attributes_1_name" />' \ + '<input name="post[comments_attributes][1][id]" type="hidden" value="2" id="post_comments_attributes_1_id" />' end assert_dom_equal expected, output_buffer @@ -1410,11 +1523,11 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[title]" type="text" value="Hello World" />' \ - '<input name="post[comments_attributes][0][id]" type="hidden" value="1" />' \ - '<input name="post[comments_attributes][0][name]" type="text" value="comment #1" />' \ - '<input name="post[comments_attributes][1][id]" type="hidden" value="2" />' \ - '<input name="post[comments_attributes][1][name]" type="text" value="comment #2" />' + '<input name="post[title]" type="text" value="Hello World" id="post_title" />' \ + '<input name="post[comments_attributes][0][id]" type="hidden" value="1" id="post_comments_attributes_0_id" />' \ + '<input name="post[comments_attributes][0][name]" type="text" value="comment #1" id="post_comments_attributes_0_name" />' \ + '<input name="post[comments_attributes][1][id]" type="hidden" value="2" id="post_comments_attributes_1_id" />' \ + '<input name="post[comments_attributes][1][name]" type="text" value="comment #2" id="post_comments_attributes_1_name" />' end assert_dom_equal expected, output_buffer @@ -1433,9 +1546,9 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[title]" type="text" value="Hello World" />' \ - '<input name="post[comments_attributes][0][name]" type="text" value="new comment" />' \ - '<input name="post[comments_attributes][1][name]" type="text" value="new comment" />' + '<input name="post[title]" type="text" value="Hello World" id="post_title" />' \ + '<input name="post[comments_attributes][0][name]" type="text" value="new comment" id="post_comments_attributes_0_name" />' \ + '<input name="post[comments_attributes][1][name]" type="text" value="new comment" id="post_comments_attributes_1_name" />' end assert_dom_equal expected, output_buffer @@ -1454,10 +1567,10 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[title]" type="text" value="Hello World" />' \ - '<input name="post[comments_attributes][0][name]" type="text" value="comment #321" />' \ - '<input name="post[comments_attributes][0][id]" type="hidden" value="321" />' \ - '<input name="post[comments_attributes][1][name]" type="text" value="new comment" />' + '<input name="post[title]" type="text" value="Hello World" id="post_title" />' \ + '<input name="post[comments_attributes][0][name]" type="text" value="comment #321" id="post_comments_attributes_0_name" />' \ + '<input name="post[comments_attributes][0][id]" type="hidden" value="321" id="post_comments_attributes_0_id"/>' \ + '<input name="post[comments_attributes][1][name]" type="text" value="new comment" id="post_comments_attributes_1_name" />' end assert_dom_equal expected, output_buffer @@ -1472,7 +1585,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[title]" type="text" value="Hello World" />' + '<input name="post[title]" type="text" value="Hello World" id="post_title" />' end assert_dom_equal expected, output_buffer @@ -1489,11 +1602,11 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[title]" type="text" value="Hello World" />' \ - '<input name="post[comments_attributes][0][name]" type="text" value="comment #1" />' \ - '<input name="post[comments_attributes][0][id]" type="hidden" value="1" />' \ - '<input name="post[comments_attributes][1][name]" type="text" value="comment #2" />' \ - '<input name="post[comments_attributes][1][id]" type="hidden" value="2" />' + '<input name="post[title]" type="text" value="Hello World" id="post_title" />' \ + '<input name="post[comments_attributes][0][name]" type="text" value="comment #1" id="post_comments_attributes_0_name" />' \ + '<input name="post[comments_attributes][0][id]" type="hidden" value="1" id="post_comments_attributes_0_id" />' \ + '<input name="post[comments_attributes][1][name]" type="text" value="comment #2" id="post_comments_attributes_1_name" />' \ + '<input name="post[comments_attributes][1][id]" type="hidden" value="2" id="post_comments_attributes_1_id" />' end assert_dom_equal expected, output_buffer @@ -1510,11 +1623,11 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[title]" type="text" value="Hello World" />' \ - '<input name="post[comments_attributes][0][name]" type="text" value="comment #1" />' \ - '<input name="post[comments_attributes][0][id]" type="hidden" value="1" />' \ - '<input name="post[comments_attributes][1][name]" type="text" value="comment #2" />' \ - '<input name="post[comments_attributes][1][id]" type="hidden" value="2" />' + '<input name="post[title]" type="text" value="Hello World" id="post_title" />' \ + '<input name="post[comments_attributes][0][name]" type="text" value="comment #1" id="post_comments_attributes_0_name" />' \ + '<input name="post[comments_attributes][0][id]" type="hidden" value="1" id="post_comments_attributes_0_id" />' \ + '<input name="post[comments_attributes][1][name]" type="text" value="comment #2" id="post_comments_attributes_1_name" />' \ + '<input name="post[comments_attributes][1][id]" type="hidden" value="2" id="post_comments_attributes_1_id" />' end assert_dom_equal expected, output_buffer @@ -1545,11 +1658,11 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[title]" type="text" value="Hello World" />' \ - '<input name="post[comments_attributes][0][name]" type="text" value="comment #1" />' \ - '<input name="post[comments_attributes][0][id]" type="hidden" value="1" />' \ - '<input name="post[comments_attributes][1][name]" type="text" value="comment #2" />' \ - '<input name="post[comments_attributes][1][id]" type="hidden" value="2" />' + '<input name="post[title]" type="text" value="Hello World" id="post_title" />' \ + '<input name="post[comments_attributes][0][name]" type="text" value="comment #1" id="post_comments_attributes_0_name" />' \ + '<input name="post[comments_attributes][0][id]" type="hidden" value="1" id="post_comments_attributes_0_id" />' \ + '<input name="post[comments_attributes][1][name]" type="text" value="comment #2" id="post_comments_attributes_1_name" />' \ + '<input name="post[comments_attributes][1][id]" type="hidden" value="2" id="post_comments_attributes_1_id" />' end assert_dom_equal expected, output_buffer @@ -1568,10 +1681,10 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[title]" type="text" value="Hello World" />' \ - '<input name="post[comments_attributes][0][name]" type="text" value="comment #321" />' \ - '<input name="post[comments_attributes][0][id]" type="hidden" value="321" />' \ - '<input name="post[comments_attributes][1][name]" type="text" value="new comment" />' + '<input name="post[title]" type="text" value="Hello World" id="post_title" />' \ + '<input name="post[comments_attributes][0][name]" type="text" value="comment #321" id="post_comments_attributes_0_name" />' \ + '<input name="post[comments_attributes][0][id]" type="hidden" value="321" id="post_comments_attributes_0_id" />' \ + '<input name="post[comments_attributes][1][name]" type="text" value="new comment" id="post_comments_attributes_1_name" />' end assert_dom_equal expected, output_buffer @@ -1588,8 +1701,8 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[comments_attributes][abc][name]" type="text" value="comment #321" />' \ - '<input name="post[comments_attributes][abc][id]" type="hidden" value="321" />' + '<input name="post[comments_attributes][abc][name]" type="text" value="comment #321" id="post_comments_attributes_abc_name" />' \ + '<input name="post[comments_attributes][abc][id]" type="hidden" value="321" id="post_comments_attributes_abc_id" />' end assert_dom_equal expected, output_buffer @@ -1605,8 +1718,8 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[comments_attributes][abc][name]" type="text" value="comment #321" />' \ - '<input name="post[comments_attributes][abc][id]" type="hidden" value="321" />' + '<input name="post[comments_attributes][abc][name]" type="text" value="comment #321" id="post_comments_attributes_abc_name" />' \ + '<input name="post[comments_attributes][abc][id]" type="hidden" value="321" id="post_comments_attributes_abc_id" />' end assert_dom_equal expected, output_buffer @@ -1628,8 +1741,8 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[comments_attributes][abc][name]" type="text" value="comment #321" />' \ - '<input name="post[comments_attributes][abc][id]" type="hidden" value="321" />' + '<input name="post[comments_attributes][abc][name]" type="text" value="comment #321" id="post_comments_attributes_abc_name" />' \ + '<input name="post[comments_attributes][abc][id]" type="hidden" value="321" id="post_comments_attributes_abc_id" />' end assert_dom_equal expected, output_buffer @@ -1714,18 +1827,18 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[comments_attributes][0][name]" type="text" value="comment #321" />' \ - '<input name="post[comments_attributes][0][relevances_attributes][0][value]" type="text" value="commentrelevance #314" />' \ - '<input name="post[comments_attributes][0][relevances_attributes][0][id]" type="hidden" value="314" />' \ - '<input name="post[comments_attributes][0][id]" type="hidden" value="321" />' \ - '<input name="post[tags_attributes][0][value]" type="text" value="tag #123" />' \ - '<input name="post[tags_attributes][0][relevances_attributes][0][value]" type="text" value="tagrelevance #3141" />' \ - '<input name="post[tags_attributes][0][relevances_attributes][0][id]" type="hidden" value="3141" />' \ - '<input name="post[tags_attributes][0][id]" type="hidden" value="123" />' \ - '<input name="post[tags_attributes][1][value]" type="text" value="tag #456" />' \ - '<input name="post[tags_attributes][1][relevances_attributes][0][value]" type="text" value="tagrelevance #31415" />' \ - '<input name="post[tags_attributes][1][relevances_attributes][0][id]" type="hidden" value="31415" />' \ - '<input name="post[tags_attributes][1][id]" type="hidden" value="456" />' + '<input name="post[comments_attributes][0][name]" type="text" value="comment #321" id="post_comments_attributes_0_name" />' \ + '<input name="post[comments_attributes][0][relevances_attributes][0][value]" type="text" value="commentrelevance #314" id="post_comments_attributes_0_relevances_attributes_0_value" />' \ + '<input name="post[comments_attributes][0][relevances_attributes][0][id]" type="hidden" value="314" id="post_comments_attributes_0_relevances_attributes_0_id"/>' \ + '<input name="post[comments_attributes][0][id]" type="hidden" value="321" id="post_comments_attributes_0_id"/>' \ + '<input name="post[tags_attributes][0][value]" type="text" value="tag #123" id="post_tags_attributes_0_value"/>' \ + '<input name="post[tags_attributes][0][relevances_attributes][0][value]" type="text" value="tagrelevance #3141" id="post_tags_attributes_0_relevances_attributes_0_value"/>' \ + '<input name="post[tags_attributes][0][relevances_attributes][0][id]" type="hidden" value="3141" id="post_tags_attributes_0_relevances_attributes_0_id"/>' \ + '<input name="post[tags_attributes][0][id]" type="hidden" value="123" id="post_tags_attributes_0_id"/>' \ + '<input name="post[tags_attributes][1][value]" type="text" value="tag #456" id="post_tags_attributes_1_value"/>' \ + '<input name="post[tags_attributes][1][relevances_attributes][0][value]" type="text" value="tagrelevance #31415" id="post_tags_attributes_1_relevances_attributes_0_value"/>' \ + '<input name="post[tags_attributes][1][relevances_attributes][0][id]" type="hidden" value="31415" id="post_tags_attributes_1_relevances_attributes_0_id"/>' \ + '<input name="post[tags_attributes][1][id]" type="hidden" value="456" id="post_tags_attributes_1_id"/>' end assert_dom_equal expected, output_buffer @@ -1741,7 +1854,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - '<input name="post[author_attributes][name]" type="text" value="hash backed author" />' + '<input name="post[author_attributes][name]" type="text" value="hash backed author" id="post_author_attributes_name" />' end assert_dom_equal expected, output_buffer @@ -1755,10 +1868,10 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = - "<input name='post[title]' type='text' value='Hello World' />" \ - "<textarea name='post[body]'>\nBack to the hill and over it again!</textarea>" \ + "<input name='post[title]' type='text' value='Hello World' id='post_title' />" \ + "<textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea>" \ "<input name='post[secret]' type='hidden' value='0' />" \ - "<input name='post[secret]' checked='checked' type='checkbox' value='1' />" + "<input name='post[secret]' checked='checked' type='checkbox' value='1' id='post_secret' />" assert_dom_equal expected, output_buffer end @@ -1771,10 +1884,10 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = - "<input name='post[123][title]' type='text' value='Hello World' />" \ - "<textarea name='post[123][body]'>\nBack to the hill and over it again!</textarea>" \ + "<input name='post[123][title]' type='text' value='Hello World' id='post_123_title' />" \ + "<textarea name='post[123][body]' id='post_123_body'>\nBack to the hill and over it again!</textarea>" \ "<input name='post[123][secret]' type='hidden' value='0' />" \ - "<input name='post[123][secret]' checked='checked' type='checkbox' value='1' />" + "<input name='post[123][secret]' checked='checked' type='checkbox' value='1' id='post_123_secret' />" assert_dom_equal expected, output_buffer end @@ -1787,10 +1900,10 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = - "<input name='post[][title]' type='text' value='Hello World' />" \ - "<textarea name='post[][body]'>\nBack to the hill and over it again!</textarea>" \ + "<input name='post[][title]' type='text' value='Hello World' id='post__title' />" \ + "<textarea name='post[][body]' id='post__body'>\nBack to the hill and over it again!</textarea>" \ "<input name='post[][secret]' type='hidden' value='0' />" \ - "<input name='post[][secret]' checked='checked' type='checkbox' value='1' />" + "<input name='post[][secret]' checked='checked' type='checkbox' value='1' id='post__secret' />" assert_dom_equal expected, output_buffer end @@ -1803,10 +1916,10 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = - "<input name='post[abc][title]' type='text' value='Hello World' />" \ - "<textarea name='post[abc][body]'>\nBack to the hill and over it again!</textarea>" \ + "<input name='post[abc][title]' type='text' value='Hello World' id='post_abc_title' />" \ + "<textarea name='post[abc][body]' id='post_abc_body'>\nBack to the hill and over it again!</textarea>" \ "<input name='post[abc][secret]' type='hidden' value='0' />" \ - "<input name='post[abc][secret]' checked='checked' type='checkbox' value='1' />" + "<input name='post[abc][secret]' checked='checked' type='checkbox' value='1' id='post_abc_secret' />" assert_dom_equal expected, output_buffer end @@ -1819,10 +1932,10 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = - "<input name='post[title]' type='text' value='Hello World' />" \ - "<textarea name='post[body]'>\nBack to the hill and over it again!</textarea>" \ + "<input name='post[title]' type='text' value='Hello World' id='post_title' />" \ + "<textarea name='post[body]' id='post_body' >\nBack to the hill and over it again!</textarea>" \ "<input name='post[secret]' type='hidden' value='0' />" \ - "<input name='post[secret]' checked='checked' type='checkbox' value='1' />" + "<input name='post[secret]' checked='checked' type='checkbox' value='1' id='post_secret' />" assert_dom_equal expected, output_buffer end @@ -1835,10 +1948,10 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = - "<input name='post[title]' type='text' value='Hello World' />" \ - "<textarea name='post[body]'>\nBack to the hill and over it again!</textarea>" \ + "<input name='post[title]' type='text' value='Hello World' id='post_title' />" \ + "<textarea name='post[body]' id='post_body' >\nBack to the hill and over it again!</textarea>" \ "<input name='post[secret]' type='hidden' value='0' />" \ - "<input name='post[secret]' checked='checked' type='checkbox' value='1' />" + "<input name='post[secret]' checked='checked' type='checkbox' value='1' id='post_secret' />" assert_dom_equal expected, output_buffer end @@ -1850,7 +1963,7 @@ class FormWithActsLikeFormForTest < FormWithTest end assert_dom_equal "<label for=\"author_post_title\">Title</label>" \ - "<input name='author[post][title]' type='text' value='Hello World' />", + "<input name='author[post][title]' type='text' value='Hello World' id='author_post_title' id='author_post_1_title' />", output_buffer end @@ -1861,7 +1974,7 @@ class FormWithActsLikeFormForTest < FormWithTest end assert_dom_equal "<label for=\"author_post_1_title\">Title</label>" \ - "<input name='author[post][1][title]' type='text' value='Hello World' />", + "<input name='author[post][1][title]' type='text' value='Hello World' id='author_post_1_title' />", output_buffer end @@ -1880,10 +1993,10 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", "create-post", method: "patch") do - "<input name='post[title]' type='text' value='Hello World' />" \ - "<textarea name='post[body]'>\nBack to the hill and over it again!</textarea>" \ + "<input name='post[title]' type='text' value='Hello World' id='post_title' />" \ + "<textarea name='post[body]' id='post_body' >\nBack to the hill and over it again!</textarea>" \ "<input name='parent_post[secret]' type='hidden' value='0' />" \ - "<input name='parent_post[secret]' checked='checked' type='checkbox' value='1' />" + "<input name='parent_post[secret]' checked='checked' type='checkbox' value='1' id='parent_post_secret' />" end assert_dom_equal expected, output_buffer @@ -1900,9 +2013,9 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", "create-post", method: "patch") do - "<input name='post[title]' type='text' value='Hello World' />" \ - "<textarea name='post[body]'>\nBack to the hill and over it again!</textarea>" \ - "<input name='post[comment][name]' type='text' value='new comment' />" + "<input name='post[title]' type='text' value='Hello World' id='post_title' />" \ + "<textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea>" \ + "<input name='post[comment][name]' type='text' value='new comment' id='post_comment_name' />" end assert_dom_equal expected, output_buffer @@ -1916,7 +2029,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - "<input name='post[category][name]' type='text' />" + "<input name='post[category][name]' type='text' id='post_category_name' />" end assert_dom_equal expected, output_buffer @@ -1940,9 +2053,9 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - "<label for='title'>Title:</label> <input name='post[title]' type='text' value='Hello World' /><br/>" \ - "<label for='body'>Body:</label> <textarea name='post[body]'>\nBack to the hill and over it again!</textarea><br/>" \ - "<label for='secret'>Secret:</label> <input name='post[secret]' type='hidden' value='0' /><input name='post[secret]' checked='checked' type='checkbox' value='1' /><br/>" + "<label for='title'>Title:</label> <input name='post[title]' type='text' value='Hello World' id='post_title'/><br/>" \ + "<label for='body'>Body:</label> <textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea><br/>" \ + "<label for='secret'>Secret:</label> <input name='post[secret]' type='hidden' value='0' /><input name='post[secret]' checked='checked' type='checkbox' value='1' id='post_secret' /><br/>" end assert_dom_equal expected, output_buffer @@ -1959,9 +2072,9 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - "<label for='title'>Title:</label> <input name='post[title]' type='text' value='Hello World' /><br/>" \ - "<label for='body'>Body:</label> <textarea name='post[body]'>\nBack to the hill and over it again!</textarea><br/>" \ - "<label for='secret'>Secret:</label> <input name='post[secret]' type='hidden' value='0' /><input name='post[secret]' checked='checked' type='checkbox' value='1' /><br/>" + "<label for='title'>Title:</label> <input name='post[title]' type='text' value='Hello World' id='post_title' /><br/>" \ + "<label for='body'>Body:</label> <textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea><br/>" \ + "<label for='secret'>Secret:</label> <input name='post[secret]' type='hidden' value='0' /><input name='post[secret]' checked='checked' type='checkbox' value='1' id='post_secret' /><br/>" end assert_dom_equal expected, output_buffer @@ -1978,7 +2091,7 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = whole_form("/posts/123", method: "patch") do - "<label for='title'>Title:</label> <input name='post[title]' type='text' value='Hello World' /><br/>" + "<label for='title'>Title:</label> <input name='post[title]' type='text' value='Hello World' id='post_title' /><br/>" end assert_dom_equal expected, output_buffer @@ -1993,7 +2106,7 @@ class FormWithActsLikeFormForTest < FormWithTest concat f.text_field(:title) end - expected = "<label for='title'>Title:</label> <input name='post[title]' type='text' value='Hello World' /><br/>" + expected = "<label for='title'>Title:</label> <input name='post[title]' type='text' value='Hello World' id='post_title' /><br/>" assert_dom_equal expected, output_buffer end @@ -2005,7 +2118,7 @@ class FormWithActsLikeFormForTest < FormWithTest concat f.text_field(:title) end - expected = "<label for='title'>Title:</label> <input name='post[title]' type='text' value='Hello World' /><br/>" + expected = "<label for='title'>Title:</label> <input name='post[title]' type='text' value='Hello World' id='post_title' /><br/>" assert_dom_equal expected, output_buffer end @@ -2018,9 +2131,9 @@ class FormWithActsLikeFormForTest < FormWithTest end expected = - "<label for='title'>Title:</label> <input name='post[title]' type='text' value='Hello World' /><br/>" \ - "<label for='body'>Body:</label> <textarea name='post[body]'>\nBack to the hill and over it again!</textarea><br/>" \ - "<label for='secret'>Secret:</label> <input name='post[secret]' type='hidden' value='0' /><input name='post[secret]' checked='checked' type='checkbox' value='1' /><br/>" + "<label for='title'>Title:</label> <input name='post[title]' type='text' value='Hello World' id='post_title'/><br/>" \ + "<label for='body'>Body:</label> <textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea><br/>" \ + "<label for='secret'>Secret:</label> <input name='post[secret]' type='hidden' value='0' /><input name='post[secret]' checked='checked' type='checkbox' value='1' id='post_secret' /><br/>" assert_dom_equal expected, output_buffer end @@ -2234,4 +2347,13 @@ class FormWithActsLikeFormForTest < FormWithTest ensure I18n.locale = old_locale end + + def with_default_enforce_utf8(value) + old_value = ActionView::Helpers::FormTagHelper.default_enforce_utf8 + ActionView::Helpers::FormTagHelper.default_enforce_utf8 = value + + yield + ensure + ActionView::Helpers::FormTagHelper.default_enforce_utf8 = old_value + end end diff --git a/actionview/test/template/form_helper_test.rb b/actionview/test/template/form_helper_test.rb index ec2e6b0959..5244204e42 100644 --- a/actionview/test/template/form_helper_test.rb +++ b/actionview/test/template/form_helper_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" require "controller/fake_models" @@ -6,6 +8,16 @@ class FormHelperTest < ActionView::TestCase tests ActionView::Helpers::FormHelper + class WithActiveStorageRoutesControllers < ActionController::Base + test_routes do + post "/rails/active_storage/direct_uploads" => "active_storage/direct_uploads#create", as: :rails_direct_uploads + end + + def url_options + { host: "testtwo.host" } + end + end + def form_for(*) @output_buffer = super end @@ -56,6 +68,9 @@ class FormHelperTest < ActionView::TestCase submit: "Save changes", another_post: { update: "Update your %{model}" + }, + "blog/post": { + update: "Update your %{model}" } } } @@ -93,7 +108,7 @@ class FormHelperTest < ActionView::TestCase @post = Post.new @comment = Comment.new - def @post.errors() + def @post.errors Class.new { def [](field); field == "author_name" ? ["can't be empty"] : [] end def empty?() false end @@ -540,6 +555,27 @@ class FormHelperTest < ActionView::TestCase assert_dom_equal expected, file_field("import", "file", multiple: true, name: "custom") end + def test_file_field_with_direct_upload_when_rails_direct_uploads_url_is_not_defined + expected = '<input type="file" name="import[file]" id="import_file" />' + assert_dom_equal expected, file_field("import", "file", direct_upload: true) + end + + def test_file_field_with_direct_upload_when_rails_direct_uploads_url_is_defined + @controller = WithActiveStorageRoutesControllers.new + + expected = '<input data-direct-upload-url="http://testtwo.host/rails/active_storage/direct_uploads" type="file" name="import[file]" id="import_file" />' + assert_dom_equal expected, file_field("import", "file", direct_upload: true) + end + + def test_file_field_with_direct_upload_dont_mutate_arguments + original_options = { class: "pix", direct_upload: true } + + expected = '<input class="pix" type="file" name="import[file]" id="import_file" />' + assert_dom_equal expected, file_field("import", "file", original_options) + + assert_equal({ class: "pix", direct_upload: true }, original_options) + end + def test_hidden_field assert_dom_equal( '<input id="post_title" name="post[title]" type="hidden" value="Hello World" />', @@ -579,7 +615,7 @@ class FormHelperTest < ActionView::TestCase end def test_check_box_is_html_safe - assert check_box("post", "secret").html_safe? + assert_predicate check_box("post", "secret"), :html_safe? end def test_check_box_checked_if_object_value_is_same_that_check_value @@ -714,19 +750,19 @@ class FormHelperTest < ActionView::TestCase end def test_check_box_with_explicit_checked_and_unchecked_values_when_object_value_is_big_decimal - @post.secret = BigDecimal.new(0) + @post.secret = BigDecimal(0) assert_dom_equal( '<input name="post[secret]" type="hidden" value="1" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="0" />', check_box("post", "secret", {}, 0, 1) ) - @post.secret = BigDecimal.new(1) + @post.secret = BigDecimal(1) assert_dom_equal( '<input name="post[secret]" type="hidden" value="1" /><input id="post_secret" name="post[secret]" type="checkbox" value="0" />', check_box("post", "secret", {}, 0, 1) ) - @post.secret = BigDecimal.new(2.2, 1) + @post.secret = BigDecimal(2.2, 1) assert_dom_equal( '<input name="post[secret]" type="hidden" value="1" /><input id="post_secret" name="post[secret]" type="checkbox" value="0" />', check_box("post", "secret", {}, 0, 1) @@ -742,7 +778,7 @@ class FormHelperTest < ActionView::TestCase end def test_check_box_with_nil_unchecked_value_is_html_safe - assert check_box("post", "secret", {}, "on", nil).html_safe? + assert_predicate check_box("post", "secret", {}, "on", nil), :html_safe? end def test_check_box_with_multiple_behavior @@ -1353,7 +1389,7 @@ class FormHelperTest < ActionView::TestCase ) assert_dom_equal( '<select name="post[secret]"></select>', - select("post", "secret", [], {}, "id" => nil) + select("post", "secret", [], {}, { "id" => nil }) ) assert_dom_equal( text_field("post", "title", "id" => nil), @@ -1527,6 +1563,38 @@ class FormHelperTest < ActionView::TestCase assert_dom_equal expected, output_buffer end + def test_form_for_is_not_affected_by_form_with_generates_ids + old_value = ActionView::Helpers::FormHelper.form_with_generates_ids + ActionView::Helpers::FormHelper.form_with_generates_ids = false + + form_for(@post, html: { id: "create-post" }) do |f| + concat f.label(:title) { "The Title" } + concat f.text_field(:title) + concat f.text_area(:body) + concat f.check_box(:secret) + concat f.submit("Create post") + concat f.button("Create post") + concat f.button { + concat content_tag(:span, "Create post") + } + end + + expected = whole_form("/posts/123", "create-post", "edit_post", method: "patch") do + "<label for='post_title'>The Title</label>" \ + "<input name='post[title]' type='text' id='post_title' value='Hello World' />" \ + "<textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea>" \ + "<input name='post[secret]' type='hidden' value='0' />" \ + "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" \ + "<input name='commit' data-disable-with='Create post' type='submit' value='Create post' />" \ + "<button name='button' type='submit'>Create post</button>" \ + "<button name='button' type='submit'><span>Create post</span></button>" + end + + assert_dom_equal expected, output_buffer + ensure + ActionView::Helpers::FormHelper.form_with_generates_ids = old_value + end + def test_form_for_with_collection_radio_buttons post = Post.new def post.active; false; end @@ -1927,6 +1995,34 @@ class FormHelperTest < ActionView::TestCase assert_dom_equal expected, output_buffer end + def test_form_for_default_enforce_utf8_false + with_default_enforce_utf8 false do + form_for(:post) do |f| + concat f.text_field(:title) + end + + expected = whole_form("/", nil, nil, enforce_utf8: false) do + "<input name='post[title]' type='text' id='post_title' value='Hello World' />" + end + + assert_dom_equal expected, output_buffer + end + end + + def test_form_for_default_enforce_utf8_true + with_default_enforce_utf8 true do + form_for(:post) do |f| + concat f.text_field(:title) + end + + expected = whole_form("/", nil, nil, enforce_utf8: true) do + "<input name='post[title]' type='text' id='post_title' value='Hello World' />" + end + + assert_dom_equal expected, output_buffer + end + end + def test_form_for_with_remote_in_html form_for(@post, url: "/", html: { remote: true, id: "create-post", method: :patch }) do |f| concat f.text_field(:title) @@ -2206,7 +2302,7 @@ class FormHelperTest < ActionView::TestCase end end - def test_submit_with_object_and_nested_lookup + def test_submit_with_object_which_is_overwritten_by_as_option with_locale :submit do form_for(@post, as: :another_post) do |f| concat f.submit @@ -2220,6 +2316,21 @@ class FormHelperTest < ActionView::TestCase end end + def test_submit_with_object_which_is_namespaced + blog_post = Blog::Post.new("And his name will be forty and four.", 44) + with_locale :submit do + form_for(blog_post) do |f| + concat f.submit + end + + expected = whole_form("/posts/44", "edit_post_44", "edit_post", method: "patch") do + "<input name='commit' data-disable-with='Update your Post' type='submit' value='Update your Post' />" + end + + assert_dom_equal expected, output_buffer + end + end + def test_nested_fields_for @comment.body = "Hello World" form_for(@post) do |f| @@ -3486,4 +3597,13 @@ class FormHelperTest < ActionView::TestCase ensure I18n.locale = old_locale end + + def with_default_enforce_utf8(value) + old_value = ActionView::Helpers::FormTagHelper.default_enforce_utf8 + ActionView::Helpers::FormTagHelper.default_enforce_utf8 = value + + yield + ensure + ActionView::Helpers::FormTagHelper.default_enforce_utf8 = old_value + end end diff --git a/actionview/test/template/form_options_helper_i18n_test.rb b/actionview/test/template/form_options_helper_i18n_test.rb index a1048fbb89..21295fa547 100644 --- a/actionview/test/template/form_options_helper_i18n_test.rb +++ b/actionview/test/template/form_options_helper_i18n_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" class FormOptionsHelperI18nTests < ActionView::TestCase diff --git a/actionview/test/template/form_options_helper_test.rb b/actionview/test/template/form_options_helper_test.rb index 792481f432..8f796bdb83 100644 --- a/actionview/test/template/form_options_helper_test.rb +++ b/actionview/test/template/form_options_helper_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" class Map < Hash @@ -335,8 +337,24 @@ class FormOptionsHelperTest < ActionView::TestCase ) end + def test_option_groups_from_collection_for_select_with_callable_group_method + group_proc = Proc.new { |c| c.countries } + assert_dom_equal( + "<optgroup label=\"<Africa>\"><option value=\"<sa>\"><South Africa></option>\n<option value=\"so\">Somalia</option></optgroup><optgroup label=\"Europe\"><option value=\"dk\" selected=\"selected\">Denmark</option>\n<option value=\"ie\">Ireland</option></optgroup>", + option_groups_from_collection_for_select(dummy_continents, group_proc, "continent_name", "country_id", "country_name", "dk") + ) + end + + def test_option_groups_from_collection_for_select_with_callable_group_label_method + label_proc = Proc.new { |c| c.continent_name } + assert_dom_equal( + "<optgroup label=\"<Africa>\"><option value=\"<sa>\"><South Africa></option>\n<option value=\"so\">Somalia</option></optgroup><optgroup label=\"Europe\"><option value=\"dk\" selected=\"selected\">Denmark</option>\n<option value=\"ie\">Ireland</option></optgroup>", + option_groups_from_collection_for_select(dummy_continents, "countries", label_proc, "country_id", "country_name", "dk") + ) + end + def test_option_groups_from_collection_for_select_returns_html_safe_string - assert option_groups_from_collection_for_select(dummy_continents, "countries", "continent_name", "country_id", "country_name", "dk").html_safe? + assert_predicate option_groups_from_collection_for_select(dummy_continents, "countries", "continent_name", "country_id", "country_name", "dk"), :html_safe? end def test_grouped_options_for_select_with_array @@ -365,7 +383,7 @@ class FormOptionsHelperTest < ActionView::TestCase assert_dom_equal( "<optgroup label=\"----------\"><option value=\"US\">US</option>\n<option value=\"Canada\">Canada</option></optgroup><optgroup label=\"----------\"><option value=\"GB\">GB</option>\n<option value=\"Germany\">Germany</option></optgroup>", - grouped_options_for_select([["US", "Canada"] , ["GB", "Germany"]], nil, divider: "----------") + grouped_options_for_select([["US", "Canada"], ["GB", "Germany"]], nil, divider: "----------") ) end @@ -384,7 +402,7 @@ class FormOptionsHelperTest < ActionView::TestCase end def test_grouped_options_for_select_returns_html_safe_string - assert grouped_options_for_select([["Hats", ["Baseball Cap", "Cowboy Hat"]]]).html_safe? + assert_predicate grouped_options_for_select([["Hats", ["Baseball Cap", "Cowboy Hat"]]]), :html_safe? end def test_grouped_options_for_select_with_prompt_returns_html_escaped_string @@ -474,7 +492,7 @@ class FormOptionsHelperTest < ActionView::TestCase end def test_time_zone_options_returns_html_safe_string - assert time_zone_options_for_select.html_safe? + assert_predicate time_zone_options_for_select, :html_safe? end def test_select @@ -489,7 +507,17 @@ class FormOptionsHelperTest < ActionView::TestCase def test_select_without_multiple assert_dom_equal( "<select id=\"post_category\" name=\"post[category]\"></select>", - select(:post, :category, "", {}, multiple: false) + select(:post, :category, "", {}, { multiple: false }) + ) + end + + def test_required_select_with_default_and_selected_placeholder + assert_dom_equal( + ['<select required="required" name="post[category]" id="post_category"><option disabled="disabled" selected="selected" value="">Choose one</option>', + '<option value="lifestyle">lifestyle</option>', + '<option value="programming">programming</option>', + '<option value="spiritual">spiritual</option></select>'].join("\n"), + select(:post, :category, ["lifestyle", "programming", "spiritual"], { selected: "", disabled: "", prompt: "Choose one" }, { required: true }) ) end @@ -637,7 +665,7 @@ class FormOptionsHelperTest < ActionView::TestCase end def test_select_with_multiple_to_add_hidden_input - output_buffer = select(:post, :category, "", {}, multiple: true) + output_buffer = select(:post, :category, "", {}, { multiple: true }) assert_dom_equal( "<input type=\"hidden\" name=\"post[category][]\" value=\"\"/><select multiple=\"multiple\" id=\"post_category\" name=\"post[category][]\"></select>", output_buffer @@ -645,7 +673,7 @@ class FormOptionsHelperTest < ActionView::TestCase end def test_select_with_multiple_and_without_hidden_input - output_buffer = select(:post, :category, "", { include_hidden: false }, multiple: true) + output_buffer = select(:post, :category, "", { include_hidden: false }, { multiple: true }) assert_dom_equal( "<select multiple=\"multiple\" id=\"post_category\" name=\"post[category][]\"></select>", output_buffer @@ -653,7 +681,7 @@ class FormOptionsHelperTest < ActionView::TestCase end def test_select_with_multiple_and_with_explicit_name_ending_with_brackets - output_buffer = select(:post, :category, [], { include_hidden: false }, multiple: true, name: "post[category][]") + output_buffer = select(:post, :category, [], { include_hidden: false }, { multiple: true, name: "post[category][]" }) assert_dom_equal( "<select multiple=\"multiple\" id=\"post_category\" name=\"post[category][]\"></select>", output_buffer @@ -661,7 +689,7 @@ class FormOptionsHelperTest < ActionView::TestCase end def test_select_with_multiple_and_disabled_to_add_disabled_hidden_input - output_buffer = select(:post, :category, "", {}, multiple: true, disabled: true) + output_buffer = select(:post, :category, "", {}, { multiple: true, disabled: true }) assert_dom_equal( "<input disabled=\"disabled\"type=\"hidden\" name=\"post[category][]\" value=\"\"/><select multiple=\"multiple\" disabled=\"disabled\" id=\"post_category\" name=\"post[category][]\"></select>", output_buffer @@ -680,7 +708,7 @@ class FormOptionsHelperTest < ActionView::TestCase def test_select_with_include_blank_false_and_required @post = Post.new @post.category = "<mus>" - e = assert_raises(ArgumentError) { select("post", "category", %w( abe <mus> hest), { include_blank: false }, required: "required") } + e = assert_raises(ArgumentError) { select("post", "category", %w( abe <mus> hest), { include_blank: false }, { required: "required" }) } assert_match(/include_blank cannot be false for a required field./, e.message) end @@ -760,7 +788,7 @@ class FormOptionsHelperTest < ActionView::TestCase @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("post", "category", [], { prompt: true, include_blank: true }, { class: "disabled", disabled: true }) ) end @@ -776,42 +804,42 @@ class FormOptionsHelperTest < ActionView::TestCase def test_required_select assert_dom_equal( %(<select id="post_category" name="post[category]" required="required"><option value=""></option>\n<option value="abe">abe</option>\n<option value="mus">mus</option>\n<option value="hest">hest</option></select>), - select("post", "category", %w(abe mus hest), {}, required: true) + select("post", "category", %w(abe mus hest), {}, { required: true }) ) end def test_required_select_with_include_blank_prompt assert_dom_equal( %(<select id="post_category" name="post[category]" required="required"><option value="">Select one</option>\n<option value="abe">abe</option>\n<option value="mus">mus</option>\n<option value="hest">hest</option></select>), - select("post", "category", %w(abe mus hest), { include_blank: "Select one" }, required: true) + select("post", "category", %w(abe mus hest), { include_blank: "Select one" }, { required: true }) ) end def test_required_select_with_prompt assert_dom_equal( %(<select id="post_category" name="post[category]" required="required"><option value="">Select one</option>\n<option value="abe">abe</option>\n<option value="mus">mus</option>\n<option value="hest">hest</option></select>), - select("post", "category", %w(abe mus hest), { prompt: "Select one" }, required: true) + select("post", "category", %w(abe mus hest), { prompt: "Select one" }, { required: true }) ) end def test_required_select_display_size_equals_to_one assert_dom_equal( %(<select id="post_category" name="post[category]" required="required" size="1"><option value=""></option>\n<option value="abe">abe</option>\n<option value="mus">mus</option>\n<option value="hest">hest</option></select>), - select("post", "category", %w(abe mus hest), {}, required: true, size: 1) + select("post", "category", %w(abe mus hest), {}, { required: true, size: 1 }) ) end def test_required_select_with_display_size_bigger_than_one assert_dom_equal( %(<select id="post_category" name="post[category]" required="required" size="2"><option value="abe">abe</option>\n<option value="mus">mus</option>\n<option value="hest">hest</option></select>), - select("post", "category", %w(abe mus hest), {}, required: true, size: 2) + select("post", "category", %w(abe mus hest), {}, { required: true, size: 2 }) ) end def test_required_select_with_multiple_option assert_dom_equal( %(<input name="post[category][]" type="hidden" value=""/><select id="post_category" multiple="multiple" name="post[category][]" required="required"><option value="abe">abe</option>\n<option value="mus">mus</option>\n<option value="hest">hest</option></select>), - select("post", "category", %w(abe mus hest), {}, required: true, multiple: true) + select("post", "category", %w(abe mus hest), {}, { required: true, multiple: true }) ) end @@ -850,7 +878,7 @@ class FormOptionsHelperTest < ActionView::TestCase assert_dom_equal( expected, - select("album[]", "genre", %w[rap rock country], {}, index: nil) + select("album[]", "genre", %w[rap rock country], {}, { index: nil }) ) end @@ -980,7 +1008,7 @@ class FormOptionsHelperTest < ActionView::TestCase assert_dom_equal( "<select id=\"post_author_name\" name=\"post[author_name]\" style=\"width: 200px\"><option value=\"\"></option>\n<option value=\"<Abe>\"><Abe></option>\n<option value=\"Babe\" selected=\"selected\">Babe</option>\n<option value=\"Cabe\">Cabe</option></select>", - collection_select("post", "author_name", dummy_posts, "author_name", "author_name", { include_blank: true }, "style" => "width: 200px") + collection_select("post", "author_name", dummy_posts, "author_name", "author_name", { include_blank: true }, { "style" => "width: 200px" }) ) end @@ -990,7 +1018,7 @@ class FormOptionsHelperTest < ActionView::TestCase assert_dom_equal( "<select id=\"post_author_name\" name=\"post[author_name]\" style=\"width: 200px\"><option value=\"\">No Selection</option>\n<option value=\"<Abe>\"><Abe></option>\n<option value=\"Babe\" selected=\"selected\">Babe</option>\n<option value=\"Cabe\">Cabe</option></select>", - collection_select("post", "author_name", dummy_posts, "author_name", "author_name", { include_blank: "No Selection" }, "style" => "width: 200px") + collection_select("post", "author_name", dummy_posts, "author_name", "author_name", { include_blank: "No Selection" }, { "style" => "width: 200px" }) ) end @@ -1001,10 +1029,10 @@ class FormOptionsHelperTest < ActionView::TestCase expected = "<input type=\"hidden\" name=\"post[author_name][]\" value=\"\"/><select id=\"post_author_name\" name=\"post[author_name][]\" multiple=\"multiple\"><option value=\"\"></option>\n<option value=\"<Abe>\"><Abe></option>\n<option value=\"Babe\" selected=\"selected\">Babe</option>\n<option value=\"Cabe\">Cabe</option></select>" # Should suffix default name with []. - assert_dom_equal expected, collection_select("post", "author_name", dummy_posts, "author_name", "author_name", { include_blank: true }, multiple: true) + assert_dom_equal expected, collection_select("post", "author_name", dummy_posts, "author_name", "author_name", { include_blank: true }, { multiple: true }) # Shouldn't suffix custom name with []. - assert_dom_equal expected, collection_select("post", "author_name", dummy_posts, "author_name", "author_name", { include_blank: true, name: "post[author_name][]" }, multiple: true) + assert_dom_equal expected, collection_select("post", "author_name", dummy_posts, "author_name", "author_name", { include_blank: true, name: "post[author_name][]" }, { multiple: true }) end def test_collection_select_with_blank_and_selected @@ -1147,7 +1175,7 @@ class FormOptionsHelperTest < ActionView::TestCase def test_time_zone_select_with_style @firm = Firm.new("D") html = time_zone_select("firm", "time_zone", nil, {}, - "style" => "color: red") + { "style" => "color: red" }) assert_dom_equal "<select id=\"firm_time_zone\" name=\"firm[time_zone]\" style=\"color: red\">" \ "<option value=\"A\">A</option>\n" \ "<option value=\"B\">B</option>\n" \ @@ -1157,13 +1185,13 @@ class FormOptionsHelperTest < ActionView::TestCase "</select>", html assert_dom_equal html, time_zone_select("firm", "time_zone", nil, {}, - style: "color: red") + { style: "color: red" }) end def test_time_zone_select_with_blank_and_style @firm = Firm.new("D") html = time_zone_select("firm", "time_zone", nil, - { include_blank: true }, "style" => "color: red") + { include_blank: true }, { "style" => "color: red" }) assert_dom_equal "<select id=\"firm_time_zone\" name=\"firm[time_zone]\" style=\"color: red\">" \ "<option value=\"\"></option>\n" \ "<option value=\"A\">A</option>\n" \ @@ -1174,13 +1202,13 @@ class FormOptionsHelperTest < ActionView::TestCase "</select>", html assert_dom_equal html, time_zone_select("firm", "time_zone", nil, - { include_blank: true }, style: "color: red") + { include_blank: true }, { style: "color: red" }) end def test_time_zone_select_with_blank_as_string_and_style @firm = Firm.new("D") html = time_zone_select("firm", "time_zone", nil, - { include_blank: "No Zone" }, "style" => "color: red") + { include_blank: "No Zone" }, { "style" => "color: red" }) assert_dom_equal "<select id=\"firm_time_zone\" name=\"firm[time_zone]\" style=\"color: red\">" \ "<option value=\"\">No Zone</option>\n" \ "<option value=\"A\">A</option>\n" \ @@ -1191,7 +1219,7 @@ class FormOptionsHelperTest < ActionView::TestCase "</select>", html assert_dom_equal html, time_zone_select("firm", "time_zone", nil, - { include_blank: "No Zone" }, style: "color: red") + { include_blank: "No Zone" }, { style: "color: red" }) end def test_time_zone_select_with_priority_zones @@ -1249,6 +1277,25 @@ class FormOptionsHelperTest < ActionView::TestCase html end + def test_time_zone_select_with_priority_zones_and_errors + @firm = Firm.new("D") + @firm.extend ActiveModel::Validations + @firm.errors[:time_zone] << "invalid" + zones = [ ActiveSupport::TimeZone.new("A"), ActiveSupport::TimeZone.new("D") ] + html = time_zone_select("firm", "time_zone", zones) + assert_dom_equal "<div class=\"field_with_errors\">" \ + "<select id=\"firm_time_zone\" name=\"firm[time_zone]\">" \ + "<option value=\"A\">A</option>\n" \ + "<option value=\"D\" selected=\"selected\">D</option>" \ + "<option value=\"\" disabled=\"disabled\">-------------</option>\n" \ + "<option value=\"B\">B</option>\n" \ + "<option value=\"C\">C</option>\n" \ + "<option value=\"E\">E</option>" \ + "</select>" \ + "</div>", + html + end + def test_time_zone_select_with_default_time_zone_and_nil_value @firm = Firm.new() @firm.time_zone = nil diff --git a/actionview/test/template/form_tag_helper_test.rb b/actionview/test/template/form_tag_helper_test.rb index 7ac15db9fe..a3500a7eb3 100644 --- a/actionview/test/template/form_tag_helper_test.rb +++ b/actionview/test/template/form_tag_helper_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" class FormTagHelperTest < ActionView::TestCase @@ -5,6 +7,16 @@ class FormTagHelperTest < ActionView::TestCase tests ActionView::Helpers::FormTagHelper + class WithActiveStorageRoutesControllers < ActionController::Base + test_routes do + post "/rails/active_storage/direct_uploads" => "active_storage/direct_uploads#create", as: :rails_direct_uploads + end + + def url_options + { host: "testtwo.host" } + end + end + def setup super @controller = BasicController.new @@ -88,56 +100,74 @@ class FormTagHelperTest < ActionView::TestCase end def test_form_tag_multipart - actual = form_tag({}, "multipart" => true) + actual = form_tag({}, { "multipart" => true }) expected = whole_form("http://www.example.com", enctype: true) assert_dom_equal expected, actual end def test_form_tag_with_method_patch - actual = form_tag({}, method: :patch) + actual = form_tag({}, { method: :patch }) expected = whole_form("http://www.example.com", method: :patch) assert_dom_equal expected, actual end def test_form_tag_with_method_put - actual = form_tag({}, method: :put) + actual = form_tag({}, { method: :put }) expected = whole_form("http://www.example.com", method: :put) assert_dom_equal expected, actual end def test_form_tag_with_method_delete - actual = form_tag({}, method: :delete) + actual = form_tag({}, { method: :delete }) expected = whole_form("http://www.example.com", method: :delete) assert_dom_equal expected, actual end def test_form_tag_with_remote - actual = form_tag({}, remote: true) + actual = form_tag({}, { remote: true }) expected = whole_form("http://www.example.com", remote: true) assert_dom_equal expected, actual end def test_form_tag_with_remote_false - actual = form_tag({}, remote: false) + actual = form_tag({}, { remote: false }) expected = whole_form assert_dom_equal expected, actual end def test_form_tag_enforce_utf8_true - actual = form_tag({}, enforce_utf8: true) + actual = form_tag({}, { enforce_utf8: true }) expected = whole_form("http://www.example.com", enforce_utf8: true) assert_dom_equal expected, actual - assert actual.html_safe? + assert_predicate actual, :html_safe? end def test_form_tag_enforce_utf8_false - actual = form_tag({}, enforce_utf8: false) + actual = form_tag({}, { enforce_utf8: false }) expected = whole_form("http://www.example.com", enforce_utf8: false) assert_dom_equal expected, actual - assert actual.html_safe? + assert_predicate actual, :html_safe? + end + + def test_form_tag_default_enforce_utf8_false + with_default_enforce_utf8 false do + actual = form_tag({}) + expected = whole_form("http://www.example.com", enforce_utf8: false) + assert_dom_equal expected, actual + assert_predicate actual, :html_safe? + end + end + + def test_form_tag_default_enforce_utf8_true + with_default_enforce_utf8 true do + actual = form_tag({}) + expected = whole_form("http://www.example.com", enforce_utf8: true) + assert_dom_equal expected, actual + assert_predicate actual, :html_safe? + end end def test_form_tag_with_block_in_erb @@ -176,6 +206,33 @@ class FormTagHelperTest < ActionView::TestCase assert_dom_equal "<input name=\"picsplz\" type=\"file\" id=\"picsplz\" class=\"pix\"/>", file_field_tag("picsplz", class: "pix") end + def test_file_field_tag_with_direct_upload_when_rails_direct_uploads_url_is_not_defined + assert_dom_equal( + "<input name=\"picsplz\" type=\"file\" id=\"picsplz\" class=\"pix\"/>", + file_field_tag("picsplz", class: "pix", direct_upload: true) + ) + end + + def test_file_field_tag_with_direct_upload_when_rails_direct_uploads_url_is_defined + @controller = WithActiveStorageRoutesControllers.new + + assert_dom_equal( + "<input name=\"picsplz\" type=\"file\" id=\"picsplz\" class=\"pix\" data-direct-upload-url=\"http://testtwo.host/rails/active_storage/direct_uploads\"/>", + file_field_tag("picsplz", class: "pix", direct_upload: true) + ) + end + + def test_file_field_tag_with_direct_upload_dont_mutate_arguments + original_options = { class: "pix", direct_upload: true } + + assert_dom_equal( + "<input name=\"picsplz\" type=\"file\" id=\"picsplz\" class=\"pix\"/>", + file_field_tag("picsplz", original_options) + ) + + assert_equal({ class: "pix", direct_upload: true }, original_options) + end + def test_password_field_tag actual = password_field_tag expected = %(<input id="password" name="password" type="password" />) @@ -602,7 +659,7 @@ class FormTagHelperTest < ActionView::TestCase def test_image_submit_tag_with_confirmation assert_dom_equal( - %(<input alt="Save" type="image" src="/images/save.gif" data-confirm="Are you sure?" />), + %(<input type="image" src="/images/save.gif" data-confirm="Are you sure?" />), image_submit_tag("save.gif", data: { confirm: "Are you sure?" }) ) end @@ -743,4 +800,13 @@ class FormTagHelperTest < ActionView::TestCase def root_elem(rendered_content) Nokogiri::HTML::DocumentFragment.parse(rendered_content).children.first # extract from nodeset end + + def with_default_enforce_utf8(value) + old_value = ActionView::Helpers::FormTagHelper.default_enforce_utf8 + ActionView::Helpers::FormTagHelper.default_enforce_utf8 = value + + yield + ensure + ActionView::Helpers::FormTagHelper.default_enforce_utf8 = old_value + end end diff --git a/actionview/test/template/html_test.rb b/actionview/test/template/html_test.rb index 60f4b0aee6..5cdff74d60 100644 --- a/actionview/test/template/html_test.rb +++ b/actionview/test/template/html_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" class HTMLTest < ActiveSupport::TestCase diff --git a/actionview/test/template/javascript_helper_test.rb b/actionview/test/template/javascript_helper_test.rb index 67747a7a83..a72bc6c2fe 100644 --- a/actionview/test/template/javascript_helper_test.rb +++ b/actionview/test/template/javascript_helper_test.rb @@ -1,14 +1,20 @@ +# frozen_string_literal: true + require "abstract_unit" class JavaScriptHelperTest < ActionView::TestCase tests ActionView::Helpers::JavaScriptHelper attr_accessor :output_buffer + attr_reader :request setup do @old_escape_html_entities_in_json = ActiveSupport.escape_html_entities_in_json ActiveSupport.escape_html_entities_in_json = true @template = self + @request = Class.new do + def send_early_hints(links) end + end.new end def teardown diff --git a/actionview/test/template/log_subscriber_test.rb b/actionview/test/template/log_subscriber_test.rb index 4c9f84f277..7f4fd25573 100644 --- a/actionview/test/template/log_subscriber_test.rb +++ b/actionview/test/template/log_subscriber_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" require "active_support/log_subscriber/test_helper" require "action_view/log_subscriber" @@ -28,7 +30,7 @@ class AVLogSubscriberTest < ActiveSupport::TestCase 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 + Rails.instance_eval { undef :root } if defined?(@defined_root) end def set_logger(logger) diff --git a/actionview/test/template/lookup_context_test.rb b/actionview/test/template/lookup_context_test.rb index b47d92df34..38469cbe3d 100644 --- a/actionview/test/template/lookup_context_test.rb +++ b/actionview/test/template/lookup_context_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" require "abstract_controller/rendering" @@ -33,7 +35,7 @@ class LookupContextTest < ActiveSupport::TestCase test "allows me to freeze and retrieve frozen formats" do @lookup_context.formats.freeze - assert @lookup_context.formats.frozen? + assert_predicate @lookup_context.formats, :frozen? end test "provides getters and setters for variants" do @@ -193,7 +195,7 @@ class LookupContextTest < ActiveSupport::TestCase assert @lookup_context.cache template = @lookup_context.disable_cache do - assert !@lookup_context.cache + assert_not @lookup_context.cache @lookup_context.find("foo", %w(test), true) end assert @lookup_context.cache diff --git a/actionview/test/template/number_helper_test.rb b/actionview/test/template/number_helper_test.rb index 678120a9c9..357ae1326a 100644 --- a/actionview/test/template/number_helper_test.rb +++ b/actionview/test/template/number_helper_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" class NumberHelperTest < ActionView::TestCase @@ -77,7 +79,7 @@ class NumberHelperTest < ActionView::TestCase assert_equal "1.23 <b>km3</b>", number_to_human(1_234_567_000_000, units: volume) assert_equal "1.23 <b>Pl</b>", number_to_human(1_234_567_000_000_000, units: volume) - #Including fractionals + # Including fractionals distance = { mili: "<b>mm</b>", centi: "<b>cm</b>", deci: "<b>dm</b>", unit: "<b>m</b>", ten: "<b>dam</b>", hundred: "<b>hm</b>", thousand: "<b>km</b>", micro: "<b>um</b>", nano: "<b>nm</b>", pico: "<b>pm</b>", femto: "<b>fm</b>" } @@ -124,43 +126,43 @@ class NumberHelperTest < ActionView::TestCase end def test_number_helpers_outputs_are_html_safe - assert number_to_human(1).html_safe? - assert !number_to_human("<script></script>").html_safe? - assert number_to_human("asdf".html_safe).html_safe? - assert number_to_human("1".html_safe).html_safe? - - assert number_to_human_size(1).html_safe? - assert number_to_human_size(1000000).html_safe? - assert !number_to_human_size("<script></script>").html_safe? - assert number_to_human_size("asdf".html_safe).html_safe? - assert number_to_human_size("1".html_safe).html_safe? - - assert number_with_precision(1, strip_insignificant_zeros: false).html_safe? - assert number_with_precision(1, strip_insignificant_zeros: true).html_safe? - assert !number_with_precision("<script></script>").html_safe? - assert number_with_precision("asdf".html_safe).html_safe? - assert number_with_precision("1".html_safe).html_safe? - - assert number_to_currency(1).html_safe? - assert !number_to_currency("<script></script>").html_safe? - assert number_to_currency("asdf".html_safe).html_safe? - assert number_to_currency("1".html_safe).html_safe? - - assert number_to_percentage(1).html_safe? - assert !number_to_percentage("<script></script>").html_safe? - assert number_to_percentage("asdf".html_safe).html_safe? - assert number_to_percentage("1".html_safe).html_safe? - - assert number_to_phone(1).html_safe? + assert_predicate number_to_human(1), :html_safe? + assert_not_predicate number_to_human("<script></script>"), :html_safe? + assert_predicate number_to_human("asdf".html_safe), :html_safe? + assert_predicate number_to_human("1".html_safe), :html_safe? + + assert_predicate number_to_human_size(1), :html_safe? + assert_predicate number_to_human_size(1000000), :html_safe? + assert_not_predicate number_to_human_size("<script></script>"), :html_safe? + assert_predicate number_to_human_size("asdf".html_safe), :html_safe? + assert_predicate number_to_human_size("1".html_safe), :html_safe? + + assert_predicate number_with_precision(1, strip_insignificant_zeros: false), :html_safe? + assert_predicate number_with_precision(1, strip_insignificant_zeros: true), :html_safe? + assert_not_predicate number_with_precision("<script></script>"), :html_safe? + assert_predicate number_with_precision("asdf".html_safe), :html_safe? + assert_predicate number_with_precision("1".html_safe), :html_safe? + + assert_predicate number_to_currency(1), :html_safe? + assert_not_predicate number_to_currency("<script></script>"), :html_safe? + assert_predicate number_to_currency("asdf".html_safe), :html_safe? + assert_predicate number_to_currency("1".html_safe), :html_safe? + + assert_predicate number_to_percentage(1), :html_safe? + assert_not_predicate number_to_percentage("<script></script>"), :html_safe? + assert_predicate number_to_percentage("asdf".html_safe), :html_safe? + assert_predicate number_to_percentage("1".html_safe), :html_safe? + + assert_predicate number_to_phone(1), :html_safe? assert_equal "<script></script>", number_to_phone("<script></script>") - assert number_to_phone("<script></script>").html_safe? - assert number_to_phone("asdf".html_safe).html_safe? - assert number_to_phone("1".html_safe).html_safe? - - assert number_with_delimiter(1).html_safe? - assert !number_with_delimiter("<script></script>").html_safe? - assert number_with_delimiter("asdf".html_safe).html_safe? - assert number_with_delimiter("1".html_safe).html_safe? + assert_predicate number_to_phone("<script></script>"), :html_safe? + assert_predicate number_to_phone("asdf".html_safe), :html_safe? + assert_predicate number_to_phone("1".html_safe), :html_safe? + + assert_predicate number_with_delimiter(1), :html_safe? + assert_not_predicate number_with_delimiter("<script></script>"), :html_safe? + assert_predicate number_with_delimiter("asdf".html_safe), :html_safe? + assert_predicate number_with_delimiter("1".html_safe), :html_safe? end def test_number_helpers_should_raise_error_if_invalid_when_specified diff --git a/actionview/test/template/output_safety_helper_test.rb b/actionview/test/template/output_safety_helper_test.rb index 537b4393ee..faeeded1c8 100644 --- a/actionview/test/template/output_safety_helper_test.rb +++ b/actionview/test/template/output_safety_helper_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" class OutputSafetyHelperTest < ActionView::TestCase @@ -10,7 +12,7 @@ class OutputSafetyHelperTest < ActionView::TestCase test "raw returns the safe string" do result = raw(@string) assert_equal @string, result - assert result.html_safe? + assert_predicate result, :html_safe? end test "raw handles nil values correctly" do @@ -51,11 +53,11 @@ class OutputSafetyHelperTest < ActionView::TestCase test "to_sentence should escape non-html_safe values" do actual = to_sentence(%w(< > & ' ")) - assert actual.html_safe? + assert_predicate actual, :html_safe? assert_equal("<, >, &, ', and "", actual) actual = to_sentence(%w(<script>)) - assert actual.html_safe? + assert_predicate actual, :html_safe? assert_equal("<script>", actual) end @@ -78,19 +80,19 @@ class OutputSafetyHelperTest < ActionView::TestCase url = "https://example.com" expected = %(<a href="#{url}">#{url}</a> and <p><marquee>shady stuff</marquee><br /></p>) actual = to_sentence([link_to(url, url), ptag]) - assert actual.html_safe? + assert_predicate actual, :html_safe? assert_equal(expected, actual) end test "to_sentence handles blank strings" do actual = to_sentence(["", "two", "three"]) - assert actual.html_safe? + assert_predicate actual, :html_safe? assert_equal ", two, and three", actual end test "to_sentence handles nil values" do actual = to_sentence([nil, "two", "three"]) - assert actual.html_safe? + assert_predicate actual, :html_safe? assert_equal ", two, and three", actual end diff --git a/actionview/test/template/partial_iteration_test.rb b/actionview/test/template/partial_iteration_test.rb index 3ebf3b550a..06bbdabac0 100644 --- a/actionview/test/template/partial_iteration_test.rb +++ b/actionview/test/template/partial_iteration_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" require "action_view/renderer/partial_renderer" diff --git a/actionview/test/template/record_identifier_test.rb b/actionview/test/template/record_identifier_test.rb index ce446715fd..29012e943d 100644 --- a/actionview/test/template/record_identifier_test.rb +++ b/actionview/test/template/record_identifier_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" require "controller/fake_models" diff --git a/actionview/test/template/record_tag_helper_test.rb b/actionview/test/template/record_tag_helper_test.rb deleted file mode 100644 index 3685230558..0000000000 --- a/actionview/test/template/record_tag_helper_test.rb +++ /dev/null @@ -1,31 +0,0 @@ -require "abstract_unit" - -class RecordTagPost - extend ActiveModel::Naming - - attr_accessor :id, :body - - def initialize - @id = 45 - @body = "What a wonderful world!" - - yield self if block_given? - end -end - -class RecordTagHelperTest < ActionView::TestCase - tests ActionView::Helpers::RecordTagHelper - - def setup - super - @post = RecordTagPost.new - end - - def test_content_tag_for - assert_raises(NoMethodError) { content_tag_for(:li, @post) } - end - - def test_div_for - assert_raises(NoMethodError) { div_for(@post, class: "special") } - end -end diff --git a/actionview/test/template/render_test.rb b/actionview/test/template/render_test.rb index 1fd8b4fe1a..8782eb4430 100644 --- a/actionview/test/template/render_test.rb +++ b/actionview/test/template/render_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" require "controller/fake_models" diff --git a/actionview/test/template/resolver_cache_test.rb b/actionview/test/template/resolver_cache_test.rb index 0ecfccd375..8a5db1346a 100644 --- a/actionview/test/template/resolver_cache_test.rb +++ b/actionview/test/template/resolver_cache_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" class ResolverCacheTest < ActiveSupport::TestCase diff --git a/actionview/test/template/resolver_patterns_test.rb b/actionview/test/template/resolver_patterns_test.rb index 8e21f4b828..1e1a4c5063 100644 --- a/actionview/test/template/resolver_patterns_test.rb +++ b/actionview/test/template/resolver_patterns_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" class ResolverPatternsTest < ActiveSupport::TestCase diff --git a/actionview/test/template/sanitize_helper_test.rb b/actionview/test/template/sanitize_helper_test.rb index 4d4ed3c35c..181f09ab65 100644 --- a/actionview/test/template/sanitize_helper_test.rb +++ b/actionview/test/template/sanitize_helper_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" # The exhaustive tests are in the rails-html-sanitizer gem. @@ -19,8 +21,8 @@ class SanitizeHelperTest < ActionView::TestCase def test_should_sanitize_illegal_style_properties raw = %(display:block; position:absolute; left:0; top:0; width:100%; height:100%; z-index:1; background-color:black; background-image:url(http://www.ragingplatypus.com/i/cam-full.jpg); background-x:center; background-y:center; background-repeat:repeat;) - expected = %(display: block; width: 100%; height: 100%; background-color: black; background-x: center; background-y: center;) - assert_equal expected, sanitize_css(raw) + expected = %r(\Adisplay:\s?block;\s?width:\s?100%;\s?height:\s?100%;\s?background-color:\s?black;\s?background-x:\s?center;\s?background-y:\s?center;\z) + assert_match expected, sanitize_css(raw) end def test_strip_tags @@ -36,6 +38,6 @@ class SanitizeHelperTest < ActionView::TestCase end def test_sanitize_is_marked_safe - assert sanitize("<html><script></script></html>").html_safe? + assert_predicate sanitize("<html><script></script></html>"), :html_safe? end end diff --git a/actionview/test/template/streaming_render_test.rb b/actionview/test/template/streaming_render_test.rb index 41b9063417..ef000300cc 100644 --- a/actionview/test/template/streaming_render_test.rb +++ b/actionview/test/template/streaming_render_test.rb @@ -1,9 +1,11 @@ +# frozen_string_literal: true + require "abstract_unit" class TestController < ActionController::Base end -class FiberedTest < ActiveSupport::TestCase +class SetupFiberedBase < ActiveSupport::TestCase def setup view_paths = ActionController::Base.view_paths @assigns = { secret: "in the sauce", name: nil } @@ -23,7 +25,9 @@ class FiberedTest < ActiveSupport::TestCase end string end +end +class FiberedTest < SetupFiberedBase def test_streaming_works content = [] body = render_body(template: "test/hello_world", layout: "layouts/yield") @@ -109,3 +113,20 @@ class FiberedTest < ActiveSupport::TestCase buffered_render(template: "test/streaming", layout: "layouts/streaming_with_capture") end end + +class FiberedWithLocaleTest < SetupFiberedBase + def setup + @old_locale = I18n.locale + I18n.locale = "da" + super + end + + def teardown + I18n.locale = @old_locale + end + + def test_render_with_streaming_and_locale + assert_equal "layout.locale: da\nview.locale: da\n\n", + buffered_render(template: "test/streaming_with_locale", layout: "layouts/streaming_with_locale") + end +end diff --git a/actionview/test/template/tag_helper_test.rb b/actionview/test/template/tag_helper_test.rb index f1e5946e14..9a6226fd04 100644 --- a/actionview/test/template/tag_helper_test.rb +++ b/actionview/test/template/tag_helper_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" class TagHelperTest < ActionView::TestCase @@ -79,7 +81,7 @@ class TagHelperTest < ActionView::TestCase def test_content_tag assert_equal "<a href=\"create\">Create</a>", content_tag("a", "Create", "href" => "create") - assert content_tag("a", "Create", "href" => "create").html_safe? + assert_predicate content_tag("a", "Create", "href" => "create"), :html_safe? assert_equal content_tag("a", "Create", "href" => "create"), content_tag("a", "Create", href: "create") assert_equal "<p><script>evil_js</script></p>", @@ -90,7 +92,7 @@ class TagHelperTest < ActionView::TestCase def test_tag_builder_with_content assert_equal "<div id=\"post_1\">Content</div>", tag.div("Content", id: "post_1") - assert tag.div("Content", id: "post_1").html_safe? + assert_predicate tag.div("Content", id: "post_1"), :html_safe? assert_equal tag.div("Content", id: "post_1"), tag.div("Content", "id": "post_1") assert_equal "<p><script>evil_js</script></p>", @@ -305,8 +307,8 @@ class TagHelperTest < ActionView::TestCase def test_tag_builder_disable_escaping assert_equal '<a href="&"></a>', tag.a(href: "&", escape_attributes: false) - assert_equal '<a href="&">cnt</a>', tag.a(href: "&" , escape_attributes: false) { "cnt" } - assert_equal '<br data-hidden="&">', tag.br("data-hidden": "&" , escape_attributes: false) + assert_equal '<a href="&">cnt</a>', tag.a(href: "&", escape_attributes: false) { "cnt" } + assert_equal '<br data-hidden="&">', tag.br("data-hidden": "&", escape_attributes: false) assert_equal '<a href="&">content</a>', tag.a("content", href: "&", escape_attributes: false) assert_equal '<a href="&">content</a>', tag.a(href: "&", escape_attributes: false) { "content" } end @@ -314,18 +316,18 @@ class TagHelperTest < ActionView::TestCase def test_data_attributes ["data", :data].each { |data| assert_dom_equal '<a data-a-float="3.14" data-a-big-decimal="-123.456" data-a-number="1" data-array="[1,2,3]" data-hash="{"key":"value"}" data-string-with-quotes="double"quote"party"" data-string="hello" data-symbol="foo" />', - tag("a", data => { a_float: 3.14, a_big_decimal: BigDecimal.new("-123.456"), a_number: 1, string: "hello", symbol: :foo, array: [1, 2, 3], hash: { key: "value" }, string_with_quotes: 'double"quote"party"' }) + tag("a", data => { a_float: 3.14, a_big_decimal: BigDecimal("-123.456"), a_number: 1, string: "hello", symbol: :foo, array: [1, 2, 3], hash: { key: "value" }, string_with_quotes: 'double"quote"party"' }) assert_dom_equal '<a data-a-float="3.14" data-a-big-decimal="-123.456" data-a-number="1" data-array="[1,2,3]" data-hash="{"key":"value"}" data-string-with-quotes="double"quote"party"" data-string="hello" data-symbol="foo" />', - tag.a(data: { a_float: 3.14, a_big_decimal: BigDecimal.new("-123.456"), a_number: 1, string: "hello", symbol: :foo, array: [1, 2, 3], hash: { key: "value" }, string_with_quotes: 'double"quote"party"' }) + tag.a(data: { a_float: 3.14, a_big_decimal: BigDecimal("-123.456"), a_number: 1, string: "hello", symbol: :foo, array: [1, 2, 3], hash: { key: "value" }, string_with_quotes: 'double"quote"party"' }) } end def test_aria_attributes ["aria", :aria].each { |aria| assert_dom_equal '<a aria-a-float="3.14" aria-a-big-decimal="-123.456" aria-a-number="1" aria-array="[1,2,3]" aria-hash="{"key":"value"}" aria-string-with-quotes="double"quote"party"" aria-string="hello" aria-symbol="foo" />', - tag("a", aria => { a_float: 3.14, a_big_decimal: BigDecimal.new("-123.456"), a_number: 1, string: "hello", symbol: :foo, array: [1, 2, 3], hash: { key: "value" }, string_with_quotes: 'double"quote"party"' }) + tag("a", aria => { a_float: 3.14, a_big_decimal: BigDecimal("-123.456"), a_number: 1, string: "hello", symbol: :foo, array: [1, 2, 3], hash: { key: "value" }, string_with_quotes: 'double"quote"party"' }) assert_dom_equal '<a aria-a-float="3.14" aria-a-big-decimal="-123.456" aria-a-number="1" aria-array="[1,2,3]" aria-hash="{"key":"value"}" aria-string-with-quotes="double"quote"party"" aria-string="hello" aria-symbol="foo" />', - tag.a(aria: { a_float: 3.14, a_big_decimal: BigDecimal.new("-123.456"), a_number: 1, string: "hello", symbol: :foo, array: [1, 2, 3], hash: { key: "value" }, string_with_quotes: 'double"quote"party"' }) + tag.a(aria: { a_float: 3.14, a_big_decimal: BigDecimal("-123.456"), a_number: 1, string: "hello", symbol: :foo, array: [1, 2, 3], hash: { key: "value" }, string_with_quotes: 'double"quote"party"' }) } end diff --git a/actionview/test/template/template_error_test.rb b/actionview/test/template/template_error_test.rb index 54c1d53b60..c4dc88e4aa 100644 --- a/actionview/test/template/template_error_test.rb +++ b/actionview/test/template/template_error_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" class TemplateErrorTest < ActiveSupport::TestCase diff --git a/actionview/test/template/template_test.rb b/actionview/test/template/template_test.rb index d3c08634bc..3dc14e36e0 100644 --- a/actionview/test/template/template_test.rb +++ b/actionview/test/template/template_test.rb @@ -1,4 +1,5 @@ # encoding: US-ASCII +# frozen_string_literal: true require "abstract_unit" require "logger" diff --git a/actionview/test/template/test_case_test.rb b/actionview/test/template/test_case_test.rb index 3deddd5706..d98fd4f9a2 100644 --- a/actionview/test/template/test_case_test.rb +++ b/actionview/test/template/test_case_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" require "rails/engine" @@ -190,7 +192,7 @@ module ActionView helper HelperThatInvokesProtectAgainstForgery test "protect_from_forgery? in any helpers returns false" do - assert !view.help_me + assert_not view.help_me end end @@ -280,6 +282,14 @@ module ActionView @customers = [DeveloperStruct.new("Eloy"), DeveloperStruct.new("Manfred")] assert_match(/Hello: EloyHello: Manfred/, render(file: "test/list")) end + + test "is able to use helpers that depend on the view flow" do + assert_not content_for?(:foo) + + content_for :foo, "bar" + assert content_for?(:foo) + assert_equal "bar", content_for(:foo) + end end class AssertionsTest < ActionView::TestCase diff --git a/actionview/test/template/test_test.rb b/actionview/test/template/test_test.rb index 52cac77bc5..78ba536dfc 100644 --- a/actionview/test/template/test_test.rb +++ b/actionview/test/template/test_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" module PeopleHelper diff --git a/actionview/test/template/testing/fixture_resolver_test.rb b/actionview/test/template/testing/fixture_resolver_test.rb index effe453fc0..9954e3500d 100644 --- a/actionview/test/template/testing/fixture_resolver_test.rb +++ b/actionview/test/template/testing/fixture_resolver_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" class FixtureResolverTest < ActiveSupport::TestCase diff --git a/actionview/test/template/testing/null_resolver_test.rb b/actionview/test/template/testing/null_resolver_test.rb index 5346fd3368..53364c1d90 100644 --- a/actionview/test/template/testing/null_resolver_test.rb +++ b/actionview/test/template/testing/null_resolver_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" class NullResolverTest < ActiveSupport::TestCase diff --git a/actionview/test/template/text_helper_test.rb b/actionview/test/template/text_helper_test.rb index 21ee4cc8e5..45edfe18be 100644 --- a/actionview/test/template/text_helper_test.rb +++ b/actionview/test/template/text_helper_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" class TextHelperTest < ActionView::TestCase @@ -17,12 +19,12 @@ class TextHelperTest < ActionView::TestCase end def test_simple_format_should_be_html_safe - assert simple_format("<b> test with html tags </b>").html_safe? + assert_predicate simple_format("<b> test with html tags </b>"), :html_safe? end def test_simple_format_included_in_isolation helper_klass = Class.new { include ActionView::Helpers::TextHelper } - assert helper_klass.new.simple_format("<b> test with html tags </b>").html_safe? + assert_predicate helper_klass.new.simple_format("<b> test with html tags </b>"), :html_safe? end def test_simple_format @@ -48,19 +50,19 @@ class TextHelperTest < ActionView::TestCase def test_simple_format_should_sanitize_input_when_sanitize_option_is_true assert_equal "<p><b> test with unsafe string </b>code!</p>", - simple_format("<b> test with unsafe string </b><script>code!</script>", {}, sanitize: true) + simple_format("<b> test with unsafe string </b><script>code!</script>", {}, { sanitize: true }) end def test_simple_format_should_not_sanitize_input_when_sanitize_option_is_false - assert_equal "<p><b> test with unsafe string </b><script>code!</script></p>", simple_format("<b> test with unsafe string </b><script>code!</script>", {}, sanitize: false) + assert_equal "<p><b> test with unsafe string </b><script>code!</script></p>", simple_format("<b> test with unsafe string </b><script>code!</script>", {}, { sanitize: false }) end def test_simple_format_with_custom_wrapper - assert_equal "<div></div>", simple_format(nil, {}, wrapper_tag: "div") + assert_equal "<div></div>", simple_format(nil, {}, { wrapper_tag: "div" }) end def test_simple_format_with_custom_wrapper_and_multi_line_breaks - assert_equal "<div>We want to put a wrapper...</div>\n\n<div>...right there.</div>", simple_format("We want to put a wrapper...\n\n...right there.", {}, wrapper_tag: "div") + assert_equal "<div>We want to put a wrapper...</div>\n\n<div>...right there.</div>", simple_format("We want to put a wrapper...\n\n...right there.", {}, { wrapper_tag: "div" }) end def test_simple_format_should_not_change_the_text_passed @@ -121,7 +123,7 @@ class TextHelperTest < ActionView::TestCase end def test_truncate_should_be_html_safe - assert truncate("Hello World!", length: 12).html_safe? + assert_predicate truncate("Hello World!", length: 12), :html_safe? end def test_truncate_should_escape_the_input @@ -134,12 +136,12 @@ class TextHelperTest < ActionView::TestCase def test_truncate_with_escape_false_should_be_html_safe truncated = truncate("Hello <script>code!</script>World!!", length: 12, escape: false) - assert truncated.html_safe? + assert_predicate truncated, :html_safe? end def test_truncate_with_block_should_be_html_safe truncated = truncate("Here's a long test and I need a continue to read link", length: 27) { link_to "Continue", "#" } - assert truncated.html_safe? + assert_predicate truncated, :html_safe? end def test_truncate_with_block_should_escape_the_input @@ -154,7 +156,7 @@ class TextHelperTest < ActionView::TestCase def test_truncate_with_block_with_escape_false_should_be_html_safe truncated = truncate("<script>code!</script>Here's a long test and I need a continue to read link", length: 27, escape: false) { link_to "Continue", "#" } - assert truncated.html_safe? + assert_predicate truncated, :html_safe? end def test_truncate_with_block_should_escape_the_block @@ -163,7 +165,7 @@ class TextHelperTest < ActionView::TestCase end def test_highlight_should_be_html_safe - assert highlight("This is a beautiful morning", "beautiful").html_safe? + assert_predicate highlight("This is a beautiful morning", "beautiful"), :html_safe? end def test_highlight @@ -295,7 +297,7 @@ class TextHelperTest < ActionView::TestCase end def test_excerpt_should_not_be_html_safe - assert !excerpt("This is a beautiful! morning", "beautiful", radius: 5).html_safe? + assert_not_predicate excerpt("This is a beautiful! morning", "beautiful", radius: 5), :html_safe? end def test_excerpt_in_borderline_cases diff --git a/actionview/test/template/text_test.rb b/actionview/test/template/text_test.rb index 72ffd5f3be..0c6470df21 100644 --- a/actionview/test/template/text_test.rb +++ b/actionview/test/template/text_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" class TextTest < ActiveSupport::TestCase diff --git a/actionview/test/template/translation_helper_test.rb b/actionview/test/template/translation_helper_test.rb index 1cfc13f337..f40595bf4d 100644 --- a/actionview/test/template/translation_helper_test.rb +++ b/actionview/test/template/translation_helper_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" module I18n @@ -73,7 +75,7 @@ class TranslationHelperTest < ActiveSupport::TestCase def test_returns_missing_translation_message_with_unescaped_interpolation expected = '<span class="translation_missing" title="translation missing: en.translations.missing, name: Kir, year: 2015, vulnerable: &quot; onclick=&quot;alert()&quot;">Missing</span>' assert_equal expected, translate(:"translations.missing", name: "Kir", year: "2015", vulnerable: %{" onclick="alert()"}) - assert translate(:"translations.missing").html_safe? + assert_predicate translate(:"translations.missing"), :html_safe? end def test_returns_missing_translation_message_does_filters_out_i18n_options @@ -143,11 +145,11 @@ class TranslationHelperTest < ActiveSupport::TestCase end def test_translate_marks_translations_named_html_as_safe_html - assert translate(:'translations.html').html_safe? + assert_predicate translate(:'translations.html'), :html_safe? end def test_translate_marks_translations_with_a_html_suffix_as_safe_html - assert translate(:'translations.hello_html').html_safe? + assert_predicate translate(:'translations.hello_html'), :html_safe? end def test_translate_escapes_interpolations_in_translations_with_a_html_suffix diff --git a/actionview/test/template/url_helper_test.rb b/actionview/test/template/url_helper_test.rb index a087c5c0cd..08cb5dfea7 100644 --- a/actionview/test/template/url_helper_test.rb +++ b/actionview/test/template/url_helper_test.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "abstract_unit" class UrlHelperTest < ActiveSupport::TestCase @@ -506,16 +508,16 @@ class UrlHelperTest < ActiveSupport::TestCase def test_current_page_considering_params @request = request_for_url("/?order=desc&page=1") - assert !current_page?(url_hash, check_parameters: true) - assert !current_page?(url_hash.merge(check_parameters: true)) - assert !current_page?(ActionController::Parameters.new(url_hash.merge(check_parameters: true)).permit!) - assert !current_page?("http://www.example.com/", check_parameters: true) + assert_not current_page?(url_hash, check_parameters: true) + assert_not current_page?(url_hash.merge(check_parameters: true)) + assert_not current_page?(ActionController::Parameters.new(url_hash.merge(check_parameters: true)).permit!) + assert_not 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) + assert_not current_page?(:back, check_parameters: false) end def test_current_page_with_params_that_match @@ -560,7 +562,7 @@ class UrlHelperTest < ActiveSupport::TestCase def test_current_page_with_not_get_verb @request = request_for_url("/events", method: :post) - assert !current_page?("/events") + assert_not current_page?("/events") end def test_link_unless_current @@ -661,7 +663,7 @@ class UrlHelperTest < ActiveSupport::TestCase end def test_mail_to_returns_html_safe_string - assert mail_to("david@loudthinking.com").html_safe? + assert_predicate mail_to("david@loudthinking.com"), :html_safe? end def test_mail_to_with_block diff --git a/actionview/test/tmp/.gitkeep b/actionview/test/tmp/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 --- a/actionview/test/tmp/.gitkeep +++ /dev/null diff --git a/actionview/test/ujs/.gitignore b/actionview/test/ujs/.gitignore deleted file mode 100644 index 31dbbff57c..0000000000 --- a/actionview/test/ujs/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/log diff --git a/actionview/test/ujs/config.ru b/actionview/test/ujs/config.ru index 213a41127a..7cd3a16acb 100644 --- a/actionview/test/ujs/config.ru +++ b/actionview/test/ujs/config.ru @@ -1,3 +1,5 @@ +# frozen_string_literal: true + $LOAD_PATH.unshift __dir__ require "server" diff --git a/actionview/test/ujs/public/test/call-ajax.js b/actionview/test/ujs/public/test/call-ajax.js new file mode 100644 index 0000000000..4d0bfb0806 --- /dev/null +++ b/actionview/test/ujs/public/test/call-ajax.js @@ -0,0 +1,26 @@ +(function() { + +module('call-ajax', { + setup: function() { + $('#qunit-fixture') + .append($('<a />', { href: '#' })) + } +}) + +asyncTest('call ajax without "ajax:beforeSend"', 1, function() { + var link = $('#qunit-fixture a') + link.bindNative('click', function() { + Rails.ajax({ + type: 'get', + url: '/', + success: function() { + ok(true, 'calling request in ajax:success') + } + }) + }) + + link.triggerNative('click') + setTimeout(function() { start() }, 50) +}) + +})() diff --git a/actionview/test/ujs/public/test/call-remote-callbacks.js b/actionview/test/ujs/public/test/call-remote-callbacks.js index 707e21541d..9c0c8cfb4b 100644 --- a/actionview/test/ujs/public/test/call-remote-callbacks.js +++ b/actionview/test/ujs/public/test/call-remote-callbacks.js @@ -12,34 +12,20 @@ module('call-remote-callbacks', { $(document).undelegate('form[data-remote]', 'ajax:send') $(document).undelegate('form[data-remote]', 'ajax:complete') $(document).undelegate('form[data-remote]', 'ajax:success') - $(document).unbind('ajaxStop') $(document).unbind('iframe:loading') } }) -function start_after_submit(form) { - form.bindNative('ajax:complete', function() { - ok(true, 'ajax:complete') - start() - }) -} - function submit(fn) { var form = $('form') - start_after_submit(form) if (fn) fn(form) form.triggerNative('submit') -} -function submit_with_button(submit_button) { - var form = $('form') - start_after_submit(form) - - submit_button.triggerNative('click') + setTimeout(function() { start() }, 13) } -asyncTest('modifying form fields with "ajax:before" sends modified data in request', 4, function() { +asyncTest('modifying form fields with "ajax:before" sends modified data in request', 3, function() { $('form[data-remote]') .append($('<input type="text" name="user_name" value="john">')) .append($('<input type="text" name="removed_user_name" value="john">')) @@ -61,7 +47,7 @@ asyncTest('modifying form fields with "ajax:before" sends modified data in reque }) }) -asyncTest('modifying data("type") with "ajax:before" requests new dataType in request', 2, function() { +asyncTest('modifying data("type") with "ajax:before" requests new dataType in request', 1, function() { $('form[data-remote]').data('type', 'html') .bindNative('ajax:before', function() { this.setAttribute('data-type', 'xml') @@ -74,7 +60,7 @@ asyncTest('modifying data("type") with "ajax:before" requests new dataType in re }) }) -asyncTest('setting data("with-credentials",true) with "ajax:before" uses new setting in request', 2, function() { +asyncTest('setting data("with-credentials",true) with "ajax:before" uses new setting in request', 1, function() { $('form[data-remote]').data('with-credentials', false) .bindNative('ajax:before', function() { this.setAttribute('data-with-credentials', true) @@ -89,21 +75,18 @@ asyncTest('setting data("with-credentials",true) with "ajax:before" uses new set asyncTest('stopping the "ajax:beforeSend" event aborts the request', 1, function() { submit(function(form) { - form.bindNative('ajax:beforeSend', function() { + form.bindNative('ajax:beforeSend', function(e) { ok(true, 'aborting request in ajax:beforeSend') - return false + e.preventDefault() }) form.unbind('ajax:send').bindNative('ajax:send', function() { ok(false, 'ajax:send should not run') }) - form.unbind('ajax:complete').bindNative('ajax:complete', function() { - ok(false, 'ajax:complete should not run') - }) - form.bindNative('ajax:error', function(e, xhr, status, error) { + form.bindNative('ajax:error', function(e, response, status, xhr) { ok(false, 'ajax:error should not run') }) - $(document).bindNative('ajaxStop', function() { - start() + form.bindNative('ajax:complete', function() { + ok(false, 'ajax:complete should not run') }) }) }) @@ -165,8 +148,8 @@ function skipIt() { .bind('iframe:loading', function() { ok(false, 'form should not get submitted') }) - .bindNative('ajax:aborted:file', function() { - return false + .bindNative('ajax:aborted:file', function(e) { + e.preventDefault() }) .triggerNative('submit') @@ -179,25 +162,22 @@ function skipIt() { } asyncTest('"ajax:beforeSend" can be observed and stopped with event delegation', 1, function() { - $(document).delegate('form[data-remote]', 'ajax:beforeSend', function() { + $(document).delegate('form[data-remote]', 'ajax:beforeSend', function(e) { ok(true, 'ajax:beforeSend observed with event delegation') - return false + e.preventDefault() }) submit(function(form) { form.unbind('ajax:send').bindNative('ajax:send', function() { ok(false, 'ajax:send should not run') }) - form.unbind('ajax:complete').bindNative('ajax:complete', function() { + form.bindNative('ajax:complete', function() { ok(false, 'ajax:complete should not run') }) - $(document).bindNative('ajaxStop', function() { - start() - }) }) }) -asyncTest('"ajax:beforeSend", "ajax:send", "ajax:success" and "ajax:complete" are triggered', 9, function() { +asyncTest('"ajax:beforeSend", "ajax:send", "ajax:success" and "ajax:complete" are triggered', 8, function() { submit(function(form) { form.bindNative('ajax:beforeSend', function(e, xhr, settings) { ok(xhr.setRequestHeader, 'first argument to "ajax:beforeSend" should be an XHR object') @@ -218,25 +198,25 @@ asyncTest('"ajax:beforeSend", "ajax:send", "ajax:success" and "ajax:complete" ar }) }) -if(window.phantom !== undefined) { - asyncTest('"ajax:beforeSend", "ajax:send", "ajax:error" and "ajax:complete" are triggered on error', 7, function() { - submit(function(form) { - form.attr('action', '/error') - form.bindNative('ajax:beforeSend', function(arg) { ok(true, 'ajax:beforeSend') }) - form.bindNative('ajax:send', function(arg) { ok(true, 'ajax:send') }) - form.bindNative('ajax:error', function(e, xhr, status, error) { - ok(xhr.getResponseHeader, 'first argument to "ajax:error" should be an XHR object') - equal(status, 'error', 'second argument to ajax:error should be a status string') - // Firefox 8 returns "Forbidden " with trailing space - equal($.trim(error), 'Forbidden', 'third argument to ajax:error should be an HTTP status response') - // Opera returns "0" for HTTP code - equal(xhr.status, window.opera ? 0 : 403, 'status code should be 403') - }) +asyncTest('"ajax:beforeSend", "ajax:send", "ajax:error" and "ajax:complete" are triggered on error', 8, function() { + submit(function(form) { + form.attr('action', '/error') + form.bindNative('ajax:beforeSend', function(arg) { ok(true, 'ajax:beforeSend') }) + form.bindNative('ajax:send', function(arg) { ok(true, 'ajax:send') }) + form.bindNative('ajax:error', function(e, response, status, xhr) { + equal(response, '', 'first argument to ajax:error should be an HTTP status response') + equal(status, 'Forbidden', 'second argument to ajax:error should be a status string') + ok(xhr.getResponseHeader, 'third argument to "ajax:error" should be an XHR object') + // Opera returns "0" for HTTP code + equal(xhr.status, window.opera ? 0 : 403, 'status code should be 403') + }) + form.bindNative('ajax:complete', function(e, xhr, status) { + ok(xhr.getResponseHeader, 'first argument to "ajax:complete" should be an XHR object') + equal(status, 'Forbidden', 'second argument to ajax:complete should be a status string') }) }) -} +}) -// IF THIS TEST IS FAILING, TRY INCREASING THE TIMEOUT AT THE BOTTOM TO > 100 asyncTest('binding to ajax callbacks via .delegate() triggers handlers properly', 4, function() { $(document) .delegate('form[data-remote]', 'ajax:beforeSend', function() { @@ -245,29 +225,15 @@ asyncTest('binding to ajax callbacks via .delegate() triggers handlers properly' .delegate('form[data-remote]', 'ajax:send', function() { ok(true, 'ajax:send handler is triggered') }) - .delegate('form[data-remote]', 'ajax:complete', function() { - ok(true, 'ajax:complete handler is triggered') - }) .delegate('form[data-remote]', 'ajax:success', function() { ok(true, 'ajax:success handler is triggered') }) - $('form[data-remote]').triggerNative('submit') - - setTimeout(function() { - start() - }, 63) -}) - -asyncTest('binding to ajax:send event to call jquery methods on ajax object', 2, function() { - $('form[data-remote]') - .bindNative('ajax:send', function(e, xhr) { - ok(true, 'event should fire') - equal(typeof(xhr.abort), 'function', 'event should pass jqXHR object') - xhr.abort() + .delegate('form[data-remote]', 'ajax:complete', function() { + ok(true, 'ajax:complete handler is triggered') }) - .triggerNative('submit') + $('form[data-remote]').triggerNative('submit') - setTimeout(function() { start() }, 35) + setTimeout(function() { start() }, 13) }) })() diff --git a/actionview/test/ujs/public/test/call-remote.js b/actionview/test/ujs/public/test/call-remote.js index 5932195363..778dc1b09a 100644 --- a/actionview/test/ujs/public/test/call-remote.js +++ b/actionview/test/ujs/public/test/call-remote.js @@ -128,6 +128,17 @@ asyncTest('execution of JS code does not modify current DOM', 1, function() { }) }) +asyncTest('HTML content should be plain-text', 1, function() { + buildForm({ method: 'post', 'data-type': 'html' }) + + $('form').append('<input type="text" name="content_type" value="text/html">') + $('form').append('<input type="text" name="content" value="<p>hello</p>">') + + submit(function(e, data, status, xhr) { + ok(data === '<p>hello</p>', 'returned data should be a plain-text string') + }) +}) + asyncTest('XML document should be parsed', 1, function() { buildForm({ method: 'post', 'data-type': 'html' }) @@ -199,7 +210,7 @@ asyncTest('allow empty form "action"', 1, function() { buildForm({ action: '' }) $('#qunit-fixture').find('form') - .bindNative('ajax:beforeSend', function(e, xhr, settings) { + .bindNative('ajax:beforeSend', function(evt, xhr, settings) { // Get current location (the same way jQuery does) try { currentLocation = location.href @@ -218,7 +229,7 @@ asyncTest('allow empty form "action"', 1, function() { // Prevent the request from actually getting sent to the current page and // causing an error. - return false + evt.preventDefault() }) .triggerNative('submit') @@ -246,7 +257,7 @@ asyncTest('intelligently guesses crossDomain behavior when target URL has a diff equal(settings.crossDomain, true, 'crossDomain should be set to true') // prevent request from actually getting sent off-domain - return false + evt.preventDefault() }) .triggerNative('submit') @@ -265,7 +276,7 @@ asyncTest('intelligently guesses crossDomain behavior when target URL consists o equal(settings.crossDomain, false, 'crossDomain should be set to false') // prevent request from actually getting sent off-domain - return false + evt.preventDefault() }) .triggerNative('submit') diff --git a/actionview/test/ujs/public/test/data-confirm.js b/actionview/test/ujs/public/test/data-confirm.js index 229b9e1466..1bd57b69ad 100644 --- a/actionview/test/ujs/public/test/data-confirm.js +++ b/actionview/test/ujs/public/test/data-confirm.js @@ -173,9 +173,9 @@ asyncTest('binding to confirm event of a link and returning false', 1, function( } $('a[data-confirm]') - .bindNative('confirm', function() { + .bindNative('confirm', function(e) { App.assertCallbackInvoked('confirm') - return false + e.preventDefault() }) .bindNative('confirm:complete', function() { App.assertCallbackNotInvoked('confirm:complete') @@ -194,9 +194,9 @@ asyncTest('binding to confirm event of a button and returning false', 1, functio } $('button[data-confirm]') - .bindNative('confirm', function() { + .bindNative('confirm', function(e) { App.assertCallbackInvoked('confirm') - return false + e.preventDefault() }) .bindNative('confirm:complete', function() { App.assertCallbackNotInvoked('confirm:complete') @@ -216,9 +216,9 @@ asyncTest('binding to confirm:complete event of a link and returning false', 2, } $('a[data-confirm]') - .bindNative('confirm:complete', function() { + .bindNative('confirm:complete', function(e) { App.assertCallbackInvoked('confirm:complete') - return false + e.preventDefault() }) .bindNative('ajax:beforeSend', function() { App.assertCallbackNotInvoked('ajax:beforeSend') @@ -238,9 +238,9 @@ asyncTest('binding to confirm:complete event of a button and returning false', 2 } $('button[data-confirm]') - .bindNative('confirm:complete', function() { + .bindNative('confirm:complete', function(e) { App.assertCallbackInvoked('confirm:complete') - return false + e.preventDefault() }) .bindNative('ajax:beforeSend', function() { App.assertCallbackNotInvoked('ajax:beforeSend') @@ -300,7 +300,7 @@ asyncTest('clicking on the children of a disabled button should not trigger a co window.confirm = function(msg) { message = msg; return false } $('button[data-confirm][disabled]') - .html("<strong>Click me</strong>") + .html('<strong>Click me</strong>') .bindNative('confirm', function() { App.assertCallbackNotInvoked('confirm') }) @@ -314,3 +314,29 @@ asyncTest('clicking on the children of a disabled button should not trigger a co start() }, 50) }) + +asyncTest('clicking on a link with data-confirm attribute with custom confirm handler. Confirm yes.', 7, function() { + var message, element + // redefine confirm function so we can make sure it's not called + window.confirm = function(msg) { + ok(false, 'confirm dialog should not be called') + } + // custom auto-confirm: + Rails.confirm = function(msg, elem) { message = msg; element = elem; return true } + + $('a[data-confirm]') + .bindNative('confirm:complete', function(e, data) { + App.assertCallbackInvoked('confirm:complete') + ok(data == true, 'confirm:complete passes in confirm answer (true)') + }) + .bindNative('ajax:success', function(e, data, status, xhr) { + App.assertCallbackInvoked('ajax:success') + App.assertRequestPath(data, '/echo') + App.assertGetRequest(data) + + equal(message, 'Are you absolutely sure?') + equal(element, $('a[data-confirm]').get(0)) + start() + }) + .triggerNative('click') +}) diff --git a/actionview/test/ujs/public/test/data-disable-with.js b/actionview/test/ujs/public/test/data-disable-with.js index b29cbbc867..645ad494c3 100644 --- a/actionview/test/ujs/public/test/data-disable-with.js +++ b/actionview/test/ujs/public/test/data-disable-with.js @@ -132,7 +132,8 @@ test('form input[type=submit][data-disable-with] re-enables when `pageshow` even }) asyncTest('form[data-remote] input[type=submit][data-disable-with] is replaced in ajax callback', 2, function() { - var form = $('form:not([data-remote])').attr('data-remote', 'true'), origFormContents = form.html() + var form = $('#qunit-fixture form:not([data-remote])').attr('data-remote', 'true'), + origFormContents = form.html() form.bindNative('ajax:success', function() { form.html(origFormContents) @@ -146,7 +147,8 @@ asyncTest('form[data-remote] input[type=submit][data-disable-with] is replaced i }) asyncTest('form[data-remote] input[data-disable-with] is replaced with disabled field in ajax callback', 2, function() { - var form = $('form:not([data-remote])').attr('data-remote', 'true'), input = form.find('input[type=submit]'), + var form = $('#qunit-fixture form:not([data-remote])').attr('data-remote', 'true'), + input = form.find('input[type=submit]'), newDisabledInput = input.clone().attr('disabled', 'disabled') form.bindNative('ajax:success', function() { @@ -238,9 +240,9 @@ asyncTest('a[data-remote][data-disable-with] re-enables when `ajax:before` event App.checkEnabledState(link, 'Click me') link - .bindNative('ajax:before', function() { + .bindNative('ajax:before', function(e) { App.checkDisabledState(link, 'clicking...') - return false + e.preventDefault() }) .triggerNative('click') @@ -256,9 +258,9 @@ asyncTest('a[data-remote][data-disable-with] re-enables when `ajax:beforeSend` e App.checkEnabledState(link, 'Click me') link - .bindNative('ajax:beforeSend', function() { + .bindNative('ajax:beforeSend', function(e) { App.checkDisabledState(link, 'clicking...') - return false + e.preventDefault() }) .triggerNative('click') @@ -293,8 +295,9 @@ asyncTest('form[data-remote] input|button|textarea[data-disable-with] does not d submit = $('<input type="submit" data-disable-with="submitting ..." name="submit2" value="Submit" />').appendTo(form) form - .bindNative('ajax:beforeSend', function() { - return false + .bindNative('ajax:beforeSend', function(e) { + e.preventDefault() + e.stopPropagation() }) .triggerNative('submit') @@ -343,9 +346,9 @@ asyncTest('button[data-remote][data-disable-with] re-enables when `ajax:before` App.checkEnabledState(button, 'Click me') button - .bindNative('ajax:before', function() { + .bindNative('ajax:before', function(e) { App.checkDisabledState(button, 'clicking...') - return false + e.preventDefault() }) .triggerNative('click') @@ -361,9 +364,9 @@ asyncTest('button[data-remote][data-disable-with] re-enables when `ajax:beforeSe App.checkEnabledState(button, 'Click me') button - .bindNative('ajax:beforeSend', function() { + .bindNative('ajax:beforeSend', function(e) { App.checkDisabledState(button, 'clicking...') - return false + e.preventDefault() }) .triggerNative('click') diff --git a/actionview/test/ujs/public/test/data-disable.js b/actionview/test/ujs/public/test/data-disable.js index ccc38cf9ae..e9919764b6 100644 --- a/actionview/test/ujs/public/test/data-disable.js +++ b/actionview/test/ujs/public/test/data-disable.js @@ -91,7 +91,7 @@ asyncTest('form input[type=submit][data-disable] disables', 6, function() { }) asyncTest('form[data-remote] input[type=submit][data-disable] is replaced in ajax callback', 2, function() { - var form = $('form:not([data-remote])').attr('data-remote', 'true'), origFormContents = form.html() + var form = $('#qunit-fixture form:not([data-remote])').attr('data-remote', 'true'), origFormContents = form.html() form.bindNative('ajax:success', function() { form.html(origFormContents) @@ -105,7 +105,7 @@ asyncTest('form[data-remote] input[type=submit][data-disable] is replaced in aja }) asyncTest('form[data-remote] input[data-disable] is replaced with disabled field in ajax callback', 2, function() { - var form = $('form:not([data-remote])').attr('data-remote', 'true'), input = form.find('input[type=submit]'), + var form = $('#qunit-fixture form:not([data-remote])').attr('data-remote', 'true'), input = form.find('input[type=submit]'), newDisabledInput = input.clone().attr('disabled', 'disabled') form.bindNative('ajax:success', function() { @@ -168,9 +168,9 @@ asyncTest('a[data-remote][data-disable] re-enables when `ajax:before` event is c App.checkEnabledState(link, 'Click me') link - .bindNative('ajax:before', function() { + .bindNative('ajax:before', function(e) { App.checkDisabledState(link, 'Click me') - return false + e.preventDefault() }) .triggerNative('click') @@ -186,9 +186,9 @@ asyncTest('a[data-remote][data-disable] re-enables when `ajax:beforeSend` event App.checkEnabledState(link, 'Click me') link - .bindNative('ajax:beforeSend', function() { + .bindNative('ajax:beforeSend', function(e) { App.checkDisabledState(link, 'Click me') - return false + e.preventDefault() }) .triggerNative('click') @@ -223,8 +223,9 @@ asyncTest('form[data-remote] input|button|textarea[data-disable] does not disabl submit = $('<input type="submit" data-disable="submitting ..." name="submit2" value="Submit" />').appendTo(form) form - .bindNative('ajax:beforeSend', function() { - return false + .bindNative('ajax:beforeSend', function(e) { + e.preventDefault() + e.stopPropagation() }) .triggerNative('submit') @@ -273,9 +274,9 @@ asyncTest('button[data-remote][data-disable] re-enables when `ajax:before` event App.checkEnabledState(button, 'Click me') button - .bindNative('ajax:before', function() { + .bindNative('ajax:before', function(e) { App.checkDisabledState(button, 'Click me') - return false + e.preventDefault() }) .triggerNative('click') @@ -291,9 +292,9 @@ asyncTest('button[data-remote][data-disable] re-enables when `ajax:beforeSend` e App.checkEnabledState(button, 'Click me') button - .bindNative('ajax:beforeSend', function() { + .bindNative('ajax:beforeSend', function(e) { App.checkDisabledState(button, 'Click me') - return false + e.preventDefault() }) .triggerNative('click') diff --git a/actionview/test/ujs/public/test/data-remote.js b/actionview/test/ujs/public/test/data-remote.js index 161a92ac11..3503c2cff3 100644 --- a/actionview/test/ujs/public/test/data-remote.js +++ b/actionview/test/ujs/public/test/data-remote.js @@ -191,9 +191,10 @@ asyncTest('submitting form with data-remote attribute should include inputs in a .triggerNative('submit') }) -asyncTest('submitting form with data-remote attribute submits input with matching [form] attribute', 5, function() { +asyncTest('submitting form with data-remote attribute submits input with matching [form] attribute', 6, function() { $('#qunit-fixture') .append($('<input type="text" name="user_data" value="value1" form="my-remote-form">')) + .append($('<input type="text" name="user_email" value="from@example.com" disabled="disabled" form="my-remote-form">')) $('form[data-remote]') .bindNative('ajax:success', function(e, data, status, xhr) { @@ -201,6 +202,7 @@ asyncTest('submitting form with data-remote attribute submits input with matchin App.assertRequestPath(data, '/echo') equal(data.params.user_name, 'john', 'ajax arguments should have key user_name with right value') equal(data.params.user_data, 'value1', 'ajax arguments should have key user_data with right value') + equal(data.params.user_email, undefined, 'ajax arguments should not have disabled field') App.assertPostRequest(data) }) .bindNative('ajax:complete', function() { start() }) @@ -270,9 +272,10 @@ asyncTest('returning false in form\'s submit bindings in non-submit-bubbling bro form .append($('<input type="submit" />')) - .bindNative('submit', function() { + .bindNative('submit', function(e) { ok(true, 'binding handler is called') - return false + e.preventDefault() + e.stopPropagation() }) .bindNative('ajax:beforeSend', function() { ok(false, 'form should not be submitted') @@ -294,8 +297,8 @@ asyncTest('clicking on a link with falsy "data-remote" attribute does not fire a .bindNative('ajax:beforeSend', function() { ok(false, 'ajax should not be triggered') }) - .bindNative('click', function() { - return false + .bindNative('click', function(e) { + e.preventDefault() }) .triggerNative('click') @@ -312,8 +315,8 @@ asyncTest('ctrl-clicking on a link with falsy "data-remote" attribute does not f .bindNative('ajax:beforeSend', function() { ok(false, 'ajax should not be triggered') }) - .bindNative('click', function() { - return false + .bindNative('click', function(e) { + e.preventDefault() }) .triggerNative('click', { metaKey: true }) @@ -331,8 +334,8 @@ asyncTest('clicking on a button with falsy "data-remote" attribute', 0, function .bindNative('ajax:beforeSend', function() { ok(false, 'ajax should not be triggered') }) - .bindNative('click', function() { - return false + .bindNative('click', function(e) { + e.preventDefault() }) .triggerNative('click') @@ -345,8 +348,8 @@ asyncTest('submitting a form with falsy "data-remote" attribute', 0, function() .bindNative('ajax:beforeSend', function() { ok(false, 'ajax should not be triggered') }) - .bindNative('submit', function() { - return false + .bindNative('submit', function(e) { + e.preventDefault() }) .triggerNative('submit') @@ -411,7 +414,7 @@ asyncTest('form buttons should only be serialized when clicked', 4, function() { asyncTest('changing a select option without "data-url" attribute still fires ajax request to current location', 1, function() { var currentLocation, ajaxLocation - buildSelect({'data-url': ''}); + buildSelect({'data-url': ''}) $('select[data-remote]') .bindNative('ajax:beforeSend', function(e, xhr, settings) { @@ -427,7 +430,7 @@ asyncTest('changing a select option without "data-url" attribute still fires aja ajaxLocation = settings.url.replace(settings.data, '').replace(/&$/, '').replace(/\?$/, '') equal(ajaxLocation, currentLocation, 'URL should be current page by default') - return false + e.preventDefault() }) .val('optionValue2') .triggerNative('change') diff --git a/actionview/test/ujs/public/test/override.js b/actionview/test/ujs/public/test/override.js index 299c7018cc..d73276ee4f 100644 --- a/actionview/test/ujs/public/test/override.js +++ b/actionview/test/ujs/public/test/override.js @@ -25,7 +25,7 @@ asyncTest('the getter for an element\'s href is overridable', 1, function() { $('#qunit-fixture a') .bindNative('ajax:beforeSend', function(e, xhr, options) { equal('/data/href', options.url) - return false + e.preventDefault() }) .triggerNative('click') start() @@ -35,7 +35,7 @@ asyncTest('the getter for an element\'s href works normally if not overridden', $('#qunit-fixture a') .bindNative('ajax:beforeSend', function(e, xhr, options) { equal(location.protocol + '//' + location.host + '/real/href', options.url) - return false + e.preventDefault() }) .triggerNative('click') start() diff --git a/actionview/test/ujs/public/test/settings.js b/actionview/test/ujs/public/test/settings.js index 299c71bb00..b1ce3b8c64 100644 --- a/actionview/test/ujs/public/test/settings.js +++ b/actionview/test/ujs/public/test/settings.js @@ -103,14 +103,16 @@ $.fn.extend({ bindNative: function(event, handler) { if (!handler) return this - this.bind(event, function(e) { + var el = this[0] + el.addEventListener(event, function(e) { var args = [] - if (e.originalEvent.detail) { - args = e.originalEvent.detail.slice() + if (e.detail) { + args = e.detail.slice() } args.unshift(e) - return handler.apply(this, args) - }) + return handler.apply(el, args) + }, false) + return this } }) diff --git a/actionview/test/ujs/public/vendor/qunit.js b/actionview/test/ujs/public/vendor/qunit.js index 0e279fde17..50a9e6455d 100644 --- a/actionview/test/ujs/public/vendor/qunit.js +++ b/actionview/test/ujs/public/vendor/qunit.js @@ -42,7 +42,7 @@ var QUnit, * with IE 7 (and prior) where Error.prototype.toString is * not properly implemented * - * Based on http://es5.github.com/#x15.11.4.4 + * Based on https://es5.github.io/#x15.11.4.4 * * @param {String|Error} error * @return {String} error message diff --git a/actionview/test/ujs/server.rb b/actionview/test/ujs/server.rb index 7deb208af0..48e9bcb65f 100644 --- a/actionview/test/ujs/server.rb +++ b/actionview/test/ujs/server.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "rack" require "rails" require "action_controller/railtie" @@ -21,18 +23,30 @@ module UJS config.public_file_server.enabled = true config.logger = Logger.new(STDOUT) config.log_level = :error + + config.content_security_policy do |policy| + policy.default_src :self, :https + policy.font_src :self, :https, :data + policy.img_src :self, :https, :data + policy.object_src :none + policy.script_src :self, :https + policy.style_src :self, :https + end + + config.content_security_policy_nonce_generator = ->(req) { SecureRandom.base64(16) } end end module TestsHelper def test_to(*names) - names = ["/vendor/qunit.js", "settings"] + names - names.map { |name| script_tag name }.join("\n").html_safe - end + names = names.map { |name| "/test/#{name}.js" } + names = %w[/vendor/qunit.js /test/settings.js] + names - def script_tag(src) - src = "/test/#{src}.js" unless src.index("/") - %(<script src="#{src}" type="text/javascript"></script>).html_safe + capture do + names.each do |name| + concat(javascript_include_tag(name)) + end + end end end @@ -54,7 +68,7 @@ class TestsController < ActionController::Base elsif params[:iframe] payload = JSON.generate(data).gsub("<", "<").gsub(">", ">") html = <<-HTML - <script> + <script nonce="#{request.content_security_policy_nonce}"> if (window.top && window.top !== window) window.top.jQuery.event.trigger('iframe:loaded', #{payload}) </script> diff --git a/actionview/test/ujs/views/layouts/application.html.erb b/actionview/test/ujs/views/layouts/application.html.erb index c787e77b84..8f6f6fc17f 100644 --- a/actionview/test/ujs/views/layouts/application.html.erb +++ b/actionview/test/ujs/views/layouts/application.html.erb @@ -2,9 +2,10 @@ <html id="html"> <head> <title><%= @title %></title> + <%= csp_meta_tag %> <link href="/vendor/qunit.css" media="screen" rel="stylesheet" type="text/css" media="screen, projection" /> <script src="/vendor/jquery-2.2.0.js" type="text/javascript"></script> - <script> + <%= javascript_tag nonce: true do %> // This is for test in override.js. // Must go before rails-ujs. document.addEventListener('rails:attachBindings', function() { @@ -15,8 +16,8 @@ e.preventDefault(); }); }); - </script> - <%= script_tag "/rails-ujs.js" %> + <% end %> + <%= javascript_include_tag "/rails-ujs.js" %> </head> <body id="body"> diff --git a/actionview/test/ujs/views/tests/index.html.erb b/actionview/test/ujs/views/tests/index.html.erb index 8de6cd0695..6b16535216 100644 --- a/actionview/test/ujs/views/tests/index.html.erb +++ b/actionview/test/ujs/views/tests/index.html.erb @@ -1,6 +1,6 @@ <% @title = "rails-ujs test" %> -<%= test_to 'data-confirm', 'data-remote', 'data-disable', 'data-disable-with', 'call-remote', 'call-remote-callbacks', 'data-method', 'override', 'csrf-refresh', 'csrf-token' %> +<%= test_to 'data-confirm', 'data-remote', 'data-disable', 'data-disable-with', 'call-remote', 'call-remote-callbacks', 'data-method', 'override', 'csrf-refresh', 'csrf-token', 'call-ajax' %> <h1 id="qunit-header"><%= @title %></h1> <h2 id="qunit-banner"></h2> |