Class: RuboCop::Cop::Kaizo::AgentNounClassName
- Inherits:
-
Base
- Object
- Base
- RuboCop::Cop::Kaizo::AgentNounClassName
- Defined in:
- lib/rubocop/cop/kaizo/agent_noun_class_name.rb
Overview
Checks for classes named as agent nouns ("doers") rather than the domain
concepts they model. A class whose name ends in er or or (Manager,
Processor, Handler) -- or in any configured ForbiddenSuffixes such
as Service -- usually signals procedural behavior that wants a clearer
domain name or a different home.
Names ending in an AllowedSuffixes entry are exempt; the match is by
suffix, so Controller clears both Controller and UsersController.
ForbiddenSuffixes always flags, even when also matched by
AllowedSuffixes -- which is how you drop a default exemption.
class definitions and Struct.new/Data.define/Class.new constant
assignments are both checked. There is no autocorrection: renaming a
class is a design decision.
Configuration
[+AllowedSuffixes+] Suffixes exempt from the er/or rule, matched
against the end of the name (+Controller+ clears
UsersController too). Default: a broad list of
legitimate -er/-or domain nouns and framework
terms (+Adapter+, Controller, Error, User,
...) -- see config/default.yml for all of them.
[+ForbiddenSuffixes+] Suffixes always flagged, even when matched by
AllowedSuffixes -- which is how a default
exemption is dropped. Default: Service, Util,
Utils.
Extend either list without restating it via RuboCop's inherit_mode: merge:
Kaizo/AgentNounClassName:
inherit_mode:
merge:
- AllowedSuffixes
AllowedSuffixes:
- Voucher # PaymentVoucher now passes
Constant Summary collapse
- MSG =
"Avoid the doer-style class name `%<name>s`. " \ "Prefer a name for the concept it models over the action it performs.".freeze
- AGENT_NOUN =
/(?:er|or)\z/i
Instance Method Summary collapse
Instance Method Details
#class_builder_assignment(node) ⇒ Object
62 63 64 65 66 67 |
# File 'lib/rubocop/cop/kaizo/agent_noun_class_name.rb', line 62 def_node_matcher :class_builder_assignment, <<~PATTERN (casgn _ $_ { (send (const _ {:Struct :Data :Class}) {:new :define} ...) (block (send (const _ {:Struct :Data :Class}) {:new :define} ...) ...) }) PATTERN |
#on_casgn(node) ⇒ Object
73 74 75 76 77 |
# File 'lib/rubocop/cop/kaizo/agent_noun_class_name.rb', line 73 def on_casgn(node) return unless (name = class_builder_assignment(node)) check_name(name.to_s, node.loc.name) end |
#on_class(node) ⇒ Object
69 70 71 |
# File 'lib/rubocop/cop/kaizo/agent_noun_class_name.rb', line 69 def on_class(node) check_name(node.identifier.short_name.to_s, node.loc.name) end |