hashdiff 0.3.5 → 0.3.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4ba86448df8842fe6323572feb2c89110954b775
4
- data.tar.gz: e3d610f32c07e65e06f825e107371caaaf2e5896
3
+ metadata.gz: 6af49f121e2b09e5dcdf8a649f6d48c25f63ae03
4
+ data.tar.gz: c6738c2b03d36f622ac1e0a3c228a863b691ac29
5
5
  SHA512:
6
- metadata.gz: 7e7b28d277160a603df99c83022f6b8bd7bb27ac5d467e351e5834ba955195ed493249b7a7e213dafe0cb1aa630c5de46fe11a95b5942de4ba9c1f4e66262ec3
7
- data.tar.gz: d5290cbc0b5c97038cce213e627fc20fcaf4e7405888c217c78b949c8fc98990ab6d3ae18b0f91d2909c069ffccc20a9d0d45aa572419252aa6eae960df6491d
6
+ metadata.gz: 8dfda8cd1b17af2c64ea4626570e7d858b76a5ed918df4b6a5703c63e0ae43c371cbe5e3573b4382aa1491915f48335e62d3b4300f3c678660f329f39e8d9b62
7
+ data.tar.gz: 71ab91ba878e19c436dbad30cc08c85645aadf6aabeed889dc8e3661102d2ddf5a98b12c7a6a8b1007a5115f64e082829f88d99abe11ad87f2a69cf504f28885
@@ -4,7 +4,10 @@ rvm:
4
4
  - 1.9.3
5
5
  - 2.0.0
6
6
  - 2.1.10
7
- - 2.2.6
8
- - 2.3.3
9
- - 2.4.0
7
+ - 2.2.8
8
+ - 2.3.4
9
+ - 2.4.2
10
10
  script: "bundle exec rake spec"
11
+
12
+ before_install:
13
+ - gem install bundler
data/Gemfile CHANGED
@@ -3,5 +3,4 @@ gemspec
3
3
 
4
4
  group :test do
5
5
  gem 'rake', '< 11'
6
- gem 'codecov'
7
6
  end
data/README.md CHANGED
@@ -91,9 +91,9 @@ HashDiff.unpatch!(b, diff).should == a
91
91
 
92
92
  ### Options
93
93
 
94
- There are seven options available: `:delimiter`, `:similarity`,
95
- `:strict`, `:numeric_tolerance`, `:strip`, `:case_insensitive`
96
- and `:array_path`.
94
+ There are eight options available: `:delimiter`, `:similarity`,
95
+ `:strict`, `:numeric_tolerance`, `:strip`, `:case_insensitive`, `:array_path`
96
+ and `:use_lcs`
97
97
 
98
98
  #### `:delimiter`
99
99
 
@@ -184,6 +184,28 @@ diff = HashDiff.diff(a, b, :array_path => true)
184
184
  diff.should == [["~", [:a], [1], {0=>1}]]
