hash_diff 0.8.0 → 1.1.1

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
- SHA1:
3
- metadata.gz: e02ff6f11b18eafa65d02ecd98cccf8a789d8cda
4
- data.tar.gz: 70710b0568a977b1e4a4c4423a1e048a4cd76acc
2
+ SHA256:
3
+ metadata.gz: 3bbc5462057be5bab5b5e0eb46aa0b8d3fc3b41990b2ea0374f24210d0ecfe1b
4
+ data.tar.gz: 60e2db4d4acb464a958e72599ca76fff28c7e3b447816a7f78afa330b626cd31
5
5
  SHA512:
6
- metadata.gz: 17ff9470571e175b9ea761f8cbd3e0d1bfa06f26d56d08e006dfa877ec3ddc9a4f95355f59b256c3ce43dc4c32f54b0a7a6d3d58a481d39b79df08e2e963b57d
7
- data.tar.gz: 9451787251c0d041a7d2b014c86bad7bbae3d442fd4bd0ddb9d968996246ca27ac747f61f96c19af66d8fcc99f9774c04b891d80383fc2ff23e54c0bd4b5ee0d
6
+ metadata.gz: bed9aa1ff38395a905043e6a013767f96f75ccf4dedd97f04ae6b2762e11543f6c98b42ff02fd8d9fb9781e7939caa864feadb366b479912dda565f0da42784c
7
+ data.tar.gz: 1943c3599f521e68e68925e48e04b718990523b89d9c7eaa4105c7112c074abf81913559335d4b4ecda3ccc406ec1107e5295b3cad331b1ee514f265edee6db8
@@ -0,0 +1,12 @@
1
+ # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
2
+ version: 2
3
+ updates:
4
+ - package-ecosystem: "bundler"
5
+ directory: "/" # Location of package manifests
6
+ schedule:
7
+ interval: "monthly"
8
+
9
+ - package-ecosystem: "github-actions"
10
+ directory: "/"
11
+ schedule:
12
+ interval: "monthly"
@@ -0,0 +1,59 @@
1
+ name: "CodeQL"
2
+
3
+ on:
4
+ push:
5
+ branches: [ master ]
6
+ pull_request:
7
+ # The branches below must be a subset of the branches above
8
+ branches: [ master ]
9
+ schedule:
10
+ - cron: '39 15 * * 4'
11
+
12
+ jobs:
13
+ analyze:
14
+ name: Analyze
15
+ runs-on: ubuntu-latest
16
+ permissions:
17
+ actions: read
18
+ contents: read
19
+ security-events: write
20
+
21
+ strategy:
22
+ fail-fast: false
23
+ matrix:
24
+ language: [ 'ruby' ]
25
+ # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
26
+ # Learn more about CodeQL language support at https://git.io/codeql-language-support
27
+
28
+ steps:
29
+ - name: Checkout repository
30
+ uses: actions/checkout@v3
31
+
32
+ # Initializes the CodeQL tools for scanning.
33
+ - name: Initialize CodeQL
34
+ uses: github/codeql-action/init@v2
35
+ with:
36
+ languages: ${{ matrix.language }}
37
+ # If you wish to specify custom queries, you can do so here or in a config file.
38
+ # By default, queries listed here will override any specified in a config file.
39
+ # Prefix the list here with "+" to use these queries and those in the config file.
40
+ # queries: ./path/to/local/query, your-org/your-repo/queries@main
41
+
42
+ # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
43
+ # If this step fails, then you should remove it and run the build manually (see below)
44
+ - name: Autobuild
45
+ uses: github/codeql-action/autobuild@v2
46
+
47
+ # ℹ️ Command-line programs to run using the OS shell.
48
+ # 📚 https://git.io/JvXDl
49
+
50
+ # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
51
+ # and modify them (or add more) to build your code if your project
52
+ # uses a compiled language
53
+
54
+ #- run: |
55
+ # make bootstrap
56
+ # make release
57
+
58
+ - name: Perform CodeQL Analysis
59
+ uses: github/codeql-action/analyze@v2
@@ -0,0 +1,25 @@
1
+ name: Ruby
2
+
3
+ on:
4
+ push:
5
+ branches: [ master ]
6
+ pull_request:
7
+ branches: [ master ]
8
+
9
+ jobs:
10
+ test:
11
+
12
+ runs-on: ubuntu-latest
13
+ strategy:
14
+ matrix:
15
+ ruby-version: ['1.9', '2.0', '2.1', '2.2', '2.4', '2.5', '2.6', '2.7', '3.0', '3.1']
16
+
17
+ steps:
18
+ - uses: actions/checkout@v3
19
+ - name: Set up Ruby
20
+ uses: ruby/setup-ruby@v1
21
+ with:
22
+ ruby-version: ${{ matrix.ruby-version }}
23
+ bundler-cache: true
24
+ - name: Run tests
25
+ run: bundle exec rake
data/.gitignore CHANGED
@@ -15,3 +15,4 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+ vendor/
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.7.3
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2013 acuppy
1
+ Copyright (c) 2013 Zeal, LLC (dba. Coding Zeal)
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -1,5 +1,6 @@
1
1
  # HashDiff
