Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new Lint/EmptyConditionalBody cop #8341

Merged
merged 1 commit into from Aug 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -20,6 +20,7 @@
* [#7425](https://github.com/rubocop-hq/rubocop/pull/7425): Add new `Lint/TopLevelReturnWithArgument` cop. ([@iamravitejag][])
* [#8417](https://github.com/rubocop-hq/rubocop/pull/8417): Add new `Style/GlobalStdStream` cop. ([@fatkodima][])
* [#7949](https://github.com/rubocop-hq/rubocop/issues/7949): Add new `Style/SingleArgumentDig` cop. ([@volfgox][])
* [#8341](https://github.com/rubocop-hq/rubocop/pull/8341): Add new `Lint/EmptyConditionalBody` cop. ([@fatkodima][])

### Bug fixes

Expand Down
6 changes: 6 additions & 0 deletions config/default.yml
Expand Up @@ -1442,6 +1442,12 @@ Lint/ElseLayout:
Enabled: true
VersionAdded: '0.17'

Lint/EmptyConditionalBody:
Description: 'This cop checks for the presence of `if`, `elsif` and `unless` branches without a body.'
Enabled: 'pending'
AllowComments: true
VersionAdded: '0.89'

Lint/EmptyEnsure:
Description: 'Checks for empty ensure block.'
Enabled: true
Expand Down
1 change: 1 addition & 0 deletions docs/modules/ROOT/pages/cops.adoc
Expand Up @@ -200,6 +200,7 @@ In the following section you find all available cops:
* xref:cops_lint.adoc#lintduplicaterescueexception[Lint/DuplicateRescueException]
* xref:cops_lint.adoc#linteachwithobjectargument[Lint/EachWithObjectArgument]
* xref:cops_lint.adoc#lintelselayout[Lint/ElseLayout]
* xref:cops_lint.adoc#lintemptyconditionalbody[Lint/EmptyConditionalBody]
* xref:cops_lint.adoc#lintemptyensure[Lint/EmptyEnsure]
* xref:cops_lint.adoc#lintemptyexpression[Lint/EmptyExpression]
* xref:cops_lint.adoc#lintemptyinterpolation[Lint/EmptyInterpolation]
Expand Down
84 changes: 84 additions & 0 deletions docs/modules/ROOT/pages/cops_lint.adoc
Expand Up @@ -893,6 +893,90 @@ else
end
----

== Lint/EmptyConditionalBody

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Pending
| Yes
| No
| 0.89
| -
|===

This cop checks for the presence of `if`, `elsif` and `unless` branches without a body.

=== Examples

[source,ruby]
----
# bad
if condition
end

# bad
unless condition
end

# bad
if condition
do_something
elsif other_condition
end

# good
if condition
do_something
end

# good
unless condition
do_something
end

# good
if condition
do_something
elsif other_condition
do_something_else
end
----

==== AllowComments: true (default)

[source,ruby]
----
# good
if condition
do_something
elsif other_condition
# noop
end
----

==== AllowComments: false

[source,ruby]
----
# bad
if condition
do_something
elsif other_condition
# noop
end
----

=== Configurable attributes

|===
| Name | Default value | Configurable values

| AllowComments
| `true`
| Boolean
|===

== Lint/EmptyEnsure

|===
Expand Down
1 change: 1 addition & 0 deletions lib/rubocop.rb
Expand Up @@ -258,6 +258,7 @@
require_relative 'rubocop/cop/lint/duplicate_rescue_exception'
require_relative 'rubocop/cop/lint/each_with_object_argument'
require_relative 'rubocop/cop/lint/else_layout'
require_relative 'rubocop/cop/lint/empty_conditional_body'
require_relative 'rubocop/cop/lint/empty_ensure'
require_relative 'rubocop/cop/lint/empty_expression'
require_relative 'rubocop/cop/lint/empty_interpolation'
Expand Down
67 changes: 67 additions & 0 deletions lib/rubocop/cop/lint/empty_conditional_body.rb
@@ -0,0 +1,67 @@
# frozen_string_literal: true

module RuboCop
module Cop
module Lint
# This cop checks for the presence of `if`, `elsif` and `unless` branches without a body.
# @example
# # bad
# if condition
# end
#
# # bad
# unless condition
# end
#
# # bad
# if condition
# do_something
# elsif other_condition
# end
#
# # good
# if condition
# do_something
# end
#
# # good
# unless condition
# do_something
# end
#
# # good
# if condition
# do_something
# elsif other_condition
# do_something_else
# end
#
# @example AllowComments: true (default)
# # good
# if condition
# do_something
# elsif other_condition
# # noop
# end
#
# @example AllowComments: false
# # bad
# if condition
# do_something
# elsif other_condition
# # noop
# end
#
class EmptyConditionalBody < Base
MSG = 'Avoid `%<keyword>s` branches without a body.'

def on_if(node)
return if node.body
return if cop_config['AllowComments'] && comment_lines?(node)

add_offense(node, message: format(MSG, keyword: node.keyword))
end
end
end
end
end
94 changes: 94 additions & 0 deletions spec/rubocop/cop/lint/empty_conditional_body_spec.rb
@@ -0,0 +1,94 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::Lint::EmptyConditionalBody, :config do
let(:cop_config) do
{ 'AllowComments' => true }
end

it 'registers an offense for missing `if` body' do
expect_offense(<<~RUBY)
if condition
^^^^^^^^^^^^ Avoid `if` branches without a body.
end
RUBY
end

it 'does not register an offense for missing `if` body with a comment' do
expect_no_offenses(<<~RUBY)
if condition
# noop
end
RUBY
end

it 'registers an offense for missing `elsif` body' do
expect_offense(<<~RUBY)
if condition
do_something
elsif other_condition
^^^^^^^^^^^^^^^^^^^^^ Avoid `elsif` branches without a body.
end
RUBY
end

it 'does not register an offense for missing `elsif` body with a comment' do
expect_no_offenses(<<~RUBY)
if condition
do_something
elsif other_condition
# noop
end
RUBY
end

it 'registers an offense for missing `unless` body' do
expect_offense(<<~RUBY)
unless condition
^^^^^^^^^^^^^^^^ Avoid `unless` branches without a body.
end
RUBY
end

it 'does not register an offense for missing `unless` body with a comment' do
expect_no_offenses(<<~RUBY)
unless condition
# noop
end
RUBY
end

context 'when AllowComments is false' do
let(:cop_config) do
{ 'AllowComments' => false }
end

it 'registers an offense for missing `if` body with a comment' do
expect_offense(<<~RUBY)
if condition
^^^^^^^^^^^^ Avoid `if` branches without a body.
# noop
end
RUBY
end

it 'registers an offense for missing `elsif` body with a comment' do
expect_offense(<<~RUBY)
if condition
do_something
elsif other_condition
^^^^^^^^^^^^^^^^^^^^^ Avoid `elsif` branches without a body.
# noop
end
RUBY
end

it 'registers an offense for missing `unless` body with a comment' do
expect_offense(<<~RUBY)
unless condition
^^^^^^^^^^^^^^^^ Avoid `unless` branches without a body.
# noop
end
RUBY
end
end
end