185
185
  ```
186
186
 
187
+ #### `:use_lcs`
188
+
189
+ The :use_lcs option is used to specify whether a
190
+ [Longest common subsequence](https://en.wikipedia.org/wiki/Longest_common_subsequence_problem)
191
+ (LCS) algorithm is used to determine differences in arrays. This defaults to
192
+ `true` but can be changed to `false` for significantly faster array comparisons
193
+ (O(n) complexity rather than O(n<sup>2</sup>) for LCS).
194
+
195
+ When :use_lcs is false the results of array comparisons have a tendency to
196
+ show changes at indexes rather than additions and subtractions when :use_lcs is
197
+ true.
198
+
199
+ Note, currently the :similarity option has no effect when :use_lcs is false.
200
+
201
+ ```ruby
202
+ a = {x: [0, 1, 2]}
203
+ b = {x: [0, 2, 2, 3]}
204
+
205
+ diff = HashDiff.diff(a, b, :use_lcs => false)
206
+ diff.should == [["~", "x[1]", 1, 2], ["+", "x[3]", 3]]
207
+ ```
208
+
187
209
  #### Specifying a custom comparison method
188
210
 
189
211
  It's possible to specify how the values of a key should be compared.
@@ -1,5 +1,13 @@
1
1
  # Change Log
2
2
 
3
+ ## v0.3.7 2017-10-08
4
+
5
+ * remove 1.8.7 support from gemspec #39
6
+
7
+ ## v0.3.6 2017-08-22
8
+
9
+ * add option `use_lcs` #35
10
+
3
11
  ## v0.3.5 2017-08-06
4
12
 
5
13
  * add option `array_path` #34
@@ -12,7 +12,7 @@ Gem::Specification.new do |s|
12
12
  s.test_files = `git ls-files -- Appraisals {spec}/*`.split("\n")
13
13
 
14
14
  s.require_paths = ['lib']
15
- s.required_ruby_version = Gem::Requirement.new(">= 1.8.7")
15
+ s.required_ruby_version = Gem::Requirement.new(">= 1.9.3")
16
16
 
17
17
  s.authors = ["Liu Fengyun"]
18
18
  s.email = ["liufengyunchina@gmail.com"]
@@ -1,5 +1,6 @@
1
1
  require 'hashdiff/util'
2
2
  require 'hashdiff/lcs'
3
+ require 'hashdiff/linear_compare_array'
3
4
  require 'hashdiff/diff'
4
5
  require 'hashdiff/patch'
5
6
  require 'hashdiff/version'
@@ -12,6 +12,7 @@ module HashDiff
12
12
  # * :numeric_tolerance (Numeric) [0] should be a positive numeric value. Value by which numeric differences must be greater than. By default, numeric values are compared exactly; with the :tolerance option, the difference between numeric values must be greater than the given value.
13
13
  # * :strip (Boolean) [false] whether or not to call #strip on strings before comparing
14
14
  # * :array_path (Boolean) [false] whether to return the path references for nested values in an array, can be used for patch compatibility with non string keys.
15
+ # * :use_lcs (Boolean) [true] whether or not to use an implementation of the Longest common subsequence algorithm for comparing arrays, produces better diffs but is slower.
15
16
  #
16
17
  # @yield [path, value1, value2] Optional block is used to compare each value, instead of default #==. If the block returns value other than true of false, then other specified comparison options will be used to do the comparison.
17
18
  #
@@ -55,6 +56,8 @@ module HashDiff
55
56
  # * :numeric_tolerance (Numeric) [0] should be a positive numeric value. Value by which numeric differences must be greater than. By default, numeric values are compared exactly; with the :tolerance option, the difference between numeric values must be greater than the given value.
56
57
  # * :strip (Boolean) [false] whether or not to call #strip on strings before comparing
57
58
  # * :array_path (Boolean) [false] whether to return the path references for nested values in an array, can be used for patch compatibility with non string keys.
59
+ # * :use_lcs (Boolean) [true] whether or not to use an implementation of the Longest common subsequence algorithm for comparing arrays, produces better diffs but is slower.
60
+ #
58
61
  #
59
62
  # @yield [path, value1, value2] Optional block is used to compare each value, instead of default #==. If the block returns value other than true of false, then other specified comparison options will be used to do the comparison.
60
63
  #
@@ -77,7 +80,8 @@ module HashDiff
77
80
  :strict => true,
78
81
  :strip => false,
79
82
  :numeric_tolerance => 0,
80
- :array_path => false
83
+ :array_path => false,
84
+ :use_lcs => true
81
85
  }.merge!(options)
82
86
 
83
87
  opts[:prefix] = [] if opts[:array_path] && opts[:prefix] == ''
@@ -105,8 +109,8 @@ module HashDiff
105
109
  end
106
110
 
107
111
  result = []
108
- if obj1.is_a?(Array)
109
- changeset = diff_array(obj1, obj2, opts) do |lcs|
112
+ if obj1.is_a?(Array) && opts[:use_lcs]
113
+ changeset = diff_array_lcs(obj1, obj2, opts) do |lcs|
110
114
  # use a's index for similarity
111
115
  lcs.each do |pair|
112
116
  prefix = prefix_append_array_index(opts[:prefix], pair[0], opts)
@@ -122,6 +126,8 @@ module HashDiff
122
126
  result << ['+', change_key, change[2]]
123
127
  end
124
128
  end
129
+ elsif obj1.is_a?(Array) && !opts[:use_lcs]
130
+ result.concat(LinearCompareArray.call(obj1, obj2, opts))
125
131
  elsif obj1.is_a?(Hash)
126
132
 
127
133
  deleted_keys = obj1.keys - obj2.keys
@@ -170,7 +176,7 @@ module HashDiff
170
176
  # @private
171
177
  #
172
178
  # diff array using LCS algorithm
173
- def self.diff_array(a, b, options = {})
179
+ def self.diff_array_lcs(a, b, options = {})
174
180
  opts = {
175
181
  :prefix => '',
176
182
  :similarity => 0.8,
@@ -223,5 +229,4 @@ module HashDiff
223
229
 
224
230
  change_set
225
231
  end
226
-
227
232
  end
@@ -0,0 +1,155 @@
1
+ module HashDiff
2
+ # @private
3
+ #
4
+ # Used to compare arrays in a linear complexity, which produces longer diffs
5
+ # than using the lcs algorithm but is considerably faster
6
+ class LinearCompareArray
7
+ def self.call(old_array, new_array, options = {})
8
+ instance = self.new(old_array, new_array, options)
9
+ instance.call
10
+ end
11
+
12
+ def call
13
+ return [] if old_array.empty? && new_array.empty?
14
+
15
+ self.old_index = 0
16
+ self.new_index = 0
17
+ # by comparing the array lengths we can expect that a number of items
18
+ # are either added or removed
19
+ self.expected_additions = new_array.length - old_array.length
20
+
21
+ loop do
22
+ if extra_items_in_old_array?
23
+ append_deletion(old_array[old_index], old_index)
24
+ elsif extra_items_in_new_array?
25
+ append_addition(new_array[new_index], new_index)
26
+ else
27
+ compare_at_index
28
+ end
29
+
30
+ self.old_index = old_index + 1
31
+ self.new_index = new_index + 1
32
+ break if iterated_through_both_arrays?
33
+ end
34
+
35
+ changes
36
+ end
37
+
38
+ private
39
+
40
+ attr_reader :old_array, :new_array, :options, :additions, :deletions, :differences
41
+ attr_accessor :old_index, :new_index, :expected_additions
42
+
43
+ def initialize(old_array, new_array, options)
44
+ @old_array = old_array
45
+ @new_array = new_array
46
+ @options = { prefix: '' }.merge!(options)
47
+
48
+ @additions = []
49
+ @deletions = []
50
+ @differences = []
51
+ end
52
+
53
+ def extra_items_in_old_array?
54
+ old_index < old_array.length && new_index >= new_array.length
55
+ end
56
+
57
+ def extra_items_in_new_array?
58
+ new_index < new_array.length && old_index >= old_array.length
59
+ end
60
+
61
+ def iterated_through_both_arrays?
62
+ old_index >= old_array.length && new_index >= new_array.length
63
+ end
64
+
65
+ def compare_at_index
66
+ difference = item_difference(old_array[old_index], new_array[new_index], old_index)
67
+ return if difference.empty?
68
+
69
+ index_after_additions = index_of_match_after_additions
70
+ append_addititions_before_match(index_after_additions)
71
+
72
+ index_after_deletions = index_of_match_after_deletions
73
+ append_deletions_before_match(index_after_deletions)
74
+
75
+ match = index_after_additions || index_after_deletions
76
+
77
+ append_differences(difference) unless match
78
+ end
79
+
80
+ def item_difference(old_item, new_item, item_index)
81
+ prefix = HashDiff.prefix_append_array_index(options[:prefix], item_index, options)
82
+ HashDiff.diff(old_item, new_item, options.merge(:prefix => prefix))
83
+ end
84
+
85
+ # look ahead in the new array to see if the current item appears later
86
+ # thereby having new items added
87
+ def index_of_match_after_additions
88
+ return unless expected_additions > 0
89
+
90
+ (1..expected_additions).each do |i|
91
+ next_difference = item_difference(
92
+ old_array[old_index],
93
+ new_array[new_index + i],
94
+ old_index
95
+ )
96
+
97
+ return new_index + i if next_difference.empty?
98
+ end
99
+
100
+ nil
101
+ end
102
+
103
+ # look ahead in the old array to see if the current item appears later
104
+ # thereby having items removed
105
+ def index_of_match_after_deletions
106
+ return unless expected_additions < 0
107
+
108
+ (1..(expected_additions.abs)).each do |i|
109
+ next_difference = item_difference(
110
+ old_array[old_index + i],
111
+ new_array[new_index],
112
+ old_index
113
+ )
114
+
115
+ return old_index + i if next_difference.empty?
116
+ end
117
+
118
+ nil
119
+ end
120
+
121
+ def append_addititions_before_match(match_index)
122
+ return unless match_index
123
+ (new_index...match_index).each { |i| append_addition(new_array[i], i) }
124
+ self.expected_additions = expected_additions - (match_index - new_index)
125
+ self.new_index = match_index
126
+ end
127
+
128
+ def append_deletions_before_match(match_index)
129
+ return unless match_index
130
+ (old_index...match_index).each { |i| append_deletion(old_array[i], i) }
131
+ self.expected_additions = expected_additions + (match_index - new_index)
132
+ self.old_index = match_index
133
+ end
134
+
135
+ def append_addition(item, index)
136
+ key = HashDiff.prefix_append_array_index(options[:prefix], index, options)
137
+ additions << ['+', key, item]
138
+ end
139
+
140
+ def append_deletion(item, index)
141
+ key = HashDiff.prefix_append_array_index(options[:prefix], index, options)
142
+ deletions << ['-', key, item]
143
+ end
144
+
145
+ def append_differences(difference)
146
+ differences.concat(difference)
147
+ end
148
+
149
+ def changes
150
+ # this algorithm only allows there to be additions or deletions
151
+ # deletions are reverse so they don't change the index of earlier items
152
+ differences + additions + deletions.reverse
153
+ end
154
+ end
155
+ end
@@ -1,3 +1,3 @@
1
1
  module HashDiff
2
- VERSION = '0.3.5'
2
+ VERSION = '0.3.7'
3
3
  end
@@ -5,7 +5,7 @@ describe HashDiff do
5
5
  a = [1, 2, 3]
6
6
  b = [1, 2, 3]
7
7
 
8
- diff = HashDiff.diff_array(a, b)
8
+ diff = HashDiff.diff_array_lcs(a, b)
9
9
  diff.should == []
10
10
  end
11
11
 
@@ -13,7 +13,7 @@ describe HashDiff do
13
13
  a = [1, 2, 3]
14
14
  b = [1, 8, 7]
15
15
 
16
- diff = HashDiff.diff_array(a, b)
16
+ diff = HashDiff.diff_array_lcs(a, b)
17
17
  diff.should == [['-', 2, 3], ['-', 1, 2], ['+', 1, 8], ['+', 2, 7]]
18
18
  end
19
19
 
@@ -21,7 +21,7 @@ describe HashDiff do
21
21
  a = [1, 2]
22
22
  b = []
23
23
 
24
- diff = HashDiff.diff_array(a, b)
24
+ diff = HashDiff.diff_array_lcs(a, b)
25
25
  diff.should == [['-', 1, 2], ['-', 0, 1]]
26
26
  end
27
27
 
@@ -29,7 +29,7 @@ describe HashDiff do
29
29
  a = []
30
30
  b = [1, 2]
31
31
 
32
- diff = HashDiff.diff_array(a, b)
32
+ diff = HashDiff.diff_array_lcs(a, b)
33
33
  diff.should == [['+', 0, 1], ['+', 1, 2]]
34
34
  end
35
35
 
@@ -37,7 +37,7 @@ describe HashDiff do
37
37
  a = [1, 3, 5, 7]
38
38
  b = [2, 3, 7, 5]
39
39
 
40
- diff = HashDiff.diff_array(a, b)
40
+ diff = HashDiff.diff_array_lcs(a, b)
41
41
  diff.should == [['-', 0, 1], ['+', 0, 2], ['+', 2, 7], ['-', 4, 7]]
42
42
  end
43
43
 
@@ -45,14 +45,14 @@ describe HashDiff do
45
45
  a = [1, 3, 4, 7]
46
46
  b = [2, 3, 7, 5]
47
47
 
48
- diff = HashDiff.diff_array(a, b)
48
+ diff = HashDiff.diff_array_lcs(a, b)
49
49
  diff.should == [['-', 0, 1], ['+', 0, 2], ['-', 2, 4], ['+', 3, 5]]
50
50
  end
51
51
 
52
52
  it "should be able to diff two arrays with similar elements" do
53
53
  a = [{'a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5}, 3]
54
54
  b = [1, {'a' => 1, 'b' => 2, 'c' => 3, 'e' => 5}]
55
- diff = HashDiff.diff_array(a, b)
55
+ diff = HashDiff.diff_array_lcs(a, b)
56
56
  diff.should == [['+', 0, 1], ['-', 2, 3]]
57
57
  end
58
58
 
@@ -310,4 +310,30 @@ describe HashDiff do
310
310
  diff.should == [['-', [time], 'foo'], ['+', [0], 'bar']]
311
311
  end
312
312
  end
313
+
314
+ context 'when :use_lcs is false' do
315
+ it 'should show items in an array as changed' do
316
+ x = [:a, :b]
317
+ y = [:c, :d]
318
+ diff = HashDiff.diff(x, y, :use_lcs => false)
319
+
320
+ diff.should == [['~', '[0]', :a, :c], ['~', '[1]', :b, :d]]
321
+ end
322
+
323
+ it 'should show additions to arrays' do
324
+ x = { :a => [0] }
325
+ y = { :a => [0, 1] }
326
+ diff = HashDiff.diff(x, y, :use_lcs => false)
327
+
328
+ diff.should == [['+', 'a[1]', 1]]
329
+ end
330
+
331
+ it 'shows changes to nested arrays' do
332
+ x = { :a => [[0, 1]] }
333
+ y = { :a => [[1, 2]] }
334
+ diff = HashDiff.diff(x, y, :use_lcs => false)
335
+
336
+ diff.should == [['~', 'a[0][0]', 0, 1], ['~', 'a[0][1]', 1, 2]]
337
+ end
338
+ end
313
339
  end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ describe HashDiff::LinearCompareArray do
4
+ it "should find no differences between two empty arrays" do
5
+ difference = described_class.call([], [])
6
+ difference.should == []
7
+ end
8
+
9
+ it "should find added items when the old array is empty" do
10
+ difference = described_class.call([], [:a, :b])
11
+ difference.should == [['+', '[0]', :a], ['+', '[1]', :b]]
12
+ end
13
+
14
+ it "should find removed items when the new array is empty" do
15
+ difference = described_class.call([:a, :b], [])
16
+ difference.should == [['-', '[1]', :b], ['-', '[0]', :a]]
17
+ end
18
+
19
+ it "should find no differences between identical arrays" do
20
+ difference = described_class.call([:a, :b], [:a, :b])
21
+ difference.should == []
22
+ end
23
+
24
+ it "should find added items in an array" do
25
+ difference = described_class.call([:a, :d], [:a, :b, :c, :d])
26
+ difference.should == [['+', '[1]', :b], ['+', '[2]', :c]]
27
+ end
28
+
29
+ it "should find removed items in an array" do
30
+ difference = described_class.call([:a, :b, :c, :d, :e, :f], [:a, :d, :f])
31
+ difference.should == [['-', '[4]', :e], ['-', '[2]', :c], ['-', '[1]', :b]]
32
+ end
33
+
34
+ it "should show additions and deletions as changed items" do
35
+ difference = described_class.call([:a, :b, :c], [:c, :b, :a])
36
+ difference.should == [['~', '[0]', :a, :c], ['~', '[2]', :c, :a]]
37
+ end
38
+
39
+ it "should show changed items in a hash" do
40
+ difference = described_class.call([{ :a => :b }], [{ :a => :c }])
41
+ difference.should == [['~', '[0].a', :b, :c]]
42
+ end
43
+
44
+ it "should show changed items and added items" do
45
+ difference = described_class.call([{ :a => 1, :b => 2 }], [{ :a => 2, :b => 2 }, :item])
46
+ difference.should == [['~', '[0].a', 1, 2], ['+', '[1]', :item]]
47
+ end
48
+ end
@@ -1,10 +1,3 @@
1
- require 'simplecov'
2
- SimpleCov.start
3
- if ENV['CI'] == 'true'
4
- require 'codecov'
5
- SimpleCov.formatter = SimpleCov::Formatter::Codecov
6
- end
7
-
8
1
  $LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
9
2
 
10
3
  require 'rubygems'
metadata CHANGED
@@ -1,69 +1,69 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hashdiff
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.5
4
+ version: 0.3.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Liu Fengyun
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-08-06 00:00:00.000000000 Z
11
+ date: 2017-10-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ~>
18
18
  - !ruby/object:Gem::Version
19
19
  version: '2.0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ~>
25
25
  - !ruby/object:Gem::Version
26
26
  version: '2.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: yard
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - '>='
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - '>='
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: bluecloth
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - '>='
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - '>='
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
- description: " HashDiff is a diff lib to compute the smallest difference between two
56
- hashes. "
55
+ description: ' HashDiff is a diff lib to compute the smallest difference between two
56
+ hashes. '
57
57
  email:
58
58
  - liufengyunchina@gmail.com
59
59
  executables: []
60
60
  extensions: []
61
61
  extra_rdoc_files: []
62
62
  files:
63
- - ".gitignore"
64
- - ".rspec"
65
- - ".travis.yml"
66
- - ".yardopts"
63
+ - .gitignore
64
+ - .rspec
65
+ - .travis.yml
66
+ - .yardopts
67
67
  - Gemfile
68
68
  - LICENSE
69
69
  - README.md
@@ -73,6 +73,7 @@ files:
73
73
  - lib/hashdiff.rb
74
74
  - lib/hashdiff/diff.rb
75
75
  - lib/hashdiff/lcs.rb
76
+ - lib/hashdiff/linear_compare_array.rb
76
77
  - lib/hashdiff/patch.rb
77
78
  - lib/hashdiff/util.rb
78
79
  - lib/hashdiff/version.rb
@@ -80,6 +81,7 @@ files:
80
81
  - spec/hashdiff/diff_array_spec.rb
81
82
  - spec/hashdiff/diff_spec.rb
82
83
  - spec/hashdiff/lcs_spec.rb
84
+ - spec/hashdiff/linear_compare_array_spec.rb
83
85
  - spec/hashdiff/patch_spec.rb
84
86
  - spec/hashdiff/util_spec.rb
85
87
  - spec/spec_helper.rb
@@ -93,19 +95,18 @@ require_paths:
93
95
  - lib
94
96
  required_ruby_version: !ruby/object:Gem::Requirement
95
97
  requirements:
96
- - - ">="
98
+ - - '>='
97
99
  - !ruby/object:Gem::Version
98
- version: 1.8.7
100
+ version: 1.9.3
99
101
  required_rubygems_version: !ruby/object:Gem::Requirement
100
102
  requirements:
101
- - - ">="
103
+ - - '>='
102
104
  - !ruby/object:Gem::Version
103
105
  version: '0'
104
106
  requirements: []
105
107
  rubyforge_project:
106
- rubygems_version: 2.5.1
108
+ rubygems_version: 2.0.14.1
107
109
  signing_key:
108
110
  specification_version: 4
109
111
  summary: HashDiff is a diff lib to compute the smallest difference between two hashes.
110
112
  test_files: []
111
- has_rdoc: