summaryrefslogtreecommitdiff
diff options
authorCédric Boutillier <boutil@debian.org>2020-12-21 15:20:56 +0100
committergit-ubuntu importer <ubuntu-devel-discuss@lists.ubuntu.com>2020-12-21 22:46:59 +0000
commit6d3afd1dc7c7216d878fe5fbbae0cc953ded9642 (patch)
treed7e20978b688da48ae5ce560ffcfdebdf87af70e
parent25085ba7898e4cabf62459ec3870b96fcf6e6cf4 (diff)
Imported using git-ubuntu import.
Notes
Notes: [ Debian Janitor ] * Trim trailing whitespace. * Update standards version to 4.4.1, no changes needed. [ Cédric Boutillier ] * New upstream version 1.0.1 * watch file to v4 * gem install layout * gitattributes * d/control: + Rules-Requires-Root set to no + Standards version bumped to 4.5.1 (no changes needed) + no explicit dependency on ruby interpreter
-rw-r--r--.rubocop.yml4
-rw-r--r--README.md30
-rw-r--r--changelog.md4
-rw-r--r--debian/changelog20
-rw-r--r--debian/control13
-rwxr-xr-xdebian/rules1
-rw-r--r--debian/salsa-ci.yml4
-rw-r--r--debian/watch2
-rw-r--r--hashdiff.gemspec2
-rw-r--r--lib/hashdiff/compare_hashes.rb15
-rw-r--r--lib/hashdiff/diff.rb3
-rw-r--r--lib/hashdiff/util.rb3
-rw-r--r--lib/hashdiff/version.rb2
-rw-r--r--spec/hashdiff/diff_spec.rb5
-rw-r--r--spec/hashdiff/readme_spec.rb15
-rw-r--r--spec/hashdiff/util_spec.rb21
16 files changed, 115 insertions, 29 deletions
diff --git a/.rubocop.yml b/.rubocop.yml
index 1686d4f..4f70ab8 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -1,4 +1,6 @@
require: rubocop-rspec
+AllCops:
+ TargetRubyVersion: 2.0 # always the lowest version we support
Metrics/PerceivedComplexity:
Enabled: false
Metrics/CyclomaticComplexity:
@@ -26,3 +28,5 @@ Style/RedundantFreeze:
Enabled: false
RSpec/ExampleLength:
Enabled: false
+RSpec/DescribeClass:
+ Enabled: false
diff --git a/README.md b/README.md
index 4774554..088ed67 100644
--- a/README.md
+++ b/README.md
@@ -32,7 +32,7 @@ Hashdiff answers the question above using an opinionated approach:
To use the gem, add the following to your Gemfile:
-```ruby
+```Ruby
gem 'hashdiff'
```
@@ -95,8 +95,8 @@ Hashdiff.unpatch!(b, diff).should == a
### Options
There are eight options available: `:delimiter`, `:similarity`,
-`:strict`, `:numeric_tolerance`, `:strip`, `:case_insensitive`, `:array_path`
-and `:use_lcs`
+`:strict`, `:indifferent`, `:numeric_tolerance`, `:strip`, `:case_insensitive`,
+`:array_path` and `:use_lcs`
#### `:delimiter`
@@ -106,7 +106,7 @@ You can specify `:delimiter` to be something other than the default dot. For exa
a = {a:{x:2, y:3, z:4}, b:{x:3, z:45}}
b = {a:{y:3}, b:{y:3, z:30}}
-diff = Hashdiff.diff(a, b, :delimiter => '\t')
+diff = Hashdiff.diff(a, b, delimiter: '\t')
diff.should == [['-', 'a\tx', 2], ['-', 'a\tz', 4], ['-', 'b\tx', 3], ['~', 'b\tz', 45, 30], ['+', 'b\ty', 3]]
```
@@ -118,6 +118,10 @@ In cases where you have similar hash objects in arrays, you can pass a custom va
The `:strict` option, which defaults to `true`, specifies whether numeric types are compared on type as well as value. By default, an Integer will never be equal to a Float (e.g. 4 != 4.0). Setting `:strict` to false makes the comparison looser (e.g. 4 == 4.0).
+#### `:indifferent`
+
+The `:indifferent` option, which defaults to `false`, specifies whether to treat hash keys indifferently. Setting `:indifferent` to true has the effect of ignoring differences between symbol keys (ie. {a: 1} ~= {'a' => 1})
+
#### `:numeric_tolerance`
The :numeric_tolerance option allows for a small numeric tolerance.
@@ -126,7 +130,7 @@ The :numeric_tolerance option allows for a small numeric tolerance.
a = {x:5, y:3.75, z:7}
b = {x:6, y:3.76, z:7}
-diff = Hashdiff.diff(a, b, :numeric_tolerance => 0.1)
+diff = Hashdiff.diff(a, b, numeric_tolerance: 0.1)
diff.should == [["~", "x", 5, 6]]
```
@@ -138,7 +142,7 @@ The :strip option strips all strings before comparing.
a = {x:5, s:'foo '}
b = {x:6, s:'foo'}
-diff = Hashdiff.diff(a, b, :comparison => { :numeric_tolerance => 0.1, :strip => true })
+diff = Hashdiff.diff(a, b, numeric_tolerance: 0.1, strip: true)
diff.should == [["~", "x", 5, 6]]
```
@@ -150,7 +154,7 @@ The :case_insensitive option makes string comparisons ignore case.
a = {x:5, s:'FooBar'}
b = {x:6, s:'foobar'}
-diff = Hashdiff.diff(a, b, :comparison => { :numeric_tolerance => 0.1, :case_insensitive => true })
+diff = Hashdiff.diff(a, b, numeric_tolerance: 0.1, case_insensitive: true)
diff.should == [["~", "x", 5, 6]]
```
@@ -164,7 +168,7 @@ is useful for `patch!` when used on hashes without string keys.
a = {x:5}
b = {'x'=>6}
-diff = Hashdiff.diff(a, b, :array_path => true)
+diff = Hashdiff.diff(a, b, array_path: true)
diff.should == [['-', [:x], 5], ['+', ['x'], 6]]
```
@@ -173,7 +177,7 @@ For cases where there are arrays in paths their index will be added to the path.
a = {x:[0,1]}
b = {x:[0,2]}
-diff = Hashdiff.diff(a, b, :array_path => true)
+diff = Hashdiff.diff(a, b, array_path: true)
diff.should == [["-", [:x, 1], 1], ["+", [:x, 1], 2]]
```
@@ -183,7 +187,7 @@ This shouldn't cause problems if you are comparing an array with a hash:
a = {x:{0=>1}}
b = {x:[1]}
-diff = Hashdiff.diff(a, b, :array_path => true)
+diff = Hashdiff.diff(a, b, array_path: true)
diff.should == [["~", [:x], {0=>1}, [1]]]
```
@@ -205,7 +209,7 @@ Note, currently the :similarity option has no effect when :use_lcs is false.
a = {x: [0, 1, 2]}
b = {x: [0, 2, 2, 3]}
-diff = Hashdiff.diff(a, b, :use_lcs => false)
+diff = Hashdiff.diff(a, b, use_lcs: false)
diff.should == [["~", "x[1]", 1, 2], ["+", "x[3]", 3]]
```
@@ -255,11 +259,11 @@ An order difference alone between two arrays can create too many diffs to be use
a = {a:'car', b:['boat', 'plane'] }
b = {a:'car', b:['plane', 'boat'] }
-Hashdiff.diff(a, b) => [["+", "b[0]", "plane"], ["-", "b[2]", "plane"]]
+Hashdiff.diff(a, b).should == [["+", "b[0]", "plane"], ["-", "b[2]", "plane"]]
b[:b].sort!
-Hashdiff.diff(a, b) => []
+Hashdiff.diff(a, b).should == []
```
## Maintainers
diff --git a/changelog.md b/changelog.md
index 6eb131d..300d635 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,5 +1,9 @@
# Change Log
+## v1.0.1 2020-02-25
+
+* Add indifferent option
+
## v1.0.0 2019-06-06
* Fix typo in readme (#72 @koic)
diff --git a/debian/changelog b/debian/changelog
index c14b7aa..dbf8c6e 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,5 +1,23 @@
+ruby-hashdiff (1.0.1-1) unstable; urgency=medium
+
+ [ Debian Janitor ]
+ * Trim trailing whitespace.
+ * Update standards version to 4.4.1, no changes needed.
+
+ [ Cédric Boutillier ]
+ * New upstream version 1.0.1
+ * watch file to v4
+ * gem install layout
+ * gitattributes
+ * d/control:
+ + Rules-Requires-Root set to no
+ + Standards version bumped to 4.5.1 (no changes needed)
+ + no explicit dependency on ruby interpreter
+
+ -- Cédric Boutillier <boutil@debian.org> Mon, 21 Dec 2020 15:20:56 +0100
+
ruby-hashdiff (1.0.0-1) unstable; urgency=medium
-
+
[ Antonio Terceiro ]
* Remove myself from Uploaders:
diff --git a/debian/control b/debian/control
index 7e21d71..8a61c55 100644
--- a/debian/control
+++ b/debian/control
@@ -1,24 +1,25 @@
Source: ruby-hashdiff
Section: ruby
Priority: optional
-Maintainer: Debian Ruby Extras Maintainers <pkg-ruby-extras-maintainers@lists.alioth.debian.org>
+Maintainer: Debian Ruby Team <pkg-ruby-extras-maintainers@lists.alioth.debian.org>
Uploaders: Cédric Boutillier <boutil@debian.org>
-Build-Depends: debhelper-compat (= 12),
- gem2deb,
+Build-Depends: debhelper-compat (= 13),
+ gem2deb (>= 1),
rake,
ruby-rspec
-Standards-Version: 4.4.0
+Standards-Version: 4.5.1
Vcs-Git: https://salsa.debian.org/ruby-team/ruby-hashdiff.git
Vcs-Browser: https://salsa.debian.org/ruby-team/ruby-hashdiff
Homepage: https://github.com/liufengyun/hashdiff
Testsuite: autopkgtest-pkg-ruby
XS-Ruby-Versions: all
+Rules-Requires-Root: no
Package: ruby-hashdiff
Architecture: all
XB-Ruby-Versions: ${ruby:Versions}
-Depends: ruby | ruby-interpreter,
- ${misc:Depends},
+Depends: ${misc:Depends},
+ ${ruby:Depends},
${shlibs:Depends}
Breaks: ruby-webmock (<< 3.6~)
Description: library for computing the smallest difference between two hashes
diff --git a/debian/rules b/debian/rules
index 3454d59..4e91465 100755
--- a/debian/rules
+++ b/debian/rules
@@ -1,6 +1,7 @@
#!/usr/bin/make -f
export GEM2DEB_TEST_RUNNER = --check-dependencies
+export DH_RUBY = --gem-install
%:
dh $@ --buildsystem=ruby --with ruby
diff --git a/debian/salsa-ci.yml b/debian/salsa-ci.yml
deleted file mode 100644
index 33c3a64..0000000
--- a/debian/salsa-ci.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-include:
- - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/salsa-ci.yml
- - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/pipeline-jobs.yml
diff --git a/debian/watch b/debian/watch
index 32cb6cd..c667309 100644
--- a/debian/watch
+++ b/debian/watch
@@ -1,2 +1,2 @@
-version=3
+version=4
https://gemwatch.debian.net/hashdiff .*/hashdiff-(.*).tar.gz
diff --git a/hashdiff.gemspec b/hashdiff.gemspec
index d4dd44b..d972f34 100644
--- a/hashdiff.gemspec
+++ b/hashdiff.gemspec
@@ -23,7 +23,7 @@ Gem::Specification.new do |s|
s.add_development_dependency('bluecloth')
s.add_development_dependency('rspec', '~> 2.0')
- s.add_development_dependency('rubocop')
+ s.add_development_dependency('rubocop', '~> 0.49.1') # last version that works with ruby 2.0
s.add_development_dependency('rubocop-rspec')
s.add_development_dependency('yard')
diff --git a/lib/hashdiff/compare_hashes.rb b/lib/hashdiff/compare_hashes.rb
index 1fd09ab..4223ac2 100644
--- a/lib/hashdiff/compare_hashes.rb
+++ b/lib/hashdiff/compare_hashes.rb
@@ -10,6 +10,15 @@ module Hashdiff
obj1_keys = obj1.keys
obj2_keys = obj2.keys
+ obj1_lookup = {}
+ obj2_lookup = {}
+
+ if opts[:indifferent]
+ obj1_lookup = obj1_keys.each_with_object({}) { |k, h| h[k.to_s] = k }
+ obj2_lookup = obj2_keys.each_with_object({}) { |k, h| h[k.to_s] = k }
+ obj1_keys = obj1_keys.map { |k| k.is_a?(Symbol) ? k.to_s : k }
+ obj2_keys = obj2_keys.map { |k| k.is_a?(Symbol) ? k.to_s : k }
+ end
added_keys = (obj2_keys - obj1_keys).sort_by(&:to_s)
common_keys = (obj1_keys & obj2_keys).sort_by(&:to_s)
@@ -19,6 +28,7 @@ module Hashdiff
# add deleted properties
deleted_keys.each do |k|
+ k = opts[:indifferent] ? obj1_lookup[k] : k
change_key = Hashdiff.prefix_append_key(opts[:prefix], k, opts)
custom_result = Hashdiff.custom_compare(opts[:comparison], change_key, obj1[k], nil)
@@ -33,13 +43,16 @@ module Hashdiff
common_keys.each do |k|
prefix = Hashdiff.prefix_append_key(opts[:prefix], k, opts)
- result.concat(Hashdiff.diff(obj1[k], obj2[k], opts.merge(prefix: prefix)))
+ k1 = opts[:indifferent] ? obj1_lookup[k] : k
+ k2 = opts[:indifferent] ? obj2_lookup[k] : k
+ result.concat(Hashdiff.diff(obj1[k1], obj2[k2], opts.merge(prefix: prefix)))
end
# added properties
added_keys.each do |k|
change_key = Hashdiff.prefix_append_key(opts[:prefix], k, opts)
+ k = opts[:indifferent] ? obj2_lookup[k] : k
custom_result = Hashdiff.custom_compare(opts[:comparison], change_key, nil, obj2[k])
if custom_result
diff --git a/lib/hashdiff/diff.rb b/lib/hashdiff/diff.rb
index 2c74f19..5a10462 100644
--- a/lib/hashdiff/diff.rb
+++ b/lib/hashdiff/diff.rb
@@ -9,6 +9,7 @@ module Hashdiff
# @param [Array, Hash] obj2
# @param [Hash] options the options to use when comparing
# * :strict (Boolean) [true] whether numeric values will be compared on type as well as value. Set to false to allow comparing Integer, Float, BigDecimal to each other
+ # * :indifferent (Boolean) [false] whether to treat hash keys indifferently. Set to true to ignore differences between symbol keys (ie. {a: 1} ~= {'a' => 1})
# * :delimiter (String) ['.'] the delimiter used when returning nested key references
# * :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.
# * :strip (Boolean) [false] whether or not to call #strip on strings before comparing
@@ -52,6 +53,7 @@ module Hashdiff
# @param [Array, Hash] obj2
# @param [Hash] options the options to use when comparing
# * :strict (Boolean) [true] whether numeric values will be compared on type as well as value. Set to false to allow comparing Integer, Float, BigDecimal to each other
+ # * :indifferent (Boolean) [false] whether to treat hash keys indifferently. Set to true to ignore differences between symbol keys (ie. {a: 1} ~= {'a' => 1})
# * :similarity (Numeric) [0.8] should be between (0, 1]. Meaningful if there are similar hashes in arrays. See {best_diff}.
# * :delimiter (String) ['.'] the delimiter used when returning nested key references
# * :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.
@@ -79,6 +81,7 @@ module Hashdiff
similarity: 0.8,
delimiter: '.',
strict: true,
+ indifferent: false,
strip: false,
numeric_tolerance: 0,
array_path: false,
diff --git a/lib/hashdiff/util.rb b/lib/hashdiff/util.rb
index 342d32e..09ed84b 100644
--- a/lib/hashdiff/util.rb
+++ b/lib/hashdiff/util.rb
@@ -16,7 +16,7 @@ module Hashdiff
diffs = count_diff diff(obja, objb, opts)
- (1 - diffs.to_f / (count_a + count_b).to_f) >= opts[:similarity]
+ (1 - diffs / (count_a + count_b).to_f) >= opts[:similarity]
end
# @private
@@ -107,6 +107,7 @@ module Hashdiff
# check if objects are comparable
def self.comparable?(obj1, obj2, strict = true)
return true if (obj1.is_a?(Array) || obj1.is_a?(Hash)) && obj2.is_a?(obj1.class)
+ return true if (obj2.is_a?(Array) || obj2.is_a?(Hash)) && obj1.is_a?(obj2.class)
return true if !strict && obj1.is_a?(Numeric) && obj2.is_a?(Numeric)
obj1.is_a?(obj2.class) && obj2.is_a?(obj1.class)
diff --git a/lib/hashdiff/version.rb b/lib/hashdiff/version.rb
index e3684f5..b6f28c4 100644
--- a/lib/hashdiff/version.rb
+++ b/lib/hashdiff/version.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
module Hashdiff
- VERSION = '1.0.0'.freeze
+ VERSION = '1.0.1'.freeze
end
diff --git a/spec/hashdiff/diff_spec.rb b/spec/hashdiff/diff_spec.rb
index 1dd7fae..c9dfd96 100644
--- a/spec/hashdiff/diff_spec.rb
+++ b/spec/hashdiff/diff_spec.rb
@@ -49,6 +49,11 @@ describe Hashdiff do
diff.should == []
end
+ it 'ignores string vs symbol differences, when indifferent is true' do
+ diff = described_class.diff({ 'a' => 2, :b => 2 }, { :a => 2, 'b' => 2, :c => 3 }, indifferent: true)
+ diff.should == [['+', 'c', 3]]
+ end
+
it 'is able to diff changes in hash value' do
diff = described_class.diff({ 'a' => 2, 'b' => 3, 'c' => ' hello' }, 'a' => 2, 'b' => 4, 'c' => 'hello')
diff.should == [['~', 'b', 3, 4], ['~', 'c', ' hello', 'hello']]
diff --git a/spec/hashdiff/readme_spec.rb b/spec/hashdiff/readme_spec.rb
new file mode 100644
index 0000000..ee9314b
--- /dev/null
+++ b/spec/hashdiff/readme_spec.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'README.md' do
+ it 'has correct examples' do
+ File.read('README.md').scan(/```ruby(.*?)```/m).flatten(1).each do |block|
+ begin
+ eval block # rubocop:disable Security/Eval
+ rescue Exception => e # rubocop:disable Lint/RescueException
+ raise "README.md code block:\n#{block}\n\nhas error:\n#{e}"
+ end
+ end
+ end
+end
diff --git a/spec/hashdiff/util_spec.rb b/spec/hashdiff/util_spec.rb
index 6f2ebdf..b9db735 100644
--- a/spec/hashdiff/util_spec.rb
+++ b/spec/hashdiff/util_spec.rb
@@ -68,6 +68,7 @@ describe Hashdiff do
it 'compares different objects without tolerance' do
expect(described_class.compare_values('hats', 'ninjas')).to be false
end
+
it 'compares other objects with tolerance' do
expect(described_class.compare_values('hats', 'ninjas', numeric_tolerance: 0.01)).to be false
end
@@ -92,4 +93,24 @@ describe Hashdiff do
expect(described_class.compare_values('horse', 'Horse', case_insensitive: true)).to be true
end
end
+
+ describe '.comparable?' do
+ it 'identifies hashes as comparable' do
+ expect(described_class.comparable?({}, {})).to be true
+ end
+
+ it 'identifies a subclass of Hash to be comparable with a Hash' do
+ other = Class.new(Hash)
+ expect(described_class.comparable?(other.new, {})).to be true
+ end
+
+ it 'identifies a Hash to be comparable with a subclass of Hash' do
+ other = Class.new(Hash)
+ expect(described_class.comparable?({}, other.new)).to be true
+ end
+
+ it 'does not identify a Numeric as comparable with a Hash' do
+ expect(described_class.comparable?(1, {})).to be false
+ end
+ end
end