11use indoc:: indoc;
2+ use mago_text_edit:: Safety ;
23use schemars:: JsonSchema ;
34use serde:: Deserialize ;
45use serde:: Serialize ;
@@ -25,6 +26,7 @@ use crate::rule_meta::RuleMeta;
2526use crate :: settings:: RuleSettings ;
2627
2728const GENERIC_ASSERTIONS : [ & str ; 4 ] = [ "assertEquals" , "assertNotEquals" , "assertSame" , "assertNotSame" ] ;
29+ const EQUALITY_ASSERTIONS : [ & str ; 2 ] = [ "assertEquals" , "assertNotEquals" ] ;
2830
2931/// Position of the literal in the assertion call.
3032#[ derive( Debug , Clone , Copy ) ]
@@ -157,13 +159,15 @@ impl LintRule for UseSpecificAssertionsRule {
157159 let first_expr = first_arg. value ( ) ;
158160 let second_expr = second_arg. value ( ) ;
159161
162+ let is_equality_assertion = EQUALITY_ASSERTIONS . contains ( & identifier. value ) ;
163+
160164 let Some ( ( specific_assertion, literal_position) ) =
161165 get_specific_assertion ( identifier. value , first_expr, second_expr)
162166 else {
163167 continue ;
164168 } ;
165169
166- let issue = Issue :: new (
170+ let mut issue = Issue :: new (
167171 self . cfg . level ( ) ,
168172 format ! ( "Use `{}` instead of `{}` for clearer test assertions." , specific_assertion, identifier. value) ,
169173 )
@@ -177,21 +181,35 @@ impl LintRule for UseSpecificAssertionsRule {
177181 identifier. value, specific_assertion
178182 ) ) ;
179183
184+ if is_equality_assertion {
185+ issue = issue. with_help ( format ! (
186+ "`{}` performs a non-strict comparison, while `{specific_assertion}` performs a strict comparison." ,
187+ identifier. value
188+ ) ) ;
189+
190+ issue = issue. with_help ( "Ensure that this change does not affect the test behavior." ) ;
191+ }
192+
180193 ctx. collector . propose ( issue, |edits| {
181- edits. push ( TextEdit :: replace ( reference. get_selector ( ) . span ( ) , specific_assertion) ) ;
194+ let safety = if is_equality_assertion { Safety :: PotentiallyUnsafe } else { Safety :: Safe } ;
195+
196+ edits. push ( TextEdit :: replace ( reference. get_selector ( ) . span ( ) , specific_assertion) . with_safety ( safety) ) ;
182197
183198 match literal_position {
184199 LiteralPosition :: First => {
185- edits. push ( TextEdit :: replace (
186- argument_list. span ( ) . start_offset ( ) ..second_expr. span ( ) . start_offset ( ) ,
187- "(" ,
188- ) ) ;
200+ edits. push (
201+ TextEdit :: replace (
202+ argument_list. span ( ) . start_offset ( ) ..second_expr. span ( ) . start_offset ( ) ,
203+ "(" ,
204+ )
205+ . with_safety ( safety) ,
206+ ) ;
189207 }
190208 LiteralPosition :: Second => {
191- edits. push ( TextEdit :: replace (
192- first_expr. span ( ) . end_offset ( ) ..argument_list. span ( ) . end_offset ( ) ,
193- ")" ,
194- ) ) ;
209+ edits. push (
210+ TextEdit :: replace ( first_expr. span ( ) . end_offset ( ) ..argument_list. span ( ) . end_offset ( ) , ")" )
211+ . with_safety ( safety ) ,
212+ ) ;
195213 }
196214 }
197215 } ) ;
0 commit comments