aff5c9f3e5
This is an ID-less table with just three columns: an association to the merge request diff the commit belongs to, the relative order of the commit within the merge request diff, and the commit SHA itself. Previously we stored much more information about the commits, so that we could display them even when they were deleted from the repo. Since 8.0, we ensure that those commits are kept around for as long as the target repo itself is, so we don't need to duplicate that data in the database.
158 lines
4.6 KiB
Ruby
158 lines
4.6 KiB
Ruby
require 'spec_helper'
|
|
|
|
describe MergeRequestDiff, models: true do
|
|
describe 'create new record' do
|
|
subject { create(:merge_request).merge_request_diff }
|
|
|
|
it { expect(subject).to be_valid }
|
|
it { expect(subject).to be_persisted }
|
|
it { expect(subject.commits.count).to eq(29) }
|
|
it { expect(subject.diffs.count).to eq(20) }
|
|
it { expect(subject.head_commit_sha).to eq('b83d6e391c22777fca1ed3012fce84f633d7fed0') }
|
|
it { expect(subject.base_commit_sha).to eq('ae73cb07c9eeaf35924a10f713b364d32b2dd34f') }
|
|
it { expect(subject.start_commit_sha).to eq('0b4bc9a49b562e85de7cc9e834518ea6828729b9') }
|
|
end
|
|
|
|
describe '#latest' do
|
|
let!(:mr) { create(:merge_request, :with_diffs) }
|
|
let!(:first_diff) { mr.merge_request_diff }
|
|
let!(:last_diff) { mr.create_merge_request_diff }
|
|
|
|
it { expect(last_diff.latest?).to be_truthy }
|
|
it { expect(first_diff.latest?).to be_falsey }
|
|
end
|
|
|
|
describe '#diffs' do
|
|
let(:mr) { create(:merge_request, :with_diffs) }
|
|
let(:mr_diff) { mr.merge_request_diff }
|
|
|
|
context 'when the :ignore_whitespace_change option is set' do
|
|
it 'creates a new compare object instead of loading from the DB' do
|
|
expect(mr_diff).not_to receive(:load_diffs)
|
|
expect(Gitlab::Git::Compare).to receive(:new).and_call_original
|
|
|
|
mr_diff.raw_diffs(ignore_whitespace_change: true)
|
|
end
|
|
end
|
|
|
|
context 'when the raw diffs are empty' do
|
|
before do
|
|
MergeRequestDiffFile.delete_all(merge_request_diff_id: mr_diff.id)
|
|
end
|
|
|
|
it 'returns an empty DiffCollection' do
|
|
expect(mr_diff.raw_diffs).to be_a(Gitlab::Git::DiffCollection)
|
|
expect(mr_diff.raw_diffs).to be_empty
|
|
end
|
|
end
|
|
|
|
context 'when the raw diffs have invalid content' do
|
|
before do
|
|
MergeRequestDiffFile.delete_all(merge_request_diff_id: mr_diff.id)
|
|
mr_diff.update_attributes(st_diffs: ["--broken-diff"])
|
|
end
|
|
|
|
it 'returns an empty DiffCollection' do
|
|
expect(mr_diff.raw_diffs.to_a).to be_empty
|
|
expect(mr_diff.raw_diffs).to be_a(Gitlab::Git::DiffCollection)
|
|
expect(mr_diff.raw_diffs).to be_empty
|
|
end
|
|
end
|
|
|
|
context 'when the raw diffs exist' do
|
|
it 'returns the diffs' do
|
|
expect(mr_diff.raw_diffs).to be_a(Gitlab::Git::DiffCollection)
|
|
expect(mr_diff.raw_diffs).not_to be_empty
|
|
end
|
|
|
|
context 'when the :paths option is set' do
|
|
let(:diffs) { mr_diff.raw_diffs(paths: ['files/ruby/popen.rb', 'files/ruby/popen.rb']) }
|
|
|
|
it 'only returns diffs that match the (old path, new path) given' do
|
|
expect(diffs.map(&:new_path)).to contain_exactly('files/ruby/popen.rb')
|
|
end
|
|
|
|
it 'uses the diffs from the DB' do
|
|
expect(mr_diff).to receive(:load_diffs)
|
|
|
|
diffs
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '#save_diffs' do
|
|
it 'saves collected state' do
|
|
mr_diff = create(:merge_request).merge_request_diff
|
|
|
|
expect(mr_diff.collected?).to be_truthy
|
|
end
|
|
|
|
it 'saves overflow state' do
|
|
allow(Commit).to receive(:max_diff_options)
|
|
.and_return(max_lines: 0, max_files: 0)
|
|
|
|
mr_diff = create(:merge_request).merge_request_diff
|
|
|
|
expect(mr_diff.overflow?).to be_truthy
|
|
end
|
|
|
|
it 'saves empty state' do
|
|
allow_any_instance_of(MergeRequestDiff).to receive_message_chain(:compare, :commits)
|
|
.and_return([])
|
|
|
|
mr_diff = create(:merge_request).merge_request_diff
|
|
|
|
expect(mr_diff.empty?).to be_truthy
|
|
end
|
|
end
|
|
|
|
describe '#commit_shas' do
|
|
it 'returns all commits SHA using serialized commits' do
|
|
subject.st_commits = [
|
|
{ id: 'sha1' },
|
|
{ id: 'sha2' }
|
|
]
|
|
|
|
expect(subject.commit_shas).to eq(%w(sha1 sha2))
|
|
end
|
|
end
|
|
|
|
describe '#compare_with' do
|
|
subject { create(:merge_request, source_branch: 'fix').merge_request_diff }
|
|
|
|
it 'delegates compare to the service' do
|
|
expect(CompareService).to receive(:new).and_call_original
|
|
|
|
subject.compare_with(nil)
|
|
end
|
|
|
|
it 'uses git diff A..B approach by default' do
|
|
diffs = subject.compare_with('0b4bc9a49b562e85de7cc9e834518ea6828729b9').diffs
|
|
|
|
expect(diffs.size).to eq(3)
|
|
end
|
|
end
|
|
|
|
describe '#commits_count' do
|
|
it 'returns number of commits using serialized commits' do
|
|
subject.st_commits = [
|
|
{ id: 'sha1' },
|
|
{ id: 'sha2' }
|
|
]
|
|
|
|
expect(subject.commits_count).to eq 2
|
|
end
|
|
end
|
|
|
|
describe '#utf8_st_diffs' do
|
|
it 'does not raise error when a hash value is in binary' do
|
|
subject.st_diffs = [
|
|
{ diff: "\0" },
|
|
{ diff: "\x05\x00\x68\x65\x6c\x6c\x6f" }
|
|
]
|
|
|
|
expect { subject.utf8_st_diffs }.not_to raise_error
|
|
end
|
|
end
|
|
end
|