Skip to content

Commit

Permalink
Obsolete StringAsInstanceDoubleConstant in favor of VerifiedDoubleRef…
Browse files Browse the repository at this point in the history
…erence for constants only
  • Loading branch information
corsonknowles committed Nov 20, 2024
1 parent 5d96600 commit 9f182e6
Show file tree
Hide file tree
Showing 11 changed files with 38 additions and 268 deletions.
5 changes: 0 additions & 5 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,3 @@ Style/StringChars: {Enabled: true}
Style/SuperWithArgsParentheses: {Enabled: true}
Style/SwapValues: {Enabled: true}
Style/YAMLFileRead: {Enabled: true}

# Enable our own pending cops.
#
RSpec/StringAsInstanceDoubleConstant:
Enabled: true
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
- Fix `RSpec/VoidExpect` to only operate inside an example block. ([@corsonknowles])
- Change `RSpec/ContextWording` cop to always report an offense when both `Prefixes` and `AllowedPatterns` are empty. ([@ydah])
- Add support for `and` and `or` compound matchers to `RSpec/ChangeByZero` cop. ([@ydah])
- Replace `RSpec/StringAsInstanceDoubleConstant` with `RSpecVerifiedDoubleReference` configured to only support constant class references. ([@corsonknowles])

## 3.1.0 (2024-10-01)

Expand Down
13 changes: 1 addition & 12 deletions config/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -930,13 +930,6 @@ RSpec/SpecFilePathSuffix:
- "**/spec/**/*"
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/SpecFilePathSuffix

RSpec/StringAsInstanceDoubleConstant:
Description: Do not use a string as `instance_double` constant.
Enabled: pending
Safe: false
VersionAdded: '3.1'
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/StringAsInstanceDoubleConstant

RSpec/StubbedMock:
Description: Checks that message expectations do not have a configured response.
Enabled: true
Expand Down Expand Up @@ -995,12 +988,8 @@ RSpec/VerifiedDoubleReference:
Description: Checks for consistent verified double reference style.
Enabled: true
SafeAutoCorrect: false
EnforcedStyle: constant
SupportedStyles:
- constant
- string
VersionAdded: 2.10.0
VersionChanged: '2.12'
VersionChanged: "<<next>>"
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/VerifiedDoubleReference

RSpec/VerifiedDoubles:
Expand Down
10 changes: 10 additions & 0 deletions config/obsoletion.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@

# Cop parameters that have been changed
# Can be treated as a warning instead of a failure with `severity: warning`
changed_enforced_styles:
- cops: RSpec/VerifiedDoubleReference
parameters: EnforcedStyle
value: string
reason: String references are not verifying unless the class is loaded.
severity: warning

