@@ -26,115 +26,6 @@ module Rails
26
26
class MinitestAssertions < Base
27
27
extend AutoCorrector
28
28
29
- MSG = 'Use `%<prefer>s`.'
30
- RESTRICT_ON_SEND = %i[
31
- assert_equal
32
- assert_not_equal
33
- assert_instance_of
34
- assert_not_instance_of
35
- assert_includes
36
- assert_not_includes
37
- assert_predicate
38
- assert_not_predicate
39
- assert_match
40
- assert_nil
41
- assert_not_nil
42
- assert_empty
43
- assert_not_empty
44
- refute_equal
45
- refute_instance_of
46
- refute_includes
47
- refute_predicate
48
- refute_nil
49
- refute_empty
50
- refute_match
51
- ] . freeze
52
-
53
- # @!method minitest_equal(node)
54
- def_node_matcher :minitest_equal , <<~PATTERN
55
- (send nil? {:assert_equal :assert_not_equal :refute_equal} $_ $_ $_?)
56
- PATTERN
57
-
58
- # @!method minitest_instance_of(node)
59
- def_node_matcher :minitest_instance_of , <<~PATTERN
60
- (send nil? {:assert_instance_of :assert_not_instance_of :refute_instance_of} $_ $_ $_?)
61
- PATTERN
62
-
63
- # @!method minitest_includes(node)
64
- def_node_matcher :minitest_includes , <<~PATTERN
65
- (send nil? {:assert_includes :assert_not_includes :refute_includes} $_ $_ $_?)
66
- PATTERN
67
-
68
- # @!method minitest_predicate(node)
69
- def_node_matcher :minitest_predicate , <<~PATTERN
70
- (send nil? {:assert_predicate :assert_not_predicate :refute_predicate} $_ ${sym} $_?)
71
- PATTERN
72
-
73
- # @!method minitest_match(node)
74
- def_node_matcher :minitest_match , <<~PATTERN
75
- (send nil? {:assert_match :refute_match} $_ $_ $_?)
76
- PATTERN
77
-
78
- # @!method minitest_nil(node)
79
- def_node_matcher :minitest_nil , <<~PATTERN
80
- (send nil? {:assert_nil :assert_not_nil :refute_nil} $_ $_?)
81
- PATTERN
82
-
83
- # @!method minitest_empty(node)
84
- def_node_matcher :minitest_empty , <<~PATTERN
85
- (send nil? {:assert_empty :assert_not_empty :refute_empty} $_ $_?)
86
- PATTERN
87
-
88
- def on_send ( node ) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
89
- minitest_equal ( node ) do |expected , actual , failure_message |
90
- on_assertion ( node , EqualAssertion . new ( expected , actual ,
91
- failure_message . first ) )
92
- end
93
-
94
- minitest_instance_of ( node ) do |expected , actual , failure_message |
95
- on_assertion ( node , InstanceOfAssertion . new ( expected , actual ,
96
- failure_message . first ) )
97
- end
98
-
99
- minitest_predicate ( node ) do |subject , predicate , failure_message |
100
- next unless predicate . value . end_with? ( '?' )
101
-
102
- on_assertion ( node , PredicateAssertion . new ( predicate , subject ,
103
- failure_message . first ) )
104
- end
105
-
106
- minitest_includes ( node ) do |collection , expected , failure_message |
107
- on_assertion ( node , IncludesAssertion . new ( expected , collection ,
108
- failure_message . first ) )
109
- end
110
-
111
- minitest_match ( node ) do |matcher , actual , failure_message |
112
- on_assertion ( node , MatchAssertion . new ( matcher , actual ,
113
- failure_message . first ) )
114
- end
115
-
116
- minitest_nil ( node ) do |actual , failure_message |
117
- on_assertion ( node , NilAssertion . new ( nil , actual ,
118
- failure_message . first ) )
119
- end
120
-
121
- minitest_empty ( node ) do |actual , failure_message |
122
- on_assertion ( node , EmptyAssertion . new ( nil , actual ,
123
- failure_message . first ) )
124
- end
125
- end
126
-
127
- def on_assertion ( node , assertion )
128
- preferred = assertion . replaced ( node )
129
- add_offense ( node , message : message ( preferred ) ) do |corrector |
130
- corrector . replace ( node , preferred )
131
- end
132
- end
133
-
134
- def message ( preferred )
135
- format ( MSG , prefer : preferred )
136
- end
137
-
138
29
# :nodoc:
139
30
class BasicAssertion
140
31
def initialize ( expected , actual , fail_message )
@@ -151,10 +42,32 @@ def replaced(node)
151
42
"expect(#{ @actual } ).#{ runner } (#{ assertion } , #{ @fail_message } )"
152
43
end
153
44
end
45
+
46
+ def negated? ( node )
47
+ raise NotImplementedError
48
+ end
49
+
50
+ def assertion
51
+ raise NotImplementedError
52
+ end
154
53
end
155
54
156
55
# :nodoc:
157
56
class EqualAssertion < BasicAssertion
57
+ MATCHERS = %i[
58
+ assert_equal
59
+ assert_not_equal
60
+ refute_equal
61
+ ] . freeze
62
+
63
+ NODE_MATCHER_PATTERN = <<~PATTERN
64
+ (send nil? {:assert_equal :assert_not_equal :refute_equal} $_ $_ $_?)
65
+ PATTERN
66
+
67
+ def self . match ( expected , actual , failure_message )
68
+ new ( expected , actual , failure_message . first )
69
+ end
70
+
158
71
def negated? ( node )
159
72
!node . method? ( :assert_equal )
160
73
end
@@ -166,6 +79,20 @@ def assertion
166
79
167
80
# :nodoc:
168
81
class InstanceOfAssertion < BasicAssertion
82
+ MATCHERS = %i[
83
+ assert_instance_of
84
+ assert_not_instance_of
85
+ refute_instance_of
86
+ ] . freeze
87
+
88
+ NODE_MATCHER_PATTERN = <<~PATTERN
89
+ (send nil? {:assert_instance_of :assert_not_instance_of :refute_instance_of} $_ $_ $_?)
90
+ PATTERN
91
+
92
+ def self . match ( expected , actual , failure_message )
93
+ new ( expected , actual , failure_message . first )
94
+ end
95
+
169
96
def negated? ( node )
170
97
!node . method? ( :assert_instance_of )
171
98
end
@@ -177,6 +104,20 @@ def assertion
177
104
178
105
# :nodoc:
179
106
class IncludesAssertion < BasicAssertion
107
+ MATCHERS = %i[
108
+ assert_includes
109
+ assert_not_includes
110
+ refute_includes
111
+ ] . freeze
112
+
113
+ NODE_MATCHER_PATTERN = <<~PATTERN
114
+ (send nil? {:assert_includes :assert_not_includes :refute_includes} $_ $_ $_?)
115
+ PATTERN
116
+
117
+ def self . match ( collection , expected , failure_message )
118
+ new ( expected , collection , failure_message . first )
119
+ end
120
+
180
121
def negated? ( node )
181
122
!node . method? ( :assert_includes )
182
123
end
@@ -188,6 +129,22 @@ def assertion
188
129
189
130
# :nodoc:
190
131
class PredicateAssertion < BasicAssertion
132
+ MATCHERS = %i[
133
+ assert_predicate
134
+ assert_not_predicate
135
+ refute_predicate
136
+ ] . freeze
137
+
138
+ NODE_MATCHER_PATTERN = <<~PATTERN
139
+ (send nil? {:assert_predicate :assert_not_predicate :refute_predicate} $_ ${sym} $_?)
140
+ PATTERN
141
+
142
+ def self . match ( subject , predicate , failure_message )
143
+ return nil unless predicate . value . end_with? ( '?' )
144
+
145
+ new ( predicate , subject , failure_message . first )
146
+ end
147
+
191
148
def negated? ( node )
192
149
!node . method? ( :assert_predicate )
193
150
end
@@ -199,6 +156,19 @@ def assertion
199
156
200
157
# :nodoc:
201
158
class MatchAssertion < BasicAssertion
159
+ MATCHERS = %i[
160
+ assert_match
161
+ refute_match
162
+ ] . freeze
163
+
164
+ NODE_MATCHER_PATTERN = <<~PATTERN
165
+ (send nil? {:assert_match :refute_match} $_ $_ $_?)
166
+ PATTERN
167
+
168
+ def self . match ( matcher , actual , failure_message )
169
+ new ( matcher , actual , failure_message . first )
170
+ end
171
+
202
172
def negated? ( node )
203
173
!node . method? ( :assert_match )
204
174
end
@@ -210,6 +180,20 @@ def assertion
210
180
211
181
# :nodoc:
212
182
class NilAssertion < BasicAssertion
183
+ MATCHERS = %i[
184
+ assert_nil
185
+ assert_not_nil
186
+ refute_nil
187
+ ] . freeze
188
+
189
+ NODE_MATCHER_PATTERN = <<~PATTERN
190
+ (send nil? {:assert_nil :assert_not_nil :refute_nil} $_ $_?)
191
+ PATTERN
192
+
193
+ def self . match ( actual , failure_message )
194
+ new ( nil , actual , failure_message . first )
195
+ end
196
+
213
197
def negated? ( node )
214
198
!node . method? ( :assert_nil )
215
199
end
@@ -221,6 +205,20 @@ def assertion
221
205
222
206
# :nodoc:
223
207
class EmptyAssertion < BasicAssertion
208
+ MATCHERS = %i[
209
+ assert_empty
210
+ assert_not_empty
211
+ refute_empty
212
+ ] . freeze
213
+
214
+ NODE_MATCHER_PATTERN = <<~PATTERN
215
+ (send nil? {:assert_empty :assert_not_empty :refute_empty} $_ $_?)
216
+ PATTERN
217
+
218
+ def self . match ( actual , failure_message )
219
+ new ( nil , actual , failure_message . first )
220
+ end
221
+
224
222
def negated? ( node )
225
223
!node . method? ( :assert_empty )
226
224
end
@@ -229,6 +227,48 @@ def assertion
229
227
'be_empty'
230
228
end
231
229
end
230
+
231
+ MSG = 'Use `%<prefer>s`.'
232
+
233
+ # TODO: replace with `BasicAssertion.subclasses` in Ruby 3.1+
234
+ ASSERTION_MATCHERS = constants ( false ) . filter_map do |c |
235
+ const = const_get ( c )
236
+
237
+ const if const . is_a? ( Class ) && const . superclass == BasicAssertion
238
+ end
239
+
240
+ RESTRICT_ON_SEND = ASSERTION_MATCHERS . flat_map { |m | m ::MATCHERS }
241
+
242
+ ASSERTION_MATCHERS . each do |m |
243
+ name = m . name . split ( '::' ) . last
244
+
245
+ def_node_matcher "minitest_#{ name } " . to_sym , m ::NODE_MATCHER_PATTERN
246
+ end
247
+
248
+ def on_send ( node )
249
+ ASSERTION_MATCHERS . each do |m |
250
+ name = m . name . split ( '::' ) . last
251
+
252
+ public_send ( "minitest_#{ name } " . to_sym , node ) do |*args |
253
+ assertion = m . match ( *args )
254
+
255
+ next if assertion . nil?
256
+
257
+ on_assertion ( node , assertion )
258
+ end
259
+ end
260
+ end
261
+
262
+ def on_assertion ( node , assertion )
263
+ preferred = assertion . replaced ( node )
264
+ add_offense ( node , message : message ( preferred ) ) do |corrector |
265
+ corrector . replace ( node , preferred )
266
+ end
267
+ end
268
+
269
+ def message ( preferred )
270
+ format ( MSG , prefer : preferred )
271
+ end
232
272
end
233
273
end
234
274
end
0 commit comments