2
- [![Build Status](https://travis-ci.org/CodingZeal/hash_diff.png?branch=master)](https://travis-ci.org/CodingZeal/hash_diff) [![Code Climate](https://codeclimate.com/github/CodingZeal/hash_diff.png)](https://codeclimate.com/github/CodingZeal/hash_diff) [![Gem Version](https://badge.fury.io/rb/hash_diff.png)](http://badge.fury.io/rb/hash_diff)
2
+
3
+ [![Ruby](https://github.com/CodingZeal/hash_diff/actions/workflows/ruby.yml/badge.svg)](https://github.com/CodingZeal/hash_diff/actions/workflows/ruby.yml) [![Code Climate](https://codeclimate.com/github/CodingZeal/hash_diff.png)](https://codeclimate.com/github/CodingZeal/hash_diff) [![Gem Version](https://badge.fury.io/rb/hash_diff.png)](http://badge.fury.io/rb/hash_diff)
3
4
 
4
5
  Deep comparison of Ruby Hash objects
5
6
 
@@ -31,7 +32,8 @@ Easily find the differences between two Ruby hashes.
31
32
  one: 'foo1'
32
33
  }
33
34
  },
34
- num: 1
35
+ num: 1,
36
+ favorite_restaurant: "Shoney's"
35
37
  }
36
38
 
37
39
  right = {
@@ -43,7 +45,8 @@ Easily find the differences between two Ruby hashes.
43
45
  two: 'foo2'
44
46
  }
45
47
  },
46
- word: 'monkey'
48
+ word: 'monkey',
49
+ favorite_restaurant: nil
47
50
  }
48
51
 
49
52
  hash_diff = HashDiff::Comparison.new( left, right )
@@ -52,19 +55,25 @@ Easily find the differences between two Ruby hashes.
52
55
  Comparison#diff returns the left and right side differences
53
56
 
54
57
  ```ruby
55
- hash_diff.diff # => { foo: ["bar", "bar2"], bar: ["foo", "foo2"], nested: { foo: ["bar", "bar2"], bar: { one: ["foo1", nil], two: [nil, "foo2"] } }, num: [1, nil], word: [nil, "monkey"] }
58
+ hash_diff.diff # => { foo: ["bar", "bar2"], bar: ["foo", "foo2"], nested: { foo: ["bar", "bar2"], bar: { one: ["foo1", HashDiff::NO_VALUE], two: [HashDiff::NO_VALUE, "foo2"] } }, num: [1, HashDiff::NO_VALUE], word: [HashDiff::NO_VALUE, "monkey"], favorite_restaurant: ["Shoney's", nil] }
56
59
  ```
57
60
 
61
+ You can also compare two arrays. The comparison is sensitive to the order of the elements in the array.
62
+
63
+ #### Missing keys
64
+
65
+ When there is a key that exists on one side it will return `HashDiff::NO_VALUE` to represent a missing key.
66
+
58
67
  Comparison#left_diff returns only the left side differences
59
68
 
60
69
  ```ruby
61
- hash_diff.left_diff # => { foo: "bar2", bar: "foo2", nested: { foo: "bar2", bar: { one: nil, two: "foo2" } }, num: nil, word: "monkey" }
70
+ hash_diff.left_diff # => {:foo=>"bar2", :bar=>"foo2", :nested=>{:foo=>"bar2", :bar=>{:one=>HashDiff::NO_VALUE, :two=>"foo2"}}, :num=>HashDiff::NO_VALUE, :favorite_restaurant=>nil, :word=>"monkey"}
62
71
  ```
63
72
 
64
73
  Comparison#right_diff returns only the right side differences
65
74
 
66
75
  ```ruby
67
- hash_diff.right_diff # => { foo: "bar", bar: "foo", nested: { foo: "bar", bar: { one: "foo1", two: nil } }, num: 1, word: nil }
76
+ hash_diff.right_diff # => {:foo=>"bar", :bar=>"foo", :nested=>{:foo=>"bar", :bar=>{:one=>"foo1", :two=>HashDiff::NO_VALUE}}, :num=>1, :favorite_restaurant=>"Shoney's", :word=>HashDiff::NO_VALUE}
68
77
  ```
