forked from rubocop/rubocop-minitest
/
global_expectations.rb
94 lines (78 loc) · 2.9 KB
/
global_expectations.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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# frozen_string_literal: true
module RuboCop
module Cop
module Minitest
# This cop checks for deprecated global expectations
# and autocorrects them to use expect format.
#
# @example
# # bad
# musts.must_equal expected_musts
# wonts.wont_match expected_wonts
# musts.must_raise TypeError
#
# # good
# _(musts).must_equal expected_musts
# _(wonts).wont_match expected_wonts
# _ { musts }.must_raise TypeError
class GlobalExpectations < Base
extend AutoCorrector
MSG = 'Use `%<preferred>s` instead.'
VALUE_MATCHERS = %i[
must_be_empty must_equal must_be_close_to must_be_within_delta
must_be_within_epsilon must_include must_be_instance_of must_be_kind_of
must_match must_be_nil must_be must_respond_to must_be_same_as
path_must_exist path_wont_exist wont_be_empty wont_equal wont_be_close_to
wont_be_within_delta wont_be_within_epsilon wont_include wont_be_instance_of
wont_be_kind_of wont_match wont_be_nil wont_be wont_respond_to wont_be_same_as
].freeze
BLOCK_MATCHERS = %i[must_output must_raise must_be_silent must_throw].freeze
RESTRICT_ON_SEND = VALUE_MATCHERS + BLOCK_MATCHERS
VALUE_MATCHERS_STR = VALUE_MATCHERS.map do |m|
":#{m}"
end.join(' ').freeze
BLOCK_MATCHERS_STR = BLOCK_MATCHERS.map do |m|
":#{m}"
end.join(' ').freeze
# There are aliases for the `_` method - `expect` and `value`
DSL_METHODS_LIST = %w[_ value expect].map do |n|
":#{n}"
end.join(' ').freeze
def_node_matcher :value_global_expectation?, <<~PATTERN
(send !(send nil? {#{DSL_METHODS_LIST}} _) {#{VALUE_MATCHERS_STR}} ...)
PATTERN
def_node_matcher :block_global_expectation?, <<~PATTERN
(send
[
!(send nil? {#{DSL_METHODS_LIST}} _)
!(block (send nil? {#{DSL_METHODS_LIST}}) _ _)
]
{#{BLOCK_MATCHERS_STR}}
_
)
PATTERN
def on_send(node)
return unless value_global_expectation?(node) || block_global_expectation?(node)
message = format(MSG, preferred: preferred_receiver(node))
add_offense(node.receiver.source_range, message: message) do |corrector|
receiver = node.receiver.source_range
if BLOCK_MATCHERS.include?(node.method_name)
corrector.wrap(receiver, '_ { ', ' }')
else
corrector.wrap(receiver, '_(', ')')
end
end
end
private
def preferred_receiver(node)
source = node.receiver.source
if BLOCK_MATCHERS.include?(node.method_name)
"_ { #{source} }"
else
"_(#{source})"
end
end
end
end
end
end