this repo has no description
at wasm 891 lines 13 kB view raw
1use crate::assert_js; 2 3#[test] 4fn case_on_error() { 5 assert_js!( 6 r#" 7fn a_result() { Error(1) } 8 9pub fn main() { 10 case a_result() { 11 Error(_) -> 1 12 _ -> 2 13 } 14}"# 15 ); 16} 17 18#[test] 19fn tuple_and_guard() { 20 assert_js!( 21 r#" 22pub fn go(x) { 23 case #(1, 2) { 24 #(1, a) if a == 2 -> 1 25 #(_, _) -> 2 26 } 27} 28"#, 29 ) 30} 31 32#[test] 33fn guard_variable_only_brought_into_scope_when_needed() { 34 assert_js!( 35 r#" 36pub fn go(x) { 37 case x { 38 // We want `a` to be defined before the guard check, and 39 // `b` to be defined only if the predicate on a matches! 40 [a, b] if a == 1 -> a + b 41 _ -> 2 42 } 43} 44"# 45 ) 46} 47 48// https://github.com/gleam-lang/gleam/issues/4221 49#[test] 50fn guard_variable_only_brought_into_scope_when_needed_1() { 51 assert_js!( 52 r#" 53pub fn main() { 54 case 1 { 55 i if i == 1 -> True 56 i if i < 2 -> True 57 _ -> False 58 } 59} 60"# 61 ) 62} 63 64// https://github.com/gleam-lang/gleam/issues/1187 65#[test] 66fn pointless() { 67 assert_js!( 68 r#" 69pub fn go(x) { 70 case x { 71 _ -> x 72 } 73} 74"#, 75 ) 76} 77 78// https://github.com/gleam-lang/gleam/issues/1188 79#[test] 80fn following_todo() { 81 assert_js!( 82 r#" 83pub fn go(x) { 84 case x { 85 True -> todo 86 _ -> 1 87 } 88} 89"#, 90 ) 91} 92 93#[test] 94fn multi_subject_catch_all() { 95 assert_js!( 96 r#" 97pub fn go(x, y) { 98 case x, y { 99 True, True -> 1 100 _, _ -> 0 101 } 102} 103"#, 104 ) 105} 106 107#[test] 108fn multi_subject_or() { 109 assert_js!( 110 r#" 111pub fn go(x, y) { 112 case x, y { 113 True, _ | _, True -> 1 114 _, _ -> 0 115 } 116} 117"#, 118 ) 119} 120 121#[test] 122fn multi_subject_no_catch_all() { 123 assert_js!( 124 r#" 125pub fn go(x, y) { 126 case x, y { 127 True, _ -> 1 128 _, True -> 2 129 False, False -> 0 130 } 131} 132"#, 133 ) 134} 135 136#[test] 137fn multi_subject_subject_assignments() { 138 assert_js!( 139 r#" 140pub fn go() { 141 case True, False { 142 True, True -> 1 143 _, _ -> 0 144 } 145} 146"#, 147 ) 148} 149 150#[test] 151fn assignment() { 152 assert_js!( 153 r#" 154pub fn go(x) { 155 let y = case x { 156 True -> 1 157 _ -> 0 158 } 159 y 160} 161"#, 162 ) 163} 164 165#[test] 166fn preassign_assignment() { 167 assert_js!( 168 r#" 169pub fn go(x) { 170 let y = case x() { 171 True -> 1 172 _ -> 0 173 } 174 y 175} 176"#, 177 ) 178} 179 180// https://github.com/gleam-lang/gleam/issues/1237 181#[test] 182fn pipe() { 183 assert_js!( 184 r#" 185pub fn go(x, f) { 186 case x |> f { 187 0 -> 1 188 _ -> 2 189 } 190} 191"#, 192 ) 193} 194 195#[test] 196fn result() { 197 assert_js!( 198 r#" 199pub fn go(x) { 200 case x { 201 Ok(_) -> 1 202 Error(_) -> 0 203 } 204} 205"#, 206 ) 207} 208 209// https://github.com/gleam-lang/gleam/issues/1506 210#[test] 211fn called_case() { 212 assert_js!( 213 r#" 214pub fn go(x, y) { 215 case x { 216 0 -> y 217 _ -> y 218 }() 219} 220"#, 221 ) 222} 223 224// https://github.com/gleam-lang/gleam/issues/1978 225#[test] 226fn case_local_var_in_tuple() { 227 assert_js!( 228 r#" 229pub fn go(x, y) { 230 let z = False 231 case True { 232 x if #(x, z) == #(True, False) -> x 233 _ -> False 234 } 235} 236"#, 237 ) 238} 239 240// https://github.com/gleam-lang/gleam/issues/2665 241#[test] 242fn case_branches_guards_are_wrapped_in_parentheses() { 243 assert_js!( 244 r#" 245pub fn anything() -> a { 246 case [] { 247 [a] if False || True -> a 248 _ -> anything() 249 } 250} 251"#, 252 ) 253} 254 255// https://github.com/gleam-lang/gleam/issues/2759 256#[test] 257fn nested_string_prefix_match() { 258 assert_js!( 259 r#" 260pub fn main() { 261 case Ok(["a", "b c", "d"]) { 262 Ok(["a", "b " <> _, "d"]) -> 1 263 _ -> 1 264 } 265} 266"# 267 ); 268} 269 270// https://github.com/gleam-lang/gleam/issues/2759 271#[test] 272fn nested_string_prefix_match_that_would_crash_on_js() { 273 assert_js!( 274 r#" 275pub fn main() { 276 case Ok(["b c", "d"]) { 277 Ok(["b " <> _, "d"]) -> 1 278 _ -> 1 279 } 280} 281"# 282 ); 283} 284 285#[test] 286fn slicing_is_handled_properly_with_multiple_branches() { 287 assert_js!( 288 r#" 289pub fn main() { 290 case "12345" { 291 "0" <> rest -> rest 292 "123" <> rest -> rest 293 _ -> "" 294 } 295} 296"# 297 ) 298} 299 300// https://github.com/gleam-lang/gleam/issues/3379 301#[test] 302fn single_clause_variables() { 303 assert_js!( 304 r#" 305pub fn main() { 306 let text = "first defined" 307 case "defined again" { 308 text -> Nil 309 } 310 let text = "a third time" 311} 312"# 313 ) 314} 315 316// https://github.com/gleam-lang/gleam/issues/3379 317#[test] 318fn single_clause_variables_assigned() { 319 assert_js!( 320 r#" 321pub fn main() { 322 let text = "first defined" 323 let other = case "defined again" { 324 text -> Nil 325 } 326 let text = "a third time" 327} 328"# 329 ) 330} 331 332// https://github.com/gleam-lang/gleam/issues/3894 333#[test] 334fn nested_string_prefix_assignment() { 335 assert_js!( 336 r#" 337type Wibble { 338 Wibble(wobble: String) 339} 340 341pub fn main() { 342 let tmp = Wibble(wobble: "wibble") 343 case tmp { 344 Wibble(wobble: "w" as wibble <> rest) -> wibble <> rest 345 _ -> panic 346 } 347} 348"# 349 ) 350} 351 352#[test] 353fn deeply_nested_string_prefix_assignment() { 354 assert_js!( 355 r#" 356type Wibble { 357 Wibble(Wobble) 358} 359type Wobble { 360 Wobble(wabble: Wabble) 361} 362type Wabble { 363 Wabble(tuple: #(Int, String)) 364} 365 366pub fn main() { 367 let tmp = Wibble(Wobble(Wabble(#(42, "wibble")))) 368 case tmp { 369 Wibble(Wobble(Wabble(#(_int, "w" as wibble <> rest)))) -> wibble <> rest 370 _ -> panic 371 } 372} 373"# 374 ) 375} 376 377// https://github.com/gleam-lang/gleam/issues/4383 378#[test] 379fn record_update_in_pipeline_in_case_clause() { 380 assert_js!( 381 " 382pub type Wibble { 383 Wibble(wibble: Int, wobble: Int) 384} 385 386fn identity(x) { 387 x 388} 389 390pub fn go(x) { 391 case x { 392 Wibble(1, _) -> Wibble(..x, wibble: 4) |> identity 393 Wibble(_, 3) -> Wibble(..x, wobble: 10) |> identity 394 _ -> panic 395 } 396} 397" 398 ); 399} 400 401#[test] 402fn pattern_matching_on_aliased_result_constructor() { 403 assert_js!( 404 " 405import gleam.{Error as E, Ok as O} 406 407pub fn go(x) { 408 case x { 409 E(_) -> 1 410 O(_) -> 2 411 } 412} 413" 414 ); 415} 416 417#[test] 418fn list_with_guard() { 419 assert_js!( 420 " 421pub fn go(x) { 422 case x { 423 [] -> 0 424 [first, ..] if first < 10 -> first * 2 425 [first, ..] -> first 426 } 427} 428" 429 ); 430} 431 432#[test] 433fn list_with_guard_no_binding() { 434 assert_js!( 435 " 436pub fn go(x) { 437 case x { 438 [] -> 0 439 [first, ..] if 1 < 10 -> first * 2 440 [first, ..] -> first 441 } 442} 443" 444 ); 445} 446 447#[test] 448fn case_building_simple_value_matched_by_pattern() { 449 assert_js!( 450 "pub fn go(x) { 451 case x { 452 1 -> 2 453 n -> n 454 } 455}" 456 ) 457} 458 459#[test] 460fn case_building_list_matched_by_pattern() { 461 assert_js!( 462 "pub fn go(x) { 463 case x { 464 [] -> [] 465 [a, b] -> [a, b] 466 [1, ..rest] -> [1, ..rest] 467 _ -> x 468 } 469}" 470 ) 471} 472 473#[test] 474fn case_building_record_matched_by_pattern() { 475 assert_js!( 476 "pub fn go(x) { 477 case x { 478 Ok(1) -> Ok(1) 479 Ok(n) -> Ok(n) 480 Error(_) -> Error(Nil) 481 } 482}" 483 ) 484} 485 486#[test] 487fn case_building_record_with_select_matched_by_pattern() { 488 assert_js!( 489 " 490import gleam 491 492pub fn go(x) { 493 case x { 494 Ok(1) -> gleam.Ok(1) 495 _ -> Error(Nil) 496 } 497}" 498 ) 499} 500 501#[test] 502fn case_building_record_with_select_matched_by_pattern_2() { 503 assert_js!( 504 " 505import gleam 506 507pub fn go(x) { 508 case x { 509 gleam.Ok(1) -> gleam.Ok(1) 510 _ -> Error(Nil) 511 } 512}" 513 ) 514} 515 516#[test] 517fn case_building_record_with_select_matched_by_pattern_3() { 518 assert_js!( 519 " 520import gleam 521 522pub fn go(x) { 523 case x { 524 gleam.Ok(1) -> Ok(1) 525 _ -> Error(Nil) 526 } 527}" 528 ) 529} 530 531#[test] 532fn case_building_matched_string_1() { 533 assert_js!( 534 r#" 535import gleam 536 537pub fn go(x) { 538 case x { 539 "a" <> rest -> "a" <> rest 540 _ -> "" 541 } 542}"# 543 ) 544} 545 546#[test] 547fn case_building_matched_string_2() { 548 assert_js!( 549 r#" 550import gleam 551 552pub fn go(x) { 553 case x { 554 "a" as a <> rest -> a <> rest 555 _ -> "" 556 } 557}"# 558 ) 559} 560 561#[test] 562fn case_building_matched_value_wrapped_in_block() { 563 assert_js!( 564 r#" 565import gleam 566 567pub fn go(x) { 568 case x { 569 1 -> { 1 } 570 _ -> 2 571 } 572}"# 573 ) 574} 575 576#[test] 577fn case_building_matched_value_alias() { 578 assert_js!( 579 r#" 580import gleam 581 582pub fn go(x) { 583 case x { 584 Ok(_) as a -> a 585 Error(Nil) -> Error(Nil) 586 } 587}"# 588 ) 589} 590 591#[test] 592fn case_building_matched_value_alias_2() { 593 assert_js!( 594 r#" 595import gleam 596 597pub fn go(x) { 598 case x { 599 Ok(1) as a -> Ok(1) 600 Ok(_) -> Ok(2) 601 Error(Nil) -> Error(Nil) 602 } 603}"# 604 ) 605} 606 607#[test] 608fn case_building_matched_value_alias_3() { 609 assert_js!( 610 r#" 611import gleam 612 613pub fn go(x) { 614 case x { 615 Ok(1 as a) -> Ok(a) 616 Ok(_) -> Ok(2) 617 Error(Nil) -> Error(Nil) 618 } 619}"# 620 ) 621} 622 623#[test] 624fn case_building_matched_no_variant_record() { 625 assert_js!( 626 r#" 627pub fn go(x) { 628 case x { 629 Ok(Nil) -> Ok(Nil) 630 _ -> Error(Nil) 631 } 632}"# 633 ) 634} 635 636#[test] 637fn case_building_matched_no_variant_record_2() { 638 assert_js!( 639 r#" 640import gleam 641 642pub fn go(x) { 643 case x { 644 Ok(gleam.Nil) -> Ok(Nil) 645 _ -> Error(Nil) 646 } 647}"# 648 ) 649} 650 651#[test] 652fn case_building_matched_no_variant_record_3() { 653 assert_js!( 654 r#" 655import gleam 656 657pub fn go(x) { 658 case x { 659 Ok(Nil) -> Ok(gleam.Nil) 660 _ -> Error(Nil) 661 } 662}"# 663 ) 664} 665 666#[test] 667fn case_building_matched_no_variant_record_4() { 668 assert_js!( 669 r#" 670import gleam 671 672pub fn go(x) { 673 case x { 674 Ok(gleam.Nil) -> Ok(gleam.Nil) 675 _ -> Error(Nil) 676 } 677}"# 678 ) 679} 680 681#[test] 682fn case_building_record_with_labels_matched_by_pattern_1() { 683 assert_js!( 684 " 685pub type Wibble { 686 Wibble(int: Int, string: String) 687 Wobble(Int) 688} 689 690pub fn go(x) { 691 case x { 692 Wibble(1, s) -> Wibble(1, s) 693 _ -> Wobble(1) 694 } 695}" 696 ) 697} 698 699#[test] 700fn case_building_record_with_labels_matched_by_pattern_2() { 701 assert_js!( 702 " 703pub type Wibble { 704 Wibble(int: Int, string: String) 705 Wobble(Int) 706} 707 708pub fn go(x) { 709 case x { 710 Wibble(string:, int:) -> Wibble(string:, int:) 711 _ -> Wobble(1) 712 } 713}" 714 ) 715} 716 717#[test] 718fn case_building_record_with_labels_matched_by_pattern_3() { 719 assert_js!( 720 " 721pub type Wibble { 722 Wibble(int: Int, string: String) 723 Wobble(Int) 724} 725 726pub fn go(x) { 727 case x { 728 // This should not be optimised away! 729 Wibble(string:, int:) -> Wibble(string:, int: 1) 730 _ -> Wobble(1) 731 } 732}" 733 ) 734} 735 736#[test] 737fn case_building_record_with_labels_matched_by_pattern_4() { 738 assert_js!( 739 " 740pub type Wibble { 741 Wibble(int: Int, string: String) 742 Wobble(Int) 743} 744 745pub fn go(x) { 746 case x { 747 Wibble(string:, int:) -> Wibble(int:, string:) 748 _ -> Wobble(1) 749 } 750}" 751 ) 752} 753 754#[test] 755fn case_building_record_with_labels_matched_by_pattern_5() { 756 assert_js!( 757 " 758pub type Wibble { 759 Wibble(int: Int, string: String) 760 Wobble(Int) 761} 762 763pub fn go(x) { 764 case x { 765 Wibble(string:, int: 1) -> Wibble(1, string:) 766 _ -> Wobble(1) 767 } 768}" 769 ) 770} 771 772#[test] 773fn case_building_record_with_labels_matched_by_pattern_6() { 774 assert_js!( 775 " 776pub type Wibble { 777 Wibble(int: Int, string: String) 778 Wobble(Int) 779} 780 781pub fn go(x) { 782 case x { 783 Wibble(1, string:) -> Wibble(string:, int: 1) 784 _ -> Wobble(1) 785 } 786}" 787 ) 788} 789 790#[test] 791fn case_with_multiple_subjects_building_simple_value_matched_by_pattern() { 792 assert_js!( 793 "pub fn go(x) { 794 case x, x + 1 { 795 1, _ -> 2 796 _, n -> n 797 } 798}" 799 ) 800} 801 802#[test] 803fn case_with_multiple_subjects_building_list_matched_by_pattern() { 804 assert_js!( 805 "pub fn go(n, x) { 806 case n, x { 807 1, [] -> [] 808 _, [a, b] -> [a, b] 809 3, [1, ..rest] -> [1, ..rest] 810 _, _ -> x 811 } 812}" 813 ) 814} 815 816#[test] 817fn case_with_multiple_subjects_building_record_matched_by_pattern() { 818 assert_js!( 819 "pub fn go(x, y) { 820 case x, y { 821 Ok(1), Error(_) -> Ok(1) 822 Error(_), Ok(n) -> Ok(n) 823 _, _ -> Error(Nil) 824 } 825}" 826 ) 827} 828 829#[test] 830fn case_with_multiple_subjects_building_same_value_as_two_subjects_one_is_picked() { 831 assert_js!( 832 " 833import gleam 834 835pub fn go(x, y) { 836 case x, y { 837 gleam.Ok(1), Ok(1) -> Ok(1) 838 _, Error(Nil) -> Error(Nil) 839 _, _ -> Error(Nil) 840 } 841}" 842 ) 843} 844 845#[test] 846fn interfering_string_pattern_fails_if_succeeding() { 847 assert_js!( 848 r#" 849pub fn wibble(bits) { 850 case bits { 851 <<"aaa", 0, _:bits>> -> 1 852 // If the first one fails, we know this one won't match, so it won't appear 853 // in the final else branch! 854 <<_, "aa", 1, _:bits>> -> 2 855 _ -> 3 856 } 857}"# 858 ); 859} 860 861#[test] 862fn interfering_string_pattern_succeeds_if_succeeding() { 863 assert_js!( 864 r#" 865pub fn wibble(bits) { 866 case bits { 867 <<"aaa", 0, _:bits>> -> 1 868 // If the first one succeeds, so will the second check, so it won't be 869 // performed twice inside the first if branch! 870 <<"aaa", 1, _:bits>> -> 2 871 _ -> 3 872 } 873}"# 874 ); 875} 876 877#[test] 878fn interfering_string_pattern_fails_if_failing() { 879 assert_js!( 880 r#" 881pub fn wibble(bits) { 882 case bits { 883 <<"aaaa", 0, _:bits>> -> 1 884 // If the first one fails we know this one will fail as well, so it won't 885 // appear in the final else branch. 886 <<_, "aaabbb", 1, _:bits>> -> 2 887 _ -> 3 888 } 889}"# 890 ); 891}