module Dyph::Support::SanityCheck

Public Instance Methods

ensure_no_lost_data(left, base, right, final_result) click to toggle source

rubocop:disable Metrics/AbcSize

# File lib/dyph/support/sanity_check.rb, line 7
def ensure_no_lost_data(left, base, right, final_result)
  result_word_map = {}
  final_result.each do |result_block|
    blocks = case result_block
      when Outcome::Resolved then result_block.result
      when Outcome::Conflicted then [result_block.left, result_block.right].flatten
      else raise "Unknown block type, #{result_block[:type]}"
    end
    count_blocks(blocks, result_word_map)
  end

  left_word_map, base_word_map, right_word_map = [left, base, right].map { |str| count_blocks(str) }

  # new words are words that are in left or right, but not in base
  new_left_words = subtract_words(left_word_map, base_word_map)
  new_right_words = subtract_words(right_word_map, base_word_map)

  # now make sure all new words are somewhere in the result
  missing_new_left_words = subtract_words(new_left_words, result_word_map)
  missing_new_right_words = subtract_words(new_right_words, result_word_map)

  if missing_new_left_words.any? || missing_new_right_words.any?
    raise BadMergeException.new(final_result)
  end
end

Private Instance Methods

count_blocks(blocks, hash={}) click to toggle source

rubocop:enable Metrics/AbcSize

# File lib/dyph/support/sanity_check.rb, line 35
def count_blocks(blocks, hash={})
  blocks.reduce(hash) do |map, block|
    map[block] ||= 0
    map[block] += 1
    map
  end
end
subtract_words(left_map, right_map) click to toggle source
# File lib/dyph/support/sanity_check.rb, line 43
def subtract_words(left_map, right_map)
  remaining_words = {}
  
  left_map.each do |word, count|
    count_in_right = right_map[word] || 0
    
    new_count = count - count_in_right
    remaining_words[word] = new_count if new_count > 0
  end
  
  remaining_words
end