diff options
8 files changed, 76 insertions, 2 deletions
diff --git a/actionpack/lib/action_controller/metal/strong_parameters.rb b/actionpack/lib/action_controller/metal/strong_parameters.rb index 1190e0ed69..baf15570d5 100644 --- a/actionpack/lib/action_controller/metal/strong_parameters.rb +++ b/actionpack/lib/action_controller/metal/strong_parameters.rb @@ -667,6 +667,7 @@ module ActionController other_hash.to_h.merge(@parameters) ) end + alias_method :with_defaults, :reverse_merge # Returns current <tt>ActionController::Parameters</tt> instance with # current hash merged into +other_hash+. @@ -674,6 +675,7 @@ module ActionController @parameters.merge!(other_hash.to_h) { |key, left, right| left } self end + alias_method :with_defaults!, :reverse_merge! # This is required by ActiveModel attribute assignment, so that user can # pass +Parameters+ to a mass assignment methods in a model. It should not diff --git a/actionpack/test/controller/parameters/parameters_permit_test.rb b/actionpack/test/controller/parameters/parameters_permit_test.rb index 9f3025587e..3e067314d6 100644 --- a/actionpack/test/controller/parameters/parameters_permit_test.rb +++ b/actionpack/test/controller/parameters/parameters_permit_test.rb @@ -310,6 +310,14 @@ class ParametersPermitTest < ActiveSupport::TestCase refute_predicate merged_params[:person], :empty? end + test "#with_defaults is an alias of reverse_merge" do + default_params = ActionController::Parameters.new(id: "1234", person: {}).permit! + merged_params = @params.with_defaults(default_params) + + assert_equal "1234", merged_params[:id] + refute_predicate merged_params[:person], :empty? + end + test "not permitted is sticky beyond reverse_merge" do refute_predicate @params.reverse_merge(a: "b"), :permitted? end @@ -327,6 +335,14 @@ class ParametersPermitTest < ActiveSupport::TestCase refute_predicate @params[:person], :empty? end + test "#with_defaults! is an alias of reverse_merge!" do + default_params = ActionController::Parameters.new(id: "1234", person: {}).permit! + @params.with_defaults!(default_params) + + assert_equal "1234", @params[:id] + refute_predicate @params[:person], :empty? + end + test "modifying the parameters" do @params[:person][:hometown] = "Chicago" @params[:person][:family] = { brother: "Jonas" } diff --git a/actionview/test/template/sanitize_helper_test.rb b/actionview/test/template/sanitize_helper_test.rb index 11ed55456f..4d4ed3c35c 100644 --- a/actionview/test/template/sanitize_helper_test.rb +++ b/actionview/test/template/sanitize_helper_test.rb @@ -1,6 +1,6 @@ require "abstract_unit" -# The exhaustive tests are in test/controller/html/sanitizer_test.rb. +# The exhaustive tests are in the rails-html-sanitizer gem. # This tests that the helpers hook up correctly to the sanitizer classes. class SanitizeHelperTest < ActionView::TestCase tests ActionView::Helpers::SanitizeHelper diff --git a/activesupport/lib/active_support/core_ext/hash/reverse_merge.rb b/activesupport/lib/active_support/core_ext/hash/reverse_merge.rb index efb9d1b8a0..061c959442 100644 --- a/activesupport/lib/active_support/core_ext/hash/reverse_merge.rb +++ b/activesupport/lib/active_support/core_ext/hash/reverse_merge.rb @@ -12,6 +12,7 @@ class Hash def reverse_merge(other_hash) other_hash.merge(self) end + alias_method :with_defaults, :reverse_merge # Destructive +reverse_merge+. def reverse_merge!(other_hash) @@ -19,4 +20,5 @@ class Hash merge!(other_hash) { |key, left, right| left } end alias_method :reverse_update, :reverse_merge! + alias_method :with_defaults!, :reverse_merge! end diff --git a/activesupport/lib/active_support/hash_with_indifferent_access.rb b/activesupport/lib/active_support/hash_with_indifferent_access.rb index 1927cddf34..1e1d6d3aac 100644 --- a/activesupport/lib/active_support/hash_with_indifferent_access.rb +++ b/activesupport/lib/active_support/hash_with_indifferent_access.rb @@ -225,11 +225,13 @@ module ActiveSupport def reverse_merge(other_hash) super(self.class.new(other_hash)) end + alias_method :with_defaults, :reverse_merge # Same semantics as +reverse_merge+ but modifies the receiver in-place. def reverse_merge!(other_hash) replace(reverse_merge(other_hash)) end + alias_method :with_defaults!, :reverse_merge! # Replaces the contents of this hash with other_hash. # diff --git a/activesupport/test/core_ext/hash_ext_test.rb b/activesupport/test/core_ext/hash_ext_test.rb index 525ea08abd..cb6babfe49 100644 --- a/activesupport/test/core_ext/hash_ext_test.rb +++ b/activesupport/test/core_ext/hash_ext_test.rb @@ -535,6 +535,16 @@ class HashExtTest < ActiveSupport::TestCase assert_equal "clobber", hash[:another] end + def test_indifferent_with_defaults_aliases_reverse_merge + hash = HashWithIndifferentAccess.new key: :old_value + actual = hash.with_defaults key: :new_value + assert_equal :old_value, actual[:key] + + hash = HashWithIndifferentAccess.new key: :old_value + hash.with_defaults! key: :new_value + assert_equal :old_value, hash[:key] + end + def test_indifferent_deleting get_hash = proc { { a: "foo" }.with_indifferent_access } hash = get_hash.call @@ -848,6 +858,21 @@ class HashExtTest < ActiveSupport::TestCase assert_equal expected, merged end + def test_with_defaults_aliases_reverse_merge + defaults = { a: "x", b: "y", c: 10 }.freeze + options = { a: 1, b: 2 } + expected = { a: 1, b: 2, c: 10 } + + # Should be an alias for reverse_merge + assert_equal expected, options.with_defaults(defaults) + assert_not_equal expected, options + + # Should be an alias for reverse_merge! + merged = options.dup + assert_equal expected, merged.with_defaults!(defaults) + assert_equal expected, merged + end + def test_slice original = { a: "x", b: "y", c: 10 } expected = { a: "x", b: "y" } diff --git a/railties/lib/rails/paths.rb b/railties/lib/rails/paths.rb index af3be10a31..6bdb673215 100644 --- a/railties/lib/rails/paths.rb +++ b/railties/lib/rails/paths.rb @@ -205,7 +205,14 @@ module Rails # Returns all expanded paths but only if they exist in the filesystem. def existent - expanded.select { |f| File.exist?(f) } + expanded.select do |f| + does_exist = File.exist?(f) + + if !does_exist && File.symlink?(f) + raise "File #{f.inspect} is a symlink that does not point to a valid file" + end + does_exist + end end def existent_directories diff --git a/railties/test/paths_test.rb b/railties/test/paths_test.rb index 7b2551062a..f3db0a51d2 100644 --- a/railties/test/paths_test.rb +++ b/railties/test/paths_test.rb @@ -274,3 +274,23 @@ class PathsTest < ActiveSupport::TestCase end end end + +class PathsIntegrationTest < ActiveSupport::TestCase + test "A failed symlink is still a valid file" do + Dir.mktmpdir do |dir| + Dir.chdir(dir) do + FileUtils.mkdir_p("foo") + File.symlink("foo/doesnotexist.rb", "foo/bar.rb") + assert_equal true, File.symlink?("foo/bar.rb") + + root = Rails::Paths::Root.new("foo") + root.add "bar.rb" + + exception = assert_raises(RuntimeError) do + root["bar.rb"].existent + end + assert_match File.expand_path("foo/bar.rb"), exception.message + end + end + end +end |