Skip to content

Commit

Permalink
Add new InternalAffairs/EmptyLineBetweenExpectOffenseAndCorrection cop
Browse files Browse the repository at this point in the history
This PR adds new `InternalAffairs/EmptyLineBetweenExpectOffenseAndCorrection` cop.
It checks whether `expect_offense` and correction expectation methods
(i.e. `expect_correction` and `expect_no_corrections`) are separated by empty line.

```ruby
# bad
it 'registers and corrects an offense' do
  expect_offense(<<~RUBY)
    bad_method
    ^^^^^^^^^^ Use `good_method`.
  RUBY
  expect_correction(<<~RUBY)
    good_method
  RUBY
end

# good
it 'registers and corrects an offense' do
  expect_offense(<<~RUBY)
    bad_method
    ^^^^^^^^^^ Use `good_method`.
  RUBY

  expect_correction(<<~RUBY)
    good_method
  RUBY
end
```

No changelog entry has been added to the changelog due to this cop is for use inside development.
  • Loading branch information
koic authored and bbatsov committed Jan 26, 2021
1 parent ad6c168 commit 1de3a9f
Show file tree
Hide file tree
Showing 55 changed files with 567 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/rubocop/cop/internal_affairs.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# frozen_string_literal: true

require_relative 'internal_affairs/empty_line_between_expect_offense_and_correction'
require_relative 'internal_affairs/method_name_equal'
require_relative 'internal_affairs/node_destructuring'
require_relative 'internal_affairs/node_type_predicate'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# frozen_string_literal: true

module RuboCop
module Cop
module InternalAffairs
# This cop checks whether `expect_offense` and correction expectation methods
# (i.e. `expect_correction` and `expect_no_corrections`) are separated by empty line.
#
# @example
# # bad
# it 'registers and corrects an offense' do
# expect_offense(<<~RUBY)
# bad_method
# ^^^^^^^^^^ Use `good_method`.
# RUBY
# expect_correction(<<~RUBY)
# good_method
# RUBY
# end
#
# # good
# it 'registers and corrects an offense' do
# expect_offense(<<~RUBY)
# bad_method
# ^^^^^^^^^^ Use `good_method`.
# RUBY
#
# expect_correction(<<~RUBY)
# good_method
# RUBY
# end
#
class EmptyLineBetweenExpectOffenseAndCorrection < Base
extend AutoCorrector

MSG = 'Add empty line between `expect_offense` and `%<expect_correction>s`.'
RESTRICT_ON_SEND = %i[expect_offense].freeze
CORRECTION_EXPECTATION_METHODS = %i[expect_correction expect_no_corrections].freeze

def on_send(node)
return unless (next_sibling = node.right_sibling) && next_sibling.send_type?

method_name = next_sibling.method_name
return unless CORRECTION_EXPECTATION_METHODS.include?(method_name)

range = offense_range(node)
return unless range.last_line + 1 == next_sibling.loc.line

add_offense(range, message: format(MSG, expect_correction: method_name)) do |corrector|
corrector.insert_after(range, "\n")
end
end

private

def offense_range(node)
first_argument = node.first_argument

if first_argument.respond_to?(:heredoc?) && first_argument.heredoc?
first_argument.loc.heredoc_end
else
node
end
end
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::InternalAffairs::EmptyLineBetweenExpectOffenseAndCorrection, :config do
it 'registers and corrects an offense when using no empty line between `expect_offense` and `expect_correction` ' \
'with heredoc argument' do
expect_offense(<<~RUBY)
expect_offense(<<~CODE)
bad_method
CODE
^^^^ Add empty line between `expect_offense` and `expect_correction`.
expect_correction(<<~CODE)
good_good
CODE
RUBY

expect_correction(<<~RUBY)
expect_offense(<<~CODE)
bad_method
CODE
expect_correction(<<~CODE)
good_good
CODE
RUBY
end

it 'registers and corrects an offense when using no empty line between `expect_offense` and `expect_correction`' \
'with variable argument' do
expect_offense(<<~RUBY)
expect_offense(code)
^^^^^^^^^^^^^^^^^^^^ Add empty line between `expect_offense` and `expect_correction`.
expect_correction(code)
RUBY

expect_correction(<<~RUBY)
expect_offense(code)
expect_correction(code)
RUBY
end

it 'registers and corrects an offense when using no empty line between `expect_offense` and `expect_no_corrections`' do
expect_offense(<<~RUBY)
expect_offense('bad_method')
^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Add empty line between `expect_offense` and `expect_no_corrections`.
expect_no_corrections
RUBY

expect_correction(<<~RUBY)
expect_offense('bad_method')
expect_no_corrections
RUBY
end

it 'does not register an offense when using only `expect_offense`' do
expect_no_offenses(<<~RUBY)
expect_offense(<<~CODE)
bad_method
CODE
RUBY
end

it 'does not register an offense when using empty line between `expect_offense` and `expect_correction` ' \
'with heredoc argument' do
expect_no_offenses(<<~RUBY)
expect_offense(<<~CODE)
bad_method
CODE
expect_correction(<<~CODE)
good_method
CODE
RUBY
end

it 'does not register an offense when using empty line between `expect_offense` and `expect_correction`' \
'with variable argument' do
expect_no_offenses(<<~RUBY)
expect_offense(bad_method)
expect_correction(good_method)
RUBY
end

it 'does not register an offense when using empty line between `expect_offense` and `expect_no_corrections`' do
expect_no_offenses(<<~RUBY)
expect_offense('bad_method')
expect_no_corrections
RUBY
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
shared_examples 'offense' do |name, _code, offense, correction|
it "registers an offense and corrects when #{name}" do
expect_offense(offense)

