debian-mirror-gitlab/spec/lib/gitlab/suggestions/file_suggestion_spec.rb
2022-08-27 11:52:29 +05:30

454 lines
12 KiB
Ruby

# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Suggestions::FileSuggestion do
def create_suggestion(new_line, to_content, lines_above = 0, lines_below = 0)
position = Gitlab::Diff::Position.new(old_path: file_path,
new_path: file_path,
old_line: nil,
new_line: new_line,
diff_refs: merge_request.diff_refs)
diff_note = create(:diff_note_on_merge_request,
noteable: merge_request,
position: position,
project: project)
create(:suggestion,
:content_from_repo,
note: diff_note,
lines_above: lines_above,
lines_below: lines_below,
to_content: to_content)
end
let_it_be(:user) { create(:user) }
let_it_be(:file_path) { 'files/ruby/popen.rb' }
let_it_be(:project) { create(:project, :repository) }
let_it_be(:merge_request) do
create(:merge_request, source_project: project, target_project: project)
end
let_it_be(:suggestion1) do
create_suggestion(9, " *** SUGGESTION 1 ***\n")
end
let_it_be(:suggestion2) do
create_suggestion(15, " *** SUGGESTION 2 ***\n")
end
let(:suggestions) { [suggestion1, suggestion2] }
let(:file_suggestion) { described_class.new(file_path, suggestions) }
describe '#line_conflict' do
def stub_suggestions(line_index_spans)
fake_suggestions = line_index_spans.map do |span|
double("Suggestion",
from_line_index: span[:from_line_index],
to_line_index: span[:to_line_index])
end
allow(file_suggestion).to(receive(:suggestions).and_return(fake_suggestions))
end
context 'when line ranges do not overlap' do
it 'return false' do
stub_suggestions(
[
{
from_line_index: 0,
to_line_index: 10
},
{
from_line_index: 11,
to_line_index: 20
}
]
)
expect(file_suggestion.line_conflict?).to be(false)
end
end
context 'when line ranges are identical' do
it 'returns true' do
stub_suggestions(
[
{
from_line_index: 0,
to_line_index: 10
},
{
from_line_index: 0,
to_line_index: 10
}
]
)
expect(file_suggestion.line_conflict?).to be(true)
end
end
context 'when one range starts, and the other ends, on the same line' do
it 'returns true' do
stub_suggestions(
[
{
from_line_index: 0,
to_line_index: 10
},
{
from_line_index: 10,
to_line_index: 20
}
]
)
expect(file_suggestion.line_conflict?).to be(true)
end
end
context 'when one line range contains the other' do
it 'returns true' do
stub_suggestions(
[
{
from_line_index: 0,
to_line_index: 10
},
{
from_line_index: 5,
to_line_index: 7
}
]
)
expect(file_suggestion.line_conflict?).to be(true)
end
end
context 'when line ranges overlap' do
it 'returns true' do
stub_suggestions(
[
{
from_line_index: 0,
to_line_index: 10
},
{
from_line_index: 8,
to_line_index: 15
}
]
)
expect(file_suggestion.line_conflict?).to be(true)
end
end
context 'when no suggestions have been added' do
it 'returns false' do
expect(file_suggestion.line_conflict?).to be(false)
end
end
end
describe '#new_content' do
context 'with two suggestions' do
let(:suggestions) { [suggestion1, suggestion2] }
it 'returns a blob with the suggestions applied to it' do
expected_content = <<-CONTENT.strip_heredoc
require 'fileutils'
require 'open3'
module Popen
extend self
def popen(cmd, path=nil)
unless cmd.is_a?(Array)
*** SUGGESTION 1 ***
end
path ||= Dir.pwd
vars = {
*** SUGGESTION 2 ***
}
options = {
chdir: path
}
unless File.directory?(path)
FileUtils.mkdir_p(path)
end
@cmd_output = ""
@cmd_status = 0
Open3.popen3(vars, *cmd, options) do |stdin, stdout, stderr, wait_thr|
@cmd_output << stdout.read
@cmd_output << stderr.read
@cmd_status = wait_thr.value.exitstatus
end
return @cmd_output, @cmd_status
end
end
CONTENT
expect(file_suggestion.new_content).to eq(expected_content)
end
end
context 'when no suggestions have been added' do
let(:suggestions) { [] }
it 'returns an empty string' do
expect(file_suggestion.new_content).to eq('')
end
end
context 'with multiline suggestions' do
let(:suggestions) { [multi_suggestion1, multi_suggestion2, multi_suggestion3] }
context 'when the previous suggestion increases the line count' do
let!(:multi_suggestion1) do
create_suggestion(9, " *** SUGGESTION 1 ***\n *** SECOND LINE ***\n *** THIRD LINE ***\n")
end
let!(:multi_suggestion2) do
create_suggestion(15, " *** SUGGESTION 2 ***\n *** SECOND LINE ***\n")
end
let!(:multi_suggestion3) do
create_suggestion(19, " chdir: *** SUGGESTION 3 ***\n")
end
it 'returns a blob with the suggestions applied to it' do
expected_content = <<-CONTENT.strip_heredoc
require 'fileutils'
require 'open3'
module Popen
extend self
def popen(cmd, path=nil)
unless cmd.is_a?(Array)
*** SUGGESTION 1 ***
*** SECOND LINE ***
*** THIRD LINE ***
end
path ||= Dir.pwd
vars = {
*** SUGGESTION 2 ***
*** SECOND LINE ***
}
options = {
chdir: *** SUGGESTION 3 ***
}
unless File.directory?(path)
FileUtils.mkdir_p(path)
end
@cmd_output = ""
@cmd_status = 0
Open3.popen3(vars, *cmd, options) do |stdin, stdout, stderr, wait_thr|
@cmd_output << stdout.read
@cmd_output << stderr.read
@cmd_status = wait_thr.value.exitstatus
end
return @cmd_output, @cmd_status
end
end
CONTENT
expect(file_suggestion.new_content).to eq(expected_content)
end
end
context 'when the previous suggestion decreases and increases the line count' do
let!(:multi_suggestion1) do
create_suggestion(9, " *** SUGGESTION 1 ***\n", 1, 1)
end
let!(:multi_suggestion2) do
create_suggestion(15, " *** SUGGESTION 2 ***\n *** SECOND LINE ***\n")
end
let!(:multi_suggestion3) do
create_suggestion(19, " chdir: *** SUGGESTION 3 ***\n")
end
it 'returns a blob with the suggestions applied to it' do
expected_content = <<-CONTENT.strip_heredoc
require 'fileutils'
require 'open3'
module Popen
extend self
def popen(cmd, path=nil)
*** SUGGESTION 1 ***
path ||= Dir.pwd
vars = {
*** SUGGESTION 2 ***
*** SECOND LINE ***
}
options = {
chdir: *** SUGGESTION 3 ***
}
unless File.directory?(path)
FileUtils.mkdir_p(path)
end
@cmd_output = ""
@cmd_status = 0
Open3.popen3(vars, *cmd, options) do |stdin, stdout, stderr, wait_thr|
@cmd_output << stdout.read
@cmd_output << stderr.read
@cmd_status = wait_thr.value.exitstatus
end
return @cmd_output, @cmd_status
end
end
CONTENT
expect(file_suggestion.new_content).to eq(expected_content)
end
end
context 'when the previous suggestion replaces with the same number of lines' do
let!(:multi_suggestion1) do
create_suggestion(9, " *** SUGGESTION 1 ***\n *** SECOND LINE ***\n *** THIRD LINE ***\n", 1, 1)
end
let!(:multi_suggestion2) do
create_suggestion(15, " *** SUGGESTION 2 ***\n")
end
let!(:multi_suggestion3) do
create_suggestion(19, " chdir: *** SUGGESTION 3 ***\n")
end
it 'returns a blob with the suggestions applied to it' do
expected_content = <<-CONTENT.strip_heredoc
require 'fileutils'
require 'open3'
module Popen
extend self
def popen(cmd, path=nil)
*** SUGGESTION 1 ***
*** SECOND LINE ***
*** THIRD LINE ***
path ||= Dir.pwd
vars = {
*** SUGGESTION 2 ***
}
options = {
chdir: *** SUGGESTION 3 ***
}
unless File.directory?(path)
FileUtils.mkdir_p(path)
end
@cmd_output = ""
@cmd_status = 0
Open3.popen3(vars, *cmd, options) do |stdin, stdout, stderr, wait_thr|
@cmd_output << stdout.read
@cmd_output << stderr.read
@cmd_status = wait_thr.value.exitstatus
end
return @cmd_output, @cmd_status
end
end
CONTENT
expect(file_suggestion.new_content).to eq(expected_content)
end
end
context 'when the previous suggestion replaces multiple lines and the suggestions were applied out of order' do
let(:suggestions) { [multi_suggestion1, multi_suggestion3, multi_suggestion2] }
let!(:multi_suggestion1) do
create_suggestion(9, " *** SUGGESTION 1 ***\n *** SECOND LINE ***\n *** THIRD LINE ***\n", 1, 1)
end
let!(:multi_suggestion3) do
create_suggestion(19, " *** SUGGESTION 3 ***\n", 1, 1)
end
let!(:multi_suggestion2) do
create_suggestion(15, " *** SUGGESTION 2 ***\n", 1, 1)
end
it 'returns a blob with the suggestions applied to it' do
expected_content = <<-CONTENT.strip_heredoc
require 'fileutils'
require 'open3'
module Popen
extend self
def popen(cmd, path=nil)
*** SUGGESTION 1 ***
*** SECOND LINE ***
*** THIRD LINE ***
path ||= Dir.pwd
*** SUGGESTION 2 ***
*** SUGGESTION 3 ***
unless File.directory?(path)
FileUtils.mkdir_p(path)
end
@cmd_output = ""
@cmd_status = 0
Open3.popen3(vars, *cmd, options) do |stdin, stdout, stderr, wait_thr|
@cmd_output << stdout.read
@cmd_output << stderr.read
@cmd_status = wait_thr.value.exitstatus
end
return @cmd_output, @cmd_status
end
end
CONTENT
expect(file_suggestion.new_content).to eq(expected_content)
end
end
end
end
end