diff options
author | Alejandro RodrÃguez <alejorro70@gmail.com> | 2017-10-07 04:41:23 +0300 |
---|---|---|
committer | Alejandro RodrÃguez <alejorro70@gmail.com> | 2017-10-13 04:03:14 +0300 |
commit | 3fcab51ebb0f3156b5d732d050b292cd3e081262 (patch) | |
tree | 7292079f50121aae6e457bfd3dadb944fb2feeec /spec/lib/gitlab/conflict | |
parent | 9cc15172deaa4582c5fd956cc163539041d018b1 (diff) |
Refactor conflict resolution to contain git ops within Gitlab::Git
This prepares the codebase for a Gitaly migration. See
https://gitlab.com/gitlab-org/gitaly/issues/553
Diffstat (limited to 'spec/lib/gitlab/conflict')
-rw-r--r-- | spec/lib/gitlab/conflict/file_collection_spec.rb | 2 | ||||
-rw-r--r-- | spec/lib/gitlab/conflict/file_spec.rb | 18 | ||||
-rw-r--r-- | spec/lib/gitlab/conflict/parser_spec.rb | 222 |
3 files changed, 10 insertions, 232 deletions
diff --git a/spec/lib/gitlab/conflict/file_collection_spec.rb b/spec/lib/gitlab/conflict/file_collection_spec.rb index a4d7628b03a..5944ce8049a 100644 --- a/spec/lib/gitlab/conflict/file_collection_spec.rb +++ b/spec/lib/gitlab/conflict/file_collection_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' describe Gitlab::Conflict::FileCollection do let(:merge_request) { create(:merge_request, source_branch: 'conflict-resolvable', target_branch: 'conflict-start') } - let(:file_collection) { described_class.read_only(merge_request) } + let(:file_collection) { described_class.new(merge_request) } describe '#files' do it 'returns an array of Conflict::Files' do diff --git a/spec/lib/gitlab/conflict/file_spec.rb b/spec/lib/gitlab/conflict/file_spec.rb index 5356e9742b4..89dd545829b 100644 --- a/spec/lib/gitlab/conflict/file_spec.rb +++ b/spec/lib/gitlab/conflict/file_spec.rb @@ -8,9 +8,10 @@ describe Gitlab::Conflict::File do let(:our_commit) { rugged.branches['conflict-resolvable'].target } let(:merge_request) { create(:merge_request, source_branch: 'conflict-resolvable', target_branch: 'conflict-start', source_project: project) } let(:index) { rugged.merge_commits(our_commit, their_commit) } - let(:conflict) { index.conflicts.last } - let(:merge_file_result) { index.merge_file('files/ruby/regex.rb') } - let(:conflict_file) { described_class.new(merge_file_result, conflict, merge_request: merge_request) } + let(:rugged_conflict) { index.conflicts.last } + let(:raw_conflict_content) { index.merge_file('files/ruby/regex.rb')[:data] } + let(:raw_conflict_file) { Gitlab::Git::ConflictFile.new(repository, our_commit.oid, rugged_conflict, raw_conflict_content) } + let(:conflict_file) { described_class.new(raw_conflict_file, merge_request: merge_request) } describe '#resolve_lines' do let(:section_keys) { conflict_file.sections.map { |section| section[:id] }.compact } @@ -48,18 +49,18 @@ describe Gitlab::Conflict::File do end end - it 'raises MissingResolution when passed a hash without resolutions for all sections' do + it 'raises ResolutionError when passed a hash without resolutions for all sections' do empty_hash = section_keys.map { |key| [key, nil] }.to_h invalid_hash = section_keys.map { |key| [key, 'invalid'] }.to_h expect { conflict_file.resolve_lines({}) } - .to raise_error(Gitlab::Conflict::File::MissingResolution) + .to raise_error(Gitlab::Git::Merge::ResolutionError) expect { conflict_file.resolve_lines(empty_hash) } - .to raise_error(Gitlab::Conflict::File::MissingResolution) + .to raise_error(Gitlab::Git::Merge::ResolutionError) expect { conflict_file.resolve_lines(invalid_hash) } - .to raise_error(Gitlab::Conflict::File::MissingResolution) + .to raise_error(Gitlab::Git::Merge::ResolutionError) end end @@ -144,7 +145,7 @@ describe Gitlab::Conflict::File do end context 'with an example file' do - let(:file) do + let(:raw_conflict_content) do <<FILE # Ensure there is no match line header here def username_regexp @@ -220,7 +221,6 @@ end FILE end - let(:conflict_file) { described_class.new({ data: file }, conflict, merge_request: merge_request) } let(:sections) { conflict_file.sections } it 'sets the correct match line headers' do diff --git a/spec/lib/gitlab/conflict/parser_spec.rb b/spec/lib/gitlab/conflict/parser_spec.rb deleted file mode 100644 index fce606a2bb5..00000000000 --- a/spec/lib/gitlab/conflict/parser_spec.rb +++ /dev/null @@ -1,222 +0,0 @@ -require 'spec_helper' - -describe Gitlab::Conflict::Parser do - let(:parser) { described_class.new } - - describe '#parse' do - def parse_text(text) - parser.parse(text, our_path: 'README.md', their_path: 'README.md') - end - - context 'when the file has valid conflicts' do - let(:text) do - <<CONFLICT -module Gitlab - module Regexp - extend self - - def username_regexp - default_regexp - end - -<<<<<<< files/ruby/regex.rb - def project_name_regexp - /\A[a-zA-Z0-9][a-zA-Z0-9_\-\. ]*\z/ - end - - def name_regexp - /\A[a-zA-Z0-9_\-\. ]*\z/ -======= - def project_name_regex - %r{\A[a-zA-Z0-9][a-zA-Z0-9_\-\. ]*\z} - end - - def name_regex - %r{\A[a-zA-Z0-9_\-\. ]*\z} ->>>>>>> files/ruby/regex.rb - end - - def path_regexp - default_regexp - end - -<<<<<<< files/ruby/regex.rb - def archive_formats_regexp - /(zip|tar|7z|tar\.gz|tgz|gz|tar\.bz2|tbz|tbz2|tb2|bz2)/ -======= - def archive_formats_regex - %r{(zip|tar|7z|tar\.gz|tgz|gz|tar\.bz2|tbz|tbz2|tb2|bz2)} ->>>>>>> files/ruby/regex.rb - end - - def git_reference_regexp - # Valid git ref regexp, see: - # https://www.kernel.org/pub/software/scm/git/docs/git-check-ref-format.html - %r{ - (?! - (?# doesn't begins with) - \/| (?# rule #6) - (?# doesn't contain) - .*(?: - [\/.]\.| (?# rule #1,3) - \/\/| (?# rule #6) - @\{| (?# rule #8) - \\ (?# rule #9) - ) - ) - [^\000-\040\177~^:?*\[]+ (?# rule #4-5) - (?# doesn't end with) - (?<!\.lock) (?# rule #1) - (?<![\/.]) (?# rule #6-7) - }x - end - - protected - -<<<<<<< files/ruby/regex.rb - def default_regexp - /\A[.?]?[a-zA-Z0-9][a-zA-Z0-9_\-\.]*(?<!\.git)\z/ -======= - def default_regex - %r{\A[.?]?[a-zA-Z0-9][a-zA-Z0-9_\-\.]*(?<!\.git)\z} ->>>>>>> files/ruby/regex.rb - end - end -end -CONFLICT - end - - let(:lines) do - parser.parse(text, our_path: 'files/ruby/regex.rb', their_path: 'files/ruby/regex.rb') - end - - it 'sets our lines as new lines' do - expect(lines[8..13]).to all(have_attributes(type: 'new')) - expect(lines[26..27]).to all(have_attributes(type: 'new')) - expect(lines[56..57]).to all(have_attributes(type: 'new')) - end - - it 'sets their lines as old lines' do - expect(lines[14..19]).to all(have_attributes(type: 'old')) - expect(lines[28..29]).to all(have_attributes(type: 'old')) - expect(lines[58..59]).to all(have_attributes(type: 'old')) - end - - it 'sets non-conflicted lines as both' do - expect(lines[0..7]).to all(have_attributes(type: nil)) - expect(lines[20..25]).to all(have_attributes(type: nil)) - expect(lines[30..55]).to all(have_attributes(type: nil)) - expect(lines[60..62]).to all(have_attributes(type: nil)) - end - - it 'sets consecutive line numbers for index, old_pos, and new_pos' do - old_line_numbers = lines.select { |line| line.type != 'new' }.map(&:old_pos) - new_line_numbers = lines.select { |line| line.type != 'old' }.map(&:new_pos) - - expect(lines.map(&:index)).to eq(0.upto(62).to_a) - expect(old_line_numbers).to eq(1.upto(53).to_a) - expect(new_line_numbers).to eq(1.upto(53).to_a) - end - end - - context 'when the file contents include conflict delimiters' do - context 'when there is a non-start delimiter first' do - it 'raises UnexpectedDelimiter when there is a middle delimiter first' do - expect { parse_text('=======') } - .to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter) - end - - it 'raises UnexpectedDelimiter when there is an end delimiter first' do - expect { parse_text('>>>>>>> README.md') } - .to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter) - end - - it 'does not raise when there is an end delimiter for a different path first' do - expect { parse_text('>>>>>>> some-other-path.md') } - .not_to raise_error - end - end - - context 'when a start delimiter is followed by a non-middle delimiter' do - let(:start_text) { "<<<<<<< README.md\n" } - let(:end_text) { "\n=======\n>>>>>>> README.md" } - - it 'raises UnexpectedDelimiter when it is followed by an end delimiter' do - expect { parse_text(start_text + '>>>>>>> README.md' + end_text) } - .to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter) - end - - it 'raises UnexpectedDelimiter when it is followed by another start delimiter' do - expect { parse_text(start_text + start_text + end_text) } - .to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter) - end - - it 'does not raise when it is followed by a start delimiter for a different path' do - expect { parse_text(start_text + '>>>>>>> some-other-path.md' + end_text) } - .not_to raise_error - end - end - - context 'when a middle delimiter is followed by a non-end delimiter' do - let(:start_text) { "<<<<<<< README.md\n=======\n" } - let(:end_text) { "\n>>>>>>> README.md" } - - it 'raises UnexpectedDelimiter when it is followed by another middle delimiter' do - expect { parse_text(start_text + '=======' + end_text) } - .to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter) - end - - it 'raises UnexpectedDelimiter when it is followed by a start delimiter' do - expect { parse_text(start_text + start_text + end_text) } - .to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter) - end - - it 'does not raise when it is followed by a start delimiter for another path' do - expect { parse_text(start_text + '<<<<<<< some-other-path.md' + end_text) } - .not_to raise_error - end - end - - it 'raises MissingEndDelimiter when there is no end delimiter at the end' do - start_text = "<<<<<<< README.md\n=======\n" - - expect { parse_text(start_text) } - .to raise_error(Gitlab::Conflict::Parser::MissingEndDelimiter) - - expect { parse_text(start_text + '>>>>>>> some-other-path.md') } - .to raise_error(Gitlab::Conflict::Parser::MissingEndDelimiter) - end - end - - context 'other file types' do - it 'raises UnmergeableFile when lines is blank, indicating a binary file' do - expect { parse_text('') } - .to raise_error(Gitlab::Conflict::Parser::UnmergeableFile) - - expect { parse_text(nil) } - .to raise_error(Gitlab::Conflict::Parser::UnmergeableFile) - end - - it 'raises UnmergeableFile when the file is over 200 KB' do - expect { parse_text('a' * 204801) } - .to raise_error(Gitlab::Conflict::Parser::UnmergeableFile) - end - - # All text from Rugged has an encoding of ASCII_8BIT, so force that in - # these strings. - context 'when the file contains UTF-8 characters' do - it 'does not raise' do - expect { parse_text("Espa\xC3\xB1a".force_encoding(Encoding::ASCII_8BIT)) } - .not_to raise_error - end - end - - context 'when the file contains non-UTF-8 characters' do - it 'raises UnsupportedEncoding' do - expect { parse_text("a\xC4\xFC".force_encoding(Encoding::ASCII_8BIT)) } - .to raise_error(Gitlab::Conflict::Parser::UnsupportedEncoding) - end - end - end - end -end |