Move diff_line preparation into presenter

Update spec
This commit is contained in:
Mark Chao 2019-03-07 12:29:02 +08:00
parent b14de8e1f5
commit cea59dbe03
4 changed files with 130 additions and 87 deletions

View file

@ -91,51 +91,20 @@ class Projects::BlobController < Projects::ApplicationController
apply_diff_view_cookie!
@form = Blobs::UnfoldPresenter.new(blob, params.to_unsafe_h)
@lines = @form.lines
@match_line = @form.match_line_text
# We can keep only 'render_diff_lines' from this conditional when
# keep only json rendering when
# https://gitlab.com/gitlab-org/gitlab-ce/issues/44988 is done
if rendered_for_merge_request?
render_diff_lines
render json: DiffLineSerializer.new.represent(@form.diff_lines)
else
@lines = @form.lines
@match_line = @form.match_line_text
render layout: false
end
end
private
# Converts a String array to Gitlab::Diff::Line array
def render_diff_lines
@lines.map! do |line|
diff_line = Gitlab::Diff::Line.new(line, nil, nil, nil, nil)
diff_line.rich_text = line
diff_line
end
add_match_line
render json: DiffLineSerializer.new.represent(@lines)
end
def add_match_line
return unless @form.unfold?
if @form.bottom? && @form.to < @blob.lines.size
old_pos = @form.to - @form.offset
new_pos = @form.to
elsif @form.since != 1
old_pos = new_pos = @form.since
end
# Match line is not needed when it reaches the top limit or bottom limit of the file.
return unless new_pos
@match_line = Gitlab::Diff::Line.new(@match_line, 'match', nil, old_pos, new_pos)
@form.bottom? ? @lines.push(@match_line) : @lines.unshift(@match_line)
end
def blob
@blob ||= @repository.blob_at(@commit.id, @path)

View file

@ -25,6 +25,17 @@ module Blobs
end
end
# Converts a String array to Gitlab::Diff::Line array, with match line added
def diff_lines
diff_lines = lines.map do |line|
Gitlab::Diff::Line.new(line, nil, nil, nil, nil, rich_text: line)
end
add_match_line(diff_lines)
diff_lines
end
def lines
strong_memoize(:lines) do
lines = @all_lines
@ -40,5 +51,25 @@ module Blobs
line = [since, lines_length].join(',')
"@@ -#{line}+#{line} @@"
end
private
def add_match_line(diff_lines)
return unless unfold?
if bottom? && to < @all_lines.size
old_pos = to - offset
new_pos = to
elsif since != 1
old_pos = new_pos = since
end
# Match line is not needed when it reaches the top limit or bottom limit of the file.
return unless new_pos
match_line = Gitlab::Diff::Line.new(match_line_text, 'match', nil, old_pos, new_pos)
bottom? ? diff_lines.push(match_line) : diff_lines.unshift(match_line)
end
end
end

View file

