BigW Consortium Gitlab

diff_helper_spec.rb 9.65 KB
Newer Older
Marin Jankovski committed
1 2 3 4 5 6
require 'spec_helper'

describe DiffHelper do
  include RepoHelpers

  let(:project) { create(:project) }
7
  let(:repository) { project.repository }
8
  let(:commit) { project.commit(sample_commit.id) }
9
  let(:diffs) { commit.raw_diffs }
10
  let(:diff) { diffs.first }
Douwe Maan committed
11
  let(:diff_refs) { commit.diff_refs }
12
  let(:diff_file) { Gitlab::Diff::File.new(diff, diff_refs: diff_refs, repository: repository) }
Marin Jankovski committed
13

14 15 16 17
  describe 'diff_view' do
    it 'returns a valid value when cookie is set' do
      helper.request.cookies[:diff_view] = 'parallel'

18
      expect(helper.diff_view).to eq :parallel
19 20 21 22 23
    end

    it 'returns a default value when cookie is invalid' do
      helper.request.cookies[:diff_view] = 'invalid'

24
      expect(helper.diff_view).to eq :inline
25 26 27 28 29
    end

    it 'returns a default value when cookie is nil' do
      expect(helper.request.cookies).to be_empty

30
      expect(helper.diff_view).to eq :inline
31 32
    end
  end
33

34
  describe 'diff_options' do
35
    it 'returns no collapse false' do
36
      expect(diff_options).to include(expanded: false)
37 38
    end

39 40 41
    it 'returns no collapse true if expanded' do
      allow(controller).to receive(:params) { { expanded: true } }
      expect(diff_options).to include(expanded: true)
42 43
    end

44
    it 'returns no collapse true if action name diff_for_path' do
45
      allow(controller).to receive(:action_name) { 'diff_for_path' }
46
      expect(diff_options).to include(expanded: true)
47
    end
48

49
    it 'returns paths if action name diff_for_path and param old path' do
50 51 52 53 54
      allow(controller).to receive(:params) { { old_path: 'lib/wadus.rb' } }
      allow(controller).to receive(:action_name) { 'diff_for_path' }
      expect(diff_options[:paths]).to include('lib/wadus.rb')
    end

55
    it 'returns paths if action name diff_for_path and param new path' do
56 57 58 59
      allow(controller).to receive(:params) { { new_path: 'lib/wadus.rb' } }
      allow(controller).to receive(:action_name) { 'diff_for_path' }
      expect(diff_options[:paths]).to include('lib/wadus.rb')
    end
60 61
  end

62
  describe '#diff_line_content' do
63 64 65 66 67 68 69 70
    context 'when the line is empty' do
      it 'returns a non breaking space' do
        expect(diff_line_content(nil)).to eq(' ')
      end

      it 'returns an HTML-safe string' do
        expect(diff_line_content(nil)).to be_html_safe
      end
Marin Jankovski committed
71 72
    end

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
    context 'when the line is not empty' do
      context 'when the line starts with +, -, or a space' do
        it 'strips the first character' do
          expect(diff_line_content('+new line')).to eq('new line')
          expect(diff_line_content('-new line')).to eq('new line')
          expect(diff_line_content(' new line')).to eq('new line')
        end

        context 'when the line is HTML-safe' do
          it 'returns an HTML-safe string' do
            expect(diff_line_content('+new line'.html_safe)).to be_html_safe
            expect(diff_line_content('-new line'.html_safe)).to be_html_safe
            expect(diff_line_content(' new line'.html_safe)).to be_html_safe
          end
        end

        context 'when the line is not HTML-safe' do
          it 'returns a non-HTML-safe string' do
            expect(diff_line_content('+new line')).not_to be_html_safe
            expect(diff_line_content('-new line')).not_to be_html_safe
            expect(diff_line_content(' new line')).not_to be_html_safe
          end
        end
      end

      context 'when the line does not start with a +, -, or a space' do
        it 'returns the string' do
          expect(diff_line_content('@@ -6,12 +6,18 @@ module Popen')).to eq('@@ -6,12 +6,18 @@ module Popen')
        end

        context 'when the line is HTML-safe' do
          it 'returns an HTML-safe string' do
            expect(diff_line_content('@@ -6,12 +6,18 @@ module Popen'.html_safe)).to be_html_safe
          end
        end

        context 'when the line is not HTML-safe' do
          it 'returns a non-HTML-safe string' do
            expect(diff_line_content('@@ -6,12 +6,18 @@ module Popen')).not_to be_html_safe
          end
        end
      end
115
    end
116 117 118 119 120 121 122 123
  end

  describe "#mark_inline_diffs" do
    let(:old_line) { %{abc 'def'} }
    let(:new_line) { %{abc "def"} }

    it "returns strings with marked inline diffs" do
      marked_old_line, marked_new_line = mark_inline_diffs(old_line, new_line)
124