69
78
 
70
79
  You can also use these shorthand methods
@@ -87,14 +96,11 @@ Hash#diff is not provided by default, and monkey patching is frowned upon by som
87
96
  left.diff(right) # => { foo: 'baz' }
88
97
  ```
89
98
 
90
- ## Credits
91
-
92
- Authored by Adam Cuppy (@acuppy) of Coding ZEAL (http://codingzeal.com)
99
+ ## License
93
100
 
94
- ![Coding ZEAL](https://googledrive.com/host/0B3TWa6M1MsWeWmxRZWhscllwTzA/ZEAL-logo-final-150.png)
101
+ Authored by the Engineering Team of [Coding ZEAL](https://codingzeal.com?utm_source=github)
95
102
 
96
- This is freely distributed under the MIT license. Use it, modify it,
97
- enjoy :)
103
+ Copyright (c) 2017 Zeal, LLC. Licensed under the [MIT license](https://opensource.org/licenses/MIT).
98
104
 
99
105
  ## Contributing
100
106
 
data/hash_diff.gemspec CHANGED
@@ -6,8 +6,8 @@ require 'hash_diff/version'
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "hash_diff"
8
8
  spec.version = HashDiff::VERSION
9
- spec.authors = ["Coding Zeal", "Adam Cuppy"]
10
- spec.email = ["info@codingzeal.com"]
9
+ spec.authors = ["Coding Zeal", "Adam Cuppy", "Mike Bianco"]
10
+ spec.email = ["info@codingzeal.com", "mike@mikebian.co"]
11
11
  spec.description = %q{Diff tool for deep Ruby hash comparison}
12
12
  spec.summary = %q{Deep Ruby Hash comparison}
13
13
  spec.homepage = "https://github.com/CodingZeal/hash_diff"
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.add_development_dependency "bundler", "~> 1.3"
21
+ spec.add_development_dependency "bundler"
22
22
  spec.add_development_dependency "rake"
23
23
  spec.add_development_dependency "rspec", "~> 3.1"
24
24
  end
@@ -34,27 +34,51 @@ module HashDiff
34
34
  end
35
35
 
36
36
  def combined_keys
37
- (left.keys + right.keys).uniq
37
+ if hash?(left) && hash?(right) then
38
+ (left.keys + right.keys).uniq
39
+ elsif array?(left) && array?(right) then
40
+ (0..[left.size, right.size].max).to_a
41
+ else
42
+ raise ArgumentError, "Don't know how to extract keys. Neither arrays nor hashes given"
43
+ end
38
44
  end
39
45
 
40
46
  def equal?(key)
41
- left[key] == right[key]
47
+ value_with_default(left, key) == value_with_default(right, key)
42
48
  end
43
49
 
44
50
  def hash?(value)
45
51
  value.is_a?(Hash)
46
52
  end
47
53
 
48
- def comparable?(key)
54
+ def array?(value)
55
+ value.is_a?(Array)
56
+ end
57
+
58
+ def comparable_hash?(key)
49
59
  hash?(left[key]) && hash?(right[key])
50
60
  end
51
61
 
62
+ def comparable_array?(key)
63
+ array?(left[key]) && array?(right[key])
64
+ end
65
+
52
66
  def report_difference(key, reporter)
53
- if comparable?(key)
67
+ if comparable_hash?(key)
68
+ self.class.new(left[key], right[key]).find_differences(&reporter)
69
+ elsif comparable_array?(key)
54
70
  self.class.new(left[key], right[key]).find_differences(&reporter)
55
71
  else
56
- reporter.call(left[key], right[key])
72
+ reporter.call(
73
+ value_with_default(left, key),
74
+ value_with_default(right, key)
75
+ )
57
76
  end
58
77
  end
78
+
79
+ def value_with_default(obj, key)
80
+ obj.fetch(key, NO_VALUE)
81
+ end
59
82
  end
60
83
  end
84
+
@@ -1,3 +1,3 @@
1
1
  module HashDiff
2
- VERSION = "0.8.0"
2
+ VERSION = "1.1.1"
3
3
  end
data/lib/hash_diff.rb CHANGED
@@ -2,6 +2,8 @@ require "hash_diff/version"
2
2
  require "hash_diff/comparison"
3
3
 
4
4
  module HashDiff
5
+ class NO_VALUE; end
6
+
5
7
  def self.patch!
6
8
  Hash.class_eval do
7
9
  def diff(right)
@@ -0,0 +1,78 @@
1
+ require "spec_helper"
2
+
3
+ describe HashDiff::Comparison do
4
+ let(:left) {
5
+ [
6
+ {
7
+ foo: 'bar',
8
+ bar: 'foo',
9
+ },
10
+ {
11
+ nested: {
12
+ foo: 'bar',
13
+ bar: {
14
+ one: 'foo1'
15
+ }
16
+ },
17
+ },
18
+ {
19
+ num: 1,
20
+ word: nil
21
+ }
22
+ ]
23
+ }
24
+
25
+ def comparison(to_compare)
26
+ HashDiff::Comparison.new(left, to_compare)
27
+ end
28
+
29
+ def right
30
+ [
31
+ {
32
+ foo: 'bar',
33
+ bar: 'foo',
34
+ },
35
+ {
36
+ nested: {
37
+ foo: 'bar',
38
+ bar: {
39
+ one: 'foo1'
40
+ }
41
+ },
42
+ },
43
+ {
44
+ num: 1,
45
+ word: nil
46
+ }
47
+ ]
48
+ end
49
+
50
+ describe 'when arrays are the same' do
51
+ it 'properly determines equality' do
52
+ expect(comparison(right).diff).to be_empty
53
+ end
54
+
55
+ it 'handles empty arrays' do
56
+ expect(HashDiff::Comparison.new([], []).diff).to be_empty
57
+ end
58
+ end
59
+
60
+ describe 'when arrays are different' do
61
+ it 'reports arrays as not equal with a different order' do
62
+ # move an item from the end to the beginning
63
+ right_shuffled = right
64
+ popped = right_shuffled.pop
65
+ right_shuffled.unshift(popped)
66
+
67
+ expect(comparison(right_shuffled).diff).to_not be_empty
68
+ end
69
+
70
+ it 'should a deep comparison' do
71
+ right_with_extra_nested_element = right
72
+ right_with_extra_nested_element[1][:nested][:bar][:two] = 'two'
73
+
74
+ expect(comparison(right_with_extra_nested_element).diff).to_not be_empty
75
+ end
76
+ end
77
+
78
+ end
@@ -2,10 +2,37 @@ require "spec_helper"
2
2
 
3
3
  describe HashDiff::Comparison do
4
4
 
5
- let(:app_v1_properties) { { foo: 'bar', bar: 'foo', nested: { foo: 'bar', bar: { one: 'foo1' } }, num: 1 } }
6
- let(:app_v2_properties) { { foo: 'bar2', bar: 'foo2', nested: { foo: 'bar2', bar: { two: 'foo2' } }, word: 'monkey' } }
5
+ let(:app_v1_properties) {
6
+ {
7
+ foo: 'bar',
8
+ bar: 'foo',
9
+ nested: {
10
+ foo: 'bar',
11
+ bar: {
12
+ one: 'foo1'
13
+ }
14
+ },
15
+ num: 1,
16
+ word: nil
17
+ }
18
+ }
19
+ let(:app_v2_properties) {
20
+ {
21
+ foo: 'bar2',
22
+ bar: 'foo2',
23
+ nested: {
24
+ foo: 'bar2',
25
+ bar: {
26
+ two: 'foo2'
27
+ }
28
+ },
29
+ word: 'monkey'
30
+ }
31
+ }
7
32
 
8
- subject(:comparison) { HashDiff::Comparison.new(app_v1_properties, app_v2_properties) }
33
+ subject(:comparison) {
34
+ HashDiff::Comparison.new(app_v1_properties, app_v2_properties)
35
+ }
9
36
 
10
37
  describe "#diff" do
11
38
  subject { comparison.diff }
@@ -18,11 +45,11 @@ describe HashDiff::Comparison do
18
45
  nested: {
19
46
  foo: ["bar", "bar2"],
20
47
  bar: {
21
- one: ["foo1", nil],
22
- two: [nil, "foo2"]
48
+ one: ["foo1", HashDiff::NO_VALUE],
49
+ two: [HashDiff::NO_VALUE, "foo2"]
23
50
  }
24
51
  },
25
- num: [1, nil],
52
+ num: [1, HashDiff::NO_VALUE],
26
53
  word: [nil, "monkey"]
27
54
  }
28
55
  }
@@ -45,6 +72,19 @@ describe HashDiff::Comparison do
45
72
  it { expect(subject).to be_empty }
46
73
  end
47
74
  end
75
+
76
+ context "when hashes have both symbol and string keys" do
77
+ let(:app_v1_properties) { { foo: "bar" } }
78
+ let(:app_v2_properties) { { "foo" => "bar" } }
79
+ let(:diff) do
80
+ {
81
+ foo: ["bar", HashDiff::NO_VALUE],
82
+ "foo" => [HashDiff::NO_VALUE, "bar"]
83
+ }
84
+ end
85
+
86
+ it { expect(subject).to eq(diff) }
87
+ end
48
88
  end
49
89
 
50
90
  describe "#left_diff" do
@@ -57,11 +97,11 @@ describe HashDiff::Comparison do
57
97
  nested: {
58
98
  foo: "bar2",
59
99
  bar: {
60
- one: nil,
100
+ one: HashDiff::NO_VALUE,
61
101
  two: "foo2"
62
102
  }
63
103
  },
64
- num: nil,
104
+ num: HashDiff::NO_VALUE,
65
105
  word: "monkey"
66
106
  }
67
107
  }
@@ -80,7 +120,7 @@ describe HashDiff::Comparison do
80
120
  foo: "bar",
81
121
  bar: {
82
122
  one: "foo1",
83
- two: nil
123
+ two: HashDiff::NO_VALUE
84
124
  }
85
125
  },
86
126
  num: 1,
metadata CHANGED
@@ -1,30 +1,31 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hash_diff
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Coding Zeal
8
8
  - Adam Cuppy
9
- autorequire:
9
+ - Mike Bianco
10
+ autorequire:
10
11
  bindir: bin
11
12
  cert_chain: []
12
- date: 2015-08-28 00:00:00.000000000 Z
13
+ date: 2022-08-29 00:00:00.000000000 Z
13
14
  dependencies:
14
15
  - !ruby/object:Gem::Dependency
15
16
  name: bundler
16
17
  requirement: !ruby/object:Gem::Requirement
17
18
  requirements:
18
- - - "~>"
19
+ - - ">="
19
20
  - !ruby/object:Gem::Version
20
- version: '1.3'
21
+ version: '0'
21
22
  type: :development
22
23
  prerelease: false
23
24
  version_requirements: !ruby/object:Gem::Requirement
24
25
  requirements:
25
- - - "~>"
26
+ - - ">="
26
27
  - !ruby/object:Gem::Version
27
- version: '1.3'
28
+ version: '0'
28
29
  - !ruby/object:Gem::Dependency
29
30
  name: rake
30
31
  requirement: !ruby/object:Gem::Requirement
@@ -56,12 +57,16 @@ dependencies:
56
57
  description: Diff tool for deep Ruby hash comparison
57
58
  email:
58
59
  - info@codingzeal.com
60
+ - mike@mikebian.co
59
61
  executables: []
60
62
  extensions: []
61
63
  extra_rdoc_files: []
62
64
  files:
65
+ - ".github/dependabot.yml"
66
+ - ".github/workflows/codeql.yml"
67
+ - ".github/workflows/ruby.yml"
63
68
  - ".gitignore"
64
- - ".travis.yml"
69
+ - ".ruby-version"
65
70
  - Gemfile
66
71
  - LICENSE.txt
67
72
  - README.md
@@ -70,6 +75,7 @@ files:
70
75
  - lib/hash_diff.rb
71
76
  - lib/hash_diff/comparison.rb
72
77
  - lib/hash_diff/version.rb
78
+ - spec/hash_diff/array_comparison_spec.rb
73
79
  - spec/hash_diff/comparison_spec.rb
74
80
  - spec/hash_diff_spec.rb
75
81
  - spec/spec_helper.rb
@@ -77,7 +83,7 @@ homepage: https://github.com/CodingZeal/hash_diff
77
83
  licenses:
78
84
  - MIT
79
85
  metadata: {}
80
- post_install_message:
86
+ post_install_message:
81
87
  rdoc_options: []
82
88
  require_paths:
83
89
  - lib
@@ -92,13 +98,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
92
98
  - !ruby/object:Gem::Version
93
99
  version: '0'
94
100
  requirements: []
95
- rubyforge_project:
96
- rubygems_version: 2.2.2
97
- signing_key:
101
+ rubygems_version: 3.1.6
102
+ signing_key:
98
103
  specification_version: 4
99
104
  summary: Deep Ruby Hash comparison
100
105
  test_files:
106
+ - spec/hash_diff/array_comparison_spec.rb
101
107
  - spec/hash_diff/comparison_spec.rb
102
108
  - spec/hash_diff_spec.rb
103
109
  - spec/spec_helper.rb
104
- has_rdoc:
data/.travis.yml DELETED
@@ -1,6 +0,0 @@
1
- script: "bundle exec rspec spec"
2
-
3
- language: ruby
4
-
5
- rvm:
6
- - 1.9.3