-
-
Notifications
You must be signed in to change notification settings - Fork 283
Add a new cop RSpec/Output
#2129
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
Open
kevinrobell-st
wants to merge
1
commit into
rubocop:master
Choose a base branch
from
kevinrobell-st:add-rspec/output-cop
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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 hidden or 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 hidden or 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 hidden or 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 hidden or 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 hidden or 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,66 @@ | ||||||||||||||||||||||||||||||||||||||||||
| # frozen_string_literal: true | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| module RuboCop | ||||||||||||||||||||||||||||||||||||||||||
| module Cop | ||||||||||||||||||||||||||||||||||||||||||
| # NOTE: This is the same as the `Rails/Output` cop with minor changes. | ||||||||||||||||||||||||||||||||||||||||||
| module RSpec | ||||||||||||||||||||||||||||||||||||||||||
| # Checks for the use of output calls like puts and print in specs. | ||||||||||||||||||||||||||||||||||||||||||
| # | ||||||||||||||||||||||||||||||||||||||||||
| # @example | ||||||||||||||||||||||||||||||||||||||||||
| # # bad | ||||||||||||||||||||||||||||||||||||||||||
| # puts 'A debug message' | ||||||||||||||||||||||||||||||||||||||||||
| # pp 'A debug message' | ||||||||||||||||||||||||||||||||||||||||||
| # print 'A debug message' | ||||||||||||||||||||||||||||||||||||||||||
| class Output < Base | ||||||||||||||||||||||||||||||||||||||||||
| include RangeHelp | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| MSG = 'Do not write to stdout in specs.' | ||||||||||||||||||||||||||||||||||||||||||
| RESTRICT_ON_SEND = %i[ap p pp pretty_print print puts binwrite syswrite | ||||||||||||||||||||||||||||||||||||||||||
| write write_nonblock].freeze | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| # @!method output?(node) | ||||||||||||||||||||||||||||||||||||||||||
| def_node_matcher :output?, <<~PATTERN | ||||||||||||||||||||||||||||||||||||||||||
| (send nil? {:ap :p :pp :pretty_print :print :puts} ...) | ||||||||||||||||||||||||||||||||||||||||||
| PATTERN | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| # @!method io_output?(node) | ||||||||||||||||||||||||||||||||||||||||||
| def_node_matcher :io_output?, <<~PATTERN | ||||||||||||||||||||||||||||||||||||||||||
| (send | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| (gvar #match_gvar?) | ||||||||||||||||||||||||||||||||||||||||||
| (const {nil? cbase} {:STDOUT :STDERR}) | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| {:binwrite :syswrite :write :write_nonblock} | ||||||||||||||||||||||||||||||||||||||||||
| ...) | ||||||||||||||||||||||||||||||||||||||||||
| PATTERN | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| # rubocop:disable Metrics/CyclomaticComplexity | ||||||||||||||||||||||||||||||||||||||||||
| def on_send(node) | ||||||||||||||||||||||||||||||||||||||||||
| return if node.parent&.call_type? || node.block_node | ||||||||||||||||||||||||||||||||||||||||||
| return if !output?(node) && !io_output?(node) | ||||||||||||||||||||||||||||||||||||||||||
| return if node.arguments.any? { |arg| arg.type?(:hash, :block_pass) } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| range = offense_range(node) | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| add_offense(range) | ||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||
| # rubocop:enable Metrics/CyclomaticComplexity | ||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+37
to
+47
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you please add the directive to the specific line where the offense occurs, instead of using a range?
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| private | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| def match_gvar?(sym) | ||||||||||||||||||||||||||||||||||||||||||
| %i[$stdout $stderr].include?(sym) | ||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| def offense_range(node) | ||||||||||||||||||||||||||||||||||||||||||
| if node.receiver | ||||||||||||||||||||||||||||||||||||||||||
| range_between(node.source_range.begin_pos, | ||||||||||||||||||||||||||||||||||||||||||
| node.loc.selector.end_pos) | ||||||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||||||
| node.loc.selector | ||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||
This file contains hidden or 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 hidden or 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,169 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| RSpec.describe RuboCop::Cop::RSpec::Output do | ||
| it 'registers an offense for using `p` method without a receiver' do | ||
| expect_offense(<<~RUBY) | ||
| p "edmond dantes" | ||
| ^ Do not write to stdout in specs. | ||
| RUBY | ||
| end | ||
|
|
||
| it 'registers an offense for using `puts` method without a receiver' do | ||
| expect_offense(<<~RUBY) | ||
| puts "sinbad" | ||
| ^^^^ Do not write to stdout in specs. | ||
| RUBY | ||
| end | ||
|
|
||
| it 'registers an offense for using `print` method without a receiver' do | ||
| expect_offense(<<~RUBY) | ||
| print "abbe busoni" | ||
| ^^^^^ Do not write to stdout in specs. | ||
| RUBY | ||
| end | ||
|
|
||
| it 'registers an offense for using `pp` method without a receiver' do | ||
| expect_offense(<<~RUBY) | ||
| pp "monte cristo" | ||
| ^^ Do not write to stdout in specs. | ||
| RUBY | ||
| end | ||
|
|
||
| it 'registers an offense with `$stdout.write`' do | ||
| expect_offense(<<~RUBY) | ||
| $stdout.write "lord wilmore" | ||
| ^^^^^^^^^^^^^ Do not write to stdout in specs. | ||
| RUBY | ||
| end | ||
|
|
||
| it 'registers an offense with `$stderr.syswrite`' do | ||
| expect_offense(<<~RUBY) | ||
| $stderr.syswrite "faria" | ||
| ^^^^^^^^^^^^^^^^ Do not write to stdout in specs. | ||
| RUBY | ||
| end | ||
|
|
||
| it 'registers an offense with `STDOUT.write`' do | ||
| expect_offense(<<~RUBY) | ||
| STDOUT.write "bertuccio" | ||
| ^^^^^^^^^^^^ Do not write to stdout in specs. | ||
| RUBY | ||
| end | ||
|
|
||
| it 'registers an offense with `::STDOUT.write`' do | ||
| expect_offense(<<~RUBY) | ||
| ::STDOUT.write "bertuccio" | ||
| ^^^^^^^^^^^^^^ Do not write to stdout in specs. | ||
| RUBY | ||
| end | ||
|
|
||
| it 'registers an offense with `STDERR.write`' do | ||
| expect_offense(<<~RUBY) | ||
| STDERR.write "bertuccio" | ||
| ^^^^^^^^^^^^ Do not write to stdout in specs. | ||
| RUBY | ||
| end | ||
|
|
||
| it 'registers an offense with `::STDERR.write`' do | ||
| expect_offense(<<~RUBY) | ||
| ::STDERR.write "bertuccio" | ||
| ^^^^^^^^^^^^^^ Do not write to stdout in specs. | ||
| RUBY | ||
| end | ||
|
|
||
| it 'does not record an offense for methods with a receiver' do | ||
| expect_no_offenses(<<~RUBY) | ||
| obj.print | ||
| something.p | ||
| nothing.pp | ||
| RUBY | ||
| end | ||
|
|
||
| it 'registers an offense for methods without arguments' do | ||
| expect_offense(<<~RUBY) | ||
| ^^^^^ Do not write to stdout in specs. | ||
| pp | ||
| ^^ Do not write to stdout in specs. | ||
| puts | ||
| ^^^^ Do not write to stdout in specs. | ||
| $stdout.write | ||
| ^^^^^^^^^^^^^ Do not write to stdout in specs. | ||
| STDERR.write | ||
| ^^^^^^^^^^^^ Do not write to stdout in specs. | ||
| RUBY | ||
| end | ||
|
|
||
| it 'registers an offense when `p` method with positional argument' do | ||
| expect_offense(<<~RUBY) | ||
| p(do_something) | ||
| ^ Do not write to stdout in specs. | ||
| RUBY | ||
| end | ||
|
|
||
| it 'does not register an offense when a method is called ' \ | ||
| 'to a local variable with the same name as a print method' do | ||
| expect_no_offenses(<<~RUBY) | ||
| p.do_something | ||
| RUBY | ||
| end | ||
|
|
||
| it 'does not register an offense when `p` method with keyword argument' do | ||
| expect_no_offenses(<<~RUBY) | ||
| p(class: 'this `p` method is a DSL') | ||
| RUBY | ||
| end | ||
|
|
||
| it 'does not register an offense when `p` method with symbol proc' do | ||
| expect_no_offenses(<<~RUBY) | ||
| p(&:this_p_method_is_a_dsl) | ||
| RUBY | ||
| end | ||
|
|
||
| it 'does not register an offense when the `p` method is called ' \ | ||
| 'with block argument' do | ||
| expect_no_offenses(<<~RUBY) | ||
| # phlex-rails gem. | ||
| div do | ||
| p { 'Some text' } | ||
| end | ||
| RUBY | ||
| end | ||
|
|
||
| it 'does not register an offense when io method is called ' \ | ||
| 'with block argument' do | ||
| expect_no_offenses(<<~RUBY) | ||
| obj.write { do_somethig } | ||
| RUBY | ||
| end | ||
|
|
||
| it 'does not register an offense when io method is called ' \ | ||
| 'with numbered block argument' do | ||
| expect_no_offenses(<<~RUBY) | ||
| obj.write { do_something(_1) } | ||
| RUBY | ||
| end | ||
|
|
||
| it 'does not register an offense when io method is called ' \ | ||
| 'with `it` parameter', :ruby34, unsupported_on: :parser do | ||
| expect_no_offenses(<<~RUBY) | ||
| obj.write { do_something(it) } | ||
| RUBY | ||
| end | ||
|
|
||
| it 'does not register an offense when a method is safe navigation called ' \ | ||
| 'to a local variable with the same name as a print method' do | ||
| expect_no_offenses(<<~RUBY) | ||
| p&.do_something | ||
| RUBY | ||
| end | ||
|
|
||
| it 'does not record an offense for comments' do | ||
| expect_no_offenses(<<~RUBY) | ||
| # print "test" | ||
| # p | ||
| # $stdout.write | ||
| # STDERR.binwrite | ||
| RUBY | ||
| end | ||
| end |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please delete this comment? It will diverge significantly from the actual Rails/Output cop in the future.