Class: RuboCop::Cop::Vicenzo::RSpec::CompetingSubjects
- Inherits:
-
RSpec::Base
- Object
- RSpec::Base
- RuboCop::Cop::Vicenzo::RSpec::CompetingSubjects
- Includes:
- DescribedMethod, ExpectationTarget, PremiseTracking
- Defined in:
- lib/rubocop/cop/vicenzo/rspec/competing_subjects.rb
Overview
Two or more definitions the expectations assert on, in a group that declares no subject, are contexts that were never written.
A group speaks about one subject. When its examples each assert on a different definition, the
group is not one scenario with several facts: it is several scenarios sharing a roof, and the
circumstance that tells them apart - the one a context would have named - lives only in the
definitions' names and in the reader's head.
The fix is structural, and it is never to pick one of them to promote. Which shape it takes depends on what the definitions are to this group, and working that out is the whole job - which is why the offense names what was found rather than prescribing a repair:
- They are different scenarios. Give each its own
context, saying out loud the circumstance it stands for, and let each declare the subject it is about. What was encoded inrecord_1/record_2becomes a sentence, and the example shrinks to the outcome alone. - One outcome covers them all. Then they were never subjects: they are the premise. Move them
into a
before, unnamed, and assert on the collection they belong to.
Both are corrections to the spec. Neither is silencing the cop: a definition named
record_1 is the shape this smell takes, so renaming it settles nothing, and an inline
disable directive keeps the hidden scenario hidden - which is the cost being paid here.
A group that already declares a subject is left alone - there the subject is settled and the other definitions are premises, whatever their names suggest.
Constant Summary collapse
- MSG =
'The expectations here are about %<names>s, so this group has no one subject. Work out ' \ 'what these definitions are to it, and let the structure say so.'
Constants included from PremiseTracking
Constants included from ExpectationTarget
ExpectationTarget::EXPECTATION_RUNNERS, ExpectationTarget::MESSAGE_MATCHERS
Constants included from DescribedMethod
DescribedMethod::BARE_METHOD_DESCRIPTION, DescribedMethod::PREFIXED_METHOD_DESCRIPTION
Instance Method Summary collapse
- #on_block(node) ⇒ Object (also: #on_numblock, #on_itblock)
Methods included from PremiseTracking
#premise_name, #root_receiver_name
Instance Method Details
#on_block(node) ⇒ Object Also known as: on_numblock, on_itblock
105 106 107 108 109 110 111 112 113 |
# File 'lib/rubocop/cop/vicenzo/rspec/competing_subjects.rb', line 105 def on_block(node) return unless example_group?(node) names = competing_names(node) return if names.size < 2 add_offense(node.send_node, message: format(MSG, names: names.join(', '))) end |