hashdiff 0.3.4 → 0.4.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/.rubocop.yml +24 -0
- data/.travis.yml +6 -5
- data/Gemfile +3 -1
- data/README.md +94 -29
- data/Rakefile +9 -4
- data/changelog.md +28 -3
- data/hashdiff.gemspec +27 -12
- data/lib/hashdiff/compare_hashes.rb +56 -0
- data/lib/hashdiff/diff.rb +65 -111
- data/lib/hashdiff/lcs.rb +27 -30
- data/lib/hashdiff/lcs_compare_arrays.rb +32 -0
- data/lib/hashdiff/linear_compare_array.rb +159 -0
- data/lib/hashdiff/patch.rb +16 -12
- data/lib/hashdiff/util.rb +59 -37
- data/lib/hashdiff/version.rb +4 -2
- data/lib/hashdiff.rb +9 -0
- data/spec/hashdiff/best_diff_spec.rb +47 -37
- data/spec/hashdiff/diff_array_spec.rb +19 -19
- data/spec/hashdiff/diff_spec.rb +217 -139
- data/spec/hashdiff/lcs_spec.rb +27 -26
- data/spec/hashdiff/linear_compare_array_spec.rb +50 -0
- data/spec/hashdiff/patch_spec.rb +129 -105
- data/spec/hashdiff/util_spec.rb +60 -43
- data/spec/spec_helper.rb +2 -0
- metadata +50 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 204c04301ec7d5b755863a0ec7b9001930a569c1
|
4
|
+
data.tar.gz: c0bf2c27e34271b637da82792549104a5b0ca2cb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 68f07faf7b58132dae314317cf90e1dae5549218d93c19be33df0460659d2e74a861f458c9f6401909ce78ca1b0cb649cc843e0a804a4dad70e3c824568bfd7c
|
7
|
+
data.tar.gz: ba2ff10babe7886c263cbac1c761a38e205880dc323199746ed6845762b462a08b7664f9f1159b5765751b020dfd38ac365fcec04e350d894f97df6b519f3c71
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require: rubocop-rspec
|
2
|
+
Metrics/PerceivedComplexity:
|
3
|
+
Enabled: false
|
4
|
+
Metrics/CyclomaticComplexity:
|
5
|
+
Enabled: false
|
6
|
+
Metrics/MethodLength:
|
7
|
+
Enabled: false
|
8
|
+
Metrics/AbcSize:
|
9
|
+
Enabled: false
|
10
|
+
Metrics/LineLength:
|
11
|
+
Enabled: false
|
12
|
+
Metrics/ClassLength:
|
13
|
+
Enabled: false
|
14
|
+
Metrics/BlockLength:
|
15
|
+
Enabled: false
|
16
|
+
Metrics/ModuleLength:
|
17
|
+
Enabled: false
|
18
|
+
Style/Documentation:
|
19
|
+
Enabled: false
|
20
|
+
Style/FrozenStringLiteralComment:
|
21
|
+
Enabled: true
|
22
|
+
EnforcedStyle: always
|
23
|
+
RSpec/ExampleLength:
|
24
|
+
Enabled: false
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,14 +1,17 @@
|
|
1
|
-
#
|
1
|
+
# Hashdiff [](http://travis-ci.org/liufengyun/hashdiff) [](http://badge.fury.io/rb/hashdiff)
|
2
2
|
|
3
|
-
|
3
|
+
Hashdiff is a ruby library to compute the smallest difference between two hashes.
|
4
4
|
|
5
5
|
It also supports comparing two arrays.
|
6
6
|
|
7
|
-
|
7
|
+
Hashdiff does not monkey-patch any existing class. All features are contained inside the `Hashdiff` module.
|
8
8
|
|
9
9
|
**Docs**: [Documentation](http://rubydoc.info/gems/hashdiff)
|
10
10
|
|
11
|
-
|
11
|
+
|
12
|
+
__WARNING__: Don't use the library for comparing large arrays, say ~10K (see #49).
|
13
|
+
|
14
|
+
## Why Hashdiff?
|
12
15
|
|
13
16
|
Given two Hashes A and B, sometimes you face the question: what's the smallest modification that can be made to change A into B?
|
14
17
|
|
@@ -18,7 +21,7 @@ An algorithm that responds to this question has to do following:
|
|
18
21
|
* Compute recursively -- Arrays and Hashes may be nested arbitrarily in A or B.
|
19
22
|
* Compute the smallest change -- it should recognize similar child Hashes or child Arrays between A and B.
|
20
23
|
|
21
|
-
|
24
|
+
Hashdiff answers the question above using an opinionated approach:
|
22
25
|
|
23
26
|
* Hash can be represented as a list of (dot-syntax-path, value) pairs. For example, `{a:[{c:2}]}` can be represented as `["a[0].c", 2]`.
|
24
27
|
* The change set can be represented using the dot-syntax representation. For example, `[['-', 'b.x', 3], ['~', 'b.z', 45, 30], ['+', 'b.y', 3]]`.
|
@@ -43,7 +46,7 @@ Two simple hashes:
|
|
43
46
|
a = {a:3, b:2}
|
44
47
|
b = {}
|
45
48
|
|
46
|
-
diff =
|
49
|
+
diff = Hashdiff.diff(a, b)
|
47
50
|
diff.should == [['-', 'a', 3], ['-', 'b', 2]]
|
48
51
|
```
|
49
52
|
|
@@ -53,7 +56,7 @@ More complex hashes:
|
|
53
56
|
a = {a:{x:2, y:3, z:4}, b:{x:3, z:45}}
|
54
57
|
b = {a:{y:3}, b:{y:3, z:30}}
|
55
58
|
|
56
|
-
diff =
|
59
|
+
diff = Hashdiff.diff(a, b)
|
57
60
|
diff.should == [['-', 'a.x', 2], ['-', 'a.z', 4], ['-', 'b.x', 3], ['~', 'b.z', 45, 30], ['+', 'b.y', 3]]
|
58
61
|
```
|
59
62
|
|
@@ -63,7 +66,7 @@ Arrays in hashes:
|
|
63
66
|
a = {a:[{x:2, y:3, z:4}, {x:11, y:22, z:33}], b:{x:3, z:45}}
|
64
67
|
b = {a:[{y:3}, {x:11, z:33}], b:{y:22}}
|
65
68
|
|
66
|
-
diff =
|
69
|
+
diff = Hashdiff.best_diff(a, b)
|
67
70
|
diff.should == [['-', 'a[0].x', 2], ['-', 'a[0].z', 4], ['-', 'a[1].y', 22], ['-', 'b.x', 3], ['-', 'b.z', 45], ['+', 'b.y', 22]]
|
68
71
|
```
|
69
72
|
|
@@ -72,27 +75,28 @@ diff.should == [['-', 'a[0].x', 2], ['-', 'a[0].z', 4], ['-', 'a[1].y', 22], ['-
|
|
72
75
|
patch example:
|
73
76
|
|
74
77
|
```ruby
|
75
|
-
a = {a
|
76
|
-
b = {a
|
78
|
+
a = {'a' => 3}
|
79
|
+
b = {'a' => {'a1' => 1, 'a2' => 2}}
|
77
80
|
|
78
|
-
diff =
|
79
|
-
|
81
|
+
diff = Hashdiff.diff(a, b)
|
82
|
+
Hashdiff.patch!(a, diff).should == b
|
80
83
|
```
|
81
84
|
|
82
85
|
unpatch example:
|
83
86
|
|
84
87
|
```ruby
|
85
|
-
a = [{a
|
86
|
-
b = [1, {a
|
88
|
+
a = [{'a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5}, {'x' => 5, 'y' => 6, 'z' => 3}, 1]
|
89
|
+
b = [1, {'a' => 1, 'b' => 2, 'c' => 3, 'e' => 5}]
|
87
90
|
|
88
|
-
diff =
|
89
|
-
|
91
|
+
diff = Hashdiff.diff(a, b) # diff two array is OK
|
92
|
+
Hashdiff.unpatch!(b, diff).should == a
|
90
93
|
```
|
91
94
|
|
92
95
|
### Options
|
93
96
|
|
94
|
-
There are
|
95
|
-
`:strict`, `:numeric_tolerance`, `:strip
|
97
|
+
There are eight options available: `:delimiter`, `:similarity`,
|
98
|
+
`:strict`, `:numeric_tolerance`, `:strip`, `:case_insensitive`, `:array_path`
|
99
|
+
and `:use_lcs`
|
96
100
|
|
97
101
|
#### `:delimiter`
|
98
102
|
|
@@ -102,7 +106,7 @@ You can specify `:delimiter` to be something other than the default dot. For exa
|
|
102
106
|
a = {a:{x:2, y:3, z:4}, b:{x:3, z:45}}
|
103
107
|
b = {a:{y:3}, b:{y:3, z:30}}
|
104
108
|
|
105
|
-
diff =
|
109
|
+
diff = Hashdiff.diff(a, b, :delimiter => '\t')
|
106
110
|
diff.should == [['-', 'a\tx', 2], ['-', 'a\tz', 4], ['-', 'b\tx', 3], ['~', 'b\tz', 45, 30], ['+', 'b\ty', 3]]
|
107
111
|
```
|
108
112
|
|
@@ -122,7 +126,7 @@ The :numeric_tolerance option allows for a small numeric tolerance.
|
|
122
126
|
a = {x:5, y:3.75, z:7}
|
123
127
|
b = {x:6, y:3.76, z:7}
|
124
128
|
|
125
|
-
diff =
|
129
|
+
diff = Hashdiff.diff(a, b, :numeric_tolerance => 0.1)
|
126
130
|
diff.should == [["~", "x", 5, 6]]
|
127
131
|
```
|
128
132
|
|
@@ -134,22 +138,77 @@ The :strip option strips all strings before comparing.
|
|
134
138
|
a = {x:5, s:'foo '}
|
135
139
|
b = {x:6, s:'foo'}
|
136
140
|
|
137
|
-
diff =
|
141
|
+
diff = Hashdiff.diff(a, b, :comparison => { :numeric_tolerance => 0.1, :strip => true })
|
138
142
|
diff.should == [["~", "x", 5, 6]]
|
139
143
|
```
|
140
144
|
|
141
145
|
#### `:case_insensitive`
|
142
146
|
|
143
|
-
The :case_insensitive option makes string
|
147
|
+
The :case_insensitive option makes string comparisons ignore case.
|
144
148
|
|
145
149
|
```ruby
|
146
150
|
a = {x:5, s:'FooBar'}
|
147
151
|
b = {x:6, s:'foobar'}
|
148
152
|
|
149
|
-
diff =
|
153
|
+
diff = Hashdiff.diff(a, b, :comparison => { :numeric_tolerance => 0.1, :case_insensitive => true })
|
150
154
|
diff.should == [["~", "x", 5, 6]]
|
151
155
|
```
|
152
156
|
|
157
|
+
#### `:array_path`
|
158
|
+
|
159
|
+
The :array_path option represents the path of the diff in an array rather than
|
160
|
+
a string. This can be used to show differences in between hash key types and
|
161
|
+
is useful for `patch!` when used on hashes without string keys.
|
162
|
+
|
163
|
+
```ruby
|
164
|
+
a = {x:5}
|
165
|
+
b = {'x'=>6}
|
166
|
+
|
167
|
+
diff = Hashdiff.diff(a, b, :array_path => true)
|
168
|
+
diff.should == [['-', [:x], 5], ['+', ['x'], 6]]
|
169
|
+
```
|
170
|
+
|
171
|
+
For cases where there are arrays in paths their index will be added to the path.
|
172
|
+
```ruby
|
173
|
+
a = {x:[0,1]}
|
174
|
+
b = {x:[0,2]}
|
175
|
+
|
176
|
+
diff = Hashdiff.diff(a, b, :array_path => true)
|
177
|
+
diff.should == [["-", [:x, 1], 1], ["+", [:x, 1], 2]]
|
178
|
+
```
|
179
|
+
|
180
|
+
This shouldn't cause problems if you are comparing an array with a hash:
|
181
|
+
|
182
|
+
```ruby
|
183
|
+
a = {x:{0=>1}}
|
184
|
+
b = {x:[1]}
|
185
|
+
|
186
|
+
diff = Hashdiff.diff(a, b, :array_path => true)
|
187
|
+
diff.should == [["~", [:x], {0=>1}, [1]]]
|
188
|
+
```
|
189
|
+
|
190
|
+
#### `:use_lcs`
|
191
|
+
|
192
|
+
The :use_lcs option is used to specify whether a
|
193
|
+
[Longest common subsequence](https://en.wikipedia.org/wiki/Longest_common_subsequence_problem)
|
194
|
+
(LCS) algorithm is used to determine differences in arrays. This defaults to
|
195
|
+
`true` but can be changed to `false` for significantly faster array comparisons
|
196
|
+
(O(n) complexity rather than O(n<sup>2</sup>) for LCS).
|
197
|
+
|
198
|
+
When :use_lcs is false the results of array comparisons have a tendency to
|
199
|
+
show changes at indexes rather than additions and subtractions when :use_lcs is
|
200
|
+
true.
|
201
|
+
|
202
|
+
Note, currently the :similarity option has no effect when :use_lcs is false.
|
203
|
+
|
204
|
+
```ruby
|
205
|
+
a = {x: [0, 1, 2]}
|
206
|
+
b = {x: [0, 2, 2, 3]}
|
207
|
+
|
208
|
+
diff = Hashdiff.diff(a, b, :use_lcs => false)
|
209
|
+
diff.should == [["~", "x[1]", 1, 2], ["+", "x[3]", 3]]
|
210
|
+
```
|
211
|
+
|
153
212
|
#### Specifying a custom comparison method
|
154
213
|
|
155
214
|
It's possible to specify how the values of a key should be compared.
|
@@ -158,7 +217,7 @@ It's possible to specify how the values of a key should be compared.
|
|
158
217
|
a = {a:'car', b:'boat', c:'plane'}
|
159
218
|
b = {a:'bus', b:'truck', c:' plan'}
|
160
219
|
|
161
|
-
diff =
|
220
|
+
diff = Hashdiff.diff(a, b) do |path, obj1, obj2|
|
162
221
|
case path
|
163
222
|
when /a|b|c/
|
164
223
|
obj1.length == obj2.length
|
@@ -174,7 +233,7 @@ The yielded params of the comparison block is `|path, obj1, obj2|`, in which pat
|
|
174
233
|
a = {a:'car', b:['boat', 'plane'] }
|
175
234
|
b = {a:'bus', b:['truck', ' plan'] }
|
176
235
|
|
177
|
-
diff =
|
236
|
+
diff = Hashdiff.diff(a, b) do |path, obj1, obj2|
|
178
237
|
case path
|
179
238
|
when 'b[*]'
|
180
239
|
obj1.length == obj2.length
|
@@ -186,6 +245,8 @@ diff.should == [["~", "a", "car", "bus"], ["~", "b[1]", "plane", " plan"], ["-",
|
|
186
245
|
|
187
246
|
When a comparison block is given, it'll be given priority over other specified options. If the block returns value other than `true` or `false`, then the two values will be compared with other specified options.
|
188
247
|
|
248
|
+
When used in conjunction with the `array_path` option, the path passed in as an argument will be an array. When determining the ordering of an array a key of `"*"` will be used in place of the `key[*]` field. It is possible, if you have hashes with integer or `"*"` keys, to have problems distinguishing between arrays and hashes - although this shouldn't be an issue unless your data is very difficult to predict and/or your custom rules are very specific.
|
249
|
+
|
189
250
|
#### Sorting arrays before comparison
|
190
251
|
|
191
252
|
An order difference alone between two arrays can create too many diffs to be useful. Consider sorting them prior to diffing.
|
@@ -194,14 +255,18 @@ An order difference alone between two arrays can create too many diffs to be use
|
|
194
255
|
a = {a:'car', b:['boat', 'plane'] }
|
195
256
|
b = {a:'car', b:['plane', 'boat'] }
|
196
257
|
|
197
|
-
|
258
|
+
Hashdiff.diff(a, b) => [["+", "b[0]", "plane"], ["-", "b[2]", "plane"]]
|
198
259
|
|
199
260
|
b[:b].sort!
|
200
261
|
|
201
|
-
|
262
|
+
Hashdiff.diff(a, b) => []
|
202
263
|
```
|
203
264
|
|
204
|
-
##
|
265
|
+
## Maintainers
|
266
|
+
|
267
|
+
- Krzysztof Rybka ([@krzysiek1507](https://github.com/krzysiek1507))
|
268
|
+
- Fengyun Liu ([@liufengyun](https://github.com/liufengyun))
|
205
269
|
|
206
|
-
|
270
|
+
## License
|
207
271
|
|
272
|
+
Hashdiff is distributed under the MIT-LICENSE.
|
data/Rakefile
CHANGED
@@ -1,13 +1,18 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
$LOAD_PATH.push File.expand_path('lib', __dir__)
|
4
|
+
|
5
|
+
require 'rubocop/rake_task'
|
2
6
|
|
3
7
|
require 'bundler'
|
4
8
|
Bundler::GemHelper.install_tasks
|
5
9
|
|
6
10
|
require 'rspec/core/rake_task'
|
7
11
|
|
8
|
-
|
12
|
+
RuboCop::RakeTask.new
|
13
|
+
|
14
|
+
task default: %w[spec rubocop]
|
9
15
|
|
10
16
|
RSpec::Core::RakeTask.new(:spec) do |spec|
|
11
|
-
spec.pattern =
|
17
|
+
spec.pattern = './spec/**/*_spec.rb'
|
12
18
|
end
|
13
|
-
|
data/changelog.md
CHANGED
@@ -1,8 +1,34 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## v0.4.0 2019-05-28
|
4
|
+
|
5
|
+
* refactoring (#56 #57 #59 #61 krzysiek1507)
|
6
|
+
* fix typo in README (#64 @pboling)
|
7
|
+
* change HashDiff to Hashdiff (#65 @jfelchner)
|
8
|
+
|
9
|
+
## v0.3.9 2019-04-22
|
10
|
+
|
11
|
+
* Performance tweak (thanks @krzysiek1507: #51 #52 #53)
|
12
|
+
|
13
|
+
## v0.3.8 2018-12-30
|
14
|
+
|
15
|
+
* Add Rubocop and drops Ruby 1.9 support #47
|
16
|
+
|
17
|
+
## v0.3.7 2017-10-08
|
18
|
+
|
19
|
+
* remove 1.8.7 support from gemspec #39
|
20
|
+
|
21
|
+
## v0.3.6 2017-08-22
|
22
|
+
|
23
|
+
* add option `use_lcs` #35
|
24
|
+
|
25
|
+
## v0.3.5 2017-08-06
|
26
|
+
|
27
|
+
* add option `array_path` #34
|
28
|
+
|
3
29
|
## v0.3.4 2017-05-01
|
4
30
|
|
5
|
-
* performance improvement of
|
31
|
+
* performance improvement of `#similar?` #31
|
6
32
|
|
7
33
|
## v0.3.2 2016-12-27
|
8
34
|
|
@@ -44,7 +70,7 @@
|
|
44
70
|
## v0.0.5 2012-7-1
|
45
71
|
|
46
72
|
* fix a bug in judging whehter two objects are similiar.
|
47
|
-
* add more spec test for
|
73
|
+
* add more spec test for `.best_diff`
|
48
74
|
|
49
75
|
## v0.0.4 2012-6-24
|
50
76
|
|
@@ -57,4 +83,3 @@ For example, `diff({a:2, c:[4, 5]}, {a:2}) will generate following output:
|
|
57
83
|
instead of following:
|
58
84
|
|
59
85
|
[['-', 'c[0]', 4], ['-', 'c[1]', 5], ['-', 'c', []]]
|
60
|
-
|
data/hashdiff.gemspec
CHANGED
@@ -1,25 +1,40 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
$LOAD_PATH << File.expand_path('lib', __dir__)
|
2
4
|
require 'hashdiff/version'
|
3
5
|
|
4
6
|
Gem::Specification.new do |s|
|
5
|
-
s.name =
|
6
|
-
s.version =
|
7
|
+
s.name = 'hashdiff'
|
8
|
+
s.version = Hashdiff::VERSION
|
7
9
|
s.license = 'MIT'
|
8
|
-
s.summary =
|
9
|
-
s.description =
|
10
|
+
s.summary = ' Hashdiff is a diff lib to compute the smallest difference between two hashes. '
|
11
|
+
s.description = ' Hashdiff is a diff lib to compute the smallest difference between two hashes. '
|
10
12
|
|
11
13
|
s.files = `git ls-files`.split("\n")
|
12
14
|
s.test_files = `git ls-files -- Appraisals {spec}/*`.split("\n")
|
13
15
|
|
14
16
|
s.require_paths = ['lib']
|
15
|
-
s.required_ruby_version = Gem::Requirement.new(
|
17
|
+
s.required_ruby_version = Gem::Requirement.new('>= 2.0.0')
|
18
|
+
s.post_install_message = 'The HashDiff constant used by this gem conflicts with another gem of a similar name. As of version 1.0 the HashDiff constant will be completely removed and replaced by Hashdiff. For more information see https://github.com/liufengyun/hashdiff/issues/45.'
|
19
|
+
|
20
|
+
s.authors = ['Liu Fengyun']
|
21
|
+
s.email = ['liufengyunchina@gmail.com']
|
16
22
|
|
17
|
-
s.
|
18
|
-
s.email = ["liufengyunchina@gmail.com"]
|
23
|
+
s.homepage = 'https://github.com/liufengyun/hashdiff'
|
19
24
|
|
20
|
-
s.
|
25
|
+
s.add_development_dependency('bluecloth')
|
26
|
+
s.add_development_dependency('rspec', '~> 2.0')
|
27
|
+
s.add_development_dependency('rubocop')
|
28
|
+
s.add_development_dependency('rubocop-rspec')
|
29
|
+
s.add_development_dependency('yard')
|
21
30
|
|
22
|
-
s.
|
23
|
-
|
24
|
-
|
31
|
+
if s.respond_to?(:metadata)
|
32
|
+
s.metadata = {
|
33
|
+
'bug_tracker_uri' => 'https://github.com/liufengyun/hashdiff/issues',
|
34
|
+
'changelog_uri' => 'https://github.com/liufengyun/hashdiff/blob/master/changelog.md',
|
35
|
+
'documentation_uri' => 'https://www.rubydoc.info/gems/hashdiff',
|
36
|
+
'homepage_uri' => 'https://github.com/liufengyun/hashdiff',
|
37
|
+
'source_code_uri' => 'https://github.com/liufengyun/hashdiff'
|
38
|
+
}
|
39
|
+
end
|
25
40
|
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Hashdiff
|
4
|
+
# @private
|
5
|
+
# Used to compare hashes
|
6
|
+
class CompareHashes
|
7
|
+
class << self
|
8
|
+
def call(obj1, obj2, opts = {})
|
9
|
+
return [] if obj1.empty? && obj2.empty?
|
10
|
+
|
11
|
+
obj1_keys = obj1.keys
|
12
|
+
obj2_keys = obj2.keys
|
13
|
+
|
14
|
+
added_keys = (obj2_keys - obj1_keys).sort_by(&:to_s)
|
15
|
+
common_keys = (obj1_keys & obj2_keys).sort_by(&:to_s)
|
16
|
+
deleted_keys = (obj1_keys - obj2_keys).sort_by(&:to_s)
|
17
|
+
|
18
|
+
result = []
|
19
|
+
|
20
|
+
# add deleted properties
|
21
|
+
deleted_keys.each do |k|
|
22
|
+
change_key = Hashdiff.prefix_append_key(opts[:prefix], k, opts)
|
23
|
+
custom_result = Hashdiff.custom_compare(opts[:comparison], change_key, obj1[k], nil)
|
24
|
+
|
25
|
+
if custom_result
|
26
|
+
result.concat(custom_result)
|
27
|
+
else
|
28
|
+
result << ['-', change_key, obj1[k]]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# recursive comparison for common keys
|
33
|
+
common_keys.each do |k|
|
34
|
+
prefix = Hashdiff.prefix_append_key(opts[:prefix], k, opts)
|
35
|
+
|
36
|
+
result.concat(Hashdiff.diff(obj1[k], obj2[k], opts.merge(prefix: prefix)))
|
37
|
+
end
|
38
|
+
|
39
|
+
# added properties
|
40
|
+
added_keys.each do |k|
|
41
|
+
change_key = Hashdiff.prefix_append_key(opts[:prefix], k, opts)
|
42
|
+
|
43
|
+
custom_result = Hashdiff.custom_compare(opts[:comparison], change_key, nil, obj2[k])
|
44
|
+
|
45
|
+
if custom_result
|
46
|
+
result.concat(custom_result)
|
47
|
+
else
|
48
|
+
result << ['+', change_key, obj2[k]]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
result
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|