changed_parameters:
- cops:
- RSpec/VariableName
Expand All @@ -28,3 +35,6 @@ extracted:
RSpec/Rails/*: rubocop-rspec_rails
RSpec/FactoryBot/*: rubocop-factory_bot
RSpec/Capybara/*: rubocop-capybara

renamed:
RSpec/StringAsInstanceDoubleConstant: RSpec/VerifiedDoubleReference
1 change: 0 additions & 1 deletion docs/modules/ROOT/pages/cops.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@
* xref:cops_rspec.adoc#rspecsortmetadata[RSpec/SortMetadata]
* xref:cops_rspec.adoc#rspecspecfilepathformat[RSpec/SpecFilePathFormat]
* xref:cops_rspec.adoc#rspecspecfilepathsuffix[RSpec/SpecFilePathSuffix]
* xref:cops_rspec.adoc#rspecstringasinstancedoubleconstant[RSpec/StringAsInstanceDoubleConstant]
* xref:cops_rspec.adoc#rspecstubbedmock[RSpec/StubbedMock]
* xref:cops_rspec.adoc#rspecsubjectdeclaration[RSpec/SubjectDeclaration]
* xref:cops_rspec.adoc#rspecsubjectstub[RSpec/SubjectStub]
Expand Down
83 changes: 8 additions & 75 deletions docs/modules/ROOT/pages/cops_rspec.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -5907,45 +5907,6 @@ spec/models/user.rb # shared_examples_for 'foo'
* https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/SpecFilePathSuffix
[#rspecstringasinstancedoubleconstant]
== RSpec/StringAsInstanceDoubleConstant
|===
| Enabled by default | Safe | Supports autocorrection | Version Added | Version Changed
| Pending
| No
| Always (Unsafe)
| 3.1
| -
|===
Do not use a string as `instance_double` constant.
[#safety-rspecstringasinstancedoubleconstant]
=== Safety
This cop is unsafe because the correction requires loading the class.
Loading before stubbing causes RSpec to only allow instance methods
to be stubbed.
[#examples-rspecstringasinstancedoubleconstant]
=== Examples
[source,ruby]
----
# bad
instance_double('User', name: 'John')
# good
instance_double(User, name: 'John')
----
[#references-rspecstringasinstancedoubleconstant]
=== References
* https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/StringAsInstanceDoubleConstant
[#rspecstubbedmock]
== RSpec/StubbedMock
Expand Down Expand Up @@ -6357,22 +6318,21 @@ let(:userFood_2) { 'fettuccine' }
| Yes
| Always (Unsafe)
| 2.10.0
| 2.12
| <<next>>
|===
Checks for consistent verified double reference style.
Only investigates references that are one of the supported styles.
[#safety-rspecverifieddoublereference]
=== Safety
This cop can be configured in your configuration using the
`EnforcedStyle` option and supports `--auto-gen-config`.
This cop is unsafe because the correction requires loading the class.
Loading before stubbing causes RSpec to only allow instance methods
to be stubbed.
[#examples-rspecverifieddoublereference]
=== Examples
[#_enforcedstyle_-constant_-_default_-rspecverifieddoublereference]
==== `EnforcedStyle: constant` (default)
[source,ruby]
----
# bad
Expand All @@ -6386,24 +6346,8 @@ let(:foo) do
end
----
[#_enforcedstyle_-string_-rspecverifieddoublereference]
==== `EnforcedStyle: string`
[source,ruby]
----
# bad
let(:foo) do
instance_double(ClassName, method_name: 'returned_value')
end
# good
let(:foo) do
instance_double('ClassName', method_name: 'returned_value')
end
----
[#reference-is-not-in-the-supported-style-list_-no-enforcement-rspecverifieddoublereference]
==== Reference is not in the supported style list. No enforcement
[#reference-is-any-dynamic-variable_-no-enforcement-rspecverifieddoublereference]
==== Reference is any dynamic variable. No enforcement
[source,ruby]
----
Expand All @@ -6413,17 +6357,6 @@ let(:foo) do
end
----
[#configurable-attributes-rspecverifieddoublereference]
=== Configurable attributes
|===
| Name | Default value | Configurable values
| EnforcedStyle
| `constant`
| `constant`, `string`
|===
[#references-rspecverifieddoublereference]
=== References
Expand Down
45 changes: 0 additions & 45 deletions lib/rubocop/cop/rspec/string_as_instance_double_constant.rb

This file was deleted.

67 changes: 14 additions & 53 deletions lib/rubocop/cop/rspec/verified_double_reference.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ module Cop
module RSpec
# Checks for consistent verified double reference style.
#
# Only investigates references that are one of the supported styles.
#
# @see https://rspec.info/features/3-12/rspec-mocks/verifying-doubles
#
# This cop can be configured in your configuration using the
# `EnforcedStyle` option and supports `--auto-gen-config`.
# @safety
# This cop is unsafe because the correction requires loading the class.
# Loading before stubbing causes RSpec to only allow instance methods
# to be stubbed.
#
# @example `EnforcedStyle: constant` (default)
# @example
# # bad
# let(:foo) do
# instance_double('ClassName', method_name: 'returned_value')
Expand All @@ -23,28 +23,17 @@ module RSpec
# instance_double(ClassName, method_name: 'returned_value')
# end
#
# @example `EnforcedStyle: string`
# # bad
# let(:foo) do
# instance_double(ClassName, method_name: 'returned_value')
# end
#
# # good
# let(:foo) do
# instance_double('ClassName', method_name: 'returned_value')
# end
#
# @example Reference is not in the supported style list. No enforcement
# @example Reference is any dynamic variable. No enforcement
#
# # good
# let(:foo) do
# instance_double(@klass, method_name: 'returned_value')
# end
class VerifiedDoubleReference < Base
extend AutoCorrector
include ConfigurableEnforcedStyle

MSG = 'Use a %<style>s class reference for verified doubles.'
MSG = 'Use a constant class reference for verified doubles. ' \
'String references are not verifying unless the class is loaded.'

RESTRICT_ON_SEND = Set[
:class_double,
Expand All @@ -57,53 +46,25 @@ class VerifiedDoubleReference < Base
:stub_model
].freeze

REFERENCE_TYPE_STYLES = {
str: :string,
const: :constant
}.freeze

# @!method verified_double(node)
def_node_matcher :verified_double, <<~PATTERN
(send
nil?
RESTRICT_ON_SEND
$_class_reference
$str
...)
PATTERN

def on_send(node)
verified_double(node) do |class_reference|
break correct_style_detected unless opposing_style?(class_reference)

message = format(MSG, style: style)
expression = class_reference.source_range

add_offense(expression, message: message) do |corrector|
offense = class_reference.source
corrector.replace(expression, correct_style(offense))

opposite_style_detected
verified_double(node) do |string_argument_node|
add_offense(string_argument_node) do |corrector|
autocorrect(corrector, string_argument_node)
end
end
end

private

def opposing_style?(class_reference)
class_reference_style = REFERENCE_TYPE_STYLES[class_reference.type]

# Only enforce supported styles
return false unless class_reference_style

class_reference_style != style
end

def correct_style(offense)
if style == :string
"'#{offense}'"
else
offense.gsub(/^['"]|['"]$/, '')
end
def autocorrect(corrector, node)
corrector.replace(node, node.value)
end
end
end
Expand Down
1 change: 0 additions & 1 deletion lib/rubocop/cop/rspec_cops.rb
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@
require_relative 'rspec/sort_metadata'
require_relative 'rspec/spec_file_path_format'
require_relative 'rspec/spec_file_path_suffix'
require_relative 'rspec/string_as_instance_double_constant'
require_relative 'rspec/stubbed_mock'
require_relative 'rspec/subject_declaration'
require_relative 'rspec/subject_stub'
Expand Down
33 changes: 0 additions & 33 deletions spec/rubocop/cop/rspec/string_as_instance_double_constant_spec.rb

This file was deleted.

Loading

0 comments on commit 9f182e6

Please sign in to comment.