Douwe Maan committed
125
      expect(marked_old_line).to eq(%q{abc <span class="idiff left right deletion">&#39;def&#39;</span>})
126
      expect(marked_old_line).to be_html_safe
Douwe Maan committed
127
      expect(marked_new_line).to eq(%q{abc <span class="idiff left right addition">&quot;def&quot;</span>})
128
      expect(marked_new_line).to be_html_safe
Marin Jankovski committed
129 130
    end
  end
131

132
  describe '#parallel_diff_discussions' do
133 134 135 136
    let(:discussion) { { 'abc_3_3' => 'comment' } }
    let(:diff_file) { double(line_code: 'abc_3_3') }

    before do
137
      helper.instance_variable_set(:@grouped_diff_discussions, discussion)
138 139 140
    end

    it 'does not put comments on nonewline lines' do
141 142 143 144 145 146 147 148 149 150
      left = Gitlab::Diff::Line.new('\\nonewline', 'old-nonewline', 3, 3, 3)
      right = Gitlab::Diff::Line.new('\\nonewline', 'new-nonewline', 3, 3, 3)

      result = helper.parallel_diff_discussions(left, right, diff_file)

      expect(result).to eq([nil, nil])
    end

    it 'puts comments on added lines' do
      left = Gitlab::Diff::Line.new('\\nonewline', 'old-nonewline', 3, 3, 3)
151
      right = Gitlab::Diff::Line.new('new line', 'new', 3, 3, 3)
152 153 154 155 156

      result = helper.parallel_diff_discussions(left, right, diff_file)

      expect(result).to eq([nil, 'comment'])
    end
157 158 159 160 161 162 163 164 165

    it 'puts comments on unchanged lines' do
      left = Gitlab::Diff::Line.new('unchanged line', nil, 3, 3, 3)
      right = Gitlab::Diff::Line.new('unchanged line', nil, 3, 3, 3)

      result = helper.parallel_diff_discussions(left, right, diff_file)

      expect(result).to eq(['comment', nil])
    end
166 167
  end

168 169 170 171 172
  describe "#diff_match_line" do
    let(:old_pos) { 40 }
    let(:new_pos) { 50 }
    let(:text) { 'some_text' }

173
    it "generates foldable top match line for inline view with empty text by default" do
174 175 176 177 178 179 180 181
      output = diff_match_line old_pos, new_pos

      expect(output).to be_html_safe
      expect(output).to have_css "td:nth-child(1):not(.js-unfold-bottom).diff-line-num.unfold.js-unfold.old_line[data-linenumber='#{old_pos}']", text: '...'
      expect(output).to have_css "td:nth-child(2):not(.js-unfold-bottom).diff-line-num.unfold.js-unfold.new_line[data-linenumber='#{new_pos}']", text: '...'
      expect(output).to have_css 'td:nth-child(3):not(.parallel).line_content.match', text: ''
    end

182
    it "allows to define text and bottom option" do
183 184 185 186 187 188 189 190
      output = diff_match_line old_pos, new_pos, text: text, bottom: true

      expect(output).to be_html_safe
      expect(output).to have_css "td:nth-child(1).diff-line-num.unfold.js-unfold.js-unfold-bottom.old_line[data-linenumber='#{old_pos}']", text: '...'
      expect(output).to have_css "td:nth-child(2).diff-line-num.unfold.js-unfold.js-unfold-bottom.new_line[data-linenumber='#{new_pos}']", text: '...'
      expect(output).to have_css 'td:nth-child(3):not(.parallel).line_content.match', text: text
    end

191
    it "generates match line for parallel view" do
192 193 194 195 196 197 198 199 200
      output = diff_match_line old_pos, new_pos, text: text, view: :parallel

      expect(output).to be_html_safe
      expect(output).to have_css "td:nth-child(1):not(.js-unfold-bottom).diff-line-num.unfold.js-unfold.old_line[data-linenumber='#{old_pos}']", text: '...'
      expect(output).to have_css 'td:nth-child(2).line_content.match.parallel', text: text
      expect(output).to have_css "td:nth-child(3):not(.js-unfold-bottom).diff-line-num.unfold.js-unfold.new_line[data-linenumber='#{new_pos}']", text: '...'
      expect(output).to have_css 'td:nth-child(4).line_content.match.parallel', text: text
    end

201
    it "allows to generate only left match line for parallel view" do
202 203 204 205 206 207 208 209
      output = diff_match_line old_pos, nil, text: text, view: :parallel

      expect(output).to be_html_safe
      expect(output).to have_css "td:nth-child(1):not(.js-unfold-bottom).diff-line-num.unfold.js-unfold.old_line[data-linenumber='#{old_pos}']", text: '...'
      expect(output).to have_css 'td:nth-child(2).line_content.match.parallel', text: text
      expect(output).not_to have_css 'td:nth-child(3)'
    end

210
    it "allows to generate only right match line for parallel view" do
211 212 213 214 215 216 217 218
      output = diff_match_line nil, new_pos, text: text, view: :parallel

      expect(output).to be_html_safe
      expect(output).to have_css "td:nth-child(1):not(.js-unfold-bottom).diff-line-num.unfold.js-unfold.new_line[data-linenumber='#{new_pos}']", text: '...'
      expect(output).to have_css 'td:nth-child(2).line_content.match.parallel', text: text
      expect(output).not_to have_css 'td:nth-child(3)'
    end
  end
Douwe Maan committed
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255

  context 'viewer related' do
    let(:viewer) { diff_file.simple_viewer }

    before do
      assign(:project, project)
    end

    describe '#diff_render_error_reason' do
      context 'for error :too_large' do
        before do
          expect(viewer).to receive(:render_error).and_return(:too_large)
        end

        it 'returns an error message' do
          expect(helper.diff_render_error_reason(viewer)).to eq('it is too large')
        end
      end

      context 'for error :server_side_but_stored_externally' do
        before do
          expect(viewer).to receive(:render_error).and_return(:server_side_but_stored_externally)
          expect(diff_file).to receive(:external_storage).and_return(:lfs)
        end

        it 'returns an error message' do
          expect(helper.diff_render_error_reason(viewer)).to eq('it is stored in LFS')
        end
      end
    end

    describe '#diff_render_error_options' do
      it 'includes a "view the blob" link' do
        expect(helper.diff_render_error_options(viewer)).to include(/view the blob/)
      end
    end
  end
Marin Jankovski committed
256
end