1use crate::ToggleBlockComments;
2use crate::editor_tests::init_test;
3use crate::test::editor_test_context::EditorTestContext;
4use gpui::TestAppContext;
5use indoc::indoc;
6use language::{BlockCommentConfig, Language, LanguageConfig};
7use std::sync::Arc;
8
9async fn setup_rust_context(cx: &mut TestAppContext) -> EditorTestContext {
10 init_test(cx, |_| {});
11 let mut cx = EditorTestContext::new(cx).await;
12
13 let rust_language = Arc::new(Language::new(
14 LanguageConfig {
15 name: "Rust".into(),
16 block_comment: Some(BlockCommentConfig {
17 start: "/* ".into(),
18 prefix: "".into(),
19 end: " */".into(),
20 tab_size: 0,
21 }),
22 ..Default::default()
23 },
24 Some(tree_sitter_rust::LANGUAGE.into()),
25 ));
26
27 cx.language_registry().add(rust_language.clone());
28 cx.update_buffer(|buffer, cx| {
29 buffer.set_language(Some(rust_language), cx);
30 });
31
32 cx
33}
34
35#[gpui::test]
36async fn test_toggle_block_comments(cx: &mut TestAppContext) {
37 let mut cx = setup_rust_context(cx).await;
38
39 cx.set_state(indoc! {"
40 fn main() {
41 let x = «1ˇ» + 2;
42 }
43 "});
44
45 cx.update_editor(|editor, window, cx| {
46 editor.toggle_block_comments(&ToggleBlockComments, window, cx);
47 });
48
49 cx.assert_editor_state(indoc! {"
50 fn main() {
51 let x = «/* 1 */ˇ» + 2;
52 }
53 "});
54
55 cx.update_editor(|editor, window, cx| {
56 editor.toggle_block_comments(&ToggleBlockComments, window, cx);
57 });
58
59 cx.assert_editor_state(indoc! {"
60 fn main() {
61 let x = «1ˇ» + 2;
62 }
63 "});
64}
65
66#[gpui::test]
67async fn test_toggle_block_comments_with_selection(cx: &mut TestAppContext) {
68 let mut cx = setup_rust_context(cx).await;
69
70 cx.set_state(indoc! {"
71 fn main() {
72 «let x = 1 + 2;ˇ»
73 }
74 "});
75
76 cx.update_editor(|editor, window, cx| {
77 editor.toggle_block_comments(&ToggleBlockComments, window, cx);
78 });
79
80 cx.assert_editor_state(indoc! {"
81 fn main() {
82 «/* let x = 1 + 2; */ˇ»
83 }
84 "});
85
86 cx.update_editor(|editor, window, cx| {
87 editor.toggle_block_comments(&ToggleBlockComments, window, cx);
88 });
89
90 cx.assert_editor_state(indoc! {"
91 fn main() {
92 «let x = 1 + 2;ˇ»
93 }
94 "});
95}
96
97#[gpui::test]
98async fn test_toggle_block_comments_multiline(cx: &mut TestAppContext) {
99 let mut cx = setup_rust_context(cx).await;
100
101 cx.set_state(indoc! {"
102 «fn main() {
103 let x = 1;
104 }ˇ»
105 "});
106
107 cx.update_editor(|editor, window, cx| {
108 editor.toggle_block_comments(&ToggleBlockComments, window, cx);
109 });
110
111 cx.assert_editor_state(indoc! {"
112 «/* fn main() {
113 let x = 1;
114 } */ˇ»
115 "});
116
117 cx.update_editor(|editor, window, cx| {
118 editor.toggle_block_comments(&ToggleBlockComments, window, cx);
119 });
120
121 cx.assert_editor_state(indoc! {"
122 «fn main() {
123 let x = 1;
124 }ˇ»
125 "});
126}
127
128#[gpui::test]
129async fn test_toggle_block_comments_cursor_inside(cx: &mut TestAppContext) {
130 let mut cx = setup_rust_context(cx).await;
131
132 cx.set_state(indoc! {"
133 fn main() {
134 let x = /* 1ˇ */ + 2;
135 }
136 "});
137
138 cx.update_editor(|editor, window, cx| {
139 editor.toggle_block_comments(&ToggleBlockComments, window, cx);
140 });
141
142 cx.assert_editor_state(indoc! {"
143 fn main() {
144 let x = 1ˇ + 2;
145 }
146 "});
147}
148
149#[gpui::test]
150async fn test_toggle_block_comments_multiple_cursors(cx: &mut TestAppContext) {
151 let mut cx = setup_rust_context(cx).await;
152
153 cx.set_state(indoc! {"
154 fn main() {
155 let x = «1ˇ» + 2;
156 let y = «3ˇ» + 4;
157 }
158 "});
159
160 cx.update_editor(|editor, window, cx| {
161 editor.toggle_block_comments(&ToggleBlockComments, window, cx);
162 });
163
164 cx.assert_editor_state(indoc! {"
165 fn main() {
166 let x = «/* 1 */ˇ» + 2;
167 let y = «/* 3 */ˇ» + 4;
168 }
169 "});
170
171 cx.update_editor(|editor, window, cx| {
172 editor.toggle_block_comments(&ToggleBlockComments, window, cx);
173 });
174
175 cx.assert_editor_state(indoc! {"
176 fn main() {
177 let x = «1ˇ» + 2;
178 let y = «3ˇ» + 4;
179 }
180 "});
181}
182
183#[gpui::test]
184async fn test_toggle_block_comments_selection_ending_on_empty_line(cx: &mut TestAppContext) {
185 let mut cx = setup_rust_context(cx).await;
186
187 cx.set_state(indoc! {"
188 «fn main() {
189 ˇ»
190 let x = 1;
191 }
192 "});
193
194 cx.update_editor(|editor, window, cx| {
195 editor.toggle_block_comments(&ToggleBlockComments, window, cx);
196 });
197
198 cx.assert_editor_state(indoc! {"
199 «/* fn main() {
200 */ˇ»
201 let x = 1;
202 }
203 "});
204
205 cx.update_editor(|editor, window, cx| {
206 editor.toggle_block_comments(&ToggleBlockComments, window, cx);
207 });
208
209 cx.assert_editor_state(indoc! {"
210 «fn main() {
211 ˇ»
212 let x = 1;
213 }
214 "});
215}
216
217#[gpui::test]
218async fn test_toggle_block_comments_empty_selection_roundtrip(cx: &mut TestAppContext) {
219 let mut cx = setup_rust_context(cx).await;
220
221 cx.set_state(indoc! {"
222 fn main() {
223 let x = ˇ1 + 2;
224 }
225 "});
226
227 cx.update_editor(|editor, window, cx| {
228 editor.toggle_block_comments(&ToggleBlockComments, window, cx);
229 });
230
231 cx.update_editor(|editor, window, cx| {
232 editor.toggle_block_comments(&ToggleBlockComments, window, cx);
233 });
234
235 cx.assert_editor_state(indoc! {"
236 fn main() {
237 let x = ˇ1 + 2;
238 }
239 "});
240}
241
242// Multi-byte Unicode characters (√ is 3 bytes in UTF-8) must not cause
243// incorrect offset arithmetic or panics.
244#[gpui::test]
245async fn test_toggle_block_comments_unicode_before_selection(cx: &mut TestAppContext) {
246 let mut cx = setup_rust_context(cx).await;
247
248 cx.set_state("let √ = «42ˇ»;");
249
250 cx.update_editor(|editor, window, cx| {
251 editor.toggle_block_comments(&ToggleBlockComments, window, cx);
252 });
253
254 cx.assert_editor_state("let √ = «/* 42 */ˇ»;");
255
256 cx.update_editor(|editor, window, cx| {
257 editor.toggle_block_comments(&ToggleBlockComments, window, cx);
258 });
259
260 cx.assert_editor_state("let √ = «42ˇ»;");
261}
262
263#[gpui::test]
264async fn test_toggle_block_comments_unicode_in_selection(cx: &mut TestAppContext) {
265 let mut cx = setup_rust_context(cx).await;
266
267 cx.set_state("«√√√ˇ»");
268
269 cx.update_editor(|editor, window, cx| {
270 editor.toggle_block_comments(&ToggleBlockComments, window, cx);
271 });
272
273 cx.assert_editor_state("«/* √√√ */ˇ»");
274
275 cx.update_editor(|editor, window, cx| {
276 editor.toggle_block_comments(&ToggleBlockComments, window, cx);
277 });
278
279 cx.assert_editor_state("«√√√ˇ»");
280}
281
282#[gpui::test]
283async fn test_toggle_block_comments_cursor_inside_unicode_comment(cx: &mut TestAppContext) {
284 let mut cx = setup_rust_context(cx).await;
285
286 cx.set_state("/* √√√ˇ */");
287
288 cx.update_editor(|editor, window, cx| {
289 editor.toggle_block_comments(&ToggleBlockComments, window, cx);
290 });
291
292 cx.assert_editor_state("√√√ˇ");
293}