require_relative '../spec_helper' require_lib 'reek/smell_warning' RSpec.describe Reek::SmellWarning do let(:uncommunicative_name_detector) { build(:smell_detector, smell_type: 'UncommunicativeVariableName') } describe 'sort order' do shared_examples_for 'first sorts ahead of second' do it 'hash differently' do expect(first.hash).not_to eq(second.hash) end it 'are not equal' do expect(first).not_to eq(second) end it 'sort correctly' do expect(first <=> second).to be < 0 end it 'does not match using eql?' do expect(first).not_to eql(second) end end context 'when smells differ only by detector' do let(:first) { build_smell_warning(smell_type: 'DuplicateMethodCall') } let(:second) { build_smell_warning(smell_type: 'FeatureEnvy') } it_behaves_like 'first sorts ahead of second' end context 'when smells differ only by lines' do let(:first) { build_smell_warning(smell_type: 'FeatureEnvy', lines: [2]) } let(:second) { build_smell_warning(smell_type: 'FeatureEnvy', lines: [3]) } it_behaves_like 'first sorts ahead of second' end context 'when smells differ only by context' do let(:first) { build_smell_warning(smell_type: 'DuplicateMethodCall', context: 'first') } let(:second) do build_smell_warning(smell_type: 'DuplicateMethodCall', context: 'second') end it_behaves_like 'first sorts ahead of second' end context 'when smells differ only by message' do let(:first) do build_smell_warning(smell_type: 'DuplicateMethodCall', context: 'ctx', message: 'first message') end let(:second) do build_smell_warning(smell_type: 'DuplicateMethodCall', context: 'ctx', message: 'second message') end it_behaves_like 'first sorts ahead of second' end context 'when smells differ by name and message' do let(:first) do build_smell_warning(smell_type: 'FeatureEnvy', message: 'second message') end let(:second) do build_smell_warning(smell_type: 'UtilityFunction', message: 'first message') end it_behaves_like 'first sorts ahead of second' end context 'when smells differ everywhere' do let(:first) do build_smell_warning(smell_type: 'DuplicateMethodCall', context: 'Dirty#a', message: 'calls @s.title twice') end let(:second) do build_smell_warning(smell_type: 'UncommunicativeVariableName', context: 'Dirty', message: "has the variable name '@s'") end it_behaves_like 'first sorts ahead of second' end end describe '#yaml_hash' do let(:context_name) { 'Module::Class#method/block' } let(:lines) { [24, 513] } let(:message) { 'test message' } let(:parameters) { { 'one' => 34, 'two' => 'second' } } let(:smell_type) { 'FeatureEnvy' } let(:source) { 'a/ruby/source/file.rb' } let(:yaml) do warning = described_class.new(smell_type, source: source, context: context_name, lines: lines, message: message, parameters: parameters) warning.yaml_hash end it 'includes the smell type' do expect(yaml['smell_type']).to eq 'FeatureEnvy' end it 'includes the context' do expect(yaml['context']).to eq context_name end it 'includes the message' do expect(yaml['message']).to eq message end it 'includes the line numbers' do expect(yaml['lines']).to match_array lines end it 'includes the source' do expect(yaml['source']).to eq source end it 'includes the documentation link' do expect(yaml['documentation_link']).to eq Reek::DocumentationLink.build('FeatureEnvy') end it 'includes the parameters' do parameters.each do |key, value| expect(yaml[key]).to eq value end end end end