spec/support/matchers/rugged_matchers.rb (123 lines of code) (raw):

# frozen_string_literal: true module RuggedMatchers extend RSpec::Matchers::DSL # Read a blob at `path` from a repository's current HEAD # # repository - Rugged::Repository object # path - Path String # # Returns a stripped String def read_head_blob(repository, path) head = repository.head repository .blob_at(head.target_id, path) .content .strip end # Verify that the current HEAD is the given one matcher :have_head do |head| def denormalize_head(ref) ref.delete_prefix('refs/heads/') end match do |repository| @repository = repository @expected_head = denormalize_head(head) @actual_head = denormalize_head(@repository.head.name) @expected_head == @actual_head end failure_message do %[expected HEAD of #{File.join(@repository.workdir)} to be "#{@expected_head}", but was "#{@actual_head}"] end failure_message_when_negated do %[expected HEAD of #{File.join(@repository.workdir)} not to be "#{@expected_head}", but was "#{@actual_head}"] end end # Verify that the current HEAD or given commit has the given title matcher :have_commit_title do |title| chain :for do |ref| @ref = ref end match do |repository| @repository = repository @expected_title = title commit = @ref ? @repository.rev_parse(@ref) : @repository.head.target @actual_title = commit.message.lines.first.chomp @expected_title == @actual_title end failure_message do %[expected last commit title of #{@ref || 'HEAD'} from #{File.join(@repository.workdir)} to be "#{@expected_title}", but was "#{@actual_title}"] end failure_message_when_negated do %[expected last commit title of #{@ref || 'HEAD'} from #{File.join(@repository.workdir)} not to be "#{@expected_title}"] end end # Verify that `repository` contains `file_path` for HEAD or given `ref`, `with` # the given optional content. matcher :have_blob do |file_path| chain :for do |ref| @ref = ref end chain :with do |content| @content = content end match do |repository| @repository = repository @commit = @ref ? @repository.rev_parse(@ref) : @repository.head.target blob = @repository.blob_at(@commit.oid, file_path) return false if blob.nil? return true if @content.nil? @actual_content = blob.content @content == @actual_content end failure_message do msg = "expected #{file_path} to exist in tree for #{@ref || @commit.oid}" if @content msg << %[ with "#{@content}" as content] msg << %[ but contained "#{@actual_content}" instead] if @actual_content end msg end failure_message_when_negated do "expected #{file_path} not to exist in tree for #{@ref || @commit.oid}" end end # Verify that `repository` has a version file at a specific version # # If no filename is given, `VERSION` will be read. Otherwise a # `GITLAB_[FILENAME]_VERSION` file will be read. # # Examples: # # expect(repository).to have_version.at('1.2.3') # expect(repository).to have_version('pages').at('2.3.4') # expect(repository).to have_version('workhorse').at('3.4.5') # expect(repository).not_to have_version('pages') matcher :have_version do |file_path| def normalize_path(file_path) if file_path.nil? 'VERSION' elsif file_path.eql?('gitaly') 'GITALY_SERVER_VERSION' else "GITLAB_#{file_path.upcase}_VERSION" end end chain :at do |version| @version = version end match do |repository| @repository = repository @actual = normalize_path(file_path) begin read_head_blob(repository, @actual) == @version rescue NoMethodError false end end match_when_negated do |repository| @repository = repository @actual = normalize_path(file_path) begin read_head_blob(repository, @actual) rescue NoMethodError true else false end end failure_message do if @version actual_version = read_head_blob(@repository, @actual) "expected #{File.join(@repository.workdir, @actual)} to be #{@version} but was #{actual_version}" else "expected #{File.join(@repository.workdir, @actual)} to exist but does not" end end failure_message_when_negated do if @version actual_version = read_head_blob(@repository, @actual) "expected #{File.join(@repository.workdir, @actual)} not to be #{actual_version}" else "expected #{@repository.workdir} not to contain #{@actual}" end end end end