module Dyph::TwoWayDiffers::OutputConverter

rubocop:disable Metrics/ModuleLength

Public Instance Methods

convert_to_dyph_output(old_text, new_text) click to toggle source
# File lib/dyph/two_way_differs/output_converter.rb, line 7
def convert_to_dyph_output(old_text, new_text)
  actions =  merge_and_partition(old_text, new_text)
  selected_actions = extract_add_deletes_changes(actions)
  correct_offsets(selected_actions)
end
merge_results(old_text, new_text) click to toggle source
# File lib/dyph/two_way_differs/output_converter.rb, line 33
def merge_results(old_text, new_text)
  merged_text = []

  if (new_text.empty?)
    no_new_text(old_text, merged_text)
  else
    prepend_old_text(old_text, merged_text)
    gather_up_actions(old_text, new_text, merged_text)
  end
  merged_text
end
objectify(merge_results) click to toggle source
# File lib/dyph/two_way_differs/output_converter.rb, line 13
def objectify(merge_results)
  merge_results.map do |result|
    action = result[:action]
    line   = result[:line]
    old_index = result[:old_index]
    new_index = result[:new_index]

    case action
    when :add
      Dyph::Action::Add.new(value: line, old_index: old_index, new_index: new_index)
    when :delete
      Dyph::Action::Delete.new(value: line, old_index: old_index, new_index: new_index)
    when :no_change
      Dyph::Action::NoChange.new(value: line.text, old_index: old_index, new_index: new_index)
    else
      raise "unhandled action"
    end
  end
end

Private Instance Methods

change_or_delete(old_text, line, prev_no_change_old, merged_text, index) click to toggle source
# File lib/dyph/two_way_differs/output_converter.rb, line 80
def change_or_delete(old_text, line, prev_no_change_old, merged_text, index)
  merged_text << {action: :no_change, line: line, old_index: line.row, new_index: index}

  ((prev_no_change_old+1) ... old_text.length).each do |n|
    break if old_text[n].is_a?(TextNode)
    merged_text << {action: :delete, line: old_text[n], old_index: n+1, new_index: index+1}
  end
end
collapse_action(actions) click to toggle source
# File lib/dyph/two_way_differs/output_converter.rb, line 128
def collapse_action(actions)
  actions.inject({}) do | hash, action |
    hash[:action] ||= action[:action]
    hash[:old_lo] ||= action[:old_lo]
    hash[:old_hi] =   action[:old_hi]
    hash[:new_lo] ||= action[:new_lo]
    hash[:new_hi] =   action[:new_hi]
    hash
  end
end
correct_offsets(selected_actions) click to toggle source
# File lib/dyph/two_way_differs/output_converter.rb, line 58
def correct_offsets(selected_actions)
  fix_offsets = set_offset(selected_actions)
  fix_offsets.map { |r| Dyph::Support::AssignAction.get_action(
    lo_a: r[:old_lo]-1 ,
    lo_b: r[:new_lo]-1,
    hi_a: r[:old_hi]-1,
    hi_b: r[:new_hi]-1
  )}
end
extract_add_deletes_changes(actions) click to toggle source
# File lib/dyph/two_way_differs/output_converter.rb, line 52
def extract_add_deletes_changes(actions)
  collapsed_actions = actions.map { |action| collapse_action(action) }
  paired_results = pair_up_add_deletes collapsed_actions
  paired_results.reject { |res| res[:action] == :no_change}
end
gather_up_actions(old_text, new_text, merged_text) click to toggle source
# File lib/dyph/two_way_differs/output_converter.rb, line 68
def gather_up_actions(old_text, new_text, merged_text)
  prev_no_change_old = - 1
  new_text.map.with_index.each do |line, i|
    if !line.is_a?(TextNode)
      merged_text << {action: :add, line: line, old_index: prev_no_change_old + 1, new_index: i+1}
    else
      prev_no_change_old = line.row
      change_or_delete(old_text, line, prev_no_change_old, merged_text, i)
    end
  end
end
is_a_pair?(actions, i) click to toggle source
# File lib/dyph/two_way_differs/output_converter.rb, line 139
def is_a_pair?(actions, i)
  action_one =  actions[i-1][:action] if actions[i-1]
  action_two =  actions[i][:action]   if actions[i]
  Set.new([action_one, action_two]) == Set.new([:add, :delete])
end
merge_and_partition(old_text, new_text) click to toggle source
# File lib/dyph/two_way_differs/output_converter.rb, line 46
def merge_and_partition(old_text, new_text)
  merged_text = merge_results(old_text, new_text)
  merge_output_lines = merged_text.map { |x| to_output_format x }
  partition_into_actions(merge_output_lines)
end
no_new_text(old_text, merged_text) click to toggle source
# File lib/dyph/two_way_differs/output_converter.rb, line 98
def no_new_text(old_text, merged_text)
  old_text.map.with_index do |line, i|
    merged_text << { action: :delete, line: line, old_index: i+1, new_index: i}
  end
end
pair_up_add_deletes(actions) click to toggle source
# File lib/dyph/two_way_differs/output_converter.rb, line 145
def pair_up_add_deletes(actions)
  results = []
  found_change = false
  (1 .. actions.length).each do |i|
    if is_a_pair?(actions, i)
      results << {
        action: :change,
        old_lo: actions[i-1][:old_lo],
        old_hi: actions[i-1][:old_hi],
        new_lo: actions[i][:new_lo],
        new_hi: actions[i][:new_hi]
      }
      found_change = true
    elsif found_change
      found_change = false
    else
      results << actions[i-1]
    end
  end
  results
end
partition_into_actions(array) click to toggle source
# File lib/dyph/two_way_differs/output_converter.rb, line 167
def partition_into_actions(array)
  array.inject([]) do |acc, x|
    if acc.length == 0 || acc.last.last[:action] != x[:action]
      acc << [x]
    else
      acc.last << x
    end
    acc
  end
end
prepend_old_text(old_text, merged_text) click to toggle source
# File lib/dyph/two_way_differs/output_converter.rb, line 89
def prepend_old_text(old_text, merged_text)
  if !old_text.first.is_a?(TextNode)
    old_text.map.with_index.each do |line, i|
      break if line.is_a?(TextNode)
      merged_text << {action: :delete, line: line, old_index:i+1, new_index: i}
    end
  end
end
set_offset(results) click to toggle source
# File lib/dyph/two_way_differs/output_converter.rb, line 104
def set_offset(results)
  results.map do |result_row|
    if result_row[:action] == :add
      result_row[:old_lo] += 1
      result_row
    elsif result_row[:action] == :delete
      result_row[:new_lo] += 1
      result_row
    else
      result_row
    end
  end
end
to_output_format(result_row) click to toggle source
# File lib/dyph/two_way_differs/output_converter.rb, line 118
def to_output_format(result_row)
  {
    action: result_row[:action],
    old_lo: result_row[:old_index],
    old_hi: result_row[:old_index],
    new_lo: result_row[:new_index],
    new_hi: result_row[:new_index]
  }
end