Fix deep_merge_hashes! handling of drops and hashes

This commit is contained in:
Parker Moore 2016-01-15 10:52:18 -08:00
parent 22931f42b8
commit 5d79c55b2c
3 changed files with 37 additions and 9 deletions

View File

@ -127,6 +127,7 @@ module Jekyll
result[key] = self[key] result[key] = self[key]
end end
end end
alias_method :to_hash, :to_h
# Inspect the drop's keys and values through a JSON representation # Inspect the drop's keys and values through a JSON representation
# of its keys and values. # of its keys and values.
@ -145,6 +146,31 @@ module Jekyll
def each_key(&block) def each_key(&block)
keys.each(&block) keys.each(&block)
end end
def merge(other, &block)
self.dup.tap do |me|
if block.nil?
me.merge!(other)
else
me.merge!(other, block)
end
end
end
def merge!(other)
other.each_key do |key|
if block_given?
self[key] = yield key, self[key], other[key]
else
if Utils.mergable?(self[key]) && Utils.mergable?(other[key])
self[key] = Utils.deep_merge_hashes(self[key], other[key])
next
end
self[key] = other[key] unless other[key].nil?
end
end
end
end end
end end
end end

View File

@ -31,14 +31,12 @@ module Jekyll
# #
# Thanks to whoever made it. # Thanks to whoever made it.
def deep_merge_hashes!(target, overwrite) def deep_merge_hashes!(target, overwrite)
overwrite.each_key do |key| target.merge!(overwrite) do |key, old_val, new_val|
if (overwrite[key].is_a?(Hash) || overwrite[key].is_a?(Drops::Drop)) && if new_val.nil?
(target[key].is_a?(Hash) || target[key].is_a?(Drops::Drop)) old_val
target[key] = Utils.deep_merge_hashes(target[key], overwrite[key]) else
next mergable?(old_val) && mergable?(new_val) ? deep_merge_hashes(old_val, new_val) : new_val
end end
target[key] = overwrite[key]
end end
if target.respond_to?(:default_proc) && overwrite.respond_to?(:default_proc) && target.default_proc.nil? if target.respond_to?(:default_proc) && overwrite.respond_to?(:default_proc) && target.default_proc.nil?
@ -48,6 +46,10 @@ module Jekyll
target target
end end
def mergable?(value)
value.is_a?(Hash) || value.is_a?(Drops::Drop)
end
# Read array from the supplied hash favouring the singular key # Read array from the supplied hash favouring the singular key
# and then the plural key, and handling any nil entries. # and then the plural key, and handling any nil entries.
# #

View File

@ -13,7 +13,7 @@ class TestUtils < JekyllUnitTest
merged = Utils.deep_merge_hashes(data, @site.site_payload) merged = Utils.deep_merge_hashes(data, @site.site_payload)
assert merged.is_a? Hash assert merged.is_a? Hash
assert merged["site"].is_a? Drops::SiteDrop assert merged["site"].is_a? Drops::SiteDrop
assert_equal data["page"], {} assert_equal data["page"], merged["page"]
end end
should "merge a hash into a drop" do should "merge a hash into a drop" do
@ -22,7 +22,7 @@ class TestUtils < JekyllUnitTest
merged = Utils.deep_merge_hashes(@site.site_payload, data) merged = Utils.deep_merge_hashes(@site.site_payload, data)
assert merged.is_a? Drops::UnifiedPayloadDrop assert merged.is_a? Drops::UnifiedPayloadDrop
assert merged["site"].is_a? Drops::SiteDrop assert merged["site"].is_a? Drops::SiteDrop
assert_equal data["page"], {} assert_equal data["page"], merged["page"]
end end
end end