Class: HashDeepDiff::Comparison

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
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(original, changed, prefix = [], reporting_engine: Reports::Diff, delta_engine: Delta) ⇒ Comparison (private)



85
86
87
88
89
90
91
# File 'lib/hash_deep_diff/comparison.rb', line 85

def initialize(original, changed, prefix = [], reporting_engine: Reports::Diff, delta_engine: Delta)
  @left = original
  @right = changed
  @path = prefix.to_ary
  @reporting_engine = reporting_engine
  @delta_engine = delta_engine
end

Instance Attribute Details

#delta_engineObject (readonly)

Returns the value of attribute delta_engine.



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

def delta_engine
  @delta_engine
end

#left(key = NO_VALUE) ⇒ Object (readonly)



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

attr_reader :reporting_engine, :delta_engine

#pathArray<Object> (readonly, private)

(is empty for top-level comparison)



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

attr_reader :reporting_engine, :delta_engine

#reporting_engineObject (readonly)

Returns the value of attribute reporting_engine.



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

def reporting_engine
  @reporting_engine
end

#right(key = NO_VALUE) ⇒ Object (readonly)



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

attr_reader :reporting_engine, :delta_engine

Instance Method Details

#common_keysArray (private)

All keys from both original and compared objects



128
129
130
131
132
133
134
# File 'lib/hash_deep_diff/comparison.rb', line 128

def common_keys
  keys = []
  keys += left.keys if left.respond_to?(:keys)
  keys += right.keys if right.respond_to?(:keys)

  keys.uniq
end

#comparison_factoryHashDeepDiff::Factories::Comparison (private)



137
138
139
# File 'lib/hash_deep_diff/comparison.rb', line 137

def comparison_factory
  HashDeepDiff::Factories::Comparison.new(reporting_engine: reporting_engine)
end

#delta(key: NO_VALUE) ⇒ HashDeepDiff::Delta (private)

factory function



143
144
145
146
147
148
# File 'lib/hash_deep_diff/comparison.rb', line 143

def delta(key: NO_VALUE)
  change_key = path
  change_key += [key] unless key == NO_VALUE

  HashDeepDiff::Delta.new(change_key: change_key, value: { left: left(key), right: right(key) })
end

#deltasArray<HashDeepDiff::Delta> (private)

HashDeepDiff::Comparison broken down into array of Delta



95
96
97
98
99
100
101
102
103
# File 'lib/hash_deep_diff/comparison.rb', line 95

def deltas
  return [delta] if common_keys.empty?

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

    memo << delta(key: key)
  end
end

#diffArray<HashDeepDiff::Delta>



56
57
58
59
60
# File 'lib/hash_deep_diff/comparison.rb', line 56

def diff
  return [] if left == right

  deltas.flat_map { |new_delta| new_delta.simple? ? new_delta : inward_comparison(new_delta) }
end

#inward_comparison(complex_delta) ⇒ Array<HashDeepDiff::Delta> (private)

depending on circumstances will return necessary comparisons



107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/hash_deep_diff/comparison.rb', line 107

def inward_comparison(complex_delta)
  if complex_delta.partial?
    [
      complex_delta.placebo,
      comparison(delta: complex_delta, modifier: :right).diff,
      comparison(delta: complex_delta, modifier: :left).diff
    ].compact.flatten
    # TOFIX add test an drop flatten
  else
    comparison(delta: complex_delta).diff
  end
end

#reportString



51
52
53
# File 'lib/hash_deep_diff/comparison.rb', line 51

def report
  diff.map { |simple_delta| reporting_engine.new(delta: simple_delta).to_s }.join
end

#values_equal?(key) ⇒ Bool (private)



122
123
124
# File 'lib/hash_deep_diff/comparison.rb', line 122

def values_equal?(key)
  right(key).instance_of?(left(key).class) && (right(key) == left(key))
end