deep_merge 1.0.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG +16 -0
- data/LICENSE +21 -0
- data/README.md +23 -1
- data/lib/deep_merge/core.rb +63 -45
- data/test/test_deep_merge.rb +18 -0
- metadata +20 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5334ff55416ba9f5edd6e9dca8152561b6e360ac
|
4
|
+
data.tar.gz: 9fa6638a3ffe2ae4733cc861259aced469018b21
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2f43b30b9fbfed2f10bdde1cfa5b48b3522de796ac13dbdf06632fb89d73fe6e6dbd505c351f9426fe284196cd314e34ace28db15d7d0c115f6181a214d835ee
|
7
|
+
data.tar.gz: 93ba0c97793fa2dbe457b0adae4823d94a1c065cb300de7e01f583154e5a937737d6d224d73823f66b9070c710904a0579a4e5cb844e026766136b9fbe4adcf7
|
data/CHANGELOG
CHANGED
@@ -1,4 +1,20 @@
|
|
1
|
+
2016-08-01 Jason Frey <fryguy9@gmail.com>
|
2
|
+
* Ship version 1.1.0
|
3
|
+
|
4
|
+
* Add testing for newer Ruby 2.2, 2.3, head, and jruby-head.
|
5
|
+
|
6
|
+
2016-06-14 Michael Sievers <michael_sievers@web.de>
|
7
|
+
* Add extend_existing_arrays option
|
8
|
+
|
9
|
+
2016-06-07 Jason Frey <fryguy9@gmail.com>
|
10
|
+
* Add overwrite_arrays option
|
11
|
+
|
12
|
+
2016-04-08 Dan Deleo <dan@kallistec.com>
|
13
|
+
* Remove support for old Ruby 1.8 and 1.9
|
14
|
+
|
1
15
|
2014-01-21 Dan DeLeo <dan@kallistec.com>
|
16
|
+
* Ship version 1.0.1
|
17
|
+
|
2
18
|
* Update knockout behavior to better handle nil (b7de40b5)
|
3
19
|
|
4
20
|
2011-08-15 Dan DeLeo <dan@kallistec.com>
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2008-2016 Steve Midgley, Daniel DeLeo
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
CHANGED
@@ -29,12 +29,16 @@ Options are specified in the last parameter passed, which should be in hash form
|
|
29
29
|
Set to true to skip any unmergeable elements from source
|
30
30
|
:knockout_prefix DEFAULT: nil
|
31
31
|
Set to string value to signify prefix which deletes elements from existing element
|
32
|
+
:overwrite_arrays DEFAULT: false
|
33
|
+
Set to true if you want to avoid merging arrays
|
32
34
|
:sort_merged_arrays DEFAULT: false
|
33
35
|
Set to true to sort all arrays that are merged together
|
34
36
|
:unpack_arrays DEFAULT: nil
|
35
37
|
Set to string value to run "Array::join" then "String::split" against all arrays
|
36
38
|
:merge_hash_arrays DEFAULT: false
|
37
39
|
Set to true to merge hashes within arrays
|
40
|
+
:extend_existing_arrays DEFAULT: false
|
41
|
+
Set to true to extend existing arrays, instead of overwriting them
|
38
42
|
:merge_debug DEFAULT: false
|
39
43
|
Set to true to get console output of merge process for debugging
|
40
44
|
|
@@ -57,6 +61,15 @@ Additionally, if the knockout_prefix is passed alone as a string, it will cause
|
|
57
61
|
dest.ko_deep_merge!(source)
|
58
62
|
Results: {:x => ""}
|
59
63
|
|
64
|
+
**:overwrite_arrays**
|
65
|
+
|
66
|
+
The purpose of this is to provide a way to replace Arrays instead of having them merge together.
|
67
|
+
|
68
|
+
source = {:x => ['1', '2']}
|
69
|
+
dest = {:x => ['3', '4']}
|
70
|
+
dest.deep_merge!(source, {:overwrite_arrays => true})
|
71
|
+
Results: {:x => ['1', '2']}
|
72
|
+
|
60
73
|
**:unpack_arrays**
|
61
74
|
|
62
75
|
The purpose of this is to permit compound elements to be passed in as strings and to be converted into discrete array elements
|
@@ -77,6 +90,15 @@ merge hashes within arrays
|
|
77
90
|
dest.deep_merge!(source, {:merge_hash_arrays => true})
|
78
91
|
Results: {:x => [{:y => 1, :z => 2}]}
|
79
92
|
|
93
|
+
**:extend_existing_arrays**
|
94
|
+
|
95
|
+
Push src elements to existing arrays, instead of overwriting them.
|
96
|
+
|
97
|
+
source = { "property" => "4" }
|
98
|
+
dest = { "property" => ["1", "2", "3"] }
|
99
|
+
dest.deep_merge!(source, {:extend_existing_arrays => true})
|
100
|
+
Results: {"property" => ["1", "2", "3", "4"]}
|
101
|
+
|
80
102
|
There are many tests for this library - and you can learn more about the features and usages of deep_merge! by just browsing the test examples.
|
81
103
|
|
82
104
|
Using deep_merge in Rails
|
@@ -110,4 +132,4 @@ Availablility
|
|
110
132
|
|
111
133
|
`deep_merge` was written by Steve Midgley, and is now maintained by Daniel DeLeo. The official home of `deep_merge` on the internet is now https://github.com/danielsdeleo/deep_merge
|
112
134
|
|
113
|
-
Copyright (c) 2008 Steve Midgley, released under the MIT license
|
135
|
+
Copyright (c) 2008-2016 Steve Midgley, released under the MIT license
|
data/lib/deep_merge/core.rb
CHANGED
@@ -26,6 +26,8 @@ module DeepMerge
|
|
26
26
|
# Set to true to skip any unmergeable elements from source
|
27
27
|
# :knockout_prefix DEFAULT: nil
|
28
28
|
# Set to string value to signify prefix which deletes elements from existing element
|
29
|
+
# :overwrite_arrays DEFAULT: false
|
30
|
+
# Set to true if you want to avoid merging arrays
|
29
31
|
# :sort_merged_arrays DEFAULT: false
|
30
32
|
# Set to true to sort all arrays that are merged together
|
31
33
|
# :unpack_arrays DEFAULT: nil
|
@@ -74,10 +76,15 @@ module DeepMerge
|
|
74
76
|
raise InvalidParameter, "overwrite_unmergeable must be true if knockout_prefix is specified in deep_merge!" if knockout_prefix && !overwrite_unmergeable
|
75
77
|
# if present: we will split and join arrays on this char before merging
|
76
78
|
array_split_char = options[:unpack_arrays] || false
|
79
|
+
# request that we avoid merging arrays
|
80
|
+
overwrite_arrays = options[:overwrite_arrays] || false
|
77
81
|
# request that we sort together any arrays when they are merged
|
78
82
|
sort_merged_arrays = options[:sort_merged_arrays] || false
|
79
83
|
# request that arrays of hashes are merged together
|
80
84
|
merge_hash_arrays = options[:merge_hash_arrays] || false
|
85
|
+
# request to extend existing arrays, instead of overwriting them
|
86
|
+
extend_existing_arrays = options[:extend_existing_arrays] || false
|
87
|
+
|
81
88
|
di = options[:debug_indent] || ''
|
82
89
|
# do nothing if source is nil
|
83
90
|
return dest if source.nil?
|
@@ -105,6 +112,8 @@ module DeepMerge
|
|
105
112
|
end
|
106
113
|
dest[src_key] = deep_merge!(src_value, src_dup, options.merge(:debug_indent => di + ' '))
|
107
114
|
end
|
115
|
+
elsif dest.kind_of?(Array) && extend_existing_arrays
|
116
|
+
dest.push(source)
|
108
117
|
else # dest isn't a hash, so we overwrite it completely (if permitted)
|
109
118
|
if overwrite_unmergeable
|
110
119
|
puts "#{di} overwriting dest: #{src_key.inspect} => #{src_value.inspect} -over-> #{dest.inspect}" if merge_debug
|
@@ -114,58 +123,67 @@ module DeepMerge
|
|
114
123
|
end
|
115
124
|
elsif source.kind_of?(Array)
|
116
125
|
puts "#{di}Arrays: #{source.inspect} :: #{dest.inspect}" if merge_debug
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
if
|
122
|
-
|
126
|
+
if overwrite_arrays
|
127
|
+
puts "#{di} overwrite arrays" if merge_debug
|
128
|
+
dest = source
|
129
|
+
else
|
130
|
+
# if we are instructed, join/split any source arrays before processing
|
131
|
+
if array_split_char
|
132
|
+
puts "#{di} split/join on source: #{source.inspect}" if merge_debug
|
133
|
+
source = source.join(array_split_char).split(array_split_char)
|
134
|
+
if dest.kind_of?(Array)
|
135
|
+
dest = dest.join(array_split_char).split(array_split_char)
|
136
|
+
end
|
123
137
|
end
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
138
|
+
# if there's a naked knockout_prefix in source, that means we are to truncate dest
|
139
|
+
if knockout_prefix && source.index(knockout_prefix)
|
140
|
+
dest = clear_or_nil(dest); source.delete(knockout_prefix)
|
141
|
+
end
|
142
|
+
if dest.kind_of?(Array)
|
143
|
+
if knockout_prefix
|
144
|
+
print "#{di} knocking out: " if merge_debug
|
145
|
+
# remove knockout prefix items from both source and dest
|
146
|
+
source.delete_if do |ko_item|
|
147
|
+
retval = false
|
148
|
+
item = ko_item.respond_to?(:gsub) ? ko_item.gsub(%r{^#{knockout_prefix}}, "") : ko_item
|
149
|
+
if item != ko_item
|
150
|
+
print "#{ko_item} - " if merge_debug
|
151
|
+
dest.delete(item)
|
152
|
+
dest.delete(ko_item)
|
153
|
+
retval = true
|
154
|
+
end
|
155
|
+
retval
|
141
156
|
end
|
142
|
-
|
157
|
+
puts if merge_debug
|
143
158
|
end
|
144
|
-
puts if merge_debug
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
159
|
+
puts "#{di} merging arrays: #{source.inspect} :: #{dest.inspect}" if merge_debug
|
160
|
+
source_all_hashes = source.all? { |i| i.kind_of?(Hash) }
|
161
|
+
dest_all_hashes = dest.all? { |i| i.kind_of?(Hash) }
|
162
|
+
if merge_hash_arrays && source_all_hashes && dest_all_hashes
|
163
|
+
# merge hashes in lists
|
164
|
+
list = []
|
165
|
+
dest.each_index do |i|
|
166
|
+
list[i] = deep_merge!(source[i] || {}, dest[i],
|
167
|
+
options.merge(:debug_indent => di + ' '))
|
168
|
+
end
|
169
|
+
list += source[dest.count..-1] if source.count > dest.count
|
170
|
+
dest = list
|
171
|
+
else
|
172
|
+
dest = dest | source
|
155
173
|
end
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
dest = dest
|
174
|
+
dest.sort! if sort_merged_arrays
|
175
|
+
elsif overwrite_unmergeable
|
176
|
+
puts "#{di} overwriting dest: #{source.inspect} -over-> #{dest.inspect}" if merge_debug
|
177
|
+
dest = overwrite_unmergeables(source, dest, options)
|
160
178
|
end
|
161
|
-
dest.sort! if sort_merged_arrays
|
162
|
-
elsif overwrite_unmergeable
|
163
|
-
puts "#{di} overwriting dest: #{source.inspect} -over-> #{dest.inspect}" if merge_debug
|
164
|
-
dest = overwrite_unmergeables(source, dest, options)
|
165
179
|
end
|
166
180
|
else # src_hash is not an array or hash, so we'll have to overwrite dest
|
167
|
-
|
168
|
-
|
181
|
+
if dest.kind_of?(Array) && extend_existing_arrays
|
182
|
+
dest.push(source)
|
183
|
+
else
|
184
|
+
puts "#{di}Others: #{source.inspect} :: #{dest.inspect}" if merge_debug
|
185
|
+
dest = overwrite_unmergeables(source, dest, options)
|
186
|
+
end
|
169
187
|
end
|
170
188
|
puts "#{di}Returning #{dest.inspect}" if merge_debug
|
171
189
|
dest
|
data/test/test_deep_merge.rb
CHANGED
@@ -87,6 +87,12 @@ class TestDeepMerge < Test::Unit::TestCase
|
|
87
87
|
DeepMerge::deep_merge!(hash_src, hash_dst)
|
88
88
|
assert_equal(["2","4","1","3"], hash_dst['property'])
|
89
89
|
|
90
|
+
# hashes holding array (overwrite)
|
91
|
+
hash_src = {"property" => ["1","3"]}
|
92
|
+
hash_dst = {"property" => ["2","4"]}
|
93
|
+
DeepMerge::deep_merge!(hash_src, hash_dst, {:overwrite_arrays => true})
|
94
|
+
assert_equal(["1","3"], hash_dst['property'])
|
95
|
+
|
90
96
|
# hashes holding array (sorted)
|
91
97
|
hash_src = {"property" => ["1","3"]}
|
92
98
|
hash_dst = {"property" => ["2","4"]}
|
@@ -213,6 +219,18 @@ class TestDeepMerge < Test::Unit::TestCase
|
|
213
219
|
DeepMerge::deep_merge!(hash_src, hash_dst)
|
214
220
|
assert_equal({"property" => {"bedroom_count" => {"king_bed" => [nil, 3], "queen_bed" => [4, nil, 1]}, "bathroom_count" => [nil, "2", "1"]}}, hash_dst)
|
215
221
|
|
222
|
+
# if extend_existig_arrays == true && destination.kind_of?(Array) && source element is neither array nor hash, push source to destionation
|
223
|
+
hash_src = { "property" => "4" }
|
224
|
+
hash_dst = { "property" => ["1", "2", "3"] }
|
225
|
+
DeepMerge::deep_merge!(hash_src, hash_dst, :extend_existing_arrays => true)
|
226
|
+
assert_equal({"property" => ["1", "2", "3", "4"]}, hash_dst)
|
227
|
+
|
228
|
+
# if extend_existig_arrays == true && destination.kind_of?(Array) && source.kind_of(Hash), push source to destionation
|
229
|
+
hash_src = { "property" => {:number => "3"} }
|
230
|
+
hash_dst = { "property" => [{:number => "1"}, {:number => "2"}] }
|
231
|
+
DeepMerge::deep_merge!(hash_src, hash_dst, :extend_existing_arrays => true)
|
232
|
+
assert_equal({"property"=>[{:number=>"1"}, {:number=>"2"}, {:number=>"3"}]}, hash_dst)
|
233
|
+
|
216
234
|
# test parameter management for knockout_prefix and overwrite unmergable
|
217
235
|
assert_raise(DeepMerge::InvalidParameter) {DeepMerge::deep_merge!(hash_src, hash_dst, {:knockout_prefix => ""})}
|
218
236
|
assert_raise(DeepMerge::InvalidParameter) {DeepMerge::deep_merge!(hash_src, hash_dst, {:preserve_unmergeables => true, :knockout_prefix => ""})}
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: deep_merge
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Steve Midgley
|
@@ -24,14 +24,30 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '10.1'
|
27
|
-
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: test-unit-minitest
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: Recursively merge hashes.
|
28
42
|
email: dan@kallistec.com
|
29
43
|
executables: []
|
30
44
|
extensions: []
|
31
45
|
extra_rdoc_files:
|
46
|
+
- LICENSE
|
32
47
|
- README.md
|
33
48
|
files:
|
34
49
|
- CHANGELOG
|
50
|
+
- LICENSE
|
35
51
|
- README.md
|
36
52
|
- Rakefile
|
37
53
|
- lib/deep_merge.rb
|
@@ -39,7 +55,7 @@ files:
|
|
39
55
|
- lib/deep_merge/deep_merge_hash.rb
|
40
56
|
- lib/deep_merge/rails_compat.rb
|
41
57
|
- test/test_deep_merge.rb
|
42
|
-
homepage:
|
58
|
+
homepage: https://github.com/danielsdeleo/deep_merge
|
43
59
|
licenses:
|
44
60
|
- MIT
|
45
61
|
metadata: {}
|
@@ -59,7 +75,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
59
75
|
version: '0'
|
60
76
|
requirements: []
|
61
77
|
rubyforge_project:
|
62
|
-
rubygems_version: 2.1
|
78
|
+
rubygems_version: 2.5.1
|
63
79
|
signing_key:
|
64
80
|
specification_version: 4
|
65
81
|
summary: Merge Deeply Nested Hashes
|