Fork of daniellemaywood.uk/gleam — Wasm codegen work
63 kB
3622 lines
1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: 2025 The Gleam contributors
3
4use std::collections::HashMap;
5
6use lsp_types::{
7 Position, PrepareRenameParams, PrepareRenamePlaceholder, Range, RenameParams,
8 TextDocumentPositionParams, Uri as Url, WorkDoneProgressParams, WorkspaceEdit,
9};
10
11use crate::url_from_path;
12
13use super::{TestProject, find_position_of, hover};
14
15/// Returns the rename range and edit to apply if the rename is valid and can be
16/// carried out.
17/// However if the rename produces an error response from the language server,
18/// the error message is returned.
19fn rename(
20 tester: &TestProject<'_>,
21 new_name: &str,
22 position: Position,
23) -> Result<Option<(Range, WorkspaceEdit)>, String> {
24 let prepare_rename_response = tester.at(position, |engine, params, _| {
25 let params = PrepareRenameParams {
26 text_document_position_params: TextDocumentPositionParams {
27 text_document: params.text_document,
28 position,
29 },
30 work_done_progress_params: WorkDoneProgressParams {
31 work_done_token: None,
32 },
33 };
34 engine.prepare_rename(params).result.unwrap()
35 });
36
37 let range = match prepare_rename_response {
38 Some(lsp_types::PrepareRenameResult::Range(range)) => range,
39 Some(lsp_types::PrepareRenameResult::PrepareRenamePlaceholder(
40 PrepareRenamePlaceholder { range, .. },
41 )) => range,
42 _ => return Ok(None),
43 };
44
45 let outcome = tester.at(position, |engine, params, _| {
46 let params = RenameParams {
47 text_document_position_params: TextDocumentPositionParams {
48 text_document: params.text_document,
49 position,
50 },
51 new_name: new_name.to_string(),
52 work_done_progress_params: WorkDoneProgressParams::default(),
53 };
54 engine.rename(params).result.unwrap()
55 });
56
57 match outcome {
58 Ok(Some(edit)) => Ok(Some((range, edit))),
59 Ok(None) => Ok(None),
60 Err(error) => Err(error.message),
61 }
62}
63
64fn rename_files(tester: &TestProject<'_>, renames: &[(&str, &str)]) -> HashMap<String, String> {
65 let edit = tester.run(|engine| {
66 let params = renames
67 .iter()
68 .map(|(old_name, new_name)| {
69 let old_url =
70 url_from_path(engine.path_for_module_name(old_name).as_str()).unwrap();
71 let new_url =
72 url_from_path(engine.path_for_module_name(new_name).as_str()).unwrap();
73 (old_url, new_url)
74 })
75 .collect();
76 engine.rename_files(params).result.unwrap()
77 });
78
79 let changes = edit
80 .expect("No text edit found")
81 .changes
82 .expect("No text edit found");
83
84 apply_code_edit(tester, changes)
85}
86
87fn apply_rename(
88 tester: &TestProject<'_>,
89 new_name: &str,
90 position: Position,
91) -> (Range, HashMap<String, String>) {
92 let (range, edit) = rename(tester, new_name, position)
93 .expect("Rename failed")
94 .expect("No rename produced");
95 let changes = edit.changes.expect("No text edit found");
96 (range, apply_code_edit(tester, changes))
97}
98
99fn apply_code_edit(
100 tester: &TestProject<'_>,
101 changes: HashMap<Url, Vec<lsp_types::TextEdit>>,
102) -> HashMap<String, String> {
103 let mut modules = HashMap::new();
104 for (uri, change) in changes {
105 let module_name = tester.module_name_from_url(&uri).expect("Valid uri");
106 let module_code = tester.src_from_module_url(&uri).expect("Module exists");
107
108 _ = modules.insert(module_name, super::apply_code_edit(module_code, change));
109 }
110
111 modules
112}
113
114fn display_result(
115 project: &TestProject<'_>,
116 modules: HashMap<String, String>,
117 renamed_modules: HashMap<&str, &str>,
118 range: Option<Range>,
119) -> String {
120 let mut output = String::from("----- BEFORE RENAME\n");
121 for (name, src) in project.root_package_modules.iter() {
122 output.push_str(&format!("-- {name}.gleam\n{src}\n\n"));
123 }
124
125 let src = project.src;
126 let app_src_before = if let Some(range) = range {
127 hover::show_hover(src, range, range.start)
128 } else {
129 src.to_string()
130 };
131 output.push_str(&format!(
132 "-- app.gleam\n{app_src_before}\n\n----- AFTER RENAME\n",
133 ));
134
135 for &(name, src) in project.root_package_modules.iter() {
136 let used_name = if let Some(new_name) = renamed_modules.get(name) {
137 new_name
138 } else {
139 name
140 };
141 output.push_str(&format!(
142 "-- {used_name}.gleam\n{}\n\n",
143 modules
144 .get(name)
145 .map(|string| string.as_str())
146 .unwrap_or(src)
147 ));
148 }
149 output.push_str(&format!(
150 "-- app.gleam\n{}",
151 modules
152 .get("app")
153 .map(|string| string.as_str())
154 .unwrap_or(src)
155 ));
156 output
157}
158
159macro_rules! assert_rename {
160 ($code:literal, $new_name:literal, $position:expr $(,)?) => {
161 assert_rename!(TestProject::for_source($code), $new_name, $position);
162 };
163
164 (($module_name:literal, $module_src:literal), $code:literal, $new_name:literal, $position:expr $(,)?) => {
165 assert_rename!(
166 TestProject::for_source($code).add_module($module_name, $module_src),
167 $new_name,
168 $position
169 );
170 };
171
172 ($project:expr, $new_name:literal, $position:expr $(,)?) => {
173 let project = $project;
174 let src = project.src;
175 let position = $position.find_position(src);
176 let (range, result) = apply_rename(&project, $new_name, position);
177
178 let output = display_result(&project, result, HashMap::new(), Some(range));
179
180 insta::assert_snapshot!(insta::internals::AutoName, output, src);
181 };
182}
183
184macro_rules! assert_no_rename {
185 ($code:literal, $new_name:literal, $position:expr $(,)?) => {
186 let project = TestProject::for_source($code);
187 assert_no_rename!(&project, $new_name, $position);
188 };
189
190 ($project:expr, $new_name:literal, $position:expr $(,)?) => {
191 let src = $project.src;
192 let position = $position.find_position(src);
193 let result = rename($project, $new_name, position);
194 assert_eq!(result, Ok(None));
195 };
196}
197
198macro_rules! assert_rename_error {
199 ($code:literal, $new_name:literal, $position:expr $(,)?) => {
200 let project = TestProject::for_source($code);
201 assert_rename_error!(&project, $new_name, $position);
202 };
203
204 ($project:expr, $new_name:literal, $position:expr $(,)?) => {
205 let src = $project.src;
206 let position = $position.find_position(src);
207 let error = rename($project, $new_name, position).unwrap_err();
208 let snapshot = format!("Error response message:\n\n{error}");
209 insta::assert_snapshot!(insta::internals::AutoName, snapshot, src);
210 };
211}
212
213macro_rules! assert_rename_files {
214 ($(($old_name:literal, $new_name:literal, $module_src:literal)),+, $code:literal, $(,)?) => {
215 let project = TestProject::for_source($code)$(.add_module($old_name, $module_src))*;
216
217 let renames = [$(($old_name, $new_name),)*];
218 let result = rename_files(&project, &renames);
219 let output = display_result(&project, result, renames.into(), None);
220
221 insta::assert_snapshot!(insta::internals::AutoName, output, project.src);
222 };
223}
224
225#[test]
226fn rename_local_variable() {
227 assert_rename!(
228 "
229pub fn main() {
230 let wibble = 10
231 wibble
232}
233",
234 "wobble",
235 find_position_of("wibble").nth_occurrence(2),
236 );
237}
238
239#[test]
240fn rename_shadowed_local_variable() {
241 assert_rename!(
242 "
243pub fn main() {
244 let wibble = 10
245 let wibble = wibble / 2
246 wibble
247}
248",
249 "wobble",
250 find_position_of("wibble /"),
251 );
252}
253
254#[test]
255fn rename_shadowing_local_variable() {
256 assert_rename!(
257 "
258pub fn main() {
259 let wibble = 10
260 let wibble = wibble / 2
261 wibble
262}
263",
264 "wobble",
265 find_position_of("wibble").nth_occurrence(4),
266 );
267}
268
269#[test]
270fn rename_local_variable_record_access() {
271 assert_rename!(
272 "
273type Wibble {
274 Wibble(wibble: Int)
275}
276
277pub fn main() {
278 let wibble = Wibble(wibble: 1)
279 wibble.wibble
280}
281",
282 "wobble",
283 find_position_of("wibble."),
284 );
285}
286#[test]
287fn rename_local_variable_guard_clause() {
288 assert_rename!(
289 "
290pub fn main() {
291 let wibble = True
292 case Nil {
293 Nil if wibble -> todo
294 _ -> panic
295 }
296 wibble || False
297}
298",
299 "wobble",
300 find_position_of("wibble ||"),
301 );
302}
303
304#[test]
305fn rename_local_variable_from_definition() {
306 assert_rename!(
307 "
308pub fn main() {
309 let wibble = 10
310 let wobble = wibble + 1
311 wobble - wibble
312}
313",
314 "some_value",
315 find_position_of("wibble =")
316 );
317}
318
319#[test]
320fn rename_local_variable_from_definition_nested_pattern() {
321 assert_rename!(
322 "
323pub fn main() {
324 let assert Ok([_, wibble, ..]) = Error(12)
325 wibble
326}
327",
328 "second_element",
329 find_position_of("wibble,")
330 );
331}
332
333#[test]
334fn rename_local_variable_assignment_pattern() {
335 assert_rename!(
336 "
337pub fn main() {
338 let assert Error(12 as something) = Error(12)
339 something
340}
341",
342 "the_error",
343 find_position_of("something").nth_occurrence(2)
344 );
345}
346
347#[test]
348fn rename_local_variable_from_definition_assignment_pattern() {
349 assert_rename!(
350 "
351pub fn main() {
352 let assert Error(12 as something) = Error(12)
353 something
354}
355",
356 "the_error",
357 find_position_of("something)")
358 );
359}
360
361#[test]
362fn rename_local_variable_argument() {
363 assert_rename!(
364 "
365pub fn add(first_number: Int, x: Int) -> Int {
366 x + first_number
367}
368",
369 "second_number",
370 find_position_of("x +")
371 );
372}
373
374#[test]
375fn rename_local_variable_argument_from_definition() {
376 assert_rename!(
377 "
378pub fn wibble(wibble: Float) {
379 wibble /. 0.3
380}
381",
382 "wobble",
383 find_position_of("wibble:")
384 );
385}
386
387#[test]
388fn rename_local_variable_label_shorthand() {
389 assert_rename!(
390 "
391type Wibble {
392 Wibble(wibble: Int)
393}
394
395pub fn main() {
396 let Wibble(wibble:) = todo
397 wibble + 1
398}
399",
400 "wobble",
401 find_position_of("wibble +")
402 );
403}
404
405#[test]
406fn rename_local_variable_label_shorthand_from_definition() {
407 assert_rename!(
408 "
409type Wibble {
410 Wibble(wibble: Int)
411}
412
413pub fn main() {
414 let Wibble(wibble:) = todo
415 wibble + 1
416}
417",
418 "wobble",
419 find_position_of("wibble:)")
420 );
421}
422
423#[test]
424fn rename_local_variable_from_label_shorthand() {
425 assert_rename!(
426 "
427type Wibble {
428 Wibble(wibble: Int)
429}
430
431pub fn main() {
432 let wibble = todo
433 Wibble(wibble:)
434}
435",
436 "wobble",
437 find_position_of("wibble:)")
438 );
439}
440
441#[test]
442fn rename_local_variable_in_bit_array_pattern() {
443 assert_rename!(
444 "
445pub fn starts_with(bits: BitArray, prefix: BitArray) -> Bool {
446 let prefix_size = bit_size(prefix)
447
448 case bits {
449 <<pref:bits-size(prefix_size), _:bits>> if pref == prefix -> True
450 _ -> False
451 }
452}
453",
454 "size_of_prefix",
455 find_position_of("prefix_size =")
456 );
457}
458
459#[test]
460fn rename_local_variable_from_bit_array_pattern() {
461 assert_rename!(
462 "
463pub fn starts_with(bits: BitArray, prefix: BitArray) -> Bool {
464 let prefix_size = bit_size(prefix)
465
466 case bits {
467 <<pref:bits-size(prefix_size), _:bits>> if pref == prefix -> True
468 _ -> False
469 }
470}
471",
472 "size_of_prefix",
473 find_position_of("prefix_size)")
474 );
475}
476
477#[test]
478fn no_rename_keyword() {
479 assert_no_rename!(
480 "
481pub fn main() {}
482",
483 "wibble",
484 find_position_of("fn"),
485 );
486}
487
488#[test]
489fn no_rename_invalid_name() {
490 assert_rename_error!(
491 "
492pub fn main() {
493 let wibble = 10
494 wibble
495}
496",
497 "Not_AValid_Name",
498 find_position_of("wibble").nth_occurrence(2)
499 );
500}
501
502#[test]
503fn rename_function_from_definition() {
504 assert_rename!(
505 (
506 "mod",
507 "
508import app
509
510fn wibble() {
511 app.something()
512}
513"
514 ),
515 "
516pub fn something() {
517 something()
518}
519
520fn something_else() {
521 something()
522}
523",
524 "some_function",
525 find_position_of("something")
526 );
527}
528
529#[test]
530fn rename_function_from_reference() {
531 assert_rename!(
532 (
533 "mod",
534 "
535import app
536
537fn wibble() {
538 app.something()
539}
540"
541 ),
542 "
543pub fn something() {
544 something()
545}
546
547fn something_else() {
548 something()
549}
550",
551 "some_function",
552 find_position_of("something").nth_occurrence(2)
553 );
554}
555
556#[test]
557fn rename_function_from_qualified_reference() {
558 assert_rename!(
559 (
560 "mod",
561 "
562pub fn wibble() {
563 wibble()
564}
565"
566 ),
567 "
568import mod
569
570pub fn main() {
571 mod.wibble()
572}
573",
574 "some_function",
575 find_position_of("wibble")
576 );
577}
578
579#[test]
580fn rename_function_from_unqualified_reference() {
581 assert_rename!(
582 (
583 "mod",
584 "
585pub fn wibble() {
586 wibble()
587}
588"
589 ),
590 "
591import mod.{wibble}
592
593pub fn main() {
594 wibble()
595 mod.wibble()
596}
597",
598 "some_function",
599 find_position_of("wibble(")
600 );
601}
602
603#[test]
604fn rename_function_from_import() {
605 assert_rename!(
606 (
607 "mod",
608 "
609pub fn wibble() {
610 wibble()
611}
612"
613 ),
614 "
615import mod.{wibble}
616
617pub fn main() {
618 wibble()
619 mod.wibble()
620}
621",
622 "some_function",
623 find_position_of("wibble")
624 );
625}
626
627#[test]
628fn rename_function_from_aliased_import() {
629 assert_rename!(
630 (
631 "mod",
632 "
633pub fn wibble() {
634 wibble()
635}
636"
637 ),
638 "
639import mod.{wibble as wobble}
640
641pub fn main() {
642 wobble()
643 mod.wibble()
644}
645",
646 "some_function",
647 find_position_of("wibble")
648 );
649}
650
651#[test]
652fn rename_function_from_aliased_import_to_original_name() {
653 assert_rename!(
654 (
655 "mod",
656 "
657pub fn wibble() {
658 wibble()
659}
660"
661 ),
662 "
663import mod.{wibble as wobble}
664
665pub fn main() {
666 wobble()
667 mod.wibble()
668}
669",
670 "wibble",
671 find_position_of("wibble")
672 );
673}
674
675#[test]
676fn rename_aliased_function() {
677 assert_rename!(
678 (
679 "mod",
680 "
681import app.{something as something_else}
682
683fn wibble() {
684 something_else()
685}
686"
687 ),
688 "
689pub fn something() {
690 something()
691}
692
693fn something_else() {
694 something()
695}
696",
697 "some_function",
698 find_position_of("something")
699 );
700}
701
702#[test]
703fn rename_function_shadowing_module() {
704 let src = "
705import gleam/list
706
707pub fn list() {
708 []
709}
710
711pub fn main() {
712 list.map(todo, todo)
713}
714 ";
715
716 assert_rename!(
717 TestProject::for_source(src).add_hex_module("gleam/list", "pub fn map(_, _) {}"),
718 "empty_list",
719 find_position_of("list()")
720 );
721}
722
723#[test]
724fn rename_function_shadowed_by_field_access() {
725 assert_rename!(
726 (
727 "mod",
728 "
729import app
730
731type App {
732 App(something: Int)
733}
734
735pub fn main() {
736 let app = App(10)
737 app.something
738}
739"
740 ),
741 "
742pub fn something() {
743 todo
744}
745",
746 "function",
747 find_position_of("something")
748 );
749}
750
751#[test]
752fn no_rename_function_with_invalid_name() {
753 assert_rename_error!(
754 "
755pub fn main() {
756 let wibble = 10
757 wibble
758}
759",
760 "Not_AValid_Name",
761 find_position_of("main")
762 );
763}
764
765#[test]
766fn no_rename_function_from_other_package() {
767 let src = "
768import wibble
769
770pub fn main() {
771 wibble.wobble()
772}
773";
774
775 assert_no_rename!(
776 &TestProject::for_source(src).add_hex_module("wibble", "pub fn wobble() { todo }"),
777 "something",
778 find_position_of("wobble")
779 );
780}
781
782#[test]
783fn rename_constant_from_definition() {
784 assert_rename!(
785 (
786 "mod",
787 "
788import app
789
790fn wibble() {
791 app.something
792}
793"
794 ),
795 "
796pub const something = 10
797
798pub fn main() {
799 something + { 4 * something }
800}
801",
802 "ten",
803 find_position_of("something")
804 );
805}
806
807#[test]
808fn rename_constant_from_reference() {
809 assert_rename!(
810 (
811 "mod",
812 "
813import app
814
815fn wibble() {
816 app.something
817}
818"
819 ),
820 "
821pub const something = 10
822
823pub fn main() {
824 something + { 4 * something }
825}
826",
827 "ten",
828 find_position_of("something").nth_occurrence(2)
829 );
830}
831
832#[test]
833fn rename_constant_from_qualified_reference() {
834 assert_rename!(
835 (
836 "mod",
837 "
838pub const something = 10
839
840fn wibble() {
841 something
842}
843"
844 ),
845 "
846import mod
847
848pub fn main() {
849 mod.something
850}
851",
852 "ten",
853 find_position_of("something")
854 );
855}
856
857#[test]
858fn rename_constant_from_unqualified_reference() {
859 assert_rename!(
860 (
861 "mod",
862 "
863pub const something = 10
864
865fn wibble() {
866 something
867}
868"
869 ),
870 "
871import mod.{something}
872
873pub fn main() {
874 something + mod.something
875}
876",
877 "ten",
878 find_position_of("something +")
879 );
880}
881
882#[test]
883fn rename_constant_from_import() {
884 assert_rename!(
885 (
886 "mod",
887 "
888pub const something = 10
889
890fn wibble() {
891 something
892}
893"
894 ),
895 "
896import mod.{something}
897
898pub fn main() {
899 something + mod.something
900}
901",
902 "ten",
903 find_position_of("something")
904 );
905}
906
907#[test]
908fn rename_constant_from_aliased_import() {
909 assert_rename!(
910 (
911 "mod",
912 "
913pub const something = 10
914
915fn wibble() {
916 something
917}
918"
919 ),
920 "
921import mod.{something as smth}
922
923pub fn main() {
924 smth + mod.something
925}
926",
927 "ten",
928 find_position_of("something")
929 );
930}
931
932#[test]
933fn rename_constant_from_aliased_import_to_original_name() {
934 assert_rename!(
935 (
936 "mod",
937 "
938pub const something = 10
939
940fn wibble() {
941 something
942}
943"
944 ),
945 "
946import mod.{something as smth}
947
948pub fn main() {
949 smth + mod.something
950}
951",
952 "something",
953 find_position_of("something")
954 );
955}
956
957#[test]
958fn rename_aliased_constant() {
959 assert_rename!(
960 (
961 "mod",
962 "
963import app.{something as some_constant}
964
965fn wibble() {
966 some_constant
967}
968"
969 ),
970 "
971pub const something = 10
972
973pub fn main() {
974 something + { 4 * something }
975}
976",
977 "ten",
978 find_position_of("something")
979 );
980}
981
982#[test]
983fn rename_constant_shadowing_module() {
984 let src = "
985import gleam/list
986
987const list = []
988
989pub fn main() {
990 list.map(todo, todo)
991}
992 ";
993
994 assert_rename!(
995 TestProject::for_source(src).add_hex_module("gleam/list", "pub fn map(_, _) {}"),
996 "empty_list",
997 find_position_of("list =")
998 );
999}
1000
1001#[test]
1002fn rename_constant_shadowed_by_field_access() {
1003 assert_rename!(
1004 (
1005 "mod",
1006 "
1007import app
1008
1009type App {
1010 App(something: Int)
1011}
1012
1013pub fn main() {
1014 let app = App(10)
1015 app.something
1016}
1017"
1018 ),
1019 "
1020pub const something = 10
1021",
1022 "constant",
1023 find_position_of("something")
1024 );
1025}
1026
1027#[test]
1028fn no_rename_constant_with_invalid_name() {
1029 assert_rename_error!(
1030 "
1031const value = 10
1032",
1033 "Ten",
1034 find_position_of("value")
1035 );
1036}
1037
1038#[test]
1039fn no_rename_constant_from_other_package() {
1040 let src = "
1041import wibble
1042
1043pub fn main() {
1044 wibble.wobble
1045}
1046";
1047
1048 assert_no_rename!(
1049 &TestProject::for_source(src).add_hex_module("wibble", "pub const wobble = 2"),
1050 "something",
1051 find_position_of("wobble")
1052 );
1053}
1054
1055#[test]
1056fn rename_type_variant_from_definition() {
1057 assert_rename!(
1058 (
1059 "mod",
1060 "
1061import app
1062
1063fn wibble() {
1064 app.Constructor(4)
1065}
1066"
1067 ),
1068 "
1069pub type Wibble {
1070 Constructor(Int)
1071}
1072
1073pub fn main() {
1074 Constructor(10)
1075}
1076",
1077 "Wibble",
1078 find_position_of("Constructor(Int")
1079 );
1080}
1081
1082#[test]
1083fn rename_type_variant_from_reference() {
1084 assert_rename!(
1085 (
1086 "mod",
1087 "
1088import app
1089
1090fn wibble() {
1091 app.Constructor(4)
1092}
1093"
1094 ),
1095 "
1096pub type Wibble {
1097 Constructor(Int)
1098}
1099
1100pub fn main() {
1101 Constructor(10)
1102}
1103",
1104 "Wibble",
1105 find_position_of("Constructor(10")
1106 );
1107}
1108
1109#[test]
1110fn rename_type_variant_from_qualified_reference() {
1111 assert_rename!(
1112 (
1113 "mod",
1114 "
1115pub type Wibble {
1116 Constructor(Int)
1117}
1118
1119fn wibble() {
1120 Constructor(42)
1121}
1122"
1123 ),
1124 "
1125import mod
1126
1127pub fn main() {
1128 mod.Constructor
1129}
1130",
1131 "Variant",
1132 find_position_of("Constructor")
1133 );
1134}
1135
1136#[test]
1137fn rename_type_variant_from_unqualified_reference() {
1138 assert_rename!(
1139 (
1140 "mod",
1141 "
1142pub type Wibble {
1143 Constructor(Int)
1144}
1145
1146fn wibble() {
1147 Constructor(81)
1148}
1149"
1150 ),
1151 "
1152import mod.{Constructor}
1153
1154pub fn main() {
1155 #(Constructor(75), mod.Constructor(57))
1156}
1157",
1158 "Number",
1159 find_position_of("Constructor(75")
1160 );
1161}
1162
1163#[test]
1164fn rename_type_variant_from_import() {
1165 assert_rename!(
1166 (
1167 "mod",
1168 "
1169pub type Wibble {
1170 Constructor(Int)
1171}
1172
1173fn wibble() {
1174 Constructor(81)
1175}
1176"
1177 ),
1178 "
1179import mod.{Constructor}
1180
1181pub fn main() {
1182 #(Constructor(75), mod.Constructor(57))
1183}
1184",
1185 "Number",
1186 find_position_of("Constructor")
1187 );
1188}
1189
1190#[test]
1191fn rename_type_variant_from_aliased_import() {
1192 assert_rename!(
1193 (
1194 "mod",
1195 "
1196pub type Wibble {
1197 Constructor(Int)
1198}
1199
1200fn wibble() {
1201 Constructor(81)
1202}
1203"
1204 ),
1205 "
1206import mod.{Constructor as C}
1207
1208pub fn main() {
1209 #(C(75), mod.Constructor(57))
1210}
1211",
1212 "Number",
1213 find_position_of("Constructor")
1214 );
1215}
1216
1217#[test]
1218fn rename_type_variant_from_aliased_import_to_original_name() {
1219 assert_rename!(
1220 (
1221 "mod",
1222 "
1223pub type Wibble {
1224 Constructor(Int)
1225}
1226
1227fn wibble() {
1228 Constructor(81)
1229}
1230"
1231 ),
1232 "
1233import mod.{Constructor as C}
1234
1235pub fn main() {
1236 #(C(75), mod.Constructor(57))
1237}
1238",
1239 "Constructor",
1240 find_position_of("Constructor")
1241 );
1242}
1243
1244#[test]
1245fn rename_aliased_type_variant() {
1246 assert_rename!(
1247 (
1248 "mod",
1249 "
1250import app.{Constructor as ValueConstructor}
1251
1252fn wibble() {
1253 ValueConstructor(172)
1254}
1255"
1256 ),
1257 "
1258pub type Wibble {
1259 Constructor(Int)
1260}
1261
1262pub fn main() {
1263 Constructor(42)
1264}
1265",
1266 "MakeAWibble",
1267 find_position_of("Constructor")
1268 );
1269}
1270
1271#[test]
1272fn no_rename_type_variant_with_invalid_name() {
1273 assert_rename_error!(
1274 "
1275pub type Wibble {
1276 Constructor(Int)
1277}
1278",
1279 "name_in_snake_case",
1280 find_position_of("Constructor")
1281 );
1282}
1283
1284#[test]
1285fn rename_custom_type_variant_pattern() {
1286 assert_rename!(
1287 "
1288pub type Type {
1289 X
1290 Y
1291}
1292
1293pub fn main(t) {
1294 case t {
1295 X -> 0
1296 Y -> 0
1297 }
1298}
1299",
1300 "Renamed",
1301 find_position_of("X")
1302 );
1303}
1304
1305#[test]
1306fn rename_imported_custom_type_variant_pattern() {
1307 assert_rename!(
1308 (
1309 "other",
1310 "
1311import app
1312
1313pub fn main(t) {
1314 case t {
1315 app.X -> 0
1316 app.Y -> 0
1317 }
1318}
1319"
1320 ),
1321 "
1322pub type Type {
1323 X
1324 Y
1325}
1326",
1327 "Renamed",
1328 find_position_of("X")
1329 );
1330}
1331
1332#[test]
1333fn rename_imported_unqualified_custom_type_variant_pattern() {
1334 assert_rename!(
1335 (
1336 "other",
1337 "
1338import app.{X, Y}
1339
1340pub fn main(t) {
1341 case t {
1342 X -> 0
1343 Y -> 0
1344 }
1345}
1346"
1347 ),
1348 "
1349pub type Type {
1350 X
1351 Y
1352}
1353",
1354 "Renamed",
1355 find_position_of("X")
1356 );
1357}
1358
1359#[test]
1360fn rename_type_variant_pattern_with_arguments() {
1361 assert_rename!(
1362 "
1363pub type Wibble {
1364 Wibble(Int)
1365 Wobble(Float)
1366}
1367
1368fn wibble() {
1369 case Wibble(10) {
1370 Wibble(20) -> todo
1371 Wibble(_) -> panic
1372 }
1373}
1374",
1375 "Variant",
1376 find_position_of("Wibble(10)")
1377 );
1378}
1379
1380#[test]
1381fn rename_type_variant_from_pattern() {
1382 assert_rename!(
1383 "
1384pub type Type {
1385 X
1386 Y
1387}
1388
1389pub fn main(t) {
1390 case t {
1391 X -> 0
1392 Y -> 0
1393 }
1394}
1395",
1396 "Renamed",
1397 find_position_of("X ->")
1398 );
1399}
1400
1401#[test]
1402fn no_rename_type_variant_from_other_package() {
1403 let src = "
1404import wibble
1405
1406pub fn main() {
1407 wibble.Wibble(10)
1408}
1409";
1410
1411 assert_no_rename!(
1412 &TestProject::for_source(src).add_hex_module("wibble", "pub type Wibble { Wibble(Int) }"),
1413 "Constructor",
1414 find_position_of("Wibble")
1415 );
1416}
1417
1418#[test]
1419fn rename_value_in_nested_module() {
1420 assert_rename!(
1421 (
1422 "sub/mod",
1423 "
1424pub fn wibble() {
1425 wibble()
1426}
1427"
1428 ),
1429 "
1430import sub/mod
1431
1432pub fn main() {
1433 mod.wibble()
1434}
1435",
1436 "some_function",
1437 find_position_of("wibble")
1438 );
1439}
1440
1441#[test]
1442fn rename_value_in_aliased_module() {
1443 assert_rename!(
1444 (
1445 "mod",
1446 "
1447pub fn wibble() {
1448 wibble()
1449}
1450"
1451 ),
1452 "
1453import mod as the_module
1454
1455pub fn main() {
1456 the_module.wibble()
1457}
1458",
1459 "some_function",
1460 find_position_of("wibble")
1461 );
1462}
1463
1464#[test]
1465fn rename_aliased_value() {
1466 assert_rename!(
1467 (
1468 "mod",
1469 "
1470import app.{Wibble as Wobble}
1471
1472fn wobble() {
1473 Wobble
1474}
1475"
1476 ),
1477 "
1478pub type Wibble { Wibble }
1479
1480pub fn main() {
1481 Wibble
1482}
1483",
1484 "Wubble",
1485 find_position_of("Wibble }")
1486 );
1487}
1488
1489#[test]
1490fn rename_type_from_definition() {
1491 assert_rename!(
1492 (
1493 "mod",
1494 "
1495import app
1496
1497fn wibble() -> app.Wibble { todo }
1498"
1499 ),
1500 "
1501pub type Wibble { Constructor }
1502
1503pub fn main(w: Wibble) -> Wibble { todo }
1504",
1505 "SomeType",
1506 find_position_of("Wibble")
1507 );
1508}
1509
1510#[test]
1511fn rename_type_from_reference() {
1512 assert_rename!(
1513 (
1514 "mod",
1515 "
1516import app
1517
1518fn wibble() -> app.Wibble { todo }
1519"
1520 ),
1521 "
1522pub type Wibble { Constructor }
1523
1524pub fn main(w: Wibble) -> Wibble { todo }
1525",
1526 "SomeType",
1527 find_position_of("Wibble").nth_occurrence(2)
1528 );
1529}
1530
1531#[test]
1532fn rename_type_from_qualified_reference() {
1533 assert_rename!(
1534 (
1535 "mod",
1536 "
1537pub type Wibble { Constructor }
1538
1539fn wibble(w: Wibble) -> Wibble { todo }
1540"
1541 ),
1542 "
1543import mod
1544
1545pub fn main(w: mod.Wibble) -> mod.Wibble { todo }
1546",
1547 "SomeType",
1548 find_position_of("Wibble")
1549 );
1550}
1551
1552#[test]
1553fn rename_type_from_unqualified_reference() {
1554 assert_rename!(
1555 (
1556 "mod",
1557 "
1558pub type Wibble { Constructor }
1559
1560fn wibble(w: Wibble) -> Wibble { todo }
1561"
1562 ),
1563 "
1564import mod.{type Wibble}
1565
1566pub fn main(w: Wibble) -> mod.Wibble { todo }
1567",
1568 "SomeType",
1569 find_position_of("Wibble)")
1570 );
1571}
1572
1573#[test]
1574fn rename_type_from_import() {
1575 assert_rename!(
1576 (
1577 "mod",
1578 "
1579pub type Wibble { Constructor }
1580
1581fn wibble(w: Wibble) -> Wibble { todo }
1582"
1583 ),
1584 "
1585import mod.{type Wibble}
1586
1587pub fn main(w: Wibble) -> mod.Wibble { todo }
1588",
1589 "SomeType",
1590 find_position_of("Wibble")
1591 );
1592}
1593
1594#[test]
1595fn rename_type_from_aliased_import() {
1596 assert_rename!(
1597 (
1598 "mod",
1599 "
1600pub type Wibble { Constructor }
1601
1602fn wibble(w: Wibble) -> Wibble { todo }
1603"
1604 ),
1605 "
1606import mod.{type Wibble as Wobble}
1607
1608pub fn main(w: Wobble) -> mod.Wibble { todo }
1609",
1610 "SomeType",
1611 find_position_of("Wibble")
1612 );
1613}
1614
1615#[test]
1616fn rename_type_from_aliased_import_to_original_name() {
1617 assert_rename!(
1618 (
1619 "mod",
1620 "
1621pub type Wibble { Constructor }
1622
1623fn wibble(w: Wibble) -> Wibble { todo }
1624"
1625 ),
1626 "
1627import mod.{type Wibble as Wobble}
1628
1629pub fn main(w: Wobble) -> mod.Wibble { todo }
1630",
1631 "Wibble",
1632 find_position_of("Wibble")
1633 );
1634}
1635
1636#[test]
1637fn rename_aliased_type() {
1638 assert_rename!(
1639 (
1640 "mod",
1641 "
1642import app.{type Wibble as Wobble}
1643
1644fn wibble() -> Wobble { todo }
1645"
1646 ),
1647 "
1648pub type Wibble { Constructor }
1649
1650pub fn main(w: Wibble) -> Wibble { todo }
1651",
1652 "SomeType",
1653 find_position_of("Wibble")
1654 );
1655}
1656
1657#[test]
1658fn no_rename_type_with_invalid_name() {
1659 assert_rename_error!(
1660 "
1661type Wibble { Wobble }
1662",
1663 "a_type_name",
1664 find_position_of("Wibble")
1665 );
1666}
1667
1668#[test]
1669fn no_rename_type_from_other_package() {
1670 let src = "
1671import wibble
1672
1673pub fn main() -> wibble.Wibble { todo }
1674";
1675
1676 assert_no_rename!(
1677 &TestProject::for_source(src).add_hex_module("wibble", "pub type Wibble { Wibble }"),
1678 "SomeType",
1679 find_position_of("Wibble")
1680 );
1681}
1682
1683// https://github.com/gleam-lang/gleam/issues/4372
1684#[test]
1685fn rename_type_referenced_in_variant_constructor_argument() {
1686 assert_rename!(
1687 (
1688 "mod",
1689 "
1690import app
1691
1692pub type Wobble {
1693 Wobble(w: app.Wibble)
1694}
1695"
1696 ),
1697 "
1698pub type Wibble {
1699 Wibble
1700}
1701
1702pub fn main() {
1703 let wibble = Wibble
1704}
1705",
1706 "SomeType",
1707 find_position_of("Wibble")
1708 );
1709}
1710
1711// https://github.com/gleam-lang/gleam/issues/4372
1712#[test]
1713fn rename_type_from_variant_constructor_argument() {
1714 assert_rename!(
1715 (
1716 "mod",
1717 "
1718pub type Wibble {
1719 Wibble
1720}
1721
1722pub fn main() {
1723 let wibble = Wibble
1724}
1725"
1726 ),
1727 "
1728import mod
1729
1730pub type Wobble {
1731 Wobble(w: mod.Wibble)
1732}
1733",
1734 "SomeType",
1735 find_position_of("Wibble")
1736 );
1737}
1738
1739// https://github.com/gleam-lang/gleam/issues/4553
1740#[test]
1741fn rename_local_variable_with_label_shorthand() {
1742 assert_rename!(
1743 "
1744pub type Wibble {
1745 Wibble(first: Int, second: Int)
1746}
1747
1748pub fn main() {
1749 let second = 2
1750 Wibble(first: 1, second:)
1751}
1752",
1753 "something",
1754 find_position_of("second =")
1755 );
1756}
1757
1758// https://github.com/gleam-lang/gleam/issues/4748
1759#[test]
1760fn rename_alternative_pattern() {
1761 assert_rename!(
1762 "
1763pub fn main(x) {
1764 case x {
1765 #(wibble, [wobble]) | #(wobble, [wibble, _]) | #(_, [wibble, wobble, ..]) ->
1766 wibble + wobble
1767 _ -> 0
1768 }
1769}
1770",
1771 "new_name",
1772 find_position_of("wibble")
1773 );
1774}
1775
1776// https://github.com/gleam-lang/gleam/issues/5091
1777#[test]
1778fn rename_alternative_pattern_aliases() {
1779 assert_rename!(
1780 "
1781pub fn main(x) {
1782 case x {
1783 [] as list | [_] as list -> list
1784 _ -> []
1785 }
1786}
1787",
1788 "new_name",
1789 find_position_of("list")
1790 );
1791}
1792
1793#[test]
1794fn rename_alternative_pattern_aliases_from_alternative() {
1795 assert_rename!(
1796 "
1797pub fn main(x) {
1798 case x {
1799 [] as list | [_] as list -> list
1800 _ -> []
1801 }
1802}
1803",
1804 "new_name",
1805 find_position_of("list").nth_occurrence(2)
1806 );
1807}
1808
1809#[test]
1810fn rename_alternative_pattern_aliases_from_usage() {
1811 assert_rename!(
1812 "
1813pub fn main(x) {
1814 case x {
1815 [] as list | [_] as list -> list
1816 _ -> []
1817 }
1818}
1819",
1820 "new_name",
1821 find_position_of("list").nth_occurrence(3)
1822 );
1823}
1824
1825#[test]
1826fn rename_alternative_pattern_alias_and_variable_1() {
1827 assert_rename!(
1828 "
1829pub fn main(x) {
1830 case x {
1831 [] as list | [_, ..list] -> list
1832 _ -> []
1833 }
1834}
1835",
1836 "new_name",
1837 find_position_of("list").nth_occurrence(1)
1838 );
1839}
1840
1841#[test]
1842fn rename_alternative_pattern_alias_and_variable_2() {
1843 assert_rename!(
1844 "
1845pub fn main(x) {
1846 case x {
1847 [] as list | [_, ..list] -> list
1848 _ -> []
1849 }
1850}
1851",
1852 "new_name",
1853 find_position_of("list").nth_occurrence(2)
1854 );
1855}
1856
1857#[test]
1858fn rename_alternative_pattern_alias_and_variable_3() {
1859 assert_rename!(
1860 "
1861pub fn main(x) {
1862 case x {
1863 [_, ..list] | [] as list -> list
1864 _ -> []
1865 }
1866}
1867",
1868 "new_name",
1869 find_position_of("list").nth_occurrence(1)
1870 );
1871}
1872
1873#[test]
1874fn rename_alternative_pattern_alias_and_variable_4() {
1875 assert_rename!(
1876 "
1877pub fn main(x) {
1878 case x {
1879 [_, ..list] | [] as list -> list
1880 _ -> []
1881 }
1882}
1883",
1884 "new_name",
1885 find_position_of("list").nth_occurrence(2)
1886 );
1887}
1888
1889#[test]
1890fn rename_alternative_pattern_from_usage() {
1891 assert_rename!(
1892 "
1893pub fn main(x) {
1894 case x {
1895 #(wibble, [wobble]) | #(wobble, [wibble, _]) | #(_, [wibble, wobble, ..]) ->
1896 wibble + wobble
1897 _ -> 0
1898 }
1899}
1900",
1901 "new_name",
1902 find_position_of("wibble +")
1903 );
1904}
1905
1906// https://github.com/gleam-lang/gleam/issues/4605
1907#[test]
1908fn rename_prelude_value() {
1909 assert_rename!(
1910 "
1911pub fn main() {
1912 Ok(10)
1913}
1914",
1915 "Success",
1916 find_position_of("Ok")
1917 );
1918}
1919#[test]
1920fn rename_prelude_type() {
1921 assert_rename!(
1922 "
1923pub fn main() -> Result(Int, Nil) {
1924 Ok(10)
1925}
1926",
1927 "SuccessOrFailure",
1928 find_position_of("Result")
1929 );
1930}
1931
1932#[test]
1933fn rename_variable_with_alternative_pattern_with_same_name() {
1934 assert_rename!(
1935 "
1936pub fn main(x) {
1937 let some_var = 10
1938
1939 case x {
1940 #(some_var, []) | #(_, [some_var]) ->
1941 some_var
1942 _ -> 0
1943 }
1944
1945 some_var
1946}
1947",
1948 "new_name",
1949 find_position_of("some_var")
1950 );
1951}
1952
1953#[test]
1954fn rename_prelude_value_with_prelude_already_imported() {
1955 assert_rename!(
1956 "
1957import gleam
1958
1959pub fn main() {
1960 Ok(gleam.Error(10))
1961}
1962",
1963 "Success",
1964 find_position_of("Ok")
1965 );
1966}
1967
1968#[test]
1969fn rename_prelude_value_with_prelude_import_with_empty_braces() {
1970 assert_rename!(
1971 "
1972import gleam.{}
1973
1974pub fn main() {
1975 Ok(gleam.Error(10))
1976}
1977",
1978 "Success",
1979 find_position_of("Ok")
1980 );
1981}
1982
1983#[test]
1984fn rename_prelude_value_with_other_prelude_value_imported() {
1985 assert_rename!(
1986 "
1987import gleam.{Error}
1988
1989pub fn main() {
1990 Ok(Error(10))
1991}
1992",
1993 "Success",
1994 find_position_of("Ok")
1995 );
1996}
1997
1998#[test]
1999fn rename_prelude_type_with_prelude_value_imported_with_trailing_comma() {
2000 assert_rename!(
2001 "
2002import gleam.{Error,}
2003
2004pub fn main() -> Result(Int, Nil) {
2005 Error(10)
2006}
2007",
2008 "OkOrError",
2009 find_position_of("Result")
2010 );
2011}
2012
2013#[test]
2014fn rename_prelude_value_with_other_module_imported() {
2015 assert_rename!(
2016 ("something", "pub type Something"),
2017 "
2018import something
2019
2020pub fn main() {
2021 Ok(10)
2022}
2023",
2024 "Success",
2025 find_position_of("Ok")
2026 );
2027}
2028
2029#[test]
2030fn rename_module_access_in_clause_guard() {
2031 assert_rename!(
2032 (
2033 "wibble",
2034 "
2035import app
2036
2037pub fn main() {
2038 case app.something {
2039 thing if thing == app.something -> True
2040 _ -> False
2041 }
2042}
2043"
2044 ),
2045 "
2046pub const something = 10
2047",
2048 "new_name",
2049 find_position_of("something")
2050 );
2051}
2052
2053#[test]
2054fn rename_variable_used_in_record_update() {
2055 assert_rename!(
2056 "
2057type Wibble {
2058 Wibble(a: Int, b: Int, c: Int)
2059}
2060
2061fn wibble(wibble: Wibble) {
2062 Wibble(..wibble, c: 1)
2063}
2064",
2065 "value",
2066 find_position_of("wibble:")
2067 );
2068}
2069
2070//https://github.com/gleam-lang/gleam/issues/4941
2071#[test]
2072fn rename_external_function() {
2073 assert_rename!(
2074 r#"
2075pub fn main() { wibble() }
2076
2077@external(erlang, "a", "a")
2078fn wibble() -> Nil
2079"#,
2080 "new_name",
2081 find_position_of("wibble").nth_occurrence(2)
2082 );
2083}
2084
2085#[test]
2086fn rename_external_javascript_function_with_pure_gleam_fallback() {
2087 assert_rename!(
2088 r#"
2089pub fn main() { wibble() }
2090
2091@external(javascript, "a", "a")
2092fn wibble() -> Nil {
2093 Nil
2094}
2095"#,
2096 "new_name",
2097 find_position_of("wibble").nth_occurrence(2)
2098 );
2099}
2100
2101#[test]
2102fn rename_nested_aliased_pattern() {
2103 assert_rename!(
2104 r#"
2105pub fn go(x) {
2106 case x {
2107 [[nested, ..] as wibble, ..] -> todo
2108 _ -> todo
2109 }
2110}
2111 "#,
2112 "new_name",
2113 find_position_of("nested")
2114 );
2115}
2116
2117#[test]
2118fn rename_module_from_import() {
2119 assert_rename!(
2120 TestProject::for_source("import option")
2121 .add_module("option", "pub type Option(a) { Some(a) None }"),
2122 "opt",
2123 find_position_of("option"),
2124 );
2125}
2126
2127#[test]
2128fn rename_works_when_error_is_present() {
2129 assert_rename!(
2130 r#"
2131fn wibble() {
2132 "test string"
2133}
2134
2135pub fn main() {
2136 1 + "1"
2137 echo wibble()
2138}
2139 "#,
2140 "wobble",
2141 find_position_of("wibble")
2142 );
2143}
2144
2145#[test]
2146fn rename_module_from_import_with_alias() {
2147 assert_rename!(
2148 TestProject::for_source("import option as opt")
2149 .add_module("option", "pub type Option(a) { Some(a) None }"),
2150 "o",
2151 find_position_of("opt"),
2152 );
2153}
2154
2155#[test]
2156fn reanem_module_from_import_with_unqualified_values() {
2157 assert_rename!(
2158 TestProject::for_source("import option . { Some, None }")
2159 .add_module("option", "pub type Option(a) { Some(a) None }"),
2160 "opt",
2161 find_position_of("option"),
2162 );
2163}
2164
2165#[test]
2166fn rename_module_from_import_with_unqualified_value_and_alias() {
2167 assert_rename!(
2168 TestProject::for_source("import option . {Some, None} as opt")
2169 .add_module("option", "pub type Option(a) { Some(a) None }"),
2170 "o",
2171 find_position_of("opt"),
2172 );
2173}
2174
2175#[test]
2176fn rename_module_from_import_namespaced() {
2177 assert_rename!(
2178 TestProject::for_source("import std / option ")
2179 .add_module("std/option", "pub type Option(a) { Some(a) None }"),
2180 "opt",
2181 find_position_of("option"),
2182 );
2183}
2184
2185#[test]
2186fn rename_module_from_import_namespaced_with_alias() {
2187 assert_rename!(
2188 TestProject::for_source("import std / option as opt")
2189 .add_module("std/option", "pub type Option(a) { Some(a) None }"),
2190 "o",
2191 find_position_of("opt"),
2192 );
2193}
2194
2195#[test]
2196fn rename_module_from_import_namespaced_with_unqualified_values() {
2197 assert_rename!(
2198 TestProject::for_source("import std / option . { Some, None }")
2199 .add_module("std/option", "pub type Option(a) { Some(a) None }"),
2200 "opt",
2201 find_position_of("option"),
2202 );
2203}
2204
2205#[test]
2206fn rename_module_from_import_namespaced_with_unqualified_value_and_alias() {
2207 assert_rename!(
2208 TestProject::for_source("import std / option . { Some, None } as opt")
2209 .add_module("std/option", "pub type Option(a) { Some(a) None }"),
2210 "o",
2211 find_position_of("opt"),
2212 );
2213}
2214
2215#[test]
2216fn rename_module_from_import_with_alias_to_original_name() {
2217 assert_rename!(
2218 TestProject::for_source("import option as opt")
2219 .add_module("option", "pub type Option(a) { Some(a) None }"),
2220 "option",
2221 find_position_of("opt"),
2222 );
2223}
2224
2225#[test]
2226fn rename_module_from_variant_in_expression() {
2227 let src = r#"
2228import option
2229
2230pub fn main() {
2231 echo option . None
2232}
2233"#;
2234 assert_rename!(
2235 TestProject::for_source(src).add_module("option", "pub type Option(a) { Some(a) None }"),
2236 "opt",
2237 find_position_of("option").nth_occurrence(2)
2238 );
2239}
2240
2241#[test]
2242fn rename_prefix_string_suffix_variable_in_case() {
2243 assert_rename!(
2244 "
2245fn main() -> String {
2246 let wibble = \"1-wibble\"
2247 case wibble {
2248 \"1\" <> rest -> rest
2249 other -> other
2250 }
2251}
2252",
2253 "new_name",
2254 find_position_of("rest").nth_occurrence(1)
2255 );
2256}
2257
2258#[test]
2259fn rename_module_from_constant_in_expression() {
2260 let src = r#"
2261import maths
2262
2263pub fn main() {
2264 echo maths . pi
2265}
2266"#;
2267
2268 assert_rename!(
2269 TestProject::for_source(src).add_module("maths", "pub const pi = 3.14"),
2270 "m",
2271 find_position_of("maths").nth_occurrence(2),
2272 );
2273}
2274
2275#[test]
2276fn rename_module_from_variant_in_const() {
2277 let src = r#"
2278import option
2279
2280const x = option .None
2281"#;
2282
2283 assert_rename!(
2284 TestProject::for_source(src).add_module("option", "pub type Option(a) { Some(a) None }"),
2285 "opt",
2286 find_position_of("option").nth_occurrence(2),
2287 );
2288}
2289
2290#[test]
2291fn rename_module_from_constant_in_const() {
2292 let src = r#"
2293import maths
2294
2295const x = maths . pi
2296"#;
2297
2298 assert_rename!(
2299 TestProject::for_source(src).add_module("maths", "pub const pi = 3.14"),
2300 "m",
2301 find_position_of("maths").nth_occurrence(2),
2302 );
2303}
2304
2305#[test]
2306fn rename_module_from_variant_in_pattern() {
2307 let src = r#"
2308import option
2309
2310pub fn is_some(option) {
2311 case option {
2312 option. Some(_) -> True
2313 option .None -> False
2314 }
2315}
2316"#;
2317
2318 assert_rename!(
2319 TestProject::for_source(src).add_module("option", "pub type Option(a) { Some(a) None }"),
2320 "opt",
2321 find_position_of("option").nth_occurrence(4),
2322 );
2323}
2324
2325#[test]
2326fn rename_prefix_string_suffix_variable_in_case_triggered_from_usage() {
2327 assert_rename!(
2328 "
2329fn main() -> String {
2330 let wibble = \"1-wibble\"
2331 case wibble {
2332 \"1\" <> rest -> rest
2333 other -> other
2334 }
2335}
2336",
2337 "new_name",
2338 find_position_of("rest").nth_occurrence(2)
2339 );
2340}
2341
2342#[test]
2343fn rename_module_from_variant_in_clause_guard() {
2344 let src = r#"
2345import option
2346
2347pub fn count_none(list) {
2348 case list {
2349 [option, ..rest] if option == option . None -> 1 + count_none(rest)
2350 [_, ..rest] -> count_none(rest)
2351 [] -> 0
2352 }
2353}
2354"#;
2355
2356 assert_rename!(
2357 TestProject::for_source(src).add_module("option", "pub type Option(a) { Some(a) None }"),
2358 "opt",
2359 find_position_of("option").nth_occurrence(4),
2360 );
2361}
2362
2363#[test]
2364fn rename_prefix_string_suffix_variable_with_alternative_definition_in_case() {
2365 assert_rename!(
2366 "
2367fn main() -> String {
2368 let wibble = \"1-wibble\"
2369 case wibble {
2370 \"1\" <> rest | \"2\" <> rest -> rest
2371 other -> other
2372 }
2373}
2374",
2375 "new_name",
2376 find_position_of("rest").nth_occurrence(1),
2377 );
2378}
2379
2380#[test]
2381fn rename_module_from_constant_in_clause_guard() {
2382 let src = r#"
2383import maths
2384
2385pub fn count_pi(list) {
2386 case list {
2387 [number, ..rest] if number == maths . pi -> 1 + count_pi(rest)
2388 [_, ..rest] -> count_pi(rest)
2389 [] -> 0
2390 }
2391}
2392"#;
2393
2394 assert_rename!(
2395 TestProject::for_source(src).add_module("maths", "pub const pi = 3.14"),
2396 "m",
2397 find_position_of("maths").nth_occurrence(2),
2398 );
2399}
2400
2401#[test]
2402fn rename_prefix_string_suffix_variable_with_alternative_definition_triggered_from_second_pattern()
2403{
2404 assert_rename!(
2405 "
2406fn main() -> String {
2407 let wibble = \"1-wibble\"
2408 case wibble {
2409 \"1\" <> rest | \"2\" <> rest -> rest
2410 other -> other
2411 }
2412}
2413",
2414 "new_name",
2415 find_position_of("rest").nth_occurrence(2),
2416 );
2417}
2418
2419#[test]
2420fn rename_module_from_type_in_custom_type() {
2421 let src = r#"
2422import option
2423
2424type Value(a) {
2425 Value(option.Option(a))
2426}
2427"#;
2428
2429 assert_rename!(
2430 TestProject::for_source(src).add_module("option", "pub type Option(a) { Some(a) None }"),
2431 "opt",
2432 find_position_of("option").nth_occurrence(2),
2433 );
2434}
2435
2436#[test]
2437fn rename_module_from_type_in_type_alias() {
2438 let src = r#"
2439import option
2440
2441type Option(a) =
2442 option.Option(a)
2443"#;
2444
2445 assert_rename!(
2446 TestProject::for_source(src).add_module("option", "pub type Option(a) { Some(a) None }"),
2447 "opt",
2448 find_position_of("option").nth_occurrence(2),
2449 );
2450}
2451
2452#[test]
2453fn rename_module_from_type_in_annotation() {
2454 let src = r#"
2455import option
2456
2457const x: option.Option(Int) = option.Some(1)
2458"#;
2459
2460 assert_rename!(
2461 TestProject::for_source(src).add_module("option", "pub type Option(a) { Some(a) None }"),
2462 "opt",
2463 find_position_of("option").nth_occurrence(2),
2464 );
2465}
2466
2467#[test]
2468fn rename_module_from_function_call() {
2469 let src = r#"
2470import option
2471
2472pub fn main() {
2473 option.is_some(option.Some(1))
2474}
2475"#;
2476
2477 let option_module = r#"
2478pub type Option(a) {
2479 Some(a)
2480 None
2481}
2482
2483pub fn is_some(option: Option(a)) -> Bool {
2484 case option {
2485 Some(_) -> True
2486 None -> False
2487 }
2488}
2489"#;
2490
2491 assert_rename!(
2492 TestProject::for_source(src).add_module("option", option_module),
2493 "opt",
2494 find_position_of("option").nth_occurrence(2),
2495 );
2496}
2497
2498#[test]
2499fn rename_prefix_string_suffix_variable_in_let_assert() {
2500 assert_rename!(
2501 "
2502fn main() -> String {
2503 let assert \"1\" <> rest = \"1-wibble\"
2504 rest
2505}
2506",
2507 "new_name",
2508 find_position_of("rest").nth_occurrence(1)
2509 );
2510}
2511
2512#[test]
2513fn rename_prefix_string_suffix_variable_in_let_assert_triggered_from_usage() {
2514 assert_rename!(
2515 "
2516fn main() -> String {
2517 let assert \"1\" <> rest = \"1-wibble\"
2518 rest
2519}
2520",
2521 "new_name",
2522 find_position_of("rest").nth_occurrence(2)
2523 );
2524}
2525
2526#[test]
2527fn rename_prefix_string_alias_in_case() {
2528 assert_rename!(
2529 "
2530fn main() -> String {
2531 let wibble = \"1-wibble\"
2532 case wibble {
2533 \"1\" as digit <> rest -> digit <> rest
2534 other -> other
2535 }
2536}
2537",
2538 "new_name",
2539 find_position_of("digit").nth_occurrence(1)
2540 );
2541}
2542
2543#[test]
2544fn rename_prefix_string_alias_in_case_triggered_from_usage() {
2545 assert_rename!(
2546 "
2547fn main() -> String {
2548 let wibble = \"1-wibble\"
2549 case wibble {
2550 \"1\" as digit <> rest -> digit <> rest
2551 other -> other
2552 }
2553}
2554",
2555 "new_name",
2556 find_position_of("digit").nth_occurrence(2)
2557 );
2558}
2559
2560#[test]
2561fn rename_prefix_string_alias_with_alternative_definitions_in_case() {
2562 assert_rename!(
2563 "
2564fn main() -> String {
2565 let wibble = \"1-wibble\"
2566 case wibble {
2567 \"1\" as digit <> rest | \"2\" as digit <> rest -> digit <> rest
2568 other -> other
2569 }
2570}
2571",
2572 "new_name",
2573 find_position_of("digit").nth_occurrence(1)
2574 );
2575}
2576
2577#[test]
2578fn rename_prefix_string_alias_with_alternative_definitions_triggered_from_second_pattern() {
2579 assert_rename!(
2580 "
2581fn main() -> String {
2582 let wibble = \"1-wibble\"
2583 case wibble {
2584 \"1\" as digit <> rest | \"2\" as digit <> rest -> digit <> rest
2585 other -> other
2586 }
2587}
2588",
2589 "new_name",
2590 find_position_of("digit").nth_occurrence(2)
2591 );
2592}
2593
2594#[test]
2595fn rename_prefix_string_alias_in_let_assert() {
2596 assert_rename!(
2597 "
2598fn main() -> String {
2599 let assert \"1\" as digit <> rest = \"1-wibble\"
2600 digit
2601}
2602",
2603 "new_name",
2604 find_position_of("digit").nth_occurrence(1)
2605 );
2606}
2607
2608#[test]
2609fn rename_prefix_string_alias_in_let_assert_triggered_from_usage() {
2610 assert_rename!(
2611 "
2612fn main() -> String {
2613 let assert \"1\" as digit <> rest = \"1-wibble\"
2614 digit
2615}
2616",
2617 "new_name",
2618 find_position_of("digit").nth_occurrence(2)
2619 );
2620}
2621
2622#[test]
2623fn rename_prefix_string_suffix_variable_nested_in_tuple() {
2624 assert_rename!(
2625 "
2626fn main() {
2627 case #(\"1-wibble\", 0) {
2628 #(\"1\" <> rest, _) -> rest
2629 _ -> \"\"
2630 }
2631}
2632",
2633 "new_name",
2634 find_position_of("rest").nth_occurrence(1)
2635 );
2636}
2637
2638#[test]
2639fn rename_prefix_string_alias_used_in_guard() {
2640 assert_rename!(
2641 "
2642fn main() {
2643 case \"1-wibble\" {
2644 \"1\" as digit <> _rest if digit == \"1\" -> digit
2645 _ -> \"\"
2646 }
2647}
2648",
2649 "new_name",
2650 find_position_of("digit").nth_occurrence(1)
2651 );
2652}
2653
2654#[test]
2655fn rename_prefix_string_suffix_used_in_guard() {
2656 assert_rename!(
2657 "
2658fn main() {
2659 case \"1-wibble\" {
2660 \"1\" <> rest if rest == \"-wibble\" -> rest
2661 _ -> \"\"
2662 }
2663}
2664",
2665 "new_name",
2666 find_position_of("rest").nth_occurrence(1)
2667 );
2668}
2669
2670#[test]
2671fn rename_prefix_string_suffix_shadowing_outer_variable() {
2672 assert_rename!(
2673 "
2674fn main() {
2675 let rest = \"outer\"
2676 case \"1-wibble\" {
2677 \"1\" <> rest -> rest
2678 _ -> rest
2679 }
2680}
2681",
2682 "new_name",
2683 find_position_of("rest").nth_occurrence(2)
2684 );
2685}
2686
2687#[test]
2688fn rename_prefix_string_alias_and_suffix_complex_guard() {
2689 assert_rename!(
2690 "
2691fn main() {
2692 case \"1-wibble\" {
2693 \"1\" as digit <> rest if digit == \"1\" && rest == \"-wibble\" -> #(digit, rest)
2694 _ -> #(\"\", \"\")
2695 }
2696}
2697",
2698 "new_name",
2699 find_position_of("digit").nth_occurrence(1)
2700 );
2701}
2702
2703#[test]
2704fn rename_module_from_alias_use() {
2705 let src = r#"
2706import maths as m
2707
2708pub fn main() {
2709 echo m .pi
2710}
2711"#;
2712
2713 assert_rename!(
2714 TestProject::for_source(src).add_module("maths", "pub const pi = 3.14"),
2715 "mth",
2716 find_position_of("m").nth_occurrence(5)
2717 );
2718}
2719
2720#[test]
2721fn rename_local_variable_from_guard() {
2722 assert_rename!(
2723 "
2724pub fn main() {
2725 let wibble = True
2726 let wobble = False
2727 case wibble {
2728 True if wobble -> !wibble
2729 False if !wobble -> wibble
2730 _ -> wobble
2731 }
2732}
2733",
2734 "something_else",
2735 find_position_of("wobble").nth_occurrence(2).under_char('o')
2736 );
2737}
2738
2739#[test]
2740fn alias_imported_module_from_guard() {
2741 assert_rename!(
2742 ("mod", "pub const wibble = 10"),
2743 "
2744import mod
2745
2746pub fn main() {
2747 let wibble = True
2748 case wibble {
2749 True if mod.wibble < 5 -> !wibble
2750 False if mod.wibble != 10 -> wibble
2751 _ -> mod.wibble + 1
2752 }
2753}
2754",
2755 "module",
2756 find_position_of("mod.wibble").under_char('m')
2757 );
2758}
2759
2760#[test]
2761fn rename_module_select_from_guard() {
2762 assert_rename!(
2763 ("mod", "pub const wibble = 10"),
2764 "
2765import mod
2766
2767pub fn main() {
2768 let wibble = True
2769 case wibble {
2770 True if mod.wibble < 5 -> !wibble
2771 False if mod.wibble != 10 -> wibble
2772 _ -> mod.wibble + 1
2773 }
2774}
2775",
2776 "ten",
2777 find_position_of("mod.wibble").under_char('w')
2778 );
2779}
2780
2781#[test]
2782fn rename_type_variable_in_function() {
2783 assert_rename!(
2784 "
2785pub fn first(a: wibble, b: wobble) -> wibble {
2786 a
2787}
2788",
2789 "value",
2790 find_position_of("wibble")
2791 );
2792}
2793
2794#[test]
2795fn rename_type_variable_in_function_from_return() {
2796 assert_rename!(
2797 "
2798pub fn first(a: wibble, b: wobble) -> wibble {
2799 a
2800}
2801",
2802 "value",
2803 find_position_of("-> wibble").under_char('l')
2804 );
2805}
2806
2807#[test]
2808fn rename_type_variable_in_function_body_not_used_in_head() {
2809 assert_rename!(
2810 "
2811pub fn something() {
2812 let x: Result(a, b) = todo
2813 let y: a = case x {
2814 Ok(a) -> a
2815 Error(_) -> panic
2816 }
2817}
2818",
2819 "ok",
2820 find_position_of(": a").under_char('a')
2821 );
2822}
2823
2824#[test]
2825fn rename_type_variable_in_function_used_in_body() {
2826 assert_rename!(
2827 "
2828pub fn first(a: wibble, b: wobble) -> wibble {
2829 let x: wibble = a
2830 let f = fn(a: wibble) -> wibble { a }
2831 f(x)
2832}
2833",
2834 "value",
2835 find_position_of("wibble")
2836 );
2837}
2838
2839#[test]
2840fn rename_type_variable_in_function_from_body() {
2841 assert_rename!(
2842 "
2843pub fn first(a: wibble, b: wobble) -> wibble {
2844 let x: wibble = a
2845 let f = fn(a: wibble) -> wibble { a }
2846 f(x)
2847}
2848",
2849 "value",
2850 find_position_of("x: wibble").under_char('i')
2851 );
2852}
2853
2854#[test]
2855fn type_variable_in_separate_function_is_not_renamed() {
2856 assert_rename!(
2857 "
2858pub fn first(a: wibble, b: wobble) -> wibble {
2859 a
2860}
2861
2862pub fn an_unrelated_function(a: wibble, b: wibble) -> wibble {
2863 a
2864}
2865",
2866 "value",
2867 find_position_of("wibble")
2868 );
2869}
2870
2871#[test]
2872fn rename_type_variable_in_constant() {
2873 assert_rename!(
2874 "
2875pub const empty: List(#(anything, anything)) = []
2876",
2877 "a",
2878 find_position_of("anything")
2879 );
2880}
2881
2882#[test]
2883fn rename_type_variable_in_type_alias() {
2884 assert_rename!(
2885 "
2886pub type Option(a) {
2887 Some(a)
2888 None
2889}
2890
2891pub type Maybe(some_type) =
2892 Option(some_type)
2893",
2894 "something",
2895 find_position_of("Option(some_type").under_char('_')
2896 );
2897}
2898
2899#[test]
2900fn rename_type_variable_in_type_alias_from_head() {
2901 assert_rename!(
2902 "
2903pub type Option(a) {
2904 Some(a)
2905 None
2906}
2907
2908pub type Maybe(some_type) =
2909 Option(some_type)
2910",
2911 "something",
2912 find_position_of("some_type")
2913 );
2914}
2915
2916#[test]
2917fn rename_type_variable_in_custom_type_from_head() {
2918 assert_rename!(
2919 "
2920pub type Option(anything) {
2921 Some(anything)
2922 None
2923}
2924",
2925 "something",
2926 find_position_of("anything")
2927 );
2928}
2929
2930#[test]
2931fn rename_type_variable_in_custom_type_from_constructor() {
2932 assert_rename!(
2933 "
2934pub type Option(anything) {
2935 Some(anything)
2936 None
2937}
2938",
2939 "something",
2940 find_position_of("Some(anything").under_char('i')
2941 );
2942}
2943
2944#[test]
2945fn invalid_type_variable_name() {
2946 assert_rename_error!(
2947 "
2948pub type Option(anything) {
2949 Some(anything)
2950 None
2951}
2952",
2953 "SomeType",
2954 find_position_of("anything")
2955 );
2956}
2957#[test]
2958fn renaming_file_modifies_imports_and_references() {
2959 assert_rename_files!(
2960 (
2961 "wibble/wobble",
2962 "wibble/wubble",
2963 "
2964pub type Wibble {
2965 Wibble
2966 Wobble
2967}
2968
2969pub const wibble = Wibble
2970"
2971 ),
2972 "
2973import wibble/wobble.{Wibble}
2974
2975pub fn main() -> wobble.Wibble {
2976 assert wobble.wibble == Wibble
2977 wobble.Wobble
2978}
2979",
2980 );
2981}
2982
2983#[test]
2984fn change_directory_of_file() {
2985 assert_rename_files!(
2986 (
2987 "wobble",
2988 "wibble/wobble",
2989 "
2990pub type Wibble {
2991 Wibble
2992 Wobble
2993}
2994
2995pub const wibble = Wibble
2996"
2997 ),
2998 "
2999import wobble.{Wibble}
3000
3001pub fn main() -> wobble.Wibble {
3002 assert wobble.wibble == Wibble
3003 wobble.Wobble
3004}
3005",
3006 );
3007}
3008
3009#[test]
3010fn rename_file_does_not_modify_aliased_imports() {
3011 assert_rename_files!(
3012 (
3013 "wibble/wobble",
3014 "wibble/wubble",
3015 "
3016pub type Wibble {
3017 Wibble
3018 Wobble
3019}
3020
3021pub const wibble = Wibble
3022"
3023 ),
3024 "
3025import wibble/wobble.{Wibble} as wibble
3026
3027pub fn main() -> wibble.Wibble {
3028 assert wibble.wibble == Wibble
3029 wibble.Wobble
3030}
3031",
3032 );
3033}
3034
3035#[test]
3036fn rename_file_removes_unnecessary_alias() {
3037 assert_rename_files!(
3038 (
3039 "wibble/wobble",
3040 "wibble/wibble",
3041 "
3042pub type Wibble {
3043 Wibble
3044 Wobble
3045}
3046
3047pub const wibble = Wibble
3048"
3049 ),
3050 "
3051import wibble/wobble.{Wibble} as wibble
3052
3053pub fn main() -> wibble.Wibble {
3054 assert wibble.wibble == Wibble
3055 wibble.Wobble
3056}
3057",
3058 );
3059}
3060
3061#[test]
3062fn rename_file_changes_all_correct_ast_nodes() {
3063 assert_rename_files!(
3064 (
3065 "wibble",
3066 "wobble",
3067 "
3068pub type Wibble {
3069 Wibble
3070 Wobble
3071}
3072
3073pub const wibble = Wibble
3074"
3075 ),
3076 "
3077import wibble
3078
3079pub const one = wibble.Wibble
3080
3081pub const two = wibble.wibble
3082
3083pub fn main() -> wibble.Wibble {
3084 case wibble.Wobble {
3085 x if x == wibble.Wibble -> x
3086 x if x == wibble.wibble -> x
3087 wibble.Wobble -> wibble.wibble
3088 }
3089}
3090",
3091 );
3092}
3093
3094#[test]
3095fn rename_multiple_files() {
3096 assert_rename_files!(
3097 (
3098 "wibble",
3099 "wibble/wibble",
3100 "pub type Wibble { Wibble Wobble }"
3101 ),
3102 (
3103 "wobble",
3104 "wibble/wobble",
3105 "import wibble
3106pub const wibble = wibble.Wobble"
3107 ),
3108 "
3109import wibble
3110import wobble
3111
3112pub fn main() -> wibble.Wibble {
3113 wobble.wibble
3114}
3115",
3116 );
3117}
3118
3119#[test]
3120fn rename_record_field_from_access() {
3121 assert_rename!(
3122 "
3123type Wibble {
3124 Wibble(wibble: Int)
3125}
3126
3127pub fn main() {
3128 let value = Wibble(wibble: 1)
3129 value.wibble
3130}
3131",
3132 "wobble",
3133 find_position_of("value.wibble").under_char('i')
3134 );
3135}
3136
3137#[test]
3138fn rename_record_field_from_constructor_label() {
3139 assert_rename!(
3140 "
3141type Wibble {
3142 Wibble(wibble: Int)
3143}
3144
3145pub fn main() {
3146 let value = Wibble(wibble: 1)
3147 value.wibble
3148}
3149",
3150 "wobble",
3151 find_position_of("wibble: 1").under_char('w')
3152 );
3153}
3154
3155#[test]
3156fn rename_record_field_from_pattern_label() {
3157 assert_rename!(
3158 "
3159type Wibble {
3160 Wibble(wibble: Int)
3161}
3162
3163pub fn main(w: Wibble) {
3164 case w {
3165 Wibble(wibble: value) -> value
3166 }
3167}
3168",
3169 "wobble",
3170 find_position_of("wibble: value").under_char('w')
3171 );
3172}
3173
3174#[test]
3175fn rename_record_field_expands_label_shorthand() {
3176 assert_rename!(
3177 "
3178type Wibble {
3179 Wibble(wibble: Int)
3180}
3181
3182pub fn main() {
3183 let wibble = 1
3184 let value = Wibble(wibble:)
3185 value.wibble
3186}
3187",
3188 "wobble",
3189 find_position_of("value.wibble").under_char('i')
3190 );
3191}
3192
3193#[test]
3194fn rename_record_field_in_record_update() {
3195 assert_rename!(
3196 "
3197type Wibble {
3198 Wibble(wibble: Int, wobble: Int)
3199}
3200
3201pub fn main(w: Wibble) {
3202 Wibble(..w, wibble: 2)
3203}
3204",
3205 "wabble",
3206 find_position_of("wibble: 2").under_char('w')
3207 );
3208}
3209
3210#[test]
3211fn rename_record_field_across_modules() {
3212 assert_rename!(
3213 ("wibble", "pub type Wibble {\n Wibble(wibble: Int)\n}"),
3214 "
3215import wibble
3216
3217pub fn main() {
3218 let value = wibble.Wibble(wibble: 1)
3219 value.wibble
3220}
3221",
3222 "wobble",
3223 find_position_of("value.wibble").under_char('i')
3224 );
3225}
3226
3227#[test]
3228fn no_rename_record_field_from_other_package() {
3229 let src = "
3230import wibble
3231
3232pub fn main() {
3233 let value = wibble.Wibble(wibble: 1)
3234 value.wibble
3235}
3236";
3237
3238 assert_no_rename!(
3239 &TestProject::for_source(src)
3240 .add_hex_module("wibble", "pub type Wibble {\n Wibble(wibble: Int)\n}"),
3241 "wobble",
3242 find_position_of("value.wibble").under_char('i')
3243 );
3244}
3245
3246#[test]
3247fn rename_record_field_in_module_not_importing_the_type_module() {
3248 assert_rename!(
3249 TestProject::for_source(
3250 "
3251import wobble
3252
3253pub fn main() {
3254 wobble.make().wibble
3255}
3256"
3257 )
3258 .add_module("wibble", "pub type Wibble {\n Wibble(wibble: Int)\n}")
3259 .add_module(
3260 "wobble",
3261 "import wibble\n\npub fn make() -> wibble.Wibble {\n wibble.Wibble(wibble: 1)\n}"
3262 ),
3263 "wabble",
3264 find_position_of("().wibble").under_char('b')
3265 );
3266}
3267
3268#[test]
3269fn rename_record_field_with_invalid_name() {
3270 assert_rename_error!(
3271 "
3272type Wibble {
3273 Wibble(wibble: Int)
3274}
3275
3276pub fn main() {
3277 let value = Wibble(wibble: 1)
3278 value.wibble
3279}
3280",
3281 "Wobble",
3282 find_position_of("value.wibble").under_char('i')
3283 );
3284}
3285
3286#[test]
3287fn rename_record_field_from_definition() {
3288 assert_rename!(
3289 "
3290type Wibble {
3291 Wibble(wibble: Int)
3292}
3293
3294pub fn main() {
3295 let value = Wibble(wibble: 1)
3296 value.wibble
3297}
3298",
3299 "wobble",
3300 find_position_of("wibble: Int").under_char('w')
3301 );
3302}
3303
3304#[test]
3305fn rename_record_field_renames_labelled_arguments_of_call_with_incorrect_arity() {
3306 assert_rename!(
3307 "
3308type Wibble {
3309 Wibble(wibble: Int, wobble: Int)
3310}
3311
3312pub fn main() {
3313 Wibble(wibble: 1)
3314}
3315",
3316 "wabble",
3317 find_position_of("wibble: Int").under_char('w')
3318 );
3319}
3320
3321#[test]
3322fn rename_record_field_ignored_by_record_update_spread() {
3323 // https://github.com/gleam-lang/gleam/pull/5533#pullrequestreview-4475156690
3324 assert_rename!(
3325 "
3326type Wibble {
3327 Wibble(wibble: Int, wobble: Int)
3328}
3329
3330pub fn main(w: Wibble) {
3331 Wibble(..w, wibble: 2)
3332}
3333",
3334 "wabble",
3335 find_position_of("wobble: Int").under_char('w')
3336 );
3337}
3338
3339#[test]
3340fn rename_record_field_ignored_by_record_update_spread_with_expression() {
3341 assert_rename!(
3342 "
3343type Wibble {
3344 Wibble(wibble: Int, wobble: Int)
3345}
3346
3347pub fn make() {
3348 Wibble(wibble: 1, wobble: 2)
3349}
3350
3351pub fn main() {
3352 Wibble(..make(), wibble: 2)
3353}
3354",
3355 "wabble",
3356 find_position_of("wobble: Int").under_char('w')
3357 );
3358}
3359
3360#[test]
3361fn rename_record_field_ignored_by_pattern_spread() {
3362 assert_rename!(
3363 "
3364type Wibble {
3365 Wibble(wibble: Int, wobble: Int)
3366}
3367
3368pub fn main(w: Wibble) {
3369 case w {
3370 Wibble(wibble: a, ..) -> a
3371 }
3372}
3373",
3374 "wabble",
3375 find_position_of("wobble: Int").under_char('w')
3376 );
3377}
3378
3379#[test]
3380fn rename_record_field_ignored_by_bare_pattern_spread() {
3381 assert_rename!(
3382 "
3383type Wibble {
3384 Wibble(wibble: Int, wobble: Int)
3385}
3386
3387pub fn main(w: Wibble) {
3388 case w {
3389 Wibble(..) -> 1
3390 }
3391}
3392",
3393 "wabble",
3394 find_position_of("wibble: Int").under_char('w')
3395 );
3396}
3397
3398#[test]
3399fn rename_record_field_shared_between_variants() {
3400 assert_rename!(
3401 "
3402pub type Shape {
3403 Square(colour: Int, width: Int)
3404 Circle(colour: Int, radius: Int)
3405}
3406
3407pub fn main() {
3408 let shape = Square(colour: 1, width: 10)
3409 case shape {
3410 Circle(colour:, ..) -> colour
3411 Square(..) -> shape.colour
3412 }
3413}
3414",
3415 "shade",
3416 find_position_of("colour: Int, width").under_char('c')
3417 );
3418}
3419
3420// https://github.com/gleam-lang/gleam/issues/5861
3421#[test]
3422fn rename_item_with_import_alias() {
3423 assert_rename!(
3424 TestProject::for_source(
3425 "
3426import wibble.{Wibble as Wobble}
3427
3428pub fn main() {
3429 let _ = Wobble
3430}
3431"
3432 )
3433 .add_module(
3434 "wibble",
3435 "
3436pub type Wibble {
3437 Wibble
3438}
3439"
3440 ),
3441 "Wubble",
3442 find_position_of("= Wobble").under_char('b')
3443 );
3444}
3445
3446// https://github.com/gleam-lang/gleam/issues/5861
3447#[test]
3448fn rename_type_with_import_alias() {
3449 assert_rename!(
3450 TestProject::for_source(
3451 "
3452import wibble.{type Wibble as Wobble}
3453
3454pub fn main() -> Wobble {
3455 todo
3456}
3457"
3458 )
3459 .add_module(
3460 "wibble",
3461 "
3462pub type Wibble {
3463 Wibble
3464}
3465"
3466 ),
3467 "Wubble",
3468 find_position_of("-> Wobble").under_char('b')
3469 );
3470}
3471
3472// https://github.com/gleam-lang/gleam/issues/5861
3473#[test]
3474fn rename_type_with_import_alias_and_other_imported_items() {
3475 assert_rename!(
3476 TestProject::for_source(
3477 "
3478import wibble.{Wibble as Wobble, type Wibble as Wobble}
3479
3480pub fn main() -> Wobble {
3481 Wobble
3482}
3483"
3484 )
3485 .add_module(
3486 "wibble",
3487 "
3488pub type Wibble {
3489 Wibble
3490}
3491"
3492 ),
3493 "Wubble",
3494 find_position_of("-> Wobble").under_char('b')
3495 );
3496}
3497
3498// https://github.com/gleam-lang/gleam/issues/5861
3499#[test]
3500fn rename_value_with_import_alias_and_other_imported_items() {
3501 assert_rename!(
3502 TestProject::for_source(
3503 "
3504import wibble.{Wibble as Wobble, type Wibble as Wobble}
3505
3506pub fn main() -> Wobble {
3507 Wobble
3508}
3509"
3510 )
3511 .add_module(
3512 "wibble",
3513 "
3514pub type Wibble {
3515 Wibble
3516}
3517"
3518 ),
3519 "Wubble",
3520 find_position_of("Wobble").nth_occurrence(4).under_char('b')
3521 );
3522}
3523
3524#[test]
3525fn rename_item_with_import_alias_to_original_name() {
3526 assert_rename!(
3527 TestProject::for_source(
3528 "
3529import wibble.{Wibble as Wobble}
3530
3531pub fn main() {
3532 let _ = Wobble
3533}
3534"
3535 )
3536 .add_module(
3537 "wibble",
3538 "
3539pub type Wibble {
3540 Wibble
3541}
3542"
3543 ),
3544 "Wibble",
3545 find_position_of("= Wobble").under_char('b')
3546 );
3547}
3548
3549#[test]
3550fn rename_type_with_import_alias_to_original_name() {
3551 assert_rename!(
3552 TestProject::for_source(
3553 "
3554import wibble.{type Wibble as Wobble}
3555
3556pub fn main() -> Wobble {
3557 todo
3558}
3559"
3560 )
3561 .add_module(
3562 "wibble",
3563 "
3564pub type Wibble {
3565 Wibble
3566}
3567"
3568 ),
3569 "Wibble",
3570 find_position_of("-> Wobble").under_char('b')
3571 );
3572}
3573
3574#[test]
3575fn rename_type_with_import_alias_to_original_name_with_other_items() {
3576 assert_rename!(
3577 TestProject::for_source(
3578 "
3579import wibble.{type Wibble as Wobble, Wibble as Wobble}
3580
3581pub fn main() -> Wobble {
3582 Wobble
3583}
3584"
3585 )
3586 .add_module(
3587 "wibble",
3588 "
3589pub type Wibble {
3590 Wibble
3591}
3592"
3593 ),
3594 "Wibble",
3595 find_position_of("-> Wobble").under_char('b')
3596 );
3597}
3598
3599#[test]
3600fn rename_item_with_import_alias_to_original_name_with_other_items() {
3601 assert_rename!(
3602 TestProject::for_source(
3603 "
3604import wibble.{type Wibble as Wobble, Wibble as Wobble}
3605
3606pub fn main() -> Wobble {
3607 Wobble
3608}
3609"
3610 )
3611 .add_module(
3612 "wibble",
3613 "
3614pub type Wibble {
3615 Wibble
3616}
3617"
3618 ),
3619 "Wibble",
3620 find_position_of("Wobble").nth_occurrence(4).under_char('b')
3621 );
3622}