# frozen_string_literal: true require 'fast_spec_helper' require_relative 'danger_spec_helper' require 'gitlab/danger/base_linter' RSpec.describe Gitlab::Danger::BaseLinter do let(:commit_class) do Struct.new(:message, :sha, :diff_parent) end let(:commit_message) { 'A commit message' } let(:commit) { commit_class.new(commit_message, anything, anything) } subject(:commit_linter) { described_class.new(commit) } describe '#failed?' do context 'with no failures' do it { expect(commit_linter).not_to be_failed } end context 'with failures' do before do commit_linter.add_problem(:subject_too_long, described_class.subject_description) end it { expect(commit_linter).to be_failed } end end describe '#add_problem' do it 'stores messages in #failures' do commit_linter.add_problem(:subject_too_long, '%s') expect(commit_linter.problems).to eq({ subject_too_long: described_class.problems_mapping[:subject_too_long] }) end end shared_examples 'a valid commit' do it 'does not have any problem' do commit_linter.lint_subject expect(commit_linter.problems).to be_empty end end describe '#lint_subject' do context 'when subject valid' do it_behaves_like 'a valid commit' end context 'when subject is too short' do let(:commit_message) { 'A B' } it 'adds a problem' do expect(commit_linter).to receive(:add_problem).with(:subject_too_short, described_class.subject_description) commit_linter.lint_subject end end context 'when subject is too long' do let(:commit_message) { 'A B ' + 'C' * described_class::MAX_LINE_LENGTH } it 'adds a problem' do expect(commit_linter).to receive(:add_problem).with(:subject_too_long, described_class.subject_description) commit_linter.lint_subject end end context 'when subject is a WIP' do let(:final_message) { 'A B C' } # commit message with prefix will be over max length. commit message without prefix will be of maximum size let(:commit_message) { described_class::WIP_PREFIX + final_message + 'D' * (described_class::MAX_LINE_LENGTH - final_message.size) } it 'does not have any problems' do commit_linter.lint_subject expect(commit_linter.problems).to be_empty end end context 'when subject is too short and too long' do let(:commit_message) { 'A ' + 'B' * described_class::MAX_LINE_LENGTH } it 'adds a problem' do expect(commit_linter).to receive(:add_problem).with(:subject_too_short, described_class.subject_description) expect(commit_linter).to receive(:add_problem).with(:subject_too_long, described_class.subject_description) commit_linter.lint_subject end end context 'when subject starts with lowercase' do let(:commit_message) { 'a B C' } it 'adds a problem' do expect(commit_linter).to receive(:add_problem).with(:subject_starts_with_lowercase, described_class.subject_description) commit_linter.lint_subject end end [ '[ci skip] A commit message', '[Ci skip] A commit message', '[API] A commit message', 'api: A commit message', 'API: A commit message', 'API: a commit message', 'API: a commit message' ].each do |message| context "when subject is '#{message}'" do let(:commit_message) { message } it 'does not add a problem' do expect(commit_linter).not_to receive(:add_problem) commit_linter.lint_subject end end end [ '[ci skip]A commit message', '[Ci skip] A commit message', '[ci skip] a commit message', 'api: a commit message', '! A commit message' ].each do |message| context "when subject is '#{message}'" do let(:commit_message) { message } it 'adds a problem' do expect(commit_linter).to receive(:add_problem).with(:subject_starts_with_lowercase, described_class.subject_description) commit_linter.lint_subject end end end context 'when subject ends with a period' do let(:commit_message) { 'A B C.' } it 'adds a problem' do expect(commit_linter).to receive(:add_problem).with(:subject_ends_with_a_period, described_class.subject_description) commit_linter.lint_subject end end end end