@@ -31,7 +31,7 @@ pub fn code_actions(
3131 if lint_id. name ( ) == UNRESOLVED_REFERENCE . name ( )
3232 && let Some ( import_quick_fix) = create_import_symbol_quick_fix ( db, file, diagnostic_range)
3333 {
34- actions. extend ( import_quick_fix)
34+ actions. extend ( import_quick_fix) ;
3535 }
3636
3737 actions. push ( QuickFix {
@@ -62,3 +62,125 @@ fn create_import_symbol_quick_fix(
6262 } ) ,
6363 )
6464}
65+
66+ #[ cfg( test) ]
67+ mod tests {
68+
69+ use crate :: code_actions;
70+
71+ use insta:: assert_snapshot;
72+ use ruff_db:: {
73+ diagnostic:: {
74+ Annotation , Diagnostic , DiagnosticFormat , DiagnosticId , DisplayDiagnosticConfig ,
75+ LintName , Span , SubDiagnostic ,
76+ } ,
77+ files:: { File , system_path_to_file} ,
78+ source:: source_text,
79+ system:: { DbWithWritableSystem , SystemPathBuf } ,
80+ } ;
81+ use ruff_diagnostics:: Fix ;
82+ use ruff_text_size:: { TextRange , TextSize } ;
83+ use ty_project:: ProjectMetadata ;
84+ use ty_python_semantic:: { lint:: LintMetadata , types:: UNRESOLVED_REFERENCE } ;
85+
86+ #[ test]
87+ fn add_ignore ( ) {
88+ let test = CodeActionTest :: with_source ( r#"b = <START>a<END> / 10"# ) ;
89+
90+ assert_snapshot ! ( test. code_actions( & UNRESOLVED_REFERENCE ) , @r"
91+ info[code-action]: Ignore 'unresolved-reference' for this line
92+ --> main.py:1:5
93+ |
94+ 1 | b = a / 10
95+ | ^
96+ |
97+ - b = a / 10
98+ 1 + b = a / 10 # ty:ignore[unresolved-reference]
99+ " )
100+ }
101+
102+ pub ( super ) struct CodeActionTest {
103+ pub ( super ) db : ty_project:: TestDb ,
104+ pub ( super ) file : File ,
105+ pub ( super ) diagnostic_range : TextRange ,
106+ }
107+
108+ impl CodeActionTest {
109+ pub ( super ) fn with_source ( source : & str ) -> Self {
110+ let mut db = ty_project:: TestDb :: new ( ProjectMetadata :: new (
111+ "test" . into ( ) ,
112+ SystemPathBuf :: from ( "/" ) ,
113+ ) ) ;
114+
115+ db. init_program ( ) . unwrap ( ) ;
116+
117+ let mut cleansed = source. to_string ( ) ;
118+
119+ let start = cleansed
120+ . find ( "<START>" )
121+ . expect ( "source text should contain a `<START>` marker" ) ;
122+ cleansed. replace_range ( start..start + "<START>" . len ( ) , "" ) ;
123+
124+ let end = cleansed
125+ . find ( "<END>" )
126+ . expect ( "source text should contain a `<END>` marker" ) ;
127+
128+ cleansed. replace_range ( end..end + "<END>" . len ( ) , "" ) ;
129+
130+ if end < start {
131+ panic ! ( "<START> marker should be before <END> marker" ) ;
132+ }
133+
134+ db. write_file ( "main.py" , cleansed)
135+ . expect ( "write to memory file system to be successful" ) ;
136+
137+ let file = system_path_to_file ( & db, "main.py" ) . expect ( "newly written file to existing" ) ;
138+
139+ Self {
140+ db,
141+ file,
142+ diagnostic_range : TextRange :: new (
143+ TextSize :: try_from ( start) . unwrap ( ) ,
144+ TextSize :: try_from ( end) . unwrap ( ) ,
145+ ) ,
146+ }
147+ }
148+
149+ pub ( super ) fn code_actions ( & self , lint : & ' static LintMetadata ) -> String {
150+ use std:: fmt:: Write ;
151+
152+ let mut buf = String :: new ( ) ;
153+
154+ let config = DisplayDiagnosticConfig :: default ( )
155+ . color ( false )
156+ . show_fix_diff ( true )
157+ . format ( DiagnosticFormat :: Full ) ;
158+
159+ for mut action in code_actions ( & self . db , self . file , self . diagnostic_range , & lint. name ) {
160+ let mut diagnostic = Diagnostic :: new (
161+ DiagnosticId :: Lint ( LintName :: of ( "code-action" ) ) ,
162+ ruff_db:: diagnostic:: Severity :: Info ,
163+ action. title ,
164+ ) ;
165+
166+ diagnostic. annotate ( Annotation :: primary (
167+ Span :: from ( self . file ) . with_range ( self . diagnostic_range ) ,
168+ ) ) ;
169+
170+ if action. preferred {
171+ diagnostic. sub ( SubDiagnostic :: new (
172+ ruff_db:: diagnostic:: SubDiagnosticSeverity :: Help ,
173+ "This is a preferred code action" ,
174+ ) ) ;
175+ }
176+
177+ let first_edit = action. edits . remove ( 0 ) ;
178+ diagnostic. set_fix ( Fix :: safe_edits ( first_edit, action. edits ) ) ;
179+
180+ write ! ( buf, "{}" , diagnostic. display( & self . db, & config) ) . unwrap ( ) ;
181+ }
182+
183+ buf
184+ }
185+ }
186+ }
0 commit comments