deep_merge 1.0.1 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|