# frozen_string_literal: true

RSpec.describe RuboCop::Cop::Performance::Casecmp do
  subject(:cop) { described_class.new }

  shared_examples 'selectors' do |selector|
    it "autocorrects str.#{selector} ==" do
      new_source = autocorrect_source("str.#{selector} == 'string'")
      expect(new_source).to eq "str.casecmp('string').zero?"
    end

    it "autocorrects str.#{selector} == with parens around arg" do
      new_source = autocorrect_source("str.#{selector} == ('string')")
      expect(new_source).to eq "str.casecmp('string').zero?"
    end

    it "autocorrects str.#{selector} !=" do
      new_source = autocorrect_source("str.#{selector} != 'string'")
      expect(new_source).to eq "!str.casecmp('string').zero?"
    end

    it "autocorrects str.#{selector} != with parens around arg" do
      new_source = autocorrect_source("str.#{selector} != ('string')")
      expect(new_source).to eq "!str.casecmp('string').zero?"
    end

    it "autocorrects str.#{selector}.eql? without parens" do
      new_source = autocorrect_source("str.#{selector}.eql? 'string'")
      expect(new_source).to eq "str.casecmp('string').zero?"
    end

    it "autocorrects str.#{selector}.eql? with parens" do
      new_source = autocorrect_source("str.#{selector}.eql?('string')")
      expect(new_source).to eq "str.casecmp('string').zero?"
    end

    it "autocorrects str.#{selector}.eql? with parens and funny spacing" do
      new_source = autocorrect_source("str.#{selector}.eql? ( 'string' )")
      expect(new_source).to eq "str.casecmp( 'string' ).zero?"
    end

    it "autocorrects == str.#{selector}" do
      new_source = autocorrect_source("'string' == str.#{selector}")
      expect(new_source).to eq "str.casecmp('string').zero?"
    end

    it "autocorrects string with parens == str.#{selector}" do
      new_source = autocorrect_source("('string') == str.#{selector}")
      expect(new_source).to eq "str.casecmp('string').zero?"
    end

    it "autocorrects string != str.#{selector}" do
      new_source = autocorrect_source("'string' != str.#{selector}")
      expect(new_source).to eq "!str.casecmp('string').zero?"
    end

    it 'autocorrects string with parens and funny spacing ' \
       "eql? str.#{selector}" do
      new_source = autocorrect_source("( 'string' ).eql? str.#{selector}")
      expect(new_source).to eq "str.casecmp( 'string' ).zero?"
    end

    it "autocorrects string.eql? str.#{selector} without parens " do
      new_source = autocorrect_source("'string'.eql? str.#{selector}")
      expect(new_source).to eq "str.casecmp('string').zero?"
    end

    it "autocorrects string.eql? str.#{selector} with parens " do
      new_source = autocorrect_source("'string'.eql?(str.#{selector})")
      expect(new_source).to eq "str.casecmp('string').zero?"
    end

    it "autocorrects obj.#{selector} == str.#{selector}" do
      new_source = autocorrect_source("obj.#{selector} == str.#{selector}")
      expect(new_source).to eq 'obj.casecmp(str).zero?'
    end

    it "autocorrects obj.#{selector} eql? str.#{selector}" do
      new_source = autocorrect_source("obj.#{selector}.eql? str.#{selector}")
      expect(new_source).to eq 'obj.casecmp(str).zero?'
    end

    it "formats the error message correctly for str.#{selector} ==" do
      inspect_source("str.#{selector} == 'string'")
      expect(cop.highlights).to eq(["str.#{selector} == 'string'"])
      expect(cop.messages).to eq(
        [
          "Use `str.casecmp('string').zero?` instead of " \
          "`str.#{selector} == 'string'`."
        ]
      )
    end

    it "formats the error message correctly for == str.#{selector}" do
      inspect_source("'string' == str.#{selector}")
      expect(cop.highlights).to eq(["'string' == str.#{selector}"])
      expect(cop.messages).to eq(
        [
          "Use `str.casecmp('string').zero?` instead of " \
          "`'string' == str.#{selector}`."
        ]
      )
    end

    it 'formats the error message correctly for ' \
       "obj.#{selector} == str.#{selector}" do
      inspect_source("obj.#{selector} == str.#{selector}")
      expect(cop.highlights).to eq(["obj.#{selector} == str.#{selector}"])
      expect(cop.messages).to eq(
        [
          'Use `obj.casecmp(str).zero?` instead of ' \
          "`obj.#{selector} == str.#{selector}`."
        ]
      )
    end

    it "doesn't report an offense for variable == str.#{selector}" do
      expect_no_offenses(<<~RUBY)
        var = "a"
        var == str.#{selector}
      RUBY
    end

    it "doesn't report an offense for str.#{selector} == variable" do
      expect_no_offenses(<<~RUBY)
        var = "a"
        str.#{selector} == var
      RUBY
    end

    it "doesn't report an offense for obj.method == str.#{selector}" do
      expect_no_offenses("obj.method == str.#{selector}")
    end

    it "doesn't report an offense for str.#{selector} == obj.method" do
      expect_no_offenses("str.#{selector} == obj.method")
    end
  end

  it_behaves_like('selectors', 'upcase')
  it_behaves_like('selectors', 'downcase')
end
