Class: RuboCop::Cop::Kaizo::SpecSubject
- Inherits:
-
Base
- Object
- Base
- RuboCop::Cop::Kaizo::SpecSubject
- Includes:
- AllowedMethods, AllowedPattern
- Defined in:
- lib/rubocop/cop/kaizo/spec_subject.rb
Overview
Requires the unit under test to be declared with subject, not let.
subject is RSpec's name for the object being specified; hiding it in a
let obscures which object the examples are about and forfeits
is_expected/one-liner syntax.
A let (or let!) is flagged when the value it returns is confidently
an instance of the class under test: the block's final expression is a
.new call on described_class, on the constant named by an enclosing
describe/context (full or short name), or on a constant matching the
spec's file name (pool_spec.rb names Pool, api_client_spec.rb
names APIClient).
A let that builds a second instance on purpose -- an other for an
equality spec, say -- is exempted through AllowedMethods or
AllowedPatterns, both matched against the let name.
There is no autocorrection: renaming the helper every example refers to is a change the spec's author should make deliberately.
Configuration
[+AllowedMethods+] let names never flagged. Default: none.
[+AllowedPatterns+] Regexps matched against the let name; a match is
exempt. Default: none.
[+Include+] Files the cop runs on. Default: **/*_spec.rb.
Kaizo/SpecSubject:
AllowedMethods:
- other # a second instance for equality specs
AllowedPatterns:
- '\Aother_'
Constant Summary collapse
- MSG =
"Declare the unit under test with `subject(:%<name>s)`, not `let`.".freeze
Instance Method Summary collapse
- #constructed_class(node) ⇒ Object
- #described_constant(node) ⇒ Object
- #let_declaration(node) ⇒ Object
- #on_block(node) ⇒ Object
Instance Method Details
#constructed_class(node) ⇒ Object
67 68 69 |
# File 'lib/rubocop/cop/kaizo/spec_subject.rb', line 67 def_node_matcher :constructed_class, <<~PATTERN (send ${(send nil? :described_class) (const _ _)} :new ...) PATTERN |
#described_constant(node) ⇒ Object
72 73 74 |
# File 'lib/rubocop/cop/kaizo/spec_subject.rb', line 72 def_node_matcher :described_constant, <<~PATTERN (block (send {(const {nil? cbase} :RSpec) nil?} {:describe :context} $(const ...) ...) ...) PATTERN |
#let_declaration(node) ⇒ Object
62 63 64 |
# File 'lib/rubocop/cop/kaizo/spec_subject.rb', line 62 def_node_matcher :let_declaration, <<~PATTERN (block (send nil? {:let :let!} (sym $_)) _ $_) PATTERN |
#on_block(node) ⇒ Object
76 77 78 79 80 81 82 83 |
# File 'lib/rubocop/cop/kaizo/spec_subject.rb', line 76 def on_block(node) name, body = let_declaration(node) return unless name return if allowed_method?(name) || matches_allowed_pattern?(name.to_s) return unless unit_under_test?(node, final_expression(body)) add_offense(node.send_node.loc.selector, message: format(MSG, name:)) end |