Skip to content

Commit 52f3c3e

Browse files
committed
Add code actions testing infrastructure
1 parent 29a26b1 commit 52f3c3e

File tree

1 file changed

+123
-1
lines changed

1 file changed

+123
-1
lines changed

crates/ty_ide/src/code_action.rs

Lines changed: 123 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)