hash_diff 0.8.0 → 1.1.1

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 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