1893 lines
64 KiB
Ruby
1893 lines
64 KiB
Ruby
require 'spec_helper'
|
|
|
|
describe Gitlab::Diff::PositionTracer, lib: true do
|
|
# Douwe's diary New York City, 2016-06-28
|
|
# --------------------------------------------------------------------------
|
|
#
|
|
# Dear diary,
|
|
#
|
|
# Ideally, we would have a test for every single diff scenario that can
|
|
# occur and that the PositionTracer should correctly trace a position
|
|
# through, across the following variables:
|
|
#
|
|
# - Old diff file type: created, changed, renamed, deleted, unchanged (5)
|
|
# - Old diff line type: added, removed, unchanged (3)
|
|
# - New diff file type: created, changed, renamed, deleted, unchanged (5)
|
|
# - New diff line type: added, removed, unchanged (3)
|
|
# - Old-to-new diff line change: kept, moved, undone (3)
|
|
#
|
|
# This adds up to 5 * 3 * 5 * 3 * 3 = 675 different potential scenarios,
|
|
# and 675 different tests to cover them all. In reality, it would be fewer,
|
|
# since one cannot have a removed line in a created file diff, for example,
|
|
# but for the sake of this diary entry, let's be pessimistic.
|
|
#
|
|
# Writing these tests is a manual and time consuming process, as every test
|
|
# requires the manual construction or finding of a combination of diffs that
|
|
# create the exact diff scenario we are looking for, and can take between
|
|
# 1 and 10 minutes, depending on the farfetchedness of the scenario and
|
|
# complexity of creating it.
|
|
#
|
|
# This means that writing tests to cover all of these scenarios would end up
|
|
# taking between 11 and 112 hours in total, which I do not believe is the
|
|
# best use of my time.
|
|
#
|
|
# A better course of action would be to think of scenarios that are likely
|
|
# to occur, but also potentially tricky to trace correctly, and only cover
|
|
# those, with a few more obvious scenarios thrown in to cover our bases.
|
|
#
|
|
# Unfortunately, I only came to the above realization once I was about
|
|
# 1/5th of the way through the process of writing ALL THE SPECS, having
|
|
# already wasted about 3 hours trying to be thorough.
|
|
#
|
|
# I did find 2 bugs while writing those though, so that's good.
|
|
#
|
|
# In any case, all of this means that the tests below will be extremely
|
|
# (excessively, unjustifiably) thorough for scenarios where "the file was
|
|
# created in the old diff" and then drop off to comparitively lackluster
|
|
# testing of other scenarios.
|
|
#
|
|
# I did still try to cover most of the obvious and potentially tricky
|
|
# scenarios, though.
|
|
|
|
include RepoHelpers
|
|
|
|
let(:project) { create(:project, :repository) }
|
|
let(:current_user) { project.owner }
|
|
let(:repository) { project.repository }
|
|
let(:file_name) { "test-file" }
|
|
let(:new_file_name) { "#{file_name}-new" }
|
|
let(:second_file_name) { "#{file_name}-2" }
|
|
let(:branch_name) { "position-tracer-test" }
|
|
|
|
let(:old_diff_refs) { raise NotImplementedError }
|
|
let(:new_diff_refs) { raise NotImplementedError }
|
|
let(:change_diff_refs) { raise NotImplementedError }
|
|
let(:old_position) { raise NotImplementedError }
|
|
|
|
let(:position_tracer) { described_class.new(project: project, old_diff_refs: old_diff_refs, new_diff_refs: new_diff_refs) }
|
|
subject { position_tracer.trace(old_position) }
|
|
|
|
def diff_refs(base_commit, head_commit)
|
|
Gitlab::Diff::DiffRefs.new(base_sha: base_commit.id, head_sha: head_commit.id)
|
|
end
|
|
|
|
def position(attrs = {})
|
|
attrs.reverse_merge!(
|
|
diff_refs: old_diff_refs
|
|
)
|
|
Gitlab::Diff::Position.new(attrs)
|
|
end
|
|
|
|
def expect_new_position(attrs, result = subject)
|
|
aggregate_failures("expect new position #{attrs.inspect}") do
|
|
if attrs.nil?
|
|
expect(result[:outdated]).to be_truthy
|
|
else
|
|
expect(result[:outdated]).to be_falsey
|
|
|
|
new_position = result[:position]
|
|
expect(new_position).not_to be_nil
|
|
|
|
expect(new_position.diff_refs).to eq(new_diff_refs)
|
|
|
|
attrs.each do |attr, value|
|
|
expect(new_position.send(attr)).to eq(value)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
def expect_change_position(attrs, result = subject)
|
|
aggregate_failures("expect change position #{attrs.inspect}") do
|
|
expect(result[:outdated]).to be_truthy
|
|
|
|
change_position = result[:position]
|
|
if attrs.nil? || attrs.empty?
|
|
expect(change_position).to be_nil
|
|
else
|
|
expect(change_position).not_to be_nil
|
|
|
|
expect(change_position.diff_refs).to eq(change_diff_refs)
|
|
|
|
attrs.each do |attr, value|
|
|
expect(change_position.send(attr)).to eq(value)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
def create_branch(new_name, branch_name)
|
|
CreateBranchService.new(project, current_user).execute(new_name, branch_name)
|
|
end
|
|
|
|
def create_file(branch_name, file_name, content)
|
|
Files::CreateService.new(
|
|
project,
|
|
current_user,
|
|
start_branch: branch_name,
|
|
branch_name: branch_name,
|
|
commit_message: "Create file",
|
|
file_path: file_name,
|
|
file_content: content
|
|
).execute
|
|
project.commit(branch_name)
|
|
end
|
|
|
|
def update_file(branch_name, file_name, content)
|
|
Files::UpdateService.new(
|
|
project,
|
|
current_user,
|
|
start_branch: branch_name,
|
|
branch_name: branch_name,
|
|
commit_message: "Update file",
|
|
file_path: file_name,
|
|
file_content: content
|
|
).execute
|
|
project.commit(branch_name)
|
|
end
|
|
|
|
def delete_file(branch_name, file_name)
|
|
Files::DeleteService.new(
|
|
project,
|
|
current_user,
|
|
start_branch: branch_name,
|
|
branch_name: branch_name,
|
|
commit_message: "Delete file",
|
|
file_path: file_name
|
|
).execute
|
|
project.commit(branch_name)
|
|
end
|
|
|
|
let(:initial_commit) do
|
|
create_branch(branch_name, "master")[:branch].name
|
|
project.commit(branch_name)
|
|
end
|
|
|
|
describe "#trace" do
|
|
describe "diff scenarios" do
|
|
let(:create_file_commit) do
|
|
initial_commit
|
|
|
|
create_file(
|
|
branch_name,
|
|
file_name,
|
|
<<-CONTENT.strip_heredoc
|
|
A
|
|
B
|
|
C
|
|
CONTENT
|
|
)
|
|
end
|
|
|
|
let(:create_second_file_commit) do
|
|
create_file_commit
|
|
|
|
create_file(
|
|
branch_name,
|
|
second_file_name,
|
|
<<-CONTENT.strip_heredoc
|
|
D
|
|
E
|
|
CONTENT
|
|
)
|
|
end
|
|
|
|
let(:update_line_commit) do
|
|
create_second_file_commit
|
|
|
|
update_file(
|
|
branch_name,
|
|
file_name,
|
|
<<-CONTENT.strip_heredoc
|
|
A
|
|
BB
|
|
C
|
|
CONTENT
|
|
)
|
|
end
|
|
|
|
let(:update_second_file_line_commit) do
|
|
update_line_commit
|
|
|
|
update_file(
|
|
branch_name,
|
|
second_file_name,
|
|
<<-CONTENT.strip_heredoc
|
|
D
|
|
EE
|
|
CONTENT
|
|
)
|
|
end
|
|
|
|
let(:move_line_commit) do
|
|
update_second_file_line_commit
|
|
|
|
update_file(
|
|
branch_name,
|
|
file_name,
|
|
<<-CONTENT.strip_heredoc
|
|
BB
|
|
A
|
|
C
|
|
CONTENT
|
|
)
|
|
end
|
|
|
|
let(:add_second_file_line_commit) do
|
|
move_line_commit
|
|
|
|
update_file(
|
|
branch_name,
|
|
second_file_name,
|
|
<<-CONTENT.strip_heredoc
|
|
D
|
|
EE
|
|
F
|
|
CONTENT
|
|
)
|
|
end
|
|
|
|
let(:move_second_file_line_commit) do
|
|
add_second_file_line_commit
|
|
|
|
update_file(
|
|
branch_name,
|
|
second_file_name,
|
|
<<-CONTENT.strip_heredoc
|
|
D
|
|
F
|
|
EE
|
|
CONTENT
|
|
)
|
|
end
|
|
|
|
let(:delete_line_commit) do
|
|
move_second_file_line_commit
|
|
|
|
update_file(
|
|
branch_name,
|
|
file_name,
|
|
<<-CONTENT.strip_heredoc
|
|
BB
|
|
A
|
|
CONTENT
|
|
)
|
|
end
|
|
|
|
let(:delete_second_file_line_commit) do
|
|
delete_line_commit
|
|
|
|
update_file(
|
|
branch_name,
|
|
second_file_name,
|
|
<<-CONTENT.strip_heredoc
|
|
D
|
|
F
|
|
CONTENT
|
|
)
|
|
end
|
|
|
|
let(:delete_file_commit) do
|
|
delete_second_file_line_commit
|
|
|
|
delete_file(branch_name, file_name)
|
|
end
|
|
|
|
let(:rename_file_commit) do
|
|
delete_file_commit
|
|
|
|
create_file(
|
|
branch_name,
|
|
new_file_name,
|
|
<<-CONTENT.strip_heredoc
|
|
BB
|
|
A
|
|
CONTENT
|
|
)
|
|
end
|
|
|
|
let(:update_line_again_commit) do
|
|
rename_file_commit
|
|
|
|
update_file(
|
|
branch_name,
|
|
new_file_name,
|
|
<<-CONTENT.strip_heredoc
|
|
BB
|
|
AA
|
|
CONTENT
|
|
)
|
|
end
|
|
|
|
let(:move_line_again_commit) do
|
|
update_line_again_commit
|
|
|
|
update_file(
|
|
branch_name,
|
|
new_file_name,
|
|
<<-CONTENT.strip_heredoc
|
|
AA
|
|
BB
|
|
CONTENT
|
|
)
|
|
end
|
|
|
|
let(:delete_line_again_commit) do
|
|
move_line_again_commit
|
|
|
|
update_file(
|
|
branch_name,
|
|
new_file_name,
|
|
<<-CONTENT.strip_heredoc
|
|
AA
|
|
CONTENT
|
|
)
|
|
end
|
|
|
|
context "when the file was created in the old diff" do
|
|
context "when the file is created in the new diff" do
|
|
context "when the position pointed at an added line in the old diff" do
|
|
context "when the file's content was unchanged between the old and the new diff" do
|
|
let(:old_diff_refs) { diff_refs(initial_commit, create_file_commit) }
|
|
let(:new_diff_refs) { diff_refs(initial_commit, create_second_file_commit) }
|
|
let(:old_position) { position(new_path: file_name, new_line: 2) }
|
|
|
|
# old diff:
|
|
# 1 + A
|
|
# 2 + B
|
|
# 3 + C
|
|
#
|
|
# new diff:
|
|
# 1 + A
|
|
# 2 + B
|
|
# 3 + C
|
|
|
|
it "returns the new position" do
|
|
expect_new_position(
|
|
new_path: old_position.new_path,
|
|
new_line: old_position.new_line
|
|
)
|
|
end
|
|
end
|
|
|
|
context "when the file's content was changed between the old and the new diff" do
|
|
context "when that line was unchanged between the old and the new diff" do
|
|
let(:old_diff_refs) { diff_refs(initial_commit, create_file_commit) }
|
|
let(:new_diff_refs) { diff_refs(initial_commit, update_line_commit) }
|
|
let(:old_position) { position(new_path: file_name, new_line: 1) }
|
|
|
|
# old diff:
|
|
# 1 + A
|
|
# 2 + B
|
|
# 3 + C
|
|
#
|
|
# new diff:
|
|
# 1 + A
|
|
# 2 + BB
|
|
# 3 + C
|
|
|
|
it "returns the new position" do
|
|
expect_new_position(
|
|
new_path: old_position.new_path,
|
|
new_line: old_position.new_line
|
|
)
|
|
end
|
|
end
|
|
|
|
context "when that line was moved between the old and the new diff" do
|
|
let(:old_diff_refs) { diff_refs(initial_commit, update_line_commit) }
|
|
let(:new_diff_refs) { diff_refs(initial_commit, move_line_commit) }
|
|
let(:old_position) { position(new_path: file_name, new_line: 2) }
|
|
|
|
# old diff:
|
|
# 1 + A
|
|
# 2 + BB
|
|
# 3 + C
|
|
#
|
|
# new diff:
|
|
# 1 + BB
|
|
# 2 + A
|
|
# 3 + C
|
|
|
|
it "returns the new position" do
|
|
expect_new_position(
|
|
new_path: old_position.new_path,
|
|
new_line: 1
|
|
)
|
|
end
|
|
end
|
|
|
|
context "when that line was changed between the old and the new diff" do
|
|
let(:old_diff_refs) { diff_refs(initial_commit, create_file_commit) }
|
|
let(:new_diff_refs) { diff_refs(initial_commit, update_line_commit) }
|
|
let(:change_diff_refs) { diff_refs(create_file_commit, update_line_commit) }
|
|
let(:old_position) { position(new_path: file_name, new_line: 2) }
|
|
|
|
# old diff:
|
|
# 1 + A
|
|
# 2 + B
|
|
# 3 + C
|
|
#
|
|
# new diff:
|
|
# 1 + A
|
|
# 2 + BB
|
|
# 3 + C
|
|
|
|
it "returns the position of the change" do
|
|
expect_change_position(
|
|
old_path: file_name,
|
|
new_path: file_name,
|
|
old_line: 2,
|
|
new_line: nil
|
|
)
|
|
end
|
|
end
|
|
|
|
context "when that line was deleted between the old and the new diff" do
|
|
let(:old_diff_refs) { diff_refs(initial_commit, update_line_commit) }
|
|
let(:new_diff_refs) { diff_refs(initial_commit, delete_line_commit) }
|
|
let(:change_diff_refs) { diff_refs(update_line_commit, delete_line_commit) }
|
|
let(:old_position) { position(new_path: file_name, new_line: 3) }
|
|
|
|
# old diff:
|
|
# 1 + A
|
|
# 2 + BB
|
|
# 3 + C
|
|
#
|
|
# new diff:
|
|
# 1 + A
|
|
# 2 + BB
|
|
|
|
it "returns the position of the change" do
|
|
expect_change_position(
|
|
old_path: file_name,
|
|
new_path: file_name,
|
|
old_line: 3,
|
|
new_line: nil
|
|
)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
context "when the file is changed in the new diff" do
|
|
context "when the position pointed at an added line in the old diff" do
|
|
context "when the file's content was unchanged between the old and the new diff" do
|
|
let(:old_diff_refs) { diff_refs(initial_commit, update_line_commit) }
|
|
let(:new_diff_refs) { diff_refs(create_file_commit, update_line_commit) }
|
|
let(:old_position) { position(new_path: file_name, new_line: 1) }
|
|
|
|
# old diff:
|
|
# 1 + A
|
|
# 2 + BB
|
|
# 3 + C
|
|
#
|
|
# new diff:
|
|
# 1 1 A
|
|
# 2 - B
|
|
# 2 + BB
|
|
# 3 3 C
|
|
|
|
it "returns the new position" do
|
|
expect_new_position(
|
|
new_path: old_position.new_path,
|
|
new_line: old_position.new_line
|
|
)
|
|
end
|
|
end
|
|
|
|
context "when the file's content was changed between the old and the new diff" do
|
|
context "when that line was unchanged between the old and the new diff" do
|
|
let(:old_diff_refs) { diff_refs(initial_commit, update_line_commit) }
|
|
let(:new_diff_refs) { diff_refs(update_line_commit, move_line_commit) }
|
|
let(:old_position) { position(new_path: file_name, new_line: 3) }
|
|
|
|
# old diff:
|
|
# 1 + A
|
|
# 2 + BB
|
|
# 3 + C
|
|
#
|
|
# new diff:
|
|
# 1 - A
|
|
# 2 1 BB
|
|
# 2 + A
|
|
# 3 3 C
|
|
|
|
it "returns the new position" do
|
|
expect_new_position(
|
|
new_path: old_position.new_path,
|
|
new_line: old_position.new_line
|
|
)
|
|
end
|
|
end
|
|
|
|
context "when that line was moved between the old and the new diff" do
|
|
let(:old_diff_refs) { diff_refs(initial_commit, update_line_commit) }
|
|
let(:new_diff_refs) { diff_refs(update_line_commit, move_line_commit) }
|
|
let(:old_position) { position(new_path: file_name, new_line: 2) }
|
|
|
|
# old diff:
|
|
# 1 + A
|
|
# 2 + BB
|
|
# 3 + C
|
|
#
|
|
# new diff:
|
|
# 1 - A
|
|
# 2 1 BB
|
|
# 2 + A
|
|
# 3 3 C
|
|
|
|
it "returns the new position" do
|
|
expect_new_position(
|
|
new_path: old_position.new_path,
|
|
new_line: 1
|
|
)
|
|
end
|
|
end
|
|
|
|
context "when that line was changed between the old and the new diff" do
|
|
let(:old_diff_refs) { diff_refs(initial_commit, create_file_commit) }
|
|
let(:new_diff_refs) { diff_refs(create_file_commit, update_line_commit) }
|
|
let(:change_diff_refs) { diff_refs(create_file_commit, update_line_commit) }
|
|
let(:old_position) { position(new_path: file_name, new_line: 2) }
|
|
|
|
# old diff:
|
|
# 1 + A
|
|
# 2 + B
|
|
# 3 + C
|
|
#
|
|
# new diff:
|
|
# 1 1 A
|
|
# 2 - B
|
|
# 2 + BB
|
|
# 3 3 C
|
|
|
|
it "returns the position of the change" do
|
|
expect_change_position(
|
|
old_path: file_name,
|
|
new_path: file_name,
|
|
old_line: 2,
|
|
new_line: nil
|
|
)
|
|
end
|
|
end
|
|
|
|
context "when that line was deleted between the old and the new diff" do
|
|
let(:old_diff_refs) { diff_refs(initial_commit, move_line_commit) }
|
|
let(:new_diff_refs) { diff_refs(move_line_commit, delete_line_commit) }
|
|
let(:change_diff_refs) { diff_refs(move_line_commit, delete_line_commit) }
|
|
let(:old_position) { position(new_path: file_name, new_line: 3) }
|
|
|
|
# old diff:
|
|
# 1 + BB
|
|
# 2 + A
|
|
# 3 + C
|
|
#
|
|
# new diff:
|
|
# 1 1 BB
|
|
# 2 2 A
|
|
# 3 - C
|
|
|
|
it "returns the position of the change" do
|
|
expect_change_position(
|
|
old_path: file_name,
|
|
new_path: file_name,
|
|
old_line: 3,
|
|
new_line: nil
|
|
)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
context "when the file is renamed in the new diff" do
|
|
context "when the position pointed at an added line in the old diff" do
|
|
context "when the file's content was unchanged between the old and the new diff" do
|
|
let(:old_diff_refs) { diff_refs(initial_commit, delete_line_commit) }
|
|
let(:new_diff_refs) { diff_refs(delete_line_commit, rename_file_commit) }
|
|
let(:change_diff_refs) { diff_refs(initial_commit, delete_line_commit) }
|
|
let(:old_position) { position(new_path: file_name, new_line: 2) }
|
|
|
|
# old diff:
|
|
# 1 + BB
|
|
# 2 + A
|
|
#
|
|
# new diff:
|
|
# file_name -> new_file_name
|
|
# 1 1 BB
|
|
# 2 2 A
|
|
|
|
it "returns the position of the change" do
|
|
expect_change_position(
|
|
old_path: file_name,
|
|
new_path: file_name,
|
|
old_line: nil,
|
|
new_line: 2
|
|
)
|
|
end
|
|
end
|
|
|
|
context "when the file's content was changed between the old and the new diff" do
|
|
context "when that line was unchanged between the old and the new diff" do
|
|
let(:old_diff_refs) { diff_refs(initial_commit, delete_line_commit) }
|
|
let(:new_diff_refs) { diff_refs(delete_line_commit, update_line_again_commit) }
|
|
let(:old_position) { position(new_path: file_name, new_line: 1) }
|
|
|
|
# old diff:
|
|
# 1 + BB
|
|
# 2 + A
|
|
#
|
|
# new diff:
|
|
# file_name -> new_file_name
|
|
# 1 1 BB
|
|
# 2 - A
|
|
# 2 + AA
|
|
|
|
it "returns the new position" do
|
|
expect_new_position(
|
|
old_path: file_name,
|
|
new_path: new_file_name,
|
|
old_line: old_position.new_line,
|
|
new_line: old_position.new_line
|
|
)
|
|
end
|
|
end
|
|
|
|
context "when that line was moved between the old and the new diff" do
|
|
let(:old_diff_refs) { diff_refs(initial_commit, delete_line_commit) }
|
|
let(:new_diff_refs) { diff_refs(delete_line_commit, move_line_again_commit) }
|
|
let(:old_position) { position(new_path: file_name, new_line: 1) }
|
|
|
|
# old diff:
|
|
# 1 + BB
|
|
# 2 + A
|
|
#
|
|
# new diff:
|
|
# file_name -> new_file_name
|
|
# 1 + AA
|
|
# 1 2 BB
|
|
# 2 - A
|
|
|
|
it "returns the new position" do
|
|
expect_new_position(
|
|
old_path: file_name,
|
|
new_path: new_file_name,
|
|
old_line: 1,
|
|
new_line: 2
|
|
)
|
|
end
|
|
end
|
|
|
|
context "when that line was changed between the old and the new diff" do
|
|
let(:old_diff_refs) { diff_refs(initial_commit, delete_line_commit) }
|
|
let(:new_diff_refs) { diff_refs(delete_line_commit, update_line_again_commit) }
|
|
let(:change_diff_refs) { diff_refs(delete_line_commit, update_line_again_commit) }
|
|
let(:old_position) { position(new_path: file_name, new_line: 2) }
|
|
|
|
# old diff:
|
|
# 1 + BB
|
|
# 2 + A
|
|
#
|
|
# new diff:
|
|
# file_name -> new_file_name
|
|
# 1 1 BB
|
|
# 2 - A
|
|
# 2 + AA
|
|
|
|
it "returns the position of the change" do
|
|
expect_change_position(
|
|
old_path: file_name,
|
|
new_path: new_file_name,
|
|
old_line: 2,
|
|
new_line: nil
|
|
)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
context "when the file is deleted in the new diff" do
|
|
context "when the position pointed at an added line in the old diff" do
|
|
context "when the file's content was unchanged between the old and the new diff" do
|
|
let(:old_diff_refs) { diff_refs(initial_commit, delete_line_commit) }
|
|
let(:new_diff_refs) { diff_refs(delete_line_commit, delete_file_commit) }
|
|
let(:change_diff_refs) { diff_refs(delete_line_commit, delete_file_commit) }
|
|
let(:old_position) { position(new_path: file_name, new_line: 2) }
|
|
|
|
# old diff:
|
|
# 1 + BB
|
|
# 2 + A
|
|
#
|
|
# new diff:
|
|
# 1 - BB
|
|
# 2 - A
|
|
|
|
it "returns the position of the change" do
|
|
expect_change_position(
|
|
old_path: file_name,
|
|
new_path: file_name,
|
|
old_line: 2,
|
|
new_line: nil
|
|
)
|
|
end
|
|
end
|
|
|
|
context "when the file's content was changed between the old and the new diff" do
|
|
context "when that line was unchanged between the old and the new diff" do
|
|
let(:old_diff_refs) { diff_refs(initial_commit, move_line_commit) }
|
|
let(:new_diff_refs) { diff_refs(delete_line_commit, delete_file_commit) }
|
|
let(:change_diff_refs) { diff_refs(move_line_commit, delete_file_commit) }
|
|
let(:old_position) { position(new_path: file_name, new_line: 2) }
|
|
|
|
# old diff:
|
|
# 1 + BB
|
|
# 2 + A
|
|
# 3 + C
|
|
#
|
|
# new diff:
|
|
# 1 - BB
|
|
# 2 - A
|
|
|
|
it "returns the position of the change" do
|
|
expect_change_position(
|
|
old_path: file_name,
|
|
new_path: file_name,
|
|
old_line: 2,
|
|
new_line: nil
|
|
)
|
|
end
|
|
end
|
|
|
|
context "when that line was moved between the old and the new diff" do
|
|
let(:old_diff_refs) { diff_refs(initial_commit, update_line_commit) }
|
|
let(:new_diff_refs) { diff_refs(move_line_commit, delete_file_commit) }
|
|
let(:change_diff_refs) { diff_refs(update_line_commit, delete_file_commit) }
|
|
let(:old_position) { position(new_path: file_name, new_line: 2) }
|
|
|
|
# old diff:
|
|
# 1 + A
|
|
# 2 + BB
|
|
# 3 + C
|
|
#
|
|
# new diff:
|
|
# 1 - BB
|
|
# 2 - A
|
|
# 3 - C
|
|
|
|
it "returns the position of the change" do
|
|
expect_change_position(
|
|
old_path: file_name,
|
|
new_path: file_name,
|
|
old_line: 2,
|
|
new_line: nil
|
|
)
|
|
end
|
|
end
|
|
|
|
context "when that line was changed between the old and the new diff" do
|
|
let(:old_diff_refs) { diff_refs(initial_commit, create_file_commit) }
|
|
let(:new_diff_refs) { diff_refs(update_line_commit, delete_file_commit) }
|
|
let(:change_diff_refs) { diff_refs(create_file_commit, delete_file_commit) }
|
|
let(:old_position) { position(new_path: file_name, new_line: 2) }
|
|
|
|
# old diff:
|
|
# 1 + A
|
|
# 2 + B
|
|
# 3 + C
|
|
#
|
|
# new diff:
|
|
# 1 - A
|
|
# 2 - BB
|
|
# 3 - C
|
|
|
|
it "returns the position of the change" do
|
|
expect_change_position(
|
|
old_path: file_name,
|
|
new_path: file_name,
|
|
old_line: 2,
|
|
new_line: nil
|
|
)
|
|
end
|
|
end
|
|
|
|
context "when that line was deleted between the old and the new diff" do
|
|
let(:old_diff_refs) { diff_refs(initial_commit, move_line_commit) }
|
|
let(:new_diff_refs) { diff_refs(delete_line_commit, delete_file_commit) }
|
|
let(:change_diff_refs) { diff_refs(move_line_commit, delete_file_commit) }
|
|
let(:old_position) { position(new_path: file_name, new_line: 3) }
|
|
|
|
# old diff:
|
|
# 1 + BB
|
|
# 2 + A
|
|
# 3 + C
|
|
#
|
|
# new diff:
|
|
# 1 - BB
|
|
# 2 - A
|
|
|
|
it "returns the position of the change" do
|
|
expect_change_position(
|
|
old_path: file_name,
|
|
new_path: file_name,
|
|
old_line: 3,
|
|
new_line: nil
|
|
)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
context "when the file is unchanged in the new diff" do
|
|
context "when the position pointed at an added line in the old diff" do
|
|
context "when the file's content was unchanged between the old and the new diff" do
|
|
let(:old_diff_refs) { diff_refs(initial_commit, create_file_commit) }
|
|
let(:new_diff_refs) { diff_refs(create_file_commit, create_second_file_commit) }
|
|
let(:change_diff_refs) { diff_refs(initial_commit, create_file_commit) }
|
|
let(:old_position) { position(new_path: file_name, new_line: 2) }
|
|
|
|
# old diff:
|
|
# 1 + A
|
|
# 2 + B
|
|
# 3 + C
|
|
#
|
|
# new diff:
|
|
# 1 1 A
|
|
# 2 2 B
|
|
# 3 3 C
|
|
|
|
it "returns the position of the change" do
|
|
expect_change_position(
|
|
old_path: file_name,
|
|
new_path: file_name,
|
|
old_line: nil,
|
|
new_line: 2
|
|
)
|
|
end
|
|
end
|
|
|
|
context "when the file's content was changed between the old and the new diff" do
|
|
context "when that line was unchanged between the old and the new diff" do
|
|
let(:old_diff_refs) { diff_refs(initial_commit, create_file_commit) }
|
|
let(:new_diff_refs) { diff_refs(update_line_commit, update_second_file_line_commit) }
|
|
let(:change_diff_refs) { diff_refs(initial_commit, update_line_commit) }
|
|
let(:old_position) { position(new_path: file_name, new_line: 1) }
|
|
|
|
# old diff:
|
|
# 1 + A
|
|
# 2 + B
|
|
# 3 + C
|
|
#
|
|
# new diff:
|
|
# 1 1 A
|
|
# 2 2 BB
|
|
# 3 3 C
|
|
|
|
it "returns the position of the change" do
|
|
expect_change_position(
|
|
old_path: file_name,
|
|
new_path: file_name,
|
|
old_line: nil,
|
|
new_line: 1
|
|
)
|
|
end
|
|
end
|
|
|
|
context "when that line was moved between the old and the new diff" do
|
|
let(:old_diff_refs) { diff_refs(initial_commit, update_line_commit) }
|
|
let(:new_diff_refs) { diff_refs(move_line_commit, move_second_file_line_commit) }
|
|
let(:change_diff_refs) { diff_refs(initial_commit, move_line_commit) }
|
|
let(:old_position) { position(new_path: file_name, new_line: 2) }
|
|
|
|
# old diff:
|
|
# 1 + A
|
|
# 2 + BB
|
|
# 3 + C
|
|
#
|
|
# new diff:
|
|
# 1 1 BB
|
|
# 2 2 A
|
|
# 3 3 C
|
|
|
|
it "returns the position of the change" do
|
|
expect_change_position(
|
|
old_path: file_name,
|
|
new_path: file_name,
|
|
old_line: nil,
|
|
new_line: 1
|
|
)
|
|
end
|
|
end
|
|
|
|
context "when that line was changed between the old and the new diff" do
|
|
let(:old_diff_refs) { diff_refs(initial_commit, create_file_commit) }
|
|
let(:new_diff_refs) { diff_refs(update_line_commit, update_second_file_line_commit) }
|
|
let(:change_diff_refs) { diff_refs(create_file_commit, update_second_file_line_commit) }
|
|
let(:old_position) { position(new_path: file_name, new_line: 2) }
|
|
|
|
# old diff:
|
|
# 1 + A
|
|
# 2 + B
|
|
# 3 + C
|
|
#
|
|
# new diff:
|
|
# 1 1 A
|
|
# 2 2 BB
|
|
# 3 3 C
|
|
|
|
it "returns the position of the change" do
|
|
expect_change_position(
|
|
old_path: file_name,
|
|
new_path: file_name,
|
|
old_line: 2,
|
|
new_line: nil
|
|
)
|
|
end
|
|
end
|
|
|
|
context "when that line was deleted between the old and the new diff" do
|
|
let(:old_diff_refs) { diff_refs(initial_commit, move_line_commit) }
|
|
let(:new_diff_refs) { diff_refs(delete_line_commit, delete_second_file_line_commit) }
|
|
let(:change_diff_refs) { diff_refs(move_line_commit, delete_second_file_line_commit) }
|
|
let(:old_position) { position(new_path: file_name, new_line: 3) }
|
|
|
|
# old diff:
|
|
# 1 + BB
|
|
# 2 + A
|
|
# 3 + C
|
|
#
|
|
# new diff:
|
|
# 1 1 BB
|
|
# 2 2 A
|
|
|
|
it "returns the position of the change" do
|
|
expect_change_position(
|
|
old_path: file_name,
|
|
new_path: file_name,
|
|
old_line: 3,
|
|
new_line: nil
|
|
)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
context "when the file was changed in the old diff" do
|
|
context "when the file is created in the new diff" do
|
|
context "when the position pointed at an added line in the old diff" do
|
|
context "when the file's content was unchanged between the old and the new diff" do
|
|
let(:old_diff_refs) { diff_refs(create_file_commit, update_line_commit) }
|
|
let(:new_diff_refs) { diff_refs(initial_commit, update_line_commit) }
|
|
let(:old_position) { position(old_path: file_name, new_path: file_name, new_line: 2) }
|
|
|
|
# old diff:
|
|
# 1 1 A
|
|
# 2 - B
|
|
# 2 + BB
|
|
# 3 3 C
|
|
#
|
|
# new diff:
|
|
# 1 + A
|
|
# 2 + BB
|
|
# 3 + C
|
|
|
|
it "returns the new position" do
|
|
expect_new_position(
|
|
new_path: old_position.new_path,
|
|
old_line: nil,
|
|
new_line: old_position.new_line
|
|
)
|
|
end
|
|
end
|
|
|
|
context "when the file's content was changed between the old and the new diff" do
|
|
context "when that line was unchanged between the old and the new diff" do
|
|
let(:old_diff_refs) { diff_refs(create_file_commit, move_line_commit) }
|
|
let(:new_diff_refs) { diff_refs(initial_commit, move_line_commit) }
|
|
let(:old_position) { position(old_path: file_name, new_path: file_name, new_line: 1) }
|
|
|
|
# old diff:
|
|
# 1 + BB
|
|
# 1 2 A
|
|
# 2 - B
|
|
# 3 3 C
|
|
#
|
|
# new diff:
|
|
# 1 + BB
|
|
# 2 + A
|
|
|
|
it "returns the new position" do
|
|
expect_new_position(
|
|
new_path: old_position.new_path,
|
|
old_line: nil,
|
|
new_line: old_position.new_line
|
|
)
|
|
end
|
|
end
|
|
|
|
context "when that line was moved between the old and the new diff" do
|
|
let(:old_diff_refs) { diff_refs(create_file_commit, update_line_commit) }
|
|
let(:new_diff_refs) { diff_refs(initial_commit, move_line_commit) }
|
|
let(:old_position) { position(old_path: file_name, new_path: file_name, new_line: 2) }
|
|
|
|
# old diff:
|
|
# 1 1 A
|
|
# 2 - B
|
|
# 2 + BB
|
|
# 3 3 C
|
|
#
|
|
# new diff:
|
|
# 1 + BB
|
|
# 2 + A
|
|
# 3 + C
|
|
|
|
it "returns the new position" do
|
|
expect_new_position(
|
|
new_path: old_position.new_path,
|
|
old_line: nil,
|
|
new_line: 1
|
|
)
|
|
end
|
|
end
|
|
|
|
context "when that line was changed or deleted between the old and the new diff" do
|
|
let(:old_diff_refs) { diff_refs(create_file_commit, move_line_commit) }
|
|
let(:new_diff_refs) { diff_refs(initial_commit, create_file_commit) }
|
|
let(:change_diff_refs) { diff_refs(move_line_commit, create_file_commit) }
|
|
let(:old_position) { position(old_path: file_name, new_path: file_name, new_line: 1) }
|
|
|
|
# old diff:
|
|
# 1 + BB
|
|
# 1 2 A
|
|
# 2 - B
|
|
# 3 3 C
|
|
#
|
|
# new diff:
|
|
# 1 + A
|
|
# 2 + B
|
|
# 3 + C
|
|
|
|
it "returns the position of the change" do
|
|
expect_change_position(
|
|
old_path: file_name,
|
|
new_path: file_name,
|
|
old_line: 1,
|
|
new_line: nil
|
|
)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
context "when the position pointed at a deleted line in the old diff" do
|
|
let(:old_diff_refs) { diff_refs(create_file_commit, update_line_commit) }
|
|
let(:new_diff_refs) { diff_refs(initial_commit, update_line_commit) }
|
|
let(:change_diff_refs) { diff_refs(create_file_commit, initial_commit) }
|
|
let(:old_position) { position(old_path: file_name, new_path: file_name, old_line: 2) }
|
|
|
|
# old diff:
|
|
# 1 1 A
|
|
# 2 - B
|
|
# 2 + BB
|
|
# 3 3 C
|
|
#
|
|
# new diff:
|
|
# 1 + A
|
|
# 2 + BB
|
|
# 3 + C
|
|
|
|
it "returns the position of the change" do
|
|
expect_change_position(
|
|
old_path: file_name,
|
|
new_path: file_name,
|
|
old_line: 2,
|
|
new_line: nil
|
|
)
|
|
end
|
|
end
|
|
|
|
context "when the position pointed at an unchanged line in the old diff" do
|
|
context "when the file's content was unchanged between the old and the new diff" do
|
|
let(:old_diff_refs) { diff_refs(create_file_commit, update_line_commit) }
|
|
let(:new_diff_refs) { diff_refs(initial_commit, update_line_commit) }
|
|
let(:old_position) { position(old_path: file_name, new_path: file_name, old_line: 1, new_line: 1) }
|
|
|
|
# old diff:
|
|
# 1 1 A
|
|
# 2 - B
|
|
# 2 + BB
|
|
# 3 3 C
|
|
#
|
|
# new diff:
|
|
# 1 + A
|
|
# 2 + BB
|
|
# 3 + C
|
|
|
|
it "returns the new position" do
|
|
expect_new_position(
|
|
new_path: old_position.new_path,
|
|
old_line: nil,
|
|
new_line: old_position.new_line
|
|
)
|
|
end
|
|
end
|
|
|
|
context "when the file's content was changed between the old and the new diff" do
|
|
context "when that line was unchanged between the old and the new diff" do
|
|
let(:old_diff_refs) { diff_refs(create_file_commit, move_line_commit) }
|
|
let(:new_diff_refs) { diff_refs(initial_commit, move_line_commit) }
|
|
let(:old_position) { position(old_path: file_name, new_path: file_name, old_line: 1, new_line: 2) }
|
|
|
|
# old diff:
|
|
# 1 + BB
|
|
# 1 2 A
|
|
# 2 - B
|
|
# 3 3 C
|
|
#
|
|
# new diff:
|
|
# 1 + BB
|
|
# 2 + A
|
|
|
|
it "returns the new position" do
|
|
expect_new_position(
|
|
new_path: old_position.new_path,
|
|
old_line: nil,
|
|
new_line: old_position.new_line
|
|
)
|
|
end
|
|
end
|
|
|
|
context "when that line was moved between the old and the new diff" do
|
|
let(:old_diff_refs) { diff_refs(move_line_commit, delete_line_commit) }
|
|
let(:new_diff_refs) { diff_refs(initial_commit, update_line_commit) }
|
|
let(:old_position) { position(old_path: file_name, new_path: file_name, old_line: 2, new_line: 2) }
|
|
|
|
# old diff:
|
|
# 1 1 BB
|
|
# 2 2 A
|
|
# 3 - C
|
|
#
|
|
# new diff:
|
|
# 1 + A
|
|
# 2 + BB
|
|
# 3 + C
|
|
|
|
it "returns the new position" do
|
|
expect_new_position(
|
|
new_path: old_position.new_path,
|
|
old_line: nil,
|
|
new_line: 1
|
|
)
|
|
end
|
|
end
|
|
|
|
context "when that line was changed or deleted between the old and the new diff" do
|
|
let(:old_diff_refs) { diff_refs(create_file_commit, move_line_commit) }
|
|
let(:new_diff_refs) { diff_refs(initial_commit, delete_line_commit) }
|
|
let(:change_diff_refs) { diff_refs(move_line_commit, delete_line_commit) }
|
|
let(:old_position) { position(old_path: file_name, new_path: file_name, old_line: 3, new_line: 3) }
|
|
|
|
# old diff:
|
|
# 1 + BB
|
|
# 1 2 A
|
|
# 2 - B
|
|
# 3 3 C
|
|
#
|
|
# new diff:
|
|
# 1 + A
|
|
# 2 + B
|
|
|
|
it "returns the position of the change" do
|
|
expect_change_position(
|
|
old_path: file_name,
|
|
new_path: file_name,
|
|
old_line: 3,
|
|
new_line: nil
|
|
)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
context "when the file is changed in the new diff" do
|
|
context "when the position pointed at an added line in the old diff" do
|
|
context "when the file's content was unchanged between the old and the new diff" do
|
|
let(:old_diff_refs) { diff_refs(create_file_commit, update_line_commit) }
|
|
let(:new_diff_refs) { diff_refs(create_file_commit, update_second_file_line_commit) }
|
|
let(:old_position) { position(old_path: file_name, new_path: file_name, new_line: 2) }
|
|
|
|
# old diff:
|
|
# 1 1 A
|
|
# 2 - B
|
|
# 2 + BB
|
|
# 3 3 C
|
|
#
|
|
# new diff:
|
|
# 1 1 A
|
|
# 2 - B
|
|
# 2 + BB
|
|
# 3 3 C
|
|
|
|
it "returns the new position" do
|
|
expect_new_position(
|
|
old_path: old_position.old_path,
|
|
new_path: old_position.new_path,
|
|
old_line: nil,
|
|
new_line: old_position.new_line
|
|
)
|
|
end
|
|
end
|
|
|
|
context "when the file's content was changed between the old and the new diff" do
|
|
context "when that line was unchanged between the old and the new diff" do
|
|
let(:old_diff_refs) { diff_refs(create_file_commit, move_line_commit) }
|
|
let(:new_diff_refs) { diff_refs(move_line_commit, delete_line_commit) }
|
|
let(:old_position) { position(old_path: file_name, new_path: file_name, new_line: 1) }
|
|
|
|
# old diff:
|
|
# 1 + BB
|
|
# 1 2 A
|
|
# 2 - B
|
|
# 3 3 C
|
|
#
|
|
# new diff:
|
|
# 1 1 BB
|
|
# 2 2 A
|
|
# 3 - C
|
|
|
|
it "returns the new position" do
|
|
expect_new_position(
|
|
old_path: old_position.old_path,
|
|
new_path: old_position.new_path,
|
|
old_line: 1,
|
|
new_line: 1
|
|
)
|
|
end
|
|
end
|
|
|
|
context "when that line was moved between the old and the new diff" do
|
|
let(:old_diff_refs) { diff_refs(create_file_commit, update_line_commit) }
|
|
let(:new_diff_refs) { diff_refs(update_line_commit, move_line_commit) }
|
|
let(:old_position) { position(old_path: file_name, new_path: file_name, new_line: 2) }
|
|
|
|
# old diff:
|
|
# 1 1 A
|
|
# 2 - B
|
|
# 2 + BB
|
|
# 3 3 C
|
|
#
|
|
# new diff:
|
|
# 1 - A
|
|
# 2 1 BB
|
|
# 2 + A
|
|
# 3 3 C
|
|
|
|
it "returns the new position" do
|
|
expect_new_position(
|
|
old_path: old_position.old_path,
|
|
new_path: old_position.new_path,
|
|
old_line: 2,
|
|
new_line: 1
|
|
)
|
|
end
|
|
end
|
|
|
|
context "when that line was changed or deleted between the old and the new diff" do
|
|
let(:old_diff_refs) { diff_refs(create_file_commit, move_line_commit) }
|
|
let(:new_diff_refs) { diff_refs(create_file_commit, update_line_commit) }
|
|
let(:change_diff_refs) { diff_refs(move_line_commit, update_line_commit) }
|
|
let(:old_position) { position(old_path: file_name, new_path: file_name, new_line: 1) }
|
|
|
|
# old diff:
|
|
# 1 + BB
|
|
# 1 2 A
|
|
# 2 - B
|
|
# 3 3 C
|
|
#
|
|
# new diff:
|
|
# 1 1 A
|
|
# 2 - B
|
|
# 2 + BB
|
|
# 3 3 C
|
|
|
|
it "returns the position of the change" do
|
|
expect_change_position(
|
|
old_path: file_name,
|
|
new_path: file_name,
|
|
old_line: 1,
|
|
new_line: nil
|
|
)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
context "when the position pointed at a deleted line in the old diff" do
|
|
context "when the file's content was unchanged between the old and the new diff" do
|
|
let(:old_diff_refs) { diff_refs(create_file_commit, update_line_commit) }
|
|
let(:new_diff_refs) { diff_refs(create_file_commit, update_second_file_line_commit) }
|
|
let(:old_position) { position(old_path: file_name, new_path: file_name, old_line: 2) }
|
|
|
|
# old diff:
|
|
# 1 1 A
|
|
# 2 - B
|
|
# 2 + BB
|
|
# 3 3 C
|
|
#
|
|
# new diff:
|
|
# 1 1 A
|
|
# 2 - B
|
|
# 2 + BB
|
|
# 3 3 C
|
|
|
|
it "returns the new position" do
|
|
expect_new_position(
|
|
old_path: old_position.old_path,
|
|
new_path: old_position.new_path,
|
|
old_line: old_position.old_line,
|
|
new_line: nil
|
|
)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "typical use scenarios" do
|
|
let(:second_branch_name) { "#{branch_name}-2" }
|
|
|
|
def expect_new_positions(old_attrs, new_attrs)
|
|
old_positions = old_attrs.map do |old_attrs|
|
|
position(old_attrs)
|
|
end
|
|
|
|
new_positions = old_positions.map do |old_position|
|
|
position_tracer.trace(old_position)
|
|
end
|
|
|
|
aggregate_failures do
|
|
new_positions.zip(new_attrs).each do |new_position, new_attrs|
|
|
if new_attrs&.delete(:change)
|
|
expect_change_position(new_attrs, new_position)
|
|
else
|
|
expect_new_position(new_attrs, new_position)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
let(:create_file_commit) do
|
|
initial_commit
|
|
|
|
create_file(
|
|
branch_name,
|
|
file_name,
|
|
<<-CONTENT.strip_heredoc
|
|
A
|
|
B
|
|
C
|
|
D
|
|
E
|
|
F
|
|
CONTENT
|
|
)
|
|
end
|
|
|
|
let(:second_create_file_commit) do
|
|
create_file_commit
|
|
|
|
create_branch(second_branch_name, branch_name)
|
|
|
|
update_file(
|
|
second_branch_name,
|
|
file_name,
|
|
<<-CONTENT.strip_heredoc
|
|
Z
|
|
Z
|
|
Z
|
|
A
|
|
B
|
|
C
|
|
D
|
|
E
|
|
F
|
|
CONTENT
|
|
)
|
|
end
|
|
|
|
let(:update_file_commit) do
|
|
second_create_file_commit
|
|
|
|
update_file(
|
|
branch_name,
|
|
file_name,
|
|
<<-CONTENT.strip_heredoc
|
|
A
|
|
C
|
|
DD
|
|
E
|
|
F
|
|
G
|
|
CONTENT
|
|
)
|
|
end
|
|
|
|
let(:update_file_again_commit) do
|
|
update_file_commit
|
|
|
|
update_file(
|
|
branch_name,
|
|
file_name,
|
|
<<-CONTENT.strip_heredoc
|
|
A
|
|
BB
|
|
C
|
|
D
|
|
E
|
|
FF
|
|
G
|
|
CONTENT
|
|
)
|
|
end
|
|
|
|
describe "simple push of new commit" do
|
|
let(:old_diff_refs) { diff_refs(create_file_commit, update_file_commit) }
|
|
let(:new_diff_refs) { diff_refs(create_file_commit, update_file_again_commit) }
|
|
let(:change_diff_refs) { diff_refs(update_file_commit, update_file_again_commit) }
|
|
|
|
# old diff:
|
|
# 1 1 A
|
|
# 2 - B
|
|
# 3 2 C
|
|
# 4 - D
|
|
# 3 + DD
|
|
# 5 4 E
|
|
# 6 5 F
|
|
# 6 + G
|
|
#
|
|
# new diff:
|
|
# 1 1 A
|
|
# 2 - B
|
|
# 2 + BB
|
|
# 3 3 C
|
|
# 4 4 D
|
|
# 5 5 E
|
|
# 6 - F
|
|
# 6 + FF
|
|
# 7 + G
|
|
|
|
it "returns the new positions" do
|
|
old_position_attrs = [
|
|
{ old_path: file_name, new_path: file_name, old_line: 1, new_line: 1 }, # A
|
|
{ old_path: file_name, old_line: 2 }, # - B
|
|
{ old_path: file_name, new_path: file_name, old_line: 3, new_line: 2 }, # C
|
|
{ old_path: file_name, old_line: 4 }, # - D
|
|
{ new_path: file_name, new_line: 3 }, # + DD
|
|
{ old_path: file_name, new_path: file_name, old_line: 5, new_line: 4 }, # E
|
|
{ old_path: file_name, new_path: file_name, old_line: 6, new_line: 5 }, # F
|
|
{ new_path: file_name, new_line: 6 }, # + G
|
|
]
|
|
|
|
new_position_attrs = [
|
|
{ old_path: file_name, new_path: file_name, old_line: 1, new_line: 1 },
|
|
{ old_path: file_name, old_line: 2 },
|
|
{ old_path: file_name, new_path: file_name, old_line: 3, new_line: 3 },
|
|
{ new_path: file_name, new_line: 4, change: true },
|
|
{ new_path: file_name, old_line: 3, change: true },
|
|
{ old_path: file_name, new_path: file_name, old_line: 5, new_line: 5 },
|
|
{ new_path: file_name, old_line: 5, change: true },
|
|
{ new_path: file_name, new_line: 7 }
|
|
]
|
|
|
|
expect_new_positions(old_position_attrs, new_position_attrs)
|
|
end
|
|
end
|
|
|
|
describe "force push to overwrite last commit" do
|
|
let(:second_create_file_commit) do
|
|
create_file_commit
|
|
|
|
create_branch(second_branch_name, branch_name)
|
|
|
|
update_file(
|
|
second_branch_name,
|
|
file_name,
|
|
<<-CONTENT.strip_heredoc
|
|
A
|
|
BB
|
|
C
|
|
D
|
|
E
|
|
FF
|
|
G
|
|
CONTENT
|
|
)
|
|
end
|
|
|
|
let(:old_diff_refs) { diff_refs(create_file_commit, update_file_commit) }
|
|
let(:new_diff_refs) { diff_refs(create_file_commit, second_create_file_commit) }
|
|
let(:change_diff_refs) { diff_refs(update_file_commit, second_create_file_commit) }
|
|
|
|
# old diff:
|
|
# 1 1 A
|
|
# 2 - B
|
|
# 3 2 C
|
|
# 4 - D
|
|
# 3 + DD
|
|
# 5 4 E
|
|
# 6 5 F
|
|
# 6 + G
|
|
#
|
|
# new diff:
|
|
# 1 1 A
|
|
# 2 - B
|
|
# 2 + BB
|
|
# 3 3 C
|
|
# 4 4 D
|
|
# 5 5 E
|
|
# 6 - F
|
|
# 6 + FF
|
|
# 7 + G
|
|
|
|
it "returns the new positions" do
|
|
old_position_attrs = [
|
|
{ old_path: file_name, new_path: file_name, old_line: 1, new_line: 1 }, # A
|
|
{ old_path: file_name, old_line: 2 }, # - B
|
|
{ old_path: file_name, new_path: file_name, old_line: 3, new_line: 2 }, # C
|
|
{ old_path: file_name, old_line: 4 }, # - D
|
|
{ new_path: file_name, new_line: 3 }, # + DD
|
|
{ old_path: file_name, new_path: file_name, old_line: 5, new_line: 4 }, # E
|
|
{ old_path: file_name, new_path: file_name, old_line: 6, new_line: 5 }, # F
|
|
{ new_path: file_name, new_line: 6 }, # + G
|
|
]
|
|
|
|
new_position_attrs = [
|
|
{ old_path: file_name, new_path: file_name, old_line: 1, new_line: 1 },
|
|
{ old_path: file_name, old_line: 2 },
|
|
{ old_path: file_name, new_path: file_name, old_line: 3, new_line: 3 },
|
|
{ new_path: file_name, new_line: 4, change: true },
|
|
{ old_path: file_name, old_line: 3, change: true },
|
|
{ old_path: file_name, new_path: file_name, old_line: 5, new_line: 5 },
|
|
{ old_path: file_name, old_line: 5, change: true },
|
|
{ new_path: file_name, new_line: 7 }
|
|
]
|
|
|
|
expect_new_positions(old_position_attrs, new_position_attrs)
|
|
end
|
|
end
|
|
|
|
describe "force push to delete last commit" do
|
|
let(:old_diff_refs) { diff_refs(create_file_commit, update_file_again_commit) }
|
|
let(:new_diff_refs) { diff_refs(create_file_commit, update_file_commit) }
|
|
let(:change_diff_refs) { diff_refs(update_file_again_commit, update_file_commit) }
|
|
|
|
# old diff:
|
|
# 1 1 A
|
|
# 2 - B
|
|
# 2 + BB
|
|
# 3 3 C
|
|
# 4 4 D
|
|
# 5 5 E
|
|
# 6 - F
|
|
# 6 + FF
|
|
# 7 + G
|
|
#
|
|
# new diff:
|
|
# 1 1 A
|
|
# 2 - B
|
|
# 3 2 C
|
|
# 4 - D
|
|
# 3 + DD
|
|
# 5 4 E
|
|
# 6 5 F
|
|
# 6 + G
|
|
|
|
it "returns the new positions" do
|
|
old_position_attrs = [
|
|
{ old_path: file_name, new_path: file_name, old_line: 1, new_line: 1 }, # A
|
|
{ old_path: file_name, old_line: 2 }, # - B
|
|
{ new_path: file_name, new_line: 2 }, # + BB
|
|
{ old_path: file_name, new_path: file_name, old_line: 3, new_line: 3 }, # C
|
|
{ old_path: file_name, new_path: file_name, old_line: 4, new_line: 4 }, # D
|
|
{ old_path: file_name, new_path: file_name, old_line: 5, new_line: 5 }, # E
|
|
{ old_path: file_name, old_line: 6 }, # - F
|
|
{ new_path: file_name, new_line: 6 }, # + FF
|
|
{ new_path: file_name, new_line: 7 }, # + G
|
|
]
|
|
|
|
new_position_attrs = [
|
|
{ old_path: file_name, new_path: file_name, old_line: 1, new_line: 1 },
|
|
{ old_path: file_name, old_line: 2 },
|
|
{ old_path: file_name, old_line: 2, change: true },
|
|
{ old_path: file_name, new_path: file_name, old_line: 3, new_line: 2 },
|
|
{ old_path: file_name, old_line: 4, change: true },
|
|
{ old_path: file_name, new_path: file_name, old_line: 5, new_line: 4 },
|
|
{ new_path: file_name, new_line: 5, change: true },
|
|
{ old_path: file_name, old_line: 6, change: true },
|
|
{ new_path: file_name, new_line: 6 }
|
|
]
|
|
|
|
expect_new_positions(old_position_attrs, new_position_attrs)
|
|
end
|
|
end
|
|
|
|
describe "rebase on top of target branch" do
|
|
let(:second_update_file_commit) do
|
|
update_file_commit
|
|
|
|
update_file(
|
|
second_branch_name,
|
|
file_name,
|
|
<<-CONTENT.strip_heredoc
|
|
Z
|
|
Z
|
|
Z
|
|
A
|
|
C
|
|
DD
|
|
E
|
|
F
|
|
G
|
|
CONTENT
|
|
)
|
|
end
|
|
|
|
let(:update_file_again_commit) do
|
|
second_update_file_commit
|
|
|
|
update_file(
|
|
branch_name,
|
|
file_name,
|
|
<<-CONTENT.strip_heredoc
|
|
A
|
|
BB
|
|
C
|
|
D
|
|
E
|
|
FF
|
|
G
|
|
CONTENT
|
|
)
|
|
end
|
|
|
|
let(:overwrite_update_file_again_commit) do
|
|
update_file_again_commit
|
|
|
|
update_file(
|
|
second_branch_name,
|
|
file_name,
|
|
<<-CONTENT.strip_heredoc
|
|
Z
|
|
Z
|
|
Z
|
|
A
|
|
BB
|
|
C
|
|
D
|
|
E
|
|
FF
|
|
G
|
|
CONTENT
|
|
)
|
|
end
|
|
|
|
let(:old_diff_refs) { diff_refs(create_file_commit, update_file_again_commit) }
|
|
let(:new_diff_refs) { diff_refs(create_file_commit, overwrite_update_file_again_commit) }
|
|
let(:change_diff_refs) { diff_refs(update_file_again_commit, overwrite_update_file_again_commit) }
|
|
|
|
# old diff:
|
|
# 1 1 A
|
|
# 2 - B
|
|
# 2 + BB
|
|
# 3 3 C
|
|
# 4 4 D
|
|
# 5 5 E
|
|
# 6 - F
|
|
# 6 + FF
|
|
# 7 + G
|
|
#
|
|
# new diff:
|
|
# 1 + Z
|
|
# 2 + Z
|
|
# 3 + Z
|
|
# 1 4 A
|
|
# 2 - B
|
|
# 5 + BB
|
|
# 3 6 C
|
|
# 4 7 D
|
|
# 5 8 E
|
|
# 6 - F
|
|
# 9 + FF
|
|
# 0 + G
|
|
|
|
it "returns the new positions" do
|
|
old_position_attrs = [
|
|
{ old_path: file_name, new_path: file_name, old_line: 1, new_line: 1 }, # A
|
|
{ old_path: file_name, old_line: 2 }, # - B
|
|
{ new_path: file_name, new_line: 2 }, # + BB
|
|
{ old_path: file_name, new_path: file_name, old_line: 3, new_line: 3 }, # C
|
|
{ old_path: file_name, new_path: file_name, old_line: 4, new_line: 4 }, # D
|
|
{ old_path: file_name, new_path: file_name, old_line: 5, new_line: 5 }, # E
|
|
{ old_path: file_name, old_line: 6 }, # - F
|
|
{ new_path: file_name, new_line: 6 }, # + FF
|
|
{ new_path: file_name, new_line: 7 }, # + G
|
|
]
|
|
|
|
new_position_attrs = [
|
|
{ old_path: file_name, new_path: file_name, old_line: 1, new_line: 4 }, # A
|
|
{ old_path: file_name, old_line: 2 }, # - B
|
|
{ new_path: file_name, new_line: 5 }, # + BB
|
|
{ old_path: file_name, new_path: file_name, old_line: 3, new_line: 6 }, # C
|
|
{ old_path: file_name, new_path: file_name, old_line: 4, new_line: 7 }, # D
|
|
{ old_path: file_name, new_path: file_name, old_line: 5, new_line: 8 }, # E
|
|
{ old_path: file_name, old_line: 6 }, # - F
|
|
{ new_path: file_name, new_line: 9 }, # + FF
|
|
{ new_path: file_name, new_line: 10 }, # + G
|
|
]
|
|
|
|
expect_new_positions(old_position_attrs, new_position_attrs)
|
|
end
|
|
end
|
|
|
|
describe "merge of target branch" do
|
|
let(:merge_commit) do
|
|
update_file_again_commit
|
|
|
|
committer = repository.user_to_committer(current_user)
|
|
|
|
options = {
|
|
message: "Merge branches",
|
|
author: committer,
|
|
committer: committer
|
|
}
|
|
|
|
merge_request = create(:merge_request, source_branch: second_create_file_commit.sha, target_branch: branch_name, source_project: project)
|
|
|
|
repository.merge(current_user, merge_request.diff_head_sha, merge_request, options)
|
|
|
|
project.commit(branch_name)
|
|
end
|
|
|
|
let(:old_diff_refs) { diff_refs(create_file_commit, update_file_again_commit) }
|
|
let(:new_diff_refs) { diff_refs(create_file_commit, merge_commit) }
|
|
let(:change_diff_refs) { diff_refs(update_file_again_commit, merge_commit) }
|
|
|
|
# old diff:
|
|
# 1 1 A
|
|
# 2 - B
|
|
# 2 + BB
|
|
# 3 3 C
|
|
# 4 4 D
|
|
# 5 5 E
|
|
# 6 - F
|
|
# 6 + FF
|
|
# 7 + G
|
|
#
|
|
# new diff:
|
|
# 1 + Z
|
|
# 2 + Z
|
|
# 3 + Z
|
|
# 1 4 A
|
|
# 2 - B
|
|
# 5 + BB
|
|
# 3 6 C
|
|
# 4 7 D
|
|
# 5 8 E
|
|
# 6 - F
|
|
# 9 + FF
|
|
# 0 + G
|
|
|
|
it "returns the new positions" do
|
|
old_position_attrs = [
|
|
{ old_path: file_name, new_path: file_name, old_line: 1, new_line: 1 }, # A
|
|
{ old_path: file_name, old_line: 2 }, # - B
|
|
{ new_path: file_name, new_line: 2 }, # + BB
|
|
{ old_path: file_name, new_path: file_name, old_line: 3, new_line: 3 }, # C
|
|
{ old_path: file_name, new_path: file_name, old_line: 4, new_line: 4 }, # D
|
|
{ old_path: file_name, new_path: file_name, old_line: 5, new_line: 5 }, # E
|
|
{ old_path: file_name, old_line: 6 }, # - F
|
|
{ new_path: file_name, new_line: 6 }, # + FF
|
|
{ new_path: file_name, new_line: 7 }, # + G
|
|
]
|
|
|
|
new_position_attrs = [
|
|
{ old_path: file_name, new_path: file_name, old_line: 1, new_line: 4 }, # A
|
|
{ old_path: file_name, old_line: 2 }, # - B
|
|
{ new_path: file_name, new_line: 5 }, # + BB
|
|
{ old_path: file_name, new_path: file_name, old_line: 3, new_line: 6 }, # C
|
|
{ old_path: file_name, new_path: file_name, old_line: 4, new_line: 7 }, # D
|
|
{ old_path: file_name, new_path: file_name, old_line: 5, new_line: 8 }, # E
|
|
{ old_path: file_name, old_line: 6 }, # - F
|
|
{ new_path: file_name, new_line: 9 }, # + FF
|
|
{ new_path: file_name, new_line: 10 }, # + G
|
|
]
|
|
|
|
expect_new_positions(old_position_attrs, new_position_attrs)
|
|
end
|
|
end
|
|
|
|
describe "changing target branch" do
|
|
let(:old_diff_refs) { diff_refs(create_file_commit, update_file_again_commit) }
|
|
let(:new_diff_refs) { diff_refs(update_file_commit, update_file_again_commit) }
|
|
let(:change_diff_refs) { diff_refs(create_file_commit, update_file_commit) }
|
|
|
|
# old diff:
|
|
# 1 1 A
|
|
# 2 - B
|
|
# 2 + BB
|
|
# 3 3 C
|
|
# 4 4 D
|
|
# 5 5 E
|
|
# 6 - F
|
|
# 6 + FF
|
|
# 7 + G
|
|
#
|
|
# new diff:
|
|
# 1 1 A
|
|
# 2 + BB
|
|
# 2 3 C
|
|
# 3 - DD
|
|
# 4 + D
|
|
# 4 5 E
|
|
# 5 - F
|
|
# 6 + FF
|
|
# 7 G
|
|
|
|
it "returns the new positions" do
|
|
old_position_attrs = [
|
|
{ old_path: file_name, new_path: file_name, old_line: 1, new_line: 1 }, # A
|
|
{ old_path: file_name, old_line: 2 }, # - B
|
|
{ new_path: file_name, new_line: 2 }, # + BB
|
|
{ old_path: file_name, new_path: file_name, old_line: 3, new_line: 3 }, # C
|
|
{ old_path: file_name, new_path: file_name, old_line: 4, new_line: 4 }, # D
|
|
{ old_path: file_name, new_path: file_name, old_line: 5, new_line: 5 }, # E
|
|
{ old_path: file_name, old_line: 6 }, # - F
|
|
{ new_path: file_name, new_line: 6 }, # + FF
|
|
{ new_path: file_name, new_line: 7 }, # + G
|
|
]
|
|
|
|
new_position_attrs = [
|
|
{ old_path: file_name, new_path: file_name, old_line: 1, new_line: 1 },
|
|
{ old_path: file_name, old_line: 2, change: true },
|
|
{ new_path: file_name, new_line: 2 },
|
|
{ old_path: file_name, new_path: file_name, old_line: 2, new_line: 3 },
|
|
{ new_path: file_name, new_line: 4 },
|
|
{ old_path: file_name, new_path: file_name, old_line: 4, new_line: 5 },
|
|
{ old_path: file_name, old_line: 5 },
|
|
{ new_path: file_name, new_line: 6 },
|
|
{ new_path: file_name, new_line: 7 }
|
|
]
|
|
|
|
expect_new_positions(old_position_attrs, new_position_attrs)
|
|
end
|
|
end
|
|
end
|
|
end
|