class Test::Unit::Diff::ReadableDiffer
Public Instance Methods
diff(options={})
click to toggle source
# File lib/test/unit/diff.rb, line 414 def diff(options={}) @result = [] operations.each do |tag, from_start, from_end, to_start, to_end| case tag when :replace diff_lines(from_start, from_end, to_start, to_end) when :delete tag_deleted(@from[from_start...from_end]) when :insert tag_inserted(@to[to_start...to_end]) when :equal tag_equal(@from[from_start...from_end]) else raise "unknown tag: #{tag}" end end @result end
Private Instance Methods
_diff_lines(from_start, from_end, to_start, to_end)
click to toggle source
# File lib/test/unit/diff.rb, line 529 def _diff_lines(from_start, from_end, to_start, to_end) if from_start < from_end if to_start < to_end diff_lines(from_start, from_end, to_start, to_end) else tag_deleted(@from[from_start...from_end]) end else tag_inserted(@to[to_start...to_end]) end end
compute_width(line, start, _end)
click to toggle source
# File lib/test/unit/diff.rb, line 551 def compute_width(line, start, _end) if line.respond_to?(:encoding) and Encoding.compatible?(Encoding::UTF_8, line.encoding) utf8_line = line[start..._end].encode(Encoding::UTF_8) width = 0 utf8_line.each_codepoint do |unicode_codepoint| if UTF8Line.wide_character?(unicode_codepoint) width += 2 else width += 1 end end width elsif line.is_a?(UTF8Line) line.compute_width(start, _end) else _end - start end end
cut_off_ratio()
click to toggle source
# File lib/test/unit/diff.rb, line 447 def cut_off_ratio 0.75 end
default_ratio()
click to toggle source
# File lib/test/unit/diff.rb, line 443 def default_ratio 0.74 end
diff_line(from_line, to_line)
click to toggle source
# File lib/test/unit/diff.rb, line 571 def diff_line(from_line, to_line) from_tags = "" to_tags = "" from_line, to_line, _operations = line_operations(from_line, to_line) _operations.each do |tag, from_start, from_end, to_start, to_end| from_width = compute_width(from_line, from_start, from_end) to_width = compute_width(to_line, to_start, to_end) case tag when :replace from_tags += "^" * from_width to_tags += "^" * to_width when :delete from_tags += "-" * from_width when :insert to_tags += "+" * to_width when :equal from_tags += " " * from_width to_tags += " " * to_width else raise "unknown tag: #{tag}" end end format_diff_point(from_line, to_line, from_tags, to_tags) end
diff_lines(from_start, from_end, to_start, to_end)
click to toggle source
# File lib/test/unit/diff.rb, line 501 def diff_lines(from_start, from_end, to_start, to_end) info = find_diff_line_info(from_start, from_end, to_start, to_end) best_ratio, from_equal_index, to_equal_index, *info = info from_best_index, to_best_index = info from_best_index ||= from_start to_best_index ||= to_start if best_ratio < cut_off_ratio if from_equal_index.nil? if to_end - to_start < from_end - from_start tag_inserted(@to[to_start...to_end]) tag_deleted(@from[from_start...from_end]) else tag_deleted(@from[from_start...from_end]) tag_inserted(@to[to_start...to_end]) end return end from_best_index = from_equal_index to_best_index = to_equal_index best_ratio = 1.0 end _diff_lines(from_start, from_best_index, to_start, to_best_index) diff_line(@from[from_best_index], @to[to_best_index]) _diff_lines(from_best_index + 1, from_end, to_best_index + 1, to_end) end
find_diff_line_info(from_start, from_end, to_start, to_end)
click to toggle source
# File lib/test/unit/diff.rb, line 473 def find_diff_line_info(from_start, from_end, to_start, to_end) best_ratio = default_ratio from_equal_index = to_equal_index = nil from_best_index = to_best_index = nil to_start.upto(to_end - 1) do |to_index| from_start.upto(from_end - 1) do |from_index| if @from[from_index] == @to[to_index] from_equal_index ||= from_index to_equal_index ||= to_index next end matcher = SequenceMatcher.new(@from[from_index], @to[to_index], &method(:space_character?)) if matcher.ratio > best_ratio best_ratio = matcher.ratio from_best_index = from_index to_best_index = to_index end end end [best_ratio, from_equal_index, to_equal_index, from_best_index, to_best_index] end
format_diff_point(from_line, to_line, from_tags, to_tags)
click to toggle source
# File lib/test/unit/diff.rb, line 596 def format_diff_point(from_line, to_line, from_tags, to_tags) common = [n_leading_characters(from_line, ?\t), n_leading_characters(to_line, ?\t)].min common = [common, n_leading_characters(from_tags[0, common], " "[0])].min from_tags = from_tags[common..-1].rstrip to_tags = to_tags[common..-1].rstrip tag_deleted([from_line]) unless from_tags.empty? tag_difference(["#{"\t" * common}#{from_tags}"]) end tag_inserted([to_line]) unless to_tags.empty? tag_difference(["#{"\t" * common}#{to_tags}"]) end end
line_operations(from_line, to_line)
click to toggle source
# File lib/test/unit/diff.rb, line 541 def line_operations(from_line, to_line) if !from_line.respond_to?(:force_encoding) and $KCODE == "UTF8" from_line = UTF8Line.new(from_line) to_line = UTF8Line.new(to_line) end matcher = SequenceMatcher.new(from_line, to_line, &method(:space_character?)) [from_line, to_line, matcher.operations] end
n_leading_characters(string, character)
click to toggle source
# File lib/test/unit/diff.rb, line 614 def n_leading_characters(string, character) n = 0 while string[n] == character n += 1 end n end
operations()
click to toggle source
# File lib/test/unit/diff.rb, line 434 def operations @operations ||= nil if @operations.nil? matcher = SequenceMatcher.new(@from, @to) @operations = matcher.operations end @operations end
space_character?(character)
click to toggle source
# File lib/test/unit/diff.rb, line 622 def space_character?(character) [" "[0], "\t"[0]].include?(character) end
tag(mark, contents)
click to toggle source
# File lib/test/unit/diff.rb, line 451 def tag(mark, contents) contents.each do |content| @result << (mark + content) end end
tag_deleted(contents)
click to toggle source
# File lib/test/unit/diff.rb, line 457 def tag_deleted(contents) tag("- ", contents) end
tag_difference(contents)
click to toggle source
# File lib/test/unit/diff.rb, line 469 def tag_difference(contents) tag("? ", contents) end
tag_equal(contents)
click to toggle source
# File lib/test/unit/diff.rb, line 465 def tag_equal(contents) tag(" ", contents) end
tag_inserted(contents)
click to toggle source
# File lib/test/unit/diff.rb, line 461 def tag_inserted(contents) tag("+ ", contents) end