Fork of daniellemaywood.uk/gleam — Wasm codegen work
2

Configure Feed

Select the types of activity you want to include in your feed.

gleam / language-server / src / tests / rename.rs
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}