Move parallel diff logic to separate class

This commit is contained in:
Douwe Maan 2016-01-20 14:51:56 +01:00
parent c7264d2a76
commit 701513dcc7
8 changed files with 148 additions and 127 deletions

View file

@ -39,110 +39,6 @@ module DiffHelper
end
end
def generate_line_code(file_path, line)
Gitlab::Diff::LineCode.generate(file_path, line.new_pos, line.old_pos)
end
def parallel_diff(diff_file, index)
lines = []
skip_next = false
diff_file.highlighted_diff_lines.each do |line|
full_line = line.text
type = line.type
line_code = generate_line_code(diff_file.file_path, line)
line_new = line.new_pos
line_old = line.old_pos
next_line = diff_file.next_line(line.index)
if next_line
next_line_code = generate_line_code(diff_file.file_path, next_line)
next_type = next_line.type
next_line = next_line.text
end
case type
when 'match', nil
# line in the right panel is the same as in the left one
lines << {
left: {
type: type,
number: line_old,
text: full_line,
line_code: line_code,
},
right: {
type: type,
number: line_new,
text: full_line,
line_code: line_code
}
}
when 'old'
case next_type
when 'new'
# Left side has text removed, right side has text added
lines << {
left: {
type: type,
number: line_old,
text: full_line,
line_code: line_code,
},
right: {
type: next_type,
number: line_new,
text: next_line,
line_code: next_line_code
}
}
skip_next = true
when 'old', nil
# Left side has text removed, right side doesn't have any change
# No next line code, no new line number, no new line text
lines << {
left: {
type: type,
number: line_old,
text: full_line,
line_code: line_code,
},
right: {
type: next_type,
number: nil,
text: "",
line_code: nil
}
}
end
when 'new'
if skip_next
# Change has been already included in previous line so no need to do it again
skip_next = false
next
else
# Change is only on the right side, left side has no change
lines << {
left: {
type: nil,
number: nil,
text: "",
line_code: line_code,
},
right: {
type: type,
number: line_new,
text: full_line,
line_code: line_code
}
}
end
end
end
lines
end
def unfold_bottom_class(bottom)
(bottom) ? 'js-unfold-bottom' : ''
end

View file

@ -1,7 +1,7 @@
/ Side-by-side diff view
%div.text-file.diff-wrap-lines.code.file-content.js-syntax-highlight
%table
- parallel_diff(diff_file, index).each do |line|
- diff_file.parallel_diff_lines.each do |line|
- left = line[:left]
- right = line[:right]
%tr.line_holder.parallel
@ -13,7 +13,7 @@
= link_to raw(left[:number]), "##{left[:line_code]}", id: left[:line_code]
- if @comments_allowed && can?(current_user, :create_note, @project)
= link_to_new_diff_note(left[:line_code], 'old')
%td.line_content{class: "parallel noteable_line #{left[:type]} #{left[:line_code]}", data: { "line_code" => left[:line_code] }}= diff_line_content(left[:text])
%td.line_content{class: "parallel noteable_line #{left[:type]} #{left[:line_code]}", data: { line_code: left[:line_code] }}= diff_line_content(left[:text])
- if right[:type] == 'new'
- new_line_class = 'new'
@ -26,7 +26,7 @@
= link_to raw(right[:number]), "##{new_line_code}", id: new_line_code
- if @comments_allowed && can?(current_user, :create_note, @project)
= link_to_new_diff_note(right[:line_code], 'new')
%td.line_content.parallel{class: "noteable_line #{new_line_class} #{new_line_code}", data: { "line_code" => new_line_code }}= diff_line_content(right[:text])
%td.line_content.parallel{class: "noteable_line #{new_line_class} #{new_line_code}", data: { line_code: new_line_code }}= diff_line_content(right[:text])
- if @reply_allowed
- comments_left, comments_right = organize_comments(left[:type], right[:type], left[:line_code], right[:line_code])

View file

@ -22,7 +22,7 @@
= link_to_new_diff_note(line_code)
%td.new_line{data: {linenumber: line.new_pos}}
= link_to raw(type == "old" ? "&nbsp;" : line.new_pos), "##{line_code}", id: line_code
%td.line_content{class: "noteable_line #{type} #{line_code}", data: { "line_code" => line_code }}= diff_line_content(line.text)
%td.line_content{class: "noteable_line #{type} #{line_code}", data: { line_code: line_code }}= diff_line_content(line.text)
- if @reply_allowed
- comments = @line_notes.select { |n| n.line_code == line_code && n.active? }.sort_by(&:created_at)

View file

@ -24,7 +24,7 @@
= raw(type == "new" ? "&nbsp;" : line.old_pos)
%td.new_line
= raw(type == "old" ? "&nbsp;" : line.new_pos)
%td.line_content{class: "noteable_line #{type} #{line_code}", "line_code" => line_code}= diff_line_content(line.text)
%td.line_content{class: "noteable_line #{type} #{line_code}", line_code: line_code}= diff_line_content(line.text)
- if line_code == note.line_code
= render "projects/notes/diff_notes_with_reply", notes: discussion_notes

View file

@ -20,6 +20,10 @@ module Gitlab
Gitlab::Diff::Highlight.new(self).highlight
end
def parallel_diff_lines
Gitlab::Diff::ParallelDiff.new(self).parallelize
end
def mode_changed?
!!(diff.a_mode && diff.b_mode && diff.a_mode != diff.b_mode)
end

View file

@ -0,0 +1,117 @@
module Gitlab
module Diff
class ParallelDiff
attr_accessor :diff_file
def initialize(diff_file)
@diff_file = diff_file
end
def parallelize
lines = []
skip_next = false
diff_file.highlighted_diff_lines.each do |line|
full_line = line.text
type = line.type
line_code = generate_line_code(diff_file.file_path, line)
line_new = line.new_pos
line_old = line.old_pos
next_line = diff_file.next_line(line.index)
if next_line
next_line_code = generate_line_code(diff_file.file_path, next_line)
next_type = next_line.type
next_line = next_line.text
end
case type
when 'match', nil
# line in the right panel is the same as in the left one
lines << {
left: {
type: type,
number: line_old,
text: full_line,
line_code: line_code,
},
right: {
type: type,
number: line_new,
text: full_line,
line_code: line_code
}
}
when 'old'
case next_type
when 'new'
# Left side has text removed, right side has text added
lines << {
left: {
type: type,
number: line_old,
text: full_line,
line_code: line_code,
},
right: {
type: next_type,
number: line_new,
text: next_line,
line_code: next_line_code
}
}
skip_next = true
when 'old', nil
# Left side has text removed, right side doesn't have any change
# No next line code, no new line number, no new line text
lines << {
left: {
type: type,
number: line_old,
text: full_line,
line_code: line_code,
},
right: {
type: next_type,
number: nil,
text: "",
line_code: nil
}
}
end
when 'new'
if skip_next
# Change has been already included in previous line so no need to do it again
skip_next = false
next
else
# Change is only on the right side, left side has no change
lines << {
left: {
type: nil,
number: nil,
text: "",
line_code: line_code,
},
right: {
type: type,
number: line_new,
text: full_line,
line_code: line_code
}
}
end
end
end
lines
end
private
def generate_line_code(file_path, line)
Gitlab::Diff::LineCode.generate(file_path, line.new_pos, line.old_pos)
end
end
end
end

View file

@ -84,20 +84,6 @@ describe DiffHelper do
end
end
describe 'parallel_diff' do
it 'should return an array of arrays containing the parsed diff' do
expect(parallel_diff(diff_file, 0)).
to match_array(parallel_diff_result_array)
end
end
describe 'generate_line_code' do
it 'should generate correct line code' do
expect(generate_line_code(diff_file.file_path, diff_file.diff_lines.first)).
to eq('2f6fcd96b88b36ce98c38da085c795a27d92a3dd_6_6')
end
end
describe 'unfold_bottom_class' do
it 'should return empty string when bottom line shouldnt be unfolded' do
expect(unfold_bottom_class(false)).to eq('')
@ -135,8 +121,4 @@ describe DiffHelper do
expect(diff_line_content(diff_file.diff_lines.first.text)).to be_html_safe
end
end
def parallel_diff_result_array
YAML.load_file("#{Rails.root}/spec/fixtures/parallel_diff_result.yml")
end
end

View file

@ -0,0 +1,22 @@
require 'spec_helper'
describe Gitlab::Diff::ParallelDiff, lib: true do
include RepoHelpers
let(:project) { create(:project) }
let(:repository) { project.repository }
let(:commit) { project.commit(sample_commit.id) }
let(:diffs) { commit.diffs }
let(:diff) { diffs.first }
let(:diff_refs) { [commit.parent, commit] }
let(:diff_file) { Gitlab::Diff::File.new(diff, diff_refs) }
subject { described_class.new(diff_file) }
let(:parallel_diff_result_array) { YAML.load_file("#{Rails.root}/spec/fixtures/parallel_diff_result.yml") }
describe '#parallelize' do
it 'should return an array of arrays containing the parsed diff' do
expect(subject.parallelize).to match_array(parallel_diff_result_array)
end
end
end