diff options
author | Nick Thomas <nick@gitlab.com> | 2018-09-04 19:30:52 +0300 |
---|---|---|
committer | Nick Thomas <nick@gitlab.com> | 2018-09-06 18:04:21 +0300 |
commit | bc3d1afe1398a32e3fab42b05092bca5f2c6c745 (patch) | |
tree | 323cbce1e75c2f8e1f33af8086c44c9174c78d87 /spec/lib/gitlab/tree_summary_spec.rb | |
parent | 43b91111d698c97c9d07617bb36db8d92bb9a0d9 (diff) |
Extract tree summary logic out of RefsController#logs_tree
Diffstat (limited to 'spec/lib/gitlab/tree_summary_spec.rb')
-rw-r--r-- | spec/lib/gitlab/tree_summary_spec.rb | 202 |
1 files changed, 202 insertions, 0 deletions
diff --git a/spec/lib/gitlab/tree_summary_spec.rb b/spec/lib/gitlab/tree_summary_spec.rb new file mode 100644 index 00000000000..7ffcef2baef --- /dev/null +++ b/spec/lib/gitlab/tree_summary_spec.rb @@ -0,0 +1,202 @@ +require 'spec_helper' + +describe Gitlab::TreeSummary do + using RSpec::Parameterized::TableSyntax + + let(:project) { create(:project, :empty_repo) } + let(:repo) { project.repository } + let(:commit) { repo.head_commit } + + let(:path) { nil } + let(:offset) { nil } + let(:limit) { nil } + + subject(:summary) { described_class.new(commit, project, path: path, offset: offset, limit: limit) } + + describe '#initialize' do + it 'defaults offset to 0' do + expect(summary.offset).to eq(0) + end + + it 'defaults limit to 25' do + expect(summary.limit).to eq(25) + end + end + + describe '#summarize' do + let(:project) { create(:project, :custom_repo, files: { 'a.txt' => '' }) } + + subject(:summarized) { summary.summarize } + + it 'returns an array of entries, and an array of commits' do + expect(summarized).to be_a(Array) + expect(summarized.size).to eq(2) + + entries, commits = *summarized + aggregate_failures do + expect(entries).to contain_exactly( + a_hash_including(file_name: 'a.txt', commit: have_attributes(id: commit.id)) + ) + + expect(commits).to match_array(entries.map { |entry| entry[:commit] }) + end + end + end + + describe '#summarize (entries)' do + let(:limit) { 2 } + + custom_files = { + 'a.txt' => '', + 'b.txt' => '', + 'directory/c.txt' => '' + } + + let(:project) { create(:project, :custom_repo, files: custom_files) } + let(:commit) { repo.head_commit } + + subject(:entries) { summary.summarize.first } + + it 'summarizes the entries within the window' do + is_expected.to contain_exactly( + a_hash_including(type: :tree, file_name: 'directory'), + a_hash_including(type: :blob, file_name: 'a.txt') + # b.txt is excluded by the limit + ) + end + + it 'references the commit and commit path in entries' do + entry = entries.first + expected_commit_path = Gitlab::Routing.url_helpers.project_commit_path(project, commit) + + expect(entry[:commit]).to be_a(::Commit) + expect(entry[:commit_path]).to eq expected_commit_path + end + + context 'in a good subdirectory' do + let(:path) { 'directory' } + + it 'summarizes the entries in the subdirectory' do + is_expected.to contain_exactly(a_hash_including(type: :blob, file_name: 'c.txt')) + end + end + + context 'in a non-existent subdirectory' do + let(:path) { 'tmp' } + + it { is_expected.to be_empty } + end + + context 'custom offset and limit' do + let(:offset) { 2 } + + it 'returns entries from the offset' do + is_expected.to contain_exactly(a_hash_including(type: :blob, file_name: 'b.txt')) + end + end + end + + describe '#summarize (commits)' do + # This is a commit in the master branch of the gitlab-test repository that + # satisfies certain assumptions these tests depend on + let(:test_commit_sha) { '7975be0116940bf2ad4321f79d02a55c5f7779aa' } + let(:whitespace_commit_sha) { '66eceea0db202bb39c4e445e8ca28689645366c5' } + + let(:project) { create(:project, :repository) } + let(:commit) { repo.commit(test_commit_sha) } + let(:limit) { nil } + let(:entries) { summary.summarize.first } + + subject(:commits) do + summary.summarize.last + end + + it 'returns an Array of ::Commit objects' do + is_expected.not_to be_empty + is_expected.to all(be_kind_of(::Commit)) + end + + it 'deduplicates commits when multiple entries reference the same commit' do + expect(commits.size).to be < entries.size + end + + context 'in a subdirectory' do + let(:path) { 'files' } + + it 'returns commits for entries in the subdirectory' do + expect(commits).to satisfy_one { |c| c.id == whitespace_commit_sha } + end + end + end + + describe '#more?' do + let(:path) { 'tmp/more' } + + where(:num_entries, :offset, :limit, :expected_result) do + 0 | 0 | 0 | false + 0 | 0 | 1 | false + + 1 | 0 | 0 | true + 1 | 0 | 1 | false + 1 | 1 | 0 | false + 1 | 1 | 1 | false + + 2 | 0 | 0 | true + 2 | 0 | 1 | true + 2 | 0 | 2 | false + 2 | 0 | 3 | false + 2 | 1 | 0 | true + 2 | 1 | 1 | false + 2 | 2 | 0 | false + 2 | 2 | 1 | false + end + + with_them do + before do + create_file('dummy', path: 'other') if num_entries.zero? + 1.upto(num_entries) { |n| create_file(n, path: path) } + end + + subject { summary.more? } + + it { is_expected.to eq(expected_result) } + end + end + + describe '#next_offset' do + let(:path) { 'tmp/next_offset' } + + where(:num_entries, :offset, :limit, :expected_result) do + 0 | 0 | 0 | 0 + 0 | 0 | 1 | 1 + 0 | 1 | 0 | 1 + 0 | 1 | 1 | 1 + + 1 | 0 | 0 | 0 + 1 | 0 | 1 | 1 + 1 | 1 | 0 | 1 + 1 | 1 | 1 | 2 + end + + with_them do + before do + create_file('dummy', path: 'other') if num_entries.zero? + 1.upto(num_entries) { |n| create_file(n, path: path) } + end + + subject { summary.next_offset } + + it { is_expected.to eq(expected_result) } + end + end + + def create_file(unique, path:) + repo.create_file( + project.creator, + "#{path}/file-#{unique}.txt", + 'content', + message: "Commit message #{unique}", + branch_name: 'master' + ) + end +end |