summaryrefslogtreecommitdiff
path: root/spec/models/compare_spec.rb
blob: 43c3580bed2301665d42392a52af4b47619386b3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# frozen_string_literal: true

require 'spec_helper'

describe Compare do
  include RepoHelpers

  let(:project) { create(:project, :public, :repository) }
  let(:commit)  { project.commit }

  let(:start_commit) { sample_image_commit }
  let(:head_commit) { sample_commit }

  let(:raw_compare) { Gitlab::Git::Compare.new(project.repository.raw_repository, start_commit.id, head_commit.id) }

  subject { described_class.new(raw_compare, project) }

  describe '#start_commit' do
    it 'returns raw compare base commit' do
      expect(subject.start_commit.id).to eq(start_commit.id)
    end

    it 'returns nil if compare base commit is nil' do
      expect(raw_compare).to receive(:base).and_return(nil)

      expect(subject.start_commit).to eq(nil)
    end
  end

  describe '#commit' do
    it 'returns raw compare head commit' do
      expect(subject.commit.id).to eq(head_commit.id)
    end

    it 'returns nil if compare head commit is nil' do
      expect(raw_compare).to receive(:head).and_return(nil)

      expect(subject.commit).to eq(nil)
    end
  end

  describe '#base_commit_sha' do
    it 'returns @base_sha if it is present' do
      expect(project).not_to receive(:merge_base_commit)

      sha = double
      service = described_class.new(raw_compare, project, base_sha: sha)

      expect(service.base_commit_sha).to eq(sha)
    end

    it 'fetches merge base SHA from repo when @base_sha is nil' do
      expect(project).to receive(:merge_base_commit)
        .with(start_commit.id, head_commit.id)
        .once
        .and_call_original

      expect(subject.base_commit_sha)
        .to eq(project.repository.merge_base(start_commit.id, head_commit.id))
    end

    it 'is memoized on first call' do
      expect(project).to receive(:merge_base_commit)
        .with(start_commit.id, head_commit.id)
        .once
        .and_call_original

      3.times { subject.base_commit_sha }
    end

    it 'returns nil if there is no start_commit' do
      expect(subject).to receive(:start_commit).and_return(nil)

      expect(subject.base_commit_sha).to eq(nil)
    end

    it 'returns nil if there is no head commit' do
      expect(subject).to receive(:head_commit).and_return(nil)

      expect(subject.base_commit_sha).to eq(nil)
    end
  end

  describe '#diff_refs' do
    it 'uses base_commit_sha sha as base_sha' do
      expect(subject.diff_refs.base_sha).to eq(subject.base_commit_sha)
    end

    it 'uses start_commit sha as start_sha' do
      expect(subject.diff_refs.start_sha).to eq(start_commit.id)
    end

    it 'uses commit sha as head sha' do
      expect(subject.diff_refs.head_sha).to eq(head_commit.id)
    end
  end

  describe '#modified_paths' do
    context 'changes are present' do
      let(:raw_compare) do
        Gitlab::Git::Compare.new(
          project.repository.raw_repository, 'before-create-delete-modify-move', 'after-create-delete-modify-move'
        )
      end

      it 'returns affected file paths, without duplication' do
        expect(subject.modified_paths).to contain_exactly(*%w{
          foo/for_move.txt
          foo/bar/for_move.txt
          foo/for_create.txt
          foo/for_delete.txt
          foo/for_edit.txt
        })
      end
    end

    context 'changes are absent' do
      let(:start_commit) { sample_commit }
      let(:head_commit) { sample_commit }

      it 'returns empty array' do
        expect(subject.modified_paths).to eq([])
      end
    end
  end
end