-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add new
Lint/ItWithoutArgumentsInBlock
cop
Follow up https://bugs.ruby-lang.org/issues/18980 and ruby/ruby#9152. Emulates the following Ruby warnings in Ruby 3.3. ```ruby $ ruby -e '0.times { it }' -e:1: warning: `it` calls without arguments will refer to the first block param in Ruby 3.4; use it() or self.it ``` `it` calls without arguments will refer to the first block param in Ruby 3.4. So use `it()` or `self.it` to ensure compatibility. ```ruby # bad do_something { it } # good do_something { it() } do_something { self.it } ```
- Loading branch information
Showing
5 changed files
with
203 additions
and
0 deletions.
There are no files selected for viewing
1 change: 1 addition & 0 deletions
1
changelog/new_add_new_lint_it_without_arguments_in_block_cop.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
* [#12516](https://github.com/rubocop/rubocop/pull/12516): Add new `Lint/ItWithoutArgumentsInBlock` cop. ([@koic][]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
# frozen_string_literal: true | ||
|
||
module RuboCop | ||
module Cop | ||
module Lint | ||
# Emulates the following Ruby warning in Ruby 3.3. | ||
# | ||
# [source,ruby] | ||
# ---- | ||
# $ ruby -e '0.times { it }' | ||
# -e:1: warning: `it` calls without arguments will refer to the first block param in Ruby 3.4; | ||
# use it() or self.it | ||
# ---- | ||
# | ||
# `it` calls without arguments will refer to the first block param in Ruby 3.4. | ||
# So use `it()` or `self.it` to ensure compatibility. | ||
# | ||
# @example | ||
# | ||
# # bad | ||
# do_something { it } | ||
# | ||
# # good | ||
# do_something { it() } | ||
# do_something { self.it } | ||
# | ||
class ItWithoutArgumentsInBlock < Base | ||
include NodePattern::Macros | ||
|
||
MSG = '`it` calls without arguments will refer to the first block param in Ruby 3.4; ' \ | ||
'use `it()` or `self.it`.' | ||
|
||
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler | ||
return unless (body = node.body) | ||
return unless node.arguments.empty_and_without_delimiters? | ||
|
||
if body.send_type? && deprecated_it_method?(body) | ||
add_offense(body) | ||
else | ||
body.each_descendant(:send).each do |send_node| | ||
next unless deprecated_it_method?(send_node) | ||
|
||
add_offense(send_node) | ||
end | ||
end | ||
end | ||
|
||
def deprecated_it_method?(node) | ||
return false unless node.method?(:it) | ||
|
||
!node.receiver && node.arguments.empty? && !node.parenthesized? && !node.block_literal? | ||
end | ||
end | ||
end | ||
end | ||
end |
139 changes: 139 additions & 0 deletions
139
spec/rubocop/cop/lint/it_without_arguments_in_block_spec.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
# frozen_string_literal: true | ||
|
||
RSpec.describe RuboCop::Cop::Lint::ItWithoutArgumentsInBlock, :config do | ||
it 'registers an offense when using `it` without arguments in the single line block' do | ||
expect_offense(<<~RUBY) | ||
0.times { it } | ||
^^ `it` calls without arguments will refer to the first block param in Ruby 3.4; use `it()` or `self.it`. | ||
RUBY | ||
end | ||
|
||
it 'registers an offense when using `it` without arguments in the multiline block' do | ||
expect_offense(<<~RUBY) | ||
0.times do | ||
it | ||
^^ `it` calls without arguments will refer to the first block param in Ruby 3.4; use `it()` or `self.it`. | ||
it = 1 | ||
it | ||
end | ||
RUBY | ||
end | ||
|
||
it 'does not register an offense when using `it` with arguments in the single line block' do | ||
expect_no_offenses(<<~RUBY) | ||
0.times { it(42) } | ||
RUBY | ||
end | ||
|
||
it 'does not register an offense when using `it` with block argument in the single line block' do | ||
expect_no_offenses(<<~RUBY) | ||
0.times { it { do_something } } | ||
RUBY | ||
end | ||
|
||
it 'does not register an offense when using `it()` in the single line block' do | ||
expect_no_offenses(<<~RUBY) | ||
0.times { it() } | ||
RUBY | ||
end | ||
|
||
it 'does not register an offense when using `self.it` in the single line block' do | ||
expect_no_offenses(<<~RUBY) | ||
0.times { self.it } | ||
RUBY | ||
end | ||
|
||
it 'does not register an offense when using `it` with arguments in the multiline block' do | ||
expect_no_offenses(<<~RUBY) | ||
0.times do | ||
it(42) | ||
it = 1 | ||
it | ||
end | ||
RUBY | ||
end | ||
|
||
it 'does not register an offense when using `it` with block argument in the multiline block' do | ||
expect_no_offenses(<<~RUBY) | ||
0.times do | ||
it { do_something } | ||
it = 1 | ||
it | ||
end | ||
RUBY | ||
end | ||
|
||
it 'does not register an offense when using `it()` in the multiline block' do | ||
expect_no_offenses(<<~RUBY) | ||
0.times do | ||
it() | ||
it = 1 | ||
it | ||
end | ||
RUBY | ||
end | ||
|
||
it 'does not register an offense when using `self.it` without arguments in the multiline block' do | ||
expect_no_offenses(<<~RUBY) | ||
0.times do | ||
self.it | ||
it = 1 | ||
it | ||
end | ||
RUBY | ||
end | ||
|
||
it 'does not register an offense when using `it` without arguments in `if` body' do | ||
expect_no_offenses(<<~RUBY) | ||
if false | ||
it | ||
end | ||
RUBY | ||
end | ||
|
||
it 'does not register an offense when using `it` without arguments in `def` body' do | ||
expect_no_offenses(<<~RUBY) | ||
def foo | ||
it | ||
end | ||
RUBY | ||
end | ||
|
||
it 'does not register an offense when using `it` without arguments in the block with empty block parameter' do | ||
expect_no_offenses(<<~RUBY) | ||
0.times { || | ||
it | ||
} | ||
RUBY | ||
end | ||
|
||
it 'does not register an offense when using `it` without arguments in the block with useless block parameter' do | ||
expect_no_offenses(<<~RUBY) | ||
0.times { |_n| | ||
it | ||
} | ||
RUBY | ||
end | ||
|
||
it 'does not register an offense when using `it` inner local variable in block' do | ||
expect_no_offenses(<<~RUBY) | ||
0.times do | ||
it = 1 | ||
it | ||
end | ||
RUBY | ||
end | ||
|
||
it 'does not register an offense when using `it` outer local variable in block' do | ||
expect_no_offenses(<<~RUBY) | ||
it = 1 | ||
0.times { it } | ||
RUBY | ||
end | ||
|
||
it 'does not register an offense when using empty block' do | ||
expect_no_offenses(<<~RUBY) | ||
0.times {} | ||
RUBY | ||
end | ||
end |