Skip to content
Snippets Groups Projects
Select Git revision
  • move-gl-dropdown
  • improve-table-pagination-spec
  • move-markdown-preview
  • winh-fix-merge-request-spec
  • master default
  • index-namespaces-lower-name
  • winh-single-karma-test
  • 10-3-stable
  • 36782-replace-team-user-role-with-add_role-user-in-specs
  • winh-modal-internal-state
  • tz-ide-file-icons
  • 38869-milestone-select
  • update-autodevops-template
  • jivl-activate-repo-cookie-preferences
  • qa-add-deploy-key
  • docs-move-article-ldap
  • 40780-choose-file
  • 22643-manual-job-page
  • refactor-cluster-show-page-conservative
  • dm-sidekiq-versioning
  • v10.4.0.pre
  • v10.3.0
  • v10.3.0-rc5
  • v10.3.0-rc4
  • v10.3.0-rc3
  • v10.3.0-rc2
  • v10.2.5
  • v10.3.0-rc1
  • v10.0.7
  • v10.1.5
  • v10.2.4
  • v10.2.3
  • v10.2.2
  • v10.2.1
  • v10.3.0.pre
  • v10.2.0
  • v10.2.0-rc4
  • v10.2.0-rc3
  • v10.1.4
  • v10.2.0-rc2
40 results

diff_collection_spec.rb

