diff --git a/lib/rubocop/cop/performance/casecmp.rb b/lib/rubocop/cop/performance/casecmp.rb index b92ef41..96cb8d4 100644 --- a/lib/rubocop/cop/performance/casecmp.rb +++ b/lib/rubocop/cop/performance/casecmp.rb @@ -54,11 +54,11 @@ def on_send(node) return unless (parts = take_method_apart(node)) _receiver, method, arg, variable = parts - good_method = build_good_method(arg, variable) + good_method = build_good_method(method, arg, variable) message = format(MSG, good: good_method, bad: node.source) add_offense(node, message: message) do |corrector| - correction(corrector, node, method, arg, variable) + autocorrect(corrector, node, good_method) end end @@ -81,22 +81,20 @@ def take_method_apart(node) [receiver, method, arg, variable] end - def correction(corrector, node, method, arg, variable) - corrector.insert_before(node.loc.expression, '!') if method == :!= - - replacement = build_good_method(arg, variable) - - corrector.replace(node.loc.expression, replacement) + def autocorrect(corrector, node, replacement) + corrector.replace(node, replacement) end - def build_good_method(arg, variable) + def build_good_method(method, arg, variable) + bang = method == :!= ? '!' : '' + # We want resulting call to be parenthesized # if arg already includes one or more sets of parens, don't add more # or if method call already used parens, again, don't add more if arg.send_type? || !parentheses?(arg) - "#{variable.source}.casecmp(#{arg.source}).zero?" + "#{bang}#{variable.source}.casecmp(#{arg.source}).zero?" else - "#{variable.source}.casecmp#{arg.source}.zero?" + "#{bang}#{variable.source}.casecmp#{arg.source}.zero?" end end end diff --git a/spec/rubocop/cop/performance/casecmp_spec.rb b/spec/rubocop/cop/performance/casecmp_spec.rb index 64e3856..b7b29c3 100644 --- a/spec/rubocop/cop/performance/casecmp_spec.rb +++ b/spec/rubocop/cop/performance/casecmp_spec.rb @@ -27,7 +27,7 @@ it "registers an offense and corrects str.#{selector} !=" do expect_offense(<<~RUBY, selector: selector) str.#{selector} != 'string' - ^^^^^{selector}^^^^^^^^^^^^ Use `str.casecmp('string').zero?` instead of `str.#{selector} != 'string'`. + ^^^^^{selector}^^^^^^^^^^^^ Use `!str.casecmp('string').zero?` instead of `str.#{selector} != 'string'`. RUBY expect_correction(<<~RUBY) @@ -38,7 +38,7 @@ it "registers an offense and corrects str.#{selector} != with parens around arg" do expect_offense(<<~RUBY, selector: selector) str.#{selector} != ('string') - ^^^^^{selector}^^^^^^^^^^^^^^ Use `str.casecmp('string').zero?` instead of `str.#{selector} != ('string')`. + ^^^^^{selector}^^^^^^^^^^^^^^ Use `!str.casecmp('string').zero?` instead of `str.#{selector} != ('string')`. RUBY expect_correction(<<~RUBY) @@ -104,7 +104,7 @@ it "registers an offense and corrects string != str.#{selector}" do expect_offense(<<~RUBY, selector: selector) 'string' != str.#{selector} - ^^^^^^^^^^^^^^^^^{selector} Use `str.casecmp('string').zero?` instead of `'string' != str.#{selector}`. + ^^^^^^^^^^^^^^^^^{selector} Use `!str.casecmp('string').zero?` instead of `'string' != str.#{selector}`. RUBY expect_correction(<<~RUBY)