@ -144,66 +144,34 @@ describe Projects::BlobController do
end
context 'when rendering for merge request' do
let(:presenter) { double(:presenter, diff_lines: diff_lines) }
let(:diff_lines) do
Array.new(3, Gitlab::Diff::Line.new('plain', nil, nil, nil, nil, rich_text: 'rich'))
end
before do
allow(Blobs::UnfoldPresenter).to receive(:new).and_return(presenter)
end
it 'renders diff context lines Gitlab::Diff::Line array' do
do_get(since: 1, to: 5, offset: 10, from_merge_request: true)
do_get(since: 1, to: 2, offset: 0, from_merge_request: true)
lines = JSON.parse(response.body)
expect(lines.first).to have_key('type')
expect(lines.first).to have_key('rich_text')
expect(lines.first).to have_key('rich_text')
expect(lines.size).to eq(diff_lines.size)
lines.each do |line|
expect(line).to have_key('type')
expect(line['text']).to eq('plain')
expect(line['rich_text']).to eq('rich')
end
end
context 'when rendering match lines' do
it 'adds top match line when "since" is less than 1' do
do_get(since: 5, to: 10, offset: 10, from_merge_request: true)
it 'handles full being true' do
do_get(full: true, from_merge_request: true)
match_line = JSON.parse(response.body).first
lines = JSON.parse(response.body)
expect(match_line['type']).to eq('match')
expect(match_line['meta_data']).to have_key('old_pos')
expect(match_line['meta_data']).to have_key('new_pos')
end
it 'does not add top match line when "since" is equal 1' do
do_get(since: 1, to: 10, offset: 10, from_merge_request: true)
match_line = JSON.parse(response.body).first
expect(match_line['type']).to be_nil
end
it 'adds bottom match line when "to" is less than blob size' do
do_get(since: 1, to: 5, offset: 10, from_merge_request: true, bottom: true)
match_line = JSON.parse(response.body).last
expect(match_line['type']).to eq('match')
expect(match_line['meta_data']).to have_key('old_pos')
expect(match_line['meta_data']).to have_key('new_pos')
end
it 'does not add bottom match line when "to" is equal to blob size' do
commit_id = project.repository.commit('master').id
blob = project.repository.blob_at(commit_id, 'CHANGELOG')
do_get(since: 1, to: blob.lines.count, offset: 10, from_merge_request: true, bottom: true)
match_line = JSON.parse(response.body).last
expect(match_line['type']).to be_nil
end
it 'returns all lines if "full" is true' do
commit_id = project.repository.commit('master').id
blob = project.repository.blob_at(commit_id, 'CHANGELOG')
do_get(full: true, from_merge_request: true, bottom: true)
match_lines = JSON.parse(response.body)
expect(match_lines.size).to eq(blob.lines.count - 1)
expect(match_lines.last['type']).to be_nil
expect(match_lines.last['text']).to include(blob.lines.last)
end
expect(lines.size).to eq(diff_lines.size)
end
end
end

View file

@ -41,6 +41,81 @@ describe Blobs::UnfoldPresenter do
end
end
describe '#diff_lines' do
let(:total_lines) { 50 }
let(:blob) { fake_blob(path: 'foo', data: (1..total_lines).to_a.join("\n")) }
context 'when "full" is true' do
let(:params) { { full: true } }
it 'returns all lines' do
lines = subject.diff_lines
expect(lines.size).to eq(total_lines)
lines.each.with_index do |line, index|
expect(line.text).to include("LC#{index + 1}")
expect(line.text).to eq(line.rich_text)
expect(line.type).to be_nil
end
end
context 'when last line is empty' do
let(:blob) { fake_blob(path: 'foo', data: "1\n2\n") }
it 'disregards last line' do
lines = subject.diff_lines
expect(lines.size).to eq(2)
end
end
end
context 'when "since" is equal to 1' do
let(:params) { { since: 1, to: 10, offset: 10 } }
it 'does not add top match line' do
line = subject.diff_lines.first
expect(line.type).to be_nil
end
end
context 'when since is greater than 1' do
let(:params) { { since: 5, to: 10, offset: 10 } }
it 'adds top match line' do
line = subject.diff_lines.first
expect(line.type).to eq('match')
expect(line.old_pos).to eq(5)
expect(line.new_pos).to eq(5)
end
end
context 'when "to" is less than blob size' do
let(:params) { { since: 1, to: 5, offset: 10, bottom: true } }
it 'adds bottom match line' do
line = subject.diff_lines.last
expect(line.type).to eq('match')
expect(line.old_pos).to eq(-5)
expect(line.new_pos).to eq(5)
end
end
context 'when "to" is equal to blob size' do
let(:params) { { since: 1, to: total_lines, offset: 10, bottom: true } }
it 'does not add bottom match line' do
line = subject.diff_lines.last
expect(line.type).to be_nil
end
end
end
describe '#lines' do
context 'when scope is specified' do
let(:params) { { since: 2, to: 3 } }