hashdiff 0.3.4 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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 [![Build Status](https://secure.travis-ci.org/liufengyun/hashdiff.svg)](http://travis-ci.org/liufengyun/hashdiff) [![Gem Version](https://badge.fury.io/rb/hashdiff.svg)](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
|