Class: HashDeepDiff::Comparison

Inherits:
Object
  • Object
show all
Defined in:
lib/hash_deep_diff/comparison.rb

Overview

Representation of the recursive difference between two hashes main parts are

  • path - empty for original hashes, otherwise path to values being compared

  • left - basically left.dig(path), left value of two being compared

  • right - basically right.dig(path), right value of two being compared

Examples:

 - { one: :a } compared with { one: :b } does not have nesting so we compare keys and values
 - { one: { two: :a, zero: z } } compared with { one: { two: :b, three: :c } } has nesting, so is represented as
   - { two: :a } compared with { two: :b, three: :c }, as there is no more nesting we compare keys and values
     and have the following comparisons
     { one: { two: :a } } compared to { one: { two: :b } } - value was changed
       i.e :a vas replaced with :b on path [:one, :two]
     { one: { zero: z } } compared to NO_VALUE - value was deleted
       i.e :z vas replaced with NO_VALUE on path [:one, :zero]
     NO_VALUE compared to { one: { three: :c } } compared - value was added
       i.e NO_VALUE vas replaced with :c on path [:one, :three]
[
  #<HashDeepDiff::Delta
    @delta={:two=>{:left=>:a, :right=>:b}},
    @prefix=[:one],
    @value={:left=>:a, :right=>:b}>,
  #<HashDeepDiff::Delta
    @delta={:zero=>{:left=>:z, :right=>HashDeepDiff::NO_VALUE}},
    @prefix=[:one],
    @value={:left=>:z, :right=>HashDeepDiff::NO_VALUE}>,
  #<HashDeepDiff::Delta
   @delta={:three=>{:left=>HashDeepDiff::NO_VALUE, :right=>:c}},
   @prefix=[:one],
   @value={:left=>HashDeepDiff::NO_VALUE, :right=>:c}>
]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(left, right, prefix = []) ⇒ Comparison (private)

Returns a new instance of Comparison.

Parameters:

  • left (Hash)

    original version of the hash

  • right (Hash)

    new version of the hash

  • prefix (Array) (defaults to: [])

    keys to fetch current comparison (not empty for nested comparisons)



65
66
67
68
69
# File 'lib/hash_deep_diff/comparison.rb', line 65

def initialize(left, right, prefix = [])
  @left = left.to_hash
  @right = right.to_hash
  @path = prefix.to_ary
end

Instance Attribute Details

#leftHash (readonly)

Returns original version of the Hash.

Returns:

  • (Hash)

    original version of the Hash



44
45
46
# File 'lib/hash_deep_diff/comparison.rb', line 44

def left
  @left
end

#pathObject (readonly)

Returns the value of attribute path.



44
# File 'lib/hash_deep_diff/comparison.rb', line 44

attr_reader :left, :right, :path

#rightHash (readonly)

Returns Hash that the original is compared to.

Returns:

  • (Hash)

    Hash that the original is compared to



44
# File 'lib/hash_deep_diff/comparison.rb', line 44

attr_reader :left, :right, :path

Instance Method Details

#common_keysArray (private)

All keys from both original and compared objects

Returns:

  • (Array)


100
101
102
# File 'lib/hash_deep_diff/comparison.rb', line 100

def common_keys
  (left.keys + right.keys).uniq
end

#comparisonArray<HashDeepDiff::Delta> (private)

Returns:



72
73
74
75
76
77
78
# File 'lib/hash_deep_diff/comparison.rb', line 72

def comparison
  common_keys.each_with_object([]) do |key, memo|
    next if values_equal?(key)

    memo << Delta.new(path: path + [key], value: { left: value_left(key), right: value_right(key) })
  end
end

#diffArray<HashDeepDiff::Delta>

Returns:



52
53
54
55
56
57
58
# File 'lib/hash_deep_diff/comparison.rb', line 52

def diff
  comparison.flat_map do |delta|
    # if there are nested hashes we need to compare them furter
    # if no we return difference between values (HashDeepDiff::Delta)
    delta.complex? ? self.class.new(delta.left, delta.right, delta.path).diff : delta
  end
end

#reportString

Returns:

  • (String)


47
48
49
# File 'lib/hash_deep_diff/comparison.rb', line 47

def report
  diff.join("\n")
end

#value_left(key) ⇒ Object (private)

Original value

Parameters:

  • key (Object)

    the key which value we’re currently comparing



88
89
90
# File 'lib/hash_deep_diff/comparison.rb', line 88

def value_left(key)
  left[key] || NO_VALUE
end

#value_right(key) ⇒ Object (private)

Value we compare to

Parameters:

  • key (Object)

    the key which value we’re currently comparing



94
95
96
# File 'lib/hash_deep_diff/comparison.rb', line 94

def value_right(key)
  right[key] || NO_VALUE
end

#values_equal?(key) ⇒ Bool (private)

Parameters:

  • key (Object)

    the key which value we’re currently comparing

Returns:

  • (Bool)


82
83
84
# File 'lib/hash_deep_diff/comparison.rb', line 82

def values_equal?(key)
  value_right(key).instance_of?(value_left(key).class) && (value_right(key) == value_left(key))
end