Blame
  • Forked from GitLab.org / GitLab FOSS
    1501 commits behind the upstream repository.
    diff_collection_spec.rb 11.47 KiB
    require 'spec_helper'
    
    describe Gitlab::Git::DiffCollection, seed_helper: true do
      subject do
        Gitlab::Git::DiffCollection.new(
          iterator,
          max_files: max_files,
          max_lines: max_lines,
          all_diffs: all_diffs,
          no_collapse: no_collapse
        )
      end
      let(:iterator) { Array.new(file_count, fake_diff(line_length, line_count)) }
      let(:file_count) { 0 }
      let(:line_length) { 1 }
      let(:line_count) { 1 }
      let(:max_files) { 10 }
      let(:max_lines) { 100 }
      let(:all_diffs) { false }
      let(:no_collapse) { true }
    
      describe '#to_a' do
        subject { super().to_a }
        it { is_expected.to be_kind_of ::Array }
      end
    
      describe '#decorate!' do
        let(:file_count) { 3 }
    
        it 'modifies the array in place' do
          count = 0
          subject.decorate! { |d| !d.nil? && count += 1 }
          expect(subject.to_a).to eq([1, 2, 3])
          expect(count).to eq(3)
        end
    
        it 'avoids future iterator iterations' do
          subject.decorate! { |d| d unless d.nil? }
    
          expect(iterator).not_to receive(:each)
    
          subject.overflow?
        end
      end
    
      context 'overflow handling' do
        context 'adding few enough files' do
          let(:file_count) { 3 }
    
          context 'and few enough lines' do
            let(:line_count) { 10 }
    
            describe '#overflow?' do
              subject { super().overflow? }
              it { is_expected.to be_falsey }
            end
    
            describe '#empty?' do
              subject { super().empty? }
              it { is_expected.to be_falsey }
            end
    
            describe '#real_size' do
              subject { super().real_size }
              it { is_expected.to eq('3') }
            end
            it { expect(subject.size).to eq(3) }
    
            context 'when limiting is disabled' do
              let(:all_diffs) { true }
    
              describe '#overflow?' do
                subject { super().overflow? }
                it { is_expected.to be_falsey }
              end
    
              describe '#empty?' do
                subject { super().empty? }
                it { is_expected.to be_falsey }
              end
    
              describe '#real_size' do
                subject { super().real_size }
                it { is_expected.to eq('3') }
              end
              it { expect(subject.size).to eq(3) }
            end
          end
    
          context 'and too many lines' do
            let(:line_count) { 1000 }
    
            describe '#overflow?' do
              subject { super().overflow? }
              it { is_expected.to be_truthy }
            end
    
            describe '#empty?' do
              subject { super().empty? }
              it { is_expected.to be_falsey }
            end
    
            describe '#real_size' do
              subject { super().real_size }
              it { is_expected.to eq('0+') }
            end
            it { expect(subject.size).to eq(0) }
    
            context 'when limiting is disabled' do
              let(:all_diffs) { true }
    
              describe '#overflow?' do
                subject { super().overflow? }
                it { is_expected.to be_falsey }
              end
    
              describe '#empty?' do
                subject { super().empty? }
                it { is_expected.to be_falsey }
              end
    
              describe '#real_size' do
                subject { super().real_size }
                it { is_expected.to eq('3') }
              end
              it { expect(subject.size).to eq(3) }
            end
          end
        end
    
        context 'adding too many files' do
          let(:file_count) { 11 }
    
          context 'and few enough lines' do
            let(:line_count) { 1 }
    
            describe '#overflow?' do
              subject { super().overflow? }
              it { is_expected.to be_truthy }
            end
    
            describe '#empty?' do
              subject { super().empty? }
              it { is_expected.to be_falsey }
            end
    
            describe '#real_size' do
              subject { super().real_size }
              it { is_expected.to eq('10+') }
            end
            it { expect(subject.size).to eq(10) }
    
            context 'when limiting is disabled' do
              let(:all_diffs) { true }
    
              describe '#overflow?' do
                subject { super().overflow? }
                it { is_expected.to be_falsey }
              end
    
              describe '#empty?' do
                subject { super().empty? }
                it { is_expected.to be_falsey }
              end
    
              describe '#real_size' do
                subject { super().real_size }
                it { is_expected.to eq('11') }
              end
              it { expect(subject.size).to eq(11) }
            end
          end
    
          context 'and too many lines' do
            let(:line_count) { 30 }
    
            describe '#overflow?' do
              subject { super().overflow? }
              it { is_expected.to be_truthy }
            end
    
            describe '#empty?' do
              subject { super().empty? }
              it { is_expected.to be_falsey }
            end
    
            describe '#real_size' do
              subject { super().real_size }
              it { is_expected.to eq('3+') }
            end
            it { expect(subject.size).to eq(3) }
    
            context 'when limiting is disabled' do
              let(:all_diffs) { true }
    
              describe '#overflow?' do
                subject { super().overflow? }
                it { is_expected.to be_falsey }
              end
    
              describe '#empty?' do
                subject { super().empty? }
                it { is_expected.to be_falsey }
              end
    
              describe '#real_size' do
                subject { super().real_size }
                it { is_expected.to eq('11') }
              end
              it { expect(subject.size).to eq(11) }
            end
          end
        end
    
        context 'adding exactly the maximum number of files' do
          let(:file_count) { 10 }
    
          context 'and few enough lines' do
            let(:line_count) { 1 }
    
            describe '#overflow?' do
              subject { super().overflow? }
              it { is_expected.to be_falsey }
            end
    
            describe '#empty?' do
              subject { super().empty? }
              it { is_expected.to be_falsey }
            end
    
            describe '#real_size' do
              subject { super().real_size }
              it { is_expected.to eq('10') }
            end
            it { expect(subject.size).to eq(10) }
          end
        end
    
        context 'adding too many bytes' do
          let(:file_count) { 10 }
          let(:line_length) { 5200 }
    
          describe '#overflow?' do
            subject { super().overflow? }
            it { is_expected.to be_truthy }
          end
    
          describe '#empty?' do
            subject { super().empty? }
            it { is_expected.to be_falsey }
          end
    
          describe '#real_size' do
            subject { super().real_size }
            it { is_expected.to eq('9+') }
          end
          it { expect(subject.size).to eq(9) }
    
          context 'when limiting is disabled' do
            let(:all_diffs) { true }
    
            describe '#overflow?' do
              subject { super().overflow? }
              it { is_expected.to be_falsey }
            end
    
            describe '#empty?' do
              subject { super().empty? }
              it { is_expected.to be_falsey }
            end
    
            describe '#real_size' do
              subject { super().real_size }
              it { is_expected.to eq('10') }
            end
            it { expect(subject.size).to eq(10) }
          end
        end
      end
    
      describe 'empty collection' do
        subject { Gitlab::Git::DiffCollection.new([]) }
    
        describe '#overflow?' do
          subject { super().overflow? }
          it { is_expected.to be_falsey }
        end
    
        describe '#empty?' do
          subject { super().empty? }
          it { is_expected.to be_truthy }
        end
    
        describe '#size' do
          subject { super().size }
          it { is_expected.to eq(0) }
        end
    
        describe '#real_size' do
          subject { super().real_size }
          it { is_expected.to eq('0')}
        end
      end
    
      describe '#each' do
        context 'when diff are too large' do
          let(:collection) do
            Gitlab::Git::DiffCollection.new([{ diff: 'a' * 204800 }])
          end
    
          it 'yields Diff instances even when they are too large' do
            expect { |b| collection.each(&b) }.
              to yield_with_args(an_instance_of(Gitlab::Git::Diff))
          end
    
          it 'prunes diffs that are too large' do
            diff = nil
    
            collection.each do |d|
              diff = d
            end
    
            expect(diff.diff).to eq('')
          end
        end
    
        context 'when diff is quite large will collapse by default' do
          let(:iterator) { [{ diff: 'a' * 20480 }] }
    
          context 'when no collapse is set' do
            let(:no_collapse) { true }
    
            it 'yields Diff instances even when they are quite big' do
              expect { |b| subject.each(&b) }.
                to yield_with_args(an_instance_of(Gitlab::Git::Diff))
            end
    
            it 'does not prune diffs' do
              diff = nil
    
              subject.each do |d|
                diff = d
              end
    
              expect(diff.diff).not_to eq('')
            end
          end
    
          context 'when no collapse is unset' do
            let(:no_collapse) { false }
    
            it 'yields Diff instances even when they are quite big' do
              expect { |b| subject.each(&b) }.
                to yield_with_args(an_instance_of(Gitlab::Git::Diff))
            end
    
            it 'prunes diffs that are quite big' do
              diff = nil
    
              subject.each do |d|
                diff = d
              end
    
              expect(diff.diff).to eq('')
            end
    
            context 'when go over safe limits on files' do
              let(:iterator) { [fake_diff(1, 1)] * 4 }
    
              before(:each) do
                stub_const('Gitlab::Git::DiffCollection::DEFAULT_LIMITS', { max_files: 2, max_lines: max_lines })
              end
    
              it 'prunes diffs by default even little ones' do
                subject.each_with_index do |d, i|
                  if i < 2
                    expect(d.diff).not_to eq('')
                  else # 90 lines
                    expect(d.diff).to eq('')
                  end
                end
              end
            end
    
            context 'when go over safe limits on lines' do
              let(:iterator) do
                [
                  fake_diff(1, 45),
                  fake_diff(1, 45),
                  fake_diff(1, 20480),
                  fake_diff(1, 1)
                ]
              end
    
              before(:each) do
                stub_const('Gitlab::Git::DiffCollection::DEFAULT_LIMITS', { max_files: max_files, max_lines: 80 })
              end
    
              it 'prunes diffs by default even little ones' do
                subject.each_with_index do |d, i|
                  if i < 2
                    expect(d.diff).not_to eq('')
                  else # 90 lines
                    expect(d.diff).to eq('')
                  end
                end
              end
            end
    
            context 'when go over safe limits on bytes' do
              let(:iterator) do
                [
                  fake_diff(1, 45),
                  fake_diff(1, 45),
                  fake_diff(1, 20480),
                  fake_diff(1, 1)
                ]
              end
    
              before(:each) do
                stub_const('Gitlab::Git::DiffCollection::DEFAULT_LIMITS', { max_files: max_files, max_lines: 80 })
              end
    
              it 'prunes diffs by default even little ones' do
                subject.each_with_index do |d, i|
                  if i < 2
                    expect(d.diff).not_to eq('')
                  else # > 80 bytes
                    expect(d.diff).to eq('')
                  end
                end
              end
            end
          end
    
          context 'when limiting is disabled' do
            let(:all_diffs) { true }
    
            it 'yields Diff instances even when they are quite big' do
              expect { |b| subject.each(&b) }.
                to yield_with_args(an_instance_of(Gitlab::Git::Diff))
            end
    
            it 'does not prune diffs' do
              diff = nil
    
              subject.each do |d|
                diff = d
              end
    
              expect(diff.diff).not_to eq('')
            end
          end
        end
      end
    
      def fake_diff(line_length, line_count)
        { 'diff' => "#{'a' * line_length}\n" * line_count }
      end
    end