Move parallel diff logic to separate class
This commit is contained in:
parent
c7264d2a76
commit
701513dcc7
8 changed files with 148 additions and 127 deletions
|
@ -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
|
||||
|
|
|
@ -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])
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
= link_to_new_diff_note(line_code)
|
||||
%td.new_line{data: {linenumber: line.new_pos}}
|
||||
= link_to raw(type == "old" ? " " : 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)
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
= raw(type == "new" ? " " : line.old_pos)
|
||||
%td.new_line
|
||||
= raw(type == "old" ? " " : 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
|
||||
|
|
|
@ -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
|
||||
|
|
117
lib/gitlab/diff/parallel_diff.rb
Normal file
117
lib/gitlab/diff/parallel_diff.rb
Normal 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
|
|
@ -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
|
||||
|
|
22
spec/lib/gitlab/diff/parallel_diff_spec.rb
Normal file
22
spec/lib/gitlab/diff/parallel_diff_spec.rb
Normal 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
|
Loading…
Reference in a new issue