-
Notifications
You must be signed in to change notification settings - Fork 441
/
avoid_global_state.rb
42 lines (39 loc) · 1.76 KB
/
avoid_global_state.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
module RuboCop
module Cop
module ViewComponent
class AvoidGlobalState < RuboCop::Cop::Base
# General documentation on `def_node_matcher`
# https://docs.rubocop.org/rubocop-ast/1.12/node_pattern.html#using-node-matcher-macros
#
# Documentation for node types (There is a `on_*` method for every Node type, so like `on_send`)
# https://docs.rubocop.org/rubocop-ast/1.12/node_types.html#node-types
#
# Documentation for the predicate nil?
# https://docs.rubocop.org/rubocop-ast/1.12/node_pattern.html#nil-or-nil
#
# Documentation for ... to match several subsequent nodes
# https://docs.rubocop.org/rubocop-ast/1.12/node_pattern.html#for-several-subsequent-nodes
def_node_matcher :params?, <<~PATTERN
(send (send nil? :params) :[] (:sym ...))
PATTERN
def_node_matcher :user_model?, <<~PATTERN
(send (const nil? :User) ...)
PATTERN
MESSAGE = 'View components should not rely on global state by %<content>s. Instead, pass the required data to the initialize method.'.freeze
# Add an offense for using params or class methods from the User model
#
# @param [RuboCop::AST::ClassNode]
def on_send(node)
case
when params?(node)
# node.source is the code which the AST pattern matched, so as an example `params[:abc]`
add_offense(node, message: format(MESSAGE, content: "using #{node.source}"))
when user_model?(node)
# node.source is the code which the AST pattern matched, so as an example `User.session`
add_offense(node, message: format(MESSAGE, content: "calling #{node.source}"))
end
end
end
end
end
end