Skip to content

Commit

Permalink
Add RSpec/NoStringifiedNoStringifiedInstanceDoubleConstant
Browse files Browse the repository at this point in the history
Addresses #1136
  • Loading branch information
corsonknowles committed Sep 17, 2024
1 parent 16cf19c commit d3d3328
Show file tree
Hide file tree
Showing 9 changed files with 138 additions and 10 deletions.
24 changes: 15 additions & 9 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -101,34 +101,40 @@ RSpec:
- expect_no_offenses
- expect_offense

RSpec/DescribeClass:
Exclude:
- spec/project/**/*.rb

RSpec/ExampleLength:
CountAsOne:
- heredoc
Max: 11

RSpec/DescribeClass:
Exclude:
- spec/project/**/*.rb
RSpec/ExpectInLet:
Enabled: true

RSpec/MultipleExpectations:
Max: 2

# `expect_offense` does not use Kernel#format or String#%
Style/FormatStringToken:
Exclude:
- spec/rubocop/**/*.rb

Style/RequireOrder:
RSpec/NoStringifiedInstanceDoubleConstant:
Enabled: true

RSpec/SpecFilePathFormat:
Exclude:
- spec/rubocop/cop/rspec/mixin/**/*.rb

# `expect_offense` does not use Kernel#format or String#%
Style/FormatStringToken:
Exclude:
- spec/rubocop/**/*.rb

Style/NumberedParameters:
Enabled: true
EnforcedStyle: disallow

Style/RequireOrder:
Enabled: true

# Enable RuboCop's pending cops up to v1.63

Gemspec/DeprecatedAttributeAssignment: {Enabled: true}
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Master (Unreleased)

## 3.0.6 (2024-09-17)

- Add `RSpec/NoStringifiedInstanceDoubleConstant` to check for and correct strings used as instance_doubles. ([@corsonknowles])

## 3.0.5 (2024-09-07)

- Fix false-negative and error for `RSpec/MetadataStyle` when non-literal args are used in metadata in `EnforceStyle: hash`. ([@cbliard])
Expand Down Expand Up @@ -920,6 +924,7 @@ Compatibility release so users can upgrade RuboCop to 0.51.0. No new features.
[@cfabianski]: https://github.com/cfabianski
[@clupprich]: https://github.com/clupprich
[@composerinteralia]: https://github.com/composerinteralia
[@corsonknowles]: https://github.com/corsonknowles
[@corydiamand]: https://github.com/corydiamand
[@darhazer]: https://github.com/Darhazer
[@daveworth]: https://github.com/daveworth
Expand Down
2 changes: 1 addition & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ task confirm_documentation: :generate_cops_documentation do
Open3.popen3('git diff --exit-code docs/')

unless process.value.success?
raise 'Please run `rake generate_cops_documentation` ' \
raise 'Please run `bundle exec rake generate_cops_documentation` ' \
'and add docs/ to the commit.'
end
end
Expand Down
7 changes: 7 additions & 0 deletions config/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -726,6 +726,13 @@ RSpec/NoExpectationExample:
- "^expect_"
- "^assert_"

RSpec/NoStringifiedInstanceDoubleConstant:
Description: Do not use a string as `instance_double` constant.
Enabled: pending
Safe: false
VersionAdded: "<<next>>"
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/NoStringifiedInstanceDoubleConstant

RSpec/NotToNot:
Description: Checks for consistent method usage for negating expectations.
Enabled: true
Expand Down
1 change: 1 addition & 0 deletions docs/modules/ROOT/pages/cops.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
* xref:cops_rspec.adoc#rspecnamedsubject[RSpec/NamedSubject]
* xref:cops_rspec.adoc#rspecnestedgroups[RSpec/NestedGroups]
* xref:cops_rspec.adoc#rspecnoexpectationexample[RSpec/NoExpectationExample]
* xref:cops_rspec.adoc#rspecnostringifiedinstancedoubleconstant[RSpec/NoStringifiedInstanceDoubleConstant]
* xref:cops_rspec.adoc#rspecnottonot[RSpec/NotToNot]
* xref:cops_rspec.adoc#rspecoverwritingsetup[RSpec/OverwritingSetup]
* xref:cops_rspec.adoc#rspecpending[RSpec/Pending]
Expand Down
29 changes: 29 additions & 0 deletions docs/modules/ROOT/pages/cops_rspec.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -4117,6 +4117,35 @@ end
* https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/NoExpectationExample
== RSpec/NoStringifiedInstanceDoubleConstant
|===
| Enabled by default | Safe | Supports autocorrection | Version Added | Version Changed
| Pending
| Yes
| Always
| <<next>>
| -
|===
Do not use a string as `instance_double` constant.
=== Examples
[source,ruby]
----
# bad
instance_double('Foo', failure_message, stubs)
# good
instance_double(Foo, failure_message, stubs)
----
=== References
* https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/NoStringifiedInstanceDoubleConstant
== RSpec/NotToNot
|===
Expand Down
42 changes: 42 additions & 0 deletions lib/rubocop/cop/rspec/no_stringified_instance_double_constant.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# frozen_string_literal: true

module RuboCop
module Cop
module RSpec
# Do not use a string as `instance_double` constant.
#
# @example
# # bad
# instance_double('Foo', failure_message, stubs)
#
# # good
# instance_double(Foo, failure_message, stubs)
#
class NoStringifiedInstanceDoubleConstant < Base
extend AutoCorrector

MSG = 'Do not use a string as `instance_double` constant.'
RESTRICT_ON_SEND = %i[instance_double].freeze

# @!method stringified_instance_double_const?(node)
def_node_matcher :stringified_instance_double_const?, <<~PATTERN
(send nil? :instance_double $...)
PATTERN

def on_send(node)
stringified_instance_double_const?(node) do |args_node|
if args_node.first.str_type?
add_offense(args_node.first) do |corrector|
autocorrect(corrector, args_node.first)
end
end
end
end

def autocorrect(corrector, node)
corrector.replace(node, node.value)
end
end
end
end
end
1 change: 1 addition & 0 deletions lib/rubocop/cop/rspec_cops.rb
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
require_relative 'rspec/named_subject'
require_relative 'rspec/nested_groups'
require_relative 'rspec/no_expectation_example'
require_relative 'rspec/no_stringified_instance_double_constant'
require_relative 'rspec/not_to_not'
require_relative 'rspec/overwriting_setup'
require_relative 'rspec/pending'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::RSpec::NoStringifiedInstanceDoubleConstant,
:config do
context 'when using a class for instance_double' do
let(:source) do
<<~RUBY
instance_double(Foo, failure_message, stubs)
RUBY
end

it { expect_no_offenses source }
end

context 'when using a symbol for instance_double' do
let(:source) do
<<~RUBY
instance_double(:Foo, failure_message, stubs)
RUBY
end

it { expect_no_offenses source }
end

context 'when using a string for instance_double' do
it 'replaces the string with the class' do
expect_offense <<~RUBY
instance_double('Foo', failure_message, stubs)
^^^^^ Do not use a string as `instance_double` constant.
RUBY

expect_correction <<~RUBY
instance_double(Foo, failure_message, stubs)
RUBY
end
end
end

0 comments on commit d3d3328

Please sign in to comment.