expect_correction(correction)
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#{code_example('a\ b \ c')}
^^ Use only a single space inside array percent literal.
RUBY

expect_correction("#{code_example('a\ b \ c')}\n")
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
^ #{message}
^ #{message}
RUBY

expect_correction("#{code_example('\ a b c\ ')}\n")
end

Expand Down
1 change: 1 addition & 0 deletions spec/rubocop/cop/layout/trailing_empty_lines_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
RUBY

expect_correction("x = 0\n")
end
end
Expand Down
8 changes: 8 additions & 0 deletions spec/rubocop/cop/lint/empty_when_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
^^^^^^^^^ Avoid `when` branches without a body.
end
RUBY

expect_no_corrections
end

Expand All @@ -24,6 +25,7 @@
else 3
end
RUBY

expect_no_corrections
end

Expand All @@ -35,6 +37,7 @@
^^^^^^^^^ Avoid `when` branches without a body.
end
RUBY

expect_no_corrections
end

Expand All @@ -47,6 +50,7 @@
else 3
end
RUBY

expect_no_corrections
end

Expand All @@ -60,6 +64,7 @@
# nothing
end
RUBY

expect_no_corrections
end

Expand All @@ -76,6 +81,7 @@
3
end
RUBY

expect_no_corrections
end

Expand All @@ -91,6 +97,7 @@
3
end
RUBY

expect_no_corrections
end
end
Expand Down Expand Up @@ -181,6 +188,7 @@
# do nothing
end
RUBY

expect_no_corrections
end
end
Expand Down
13 changes: 13 additions & 0 deletions spec/rubocop/cop/lint/literal_in_interpolation_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"this is the #{%{literal}}"
^{literal} Literal interpolation detected.
RUBY

expect_correction(<<~RUBY)
"this is the #{expected}"
RUBY
Expand All @@ -36,6 +37,7 @@
"this is the #{%{literal}} literally"
^{literal} Literal interpolation detected.
RUBY

expect_correction(<<~RUBY)
"this is the #{expected} literally"
RUBY
Expand All @@ -47,6 +49,7 @@
^{literal} Literal interpolation detected.
_{literal} ^{literal} Literal interpolation detected.
RUBY

expect_correction(<<~RUBY)
"some #{expected} with #{expected} too"
RUBY
Expand All @@ -59,6 +62,7 @@
"this is #{%{literal}} with #{a} now"
^{literal} Literal interpolation detected.
RUBY

expect_correction(<<~RUBY)
"this is #{expected} with \#{a} now"
RUBY
Expand All @@ -71,6 +75,7 @@
"this is #{a} with #{%{literal}} now"
^{literal} Literal interpolation detected.
RUBY

expect_correction(<<~RUBY)
"this is \#{a} with #{expected} now"
RUBY
Expand Down Expand Up @@ -145,6 +150,7 @@
%{prefix}[this #{%{literal}} is not significant]
_{prefix} ^{literal} Literal interpolation detected.
RUBY

expect_correction(<<~RUBY)
#{prefix}[this #{word} is not significant]
RUBY
Expand All @@ -155,6 +161,7 @@
%{prefix}[this #{%{literal}} is not significant]
_{prefix} ^{literal} Literal interpolation detected.
RUBY

expect_correction(<<~RUBY)
#{prefix}[this #{word} is not significant]
RUBY
Expand All @@ -165,6 +172,7 @@
%{prefix}[this #{%{literal}} is not significant]
_{prefix} ^{literal} Literal interpolation detected.
RUBY

expect_correction(<<~RUBY)
#{prefix}[this #{[word].inspect.gsub(/"/, '\"')} is not significant]
RUBY
Expand All @@ -175,6 +183,7 @@
%{prefix}[this #{%{literal}} is not significant]
_{prefix} ^{literal} Literal interpolation detected.
RUBY

expect_correction(<<~RUBY)
#{prefix}[this #{[word.to_sym].inspect} is not significant]
RUBY
Expand Down Expand Up @@ -207,6 +216,7 @@
"this is the #{%{keyword}} #{1}"
_{keyword} ^ Literal interpolation detected.
RUBY

expect_correction(<<~RUBY)
"this is the \#{#{keyword}} 1"
RUBY
Expand Down Expand Up @@ -300,6 +310,7 @@
:"this is the #{%{literal}}"
^{literal} Literal interpolation detected.
RUBY

expect_correction(<<~RUBY)
:"this is the #{expected}"
RUBY
Expand All @@ -310,6 +321,7 @@
`this is the #{%{literal}}`
^{literal} Literal interpolation detected.
RUBY

expect_correction(<<~RUBY)
\`this is the #{expected}\`
RUBY
Expand All @@ -320,6 +332,7 @@
/this is the #{%{literal}}/
^{literal} Literal interpolation detected.
RUBY

expect_correction(<<~RUBY)
/this is the #{expected}/
RUBY
Expand Down
3 changes: 3 additions & 0 deletions spec/rubocop/cop/lint/redundant_cop_disable_directive_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
# rubocop:disable Metrics/MethodLength
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Unnecessary disabling of `Metrics/MethodLength`.
RUBY

expect_correction('')
end
end
Expand All @@ -36,6 +37,7 @@
# rubocop:disable UnknownCop
^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Unnecessary disabling of `UnknownCop` (unknown cop).
RUBY

expect_correction('')
end
end
Expand Down Expand Up @@ -121,6 +123,7 @@
# rubocop:disable Metrics/ClassLength, Metrics/MethodLength
^^^^^^^^^^^^^^^^^^^ Unnecessary disabling of `Metrics/ClassLength`.
RUBY

expect_correction(<<~RUBY)
# rubocop:disable Metrics/MethodLength
RUBY
Expand Down
Loading

0 comments on commit 1de3a9f

Please sign in to comment.