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

Configure Feed

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

gleam / compiler-core / src / javascript / tests / case_clause_guards.rs
9.6 kB 627 lines
1// SPDX-License-Identifier: Apache-2.0 2// SPDX-FileCopyrightText: 2021 The Gleam contributors 3 4use crate::assert_js; 5 6#[test] 7fn referencing_pattern_var() { 8 assert_js!( 9 r#"pub fn main(xs) { 10 case xs { 11 #(x) if x -> 1 12 _ -> 0 13 } 14} 15"#, 16 ); 17} 18 19#[test] 20fn rebound_var() { 21 assert_js!( 22 r#"pub fn main() { 23 let x = False 24 let x = True 25 case x { 26 _ if x -> 1 27 _ -> 0 28 } 29} 30"#, 31 ); 32} 33 34#[test] 35fn bitarray_with_var() { 36 assert_js!( 37 r#"pub fn main() { 38 case 5 { 39 z if <<z>> == <<z>> -> Nil 40 _ -> Nil 41 } 42} 43"#, 44 ) 45} 46 47// https://github.com/gleam-lang/gleam/issues/3004 48#[test] 49fn keyword_var() { 50 assert_js!( 51 r#" 52pub const function = 5 53pub const do = 10 54pub fn main() { 55 let class = 5 56 let while = 10 57 let var = 7 58 case var { 59 _ if class == while -> True 60 _ if [class] == [5] -> True 61 function if #(function) == #(5) -> False 62 _ if do == function -> True 63 while if while > 5 -> False 64 class -> False 65 } 66} 67"#, 68 ); 69} 70 71#[test] 72fn operator_wrapping_right() { 73 assert_js!( 74 r#"pub fn main(xs, y: Bool, z: Bool) { 75 case xs { 76 #(x) if x == { y == z } -> 1 77 _ -> 0 78 } 79} 80"#, 81 ); 82} 83 84#[test] 85fn operator_wrapping_left() { 86 assert_js!( 87 r#"pub fn main(xs, y: Bool, z: Bool) { 88 case xs { 89 #(x) if { x == y } == z -> 1 90 _ -> 0 91 } 92} 93"#, 94 ); 95} 96 97#[test] 98fn eq_scalar() { 99 assert_js!( 100 r#"pub fn main(xs, y: Int) { 101 case xs { 102 #(x) if x == y -> 1 103 _ -> 0 104 } 105} 106"#, 107 ); 108} 109 110#[test] 111fn not_eq_scalar() { 112 assert_js!( 113 r#"pub fn main(xs, y: Int) { 114 case xs { 115 #(x) if x != y -> 1 116 _ -> 0 117 } 118} 119"#, 120 ); 121} 122 123#[test] 124fn tuple_index() { 125 assert_js!( 126 r#"pub fn main(x, xs: #(Bool, Bool, Bool)) { 127 case x { 128 _ if xs.2 -> 1 129 _ -> 0 130 } 131} 132"#, 133 ); 134} 135 136#[test] 137fn not_eq_complex() { 138 assert_js!( 139 r#"pub fn main(xs, y) { 140 case xs { 141 #(x) if xs != y -> x 142 _ -> 0 143 } 144} 145"#, 146 ); 147} 148 149#[test] 150fn eq_complex() { 151 assert_js!( 152 r#"pub fn main(xs, y) { 153 case xs { 154 #(x) if xs == y -> x 155 _ -> 0 156 } 157} 158"#, 159 ); 160} 161 162#[test] 163fn constant() { 164 assert_js!( 165 r#"pub fn main(xs) { 166 case xs { 167 #(x) if x == 1 -> x 168 _ -> 0 169 } 170} 171"#, 172 ); 173} 174 175#[test] 176fn alternative_patterns() { 177 assert_js!( 178 r#"pub fn main(xs) { 179 case xs { 180 1 | 2 -> 0 181 _ -> 1 182 } 183} 184"#, 185 ); 186} 187 188#[test] 189fn alternative_patterns_list() { 190 assert_js!( 191 r#"pub fn main(xs) -> Int { 192 case xs { 193 [1] | [1, 2] -> 0 194 _ -> 1 195 } 196} 197"#, 198 ); 199} 200 201#[test] 202fn alternative_patterns_assignment() { 203 assert_js!( 204 r#"pub fn main(xs) -> Int { 205 case xs { 206 [x] | [_, x] -> x 207 _ -> 1 208 } 209} 210"#, 211 ); 212} 213 214#[test] 215fn alternative_patterns_guard() { 216 assert_js!( 217 r#"pub fn main(xs) -> Int { 218 case xs { 219 [x] | [_, x] if x == 1 -> x 220 _ -> 0 221 } 222} 223"#, 224 ); 225} 226 227#[test] 228fn field_access() { 229 assert_js!( 230 r#" 231 pub type Person { 232 Person(username: String, name: String, age: Int) 233 } 234 pub fn main() { 235 let given_name = "jack" 236 let raiden = Person("raiden", "jack", 31) 237 case given_name { 238 name if name == raiden.name -> "It's jack" 239 _ -> "It's not jack" 240 } 241 } 242 "# 243 ) 244} 245 246#[test] 247fn nested_record_access() { 248 assert_js!( 249 r#" 250pub type A { 251 A(b: B) 252} 253 254pub type B { 255 B(c: C) 256} 257 258pub type C { 259 C(d: Bool) 260} 261 262pub fn a(a: A) { 263 case a { 264 _ if a.b.c.d -> 1 265 _ -> 0 266 } 267} 268"# 269 ); 270} 271 272#[test] 273fn module_string_access() { 274 assert_js!( 275 ( 276 "package", 277 "hero", 278 r#" 279 pub const ironman = "Tony Stark" 280 "# 281 ), 282 r#" 283 import hero 284 pub fn main() { 285 let name = "Tony Stark" 286 case name { 287 n if n == hero.ironman -> True 288 _ -> False 289 } 290 } 291 "# 292 ); 293} 294 295#[test] 296fn module_list_access() { 297 assert_js!( 298 ( 299 "package", 300 "hero", 301 r#" 302 pub const heroes = ["Tony Stark", "Bruce Wayne"] 303 "# 304 ), 305 r#" 306 import hero 307 pub fn main() { 308 let names = ["Tony Stark", "Bruce Wayne"] 309 case names { 310 n if n == hero.heroes -> True 311 _ -> False 312 } 313 } 314 "# 315 ); 316} 317 318#[test] 319fn module_tuple_access() { 320 assert_js!( 321 ( 322 "package", 323 "hero", 324 r#" 325 pub const hero = #("ironman", "Tony Stark") 326 "# 327 ), 328 r#" 329 import hero 330 pub fn main() { 331 let name = "Tony Stark" 332 case name { 333 n if n == hero.hero.1 -> True 334 _ -> False 335 } 336 } 337 "# 338 ); 339} 340 341#[test] 342fn module_access() { 343 assert_js!( 344 ( 345 "package", 346 "hero", 347 r#" 348 pub type Hero { 349 Hero(name: String) 350 } 351 pub const ironman = Hero("Tony Stark") 352 "# 353 ), 354 r#" 355 import hero 356 pub fn main() { 357 let name = "Tony Stark" 358 case name { 359 n if n == hero.ironman.name -> True 360 _ -> False 361 } 362 } 363 "# 364 ); 365} 366 367#[test] 368fn module_access_submodule() { 369 assert_js!( 370 ( 371 "package", 372 "hero/submodule", 373 r#" 374 pub type Hero { 375 Hero(name: String) 376 } 377 pub const ironman = Hero("Tony Stark") 378 "# 379 ), 380 r#" 381 import hero/submodule 382 pub fn main() { 383 let name = "Tony Stark" 384 case name { 385 n if n == submodule.ironman.name -> True 386 _ -> False 387 } 388 } 389 "# 390 ); 391} 392 393#[test] 394fn module_access_aliased() { 395 assert_js!( 396 ( 397 "package", 398 "hero/submodule", 399 r#" 400 pub type Hero { 401 Hero(name: String) 402 } 403 pub const ironman = Hero("Tony Stark") 404 "# 405 ), 406 r#" 407 import hero/submodule as myhero 408 pub fn main() { 409 let name = "Tony Stark" 410 case name { 411 n if n == myhero.ironman.name -> True 412 _ -> False 413 } 414 } 415 "# 416 ); 417} 418 419#[test] 420fn module_nested_access() { 421 assert_js!( 422 ( 423 "package", 424 "hero", 425 r#" 426 pub type Person { 427 Person(name: String) 428 } 429 pub type Hero { 430 Hero(secret_identity: Person) 431 } 432 const bruce = Person("Bruce Wayne") 433 pub const batman = Hero(bruce) 434 "# 435 ), 436 r#" 437 import hero 438 pub fn main() { 439 let name = "Bruce Wayne" 440 case name { 441 n if n == hero.batman.secret_identity.name -> True 442 _ -> False 443 } 444 } 445 "# 446 ); 447} 448 449#[test] 450fn not() { 451 assert_js!( 452 r#"pub fn main(x, y) { 453 case x { 454 _ if !y -> 0 455 _ -> 1 456 } 457} 458"#, 459 ); 460} 461 462#[test] 463fn not_two() { 464 assert_js!( 465 r#"pub fn main(x, y) { 466 case x { 467 _ if !y && !x -> 0 468 _ -> 1 469 } 470} 471"#, 472 ); 473} 474 475#[test] 476fn custom_type_constructor_imported_and_aliased() { 477 assert_js!( 478 ("package", "other_module", "pub type T { A }"), 479 r#"import other_module.{A as B} 480pub fn func() { 481 case B { 482 x if x == B -> True 483 _ -> False 484 } 485} 486"#, 487 ); 488} 489 490#[test] 491fn imported_aliased_ok() { 492 assert_js!( 493 r#"import gleam.{Ok as Y} 494pub type X { 495 Ok 496} 497pub fn func() { 498 case Y { 499 y if y == Y -> True 500 _ -> False 501 } 502} 503"#, 504 ); 505} 506 507#[test] 508fn imported_ok() { 509 assert_js!( 510 r#"import gleam 511pub type X { 512 Ok 513} 514pub fn func(x) { 515 case gleam.Ok { 516 _ if [] == [ gleam.Ok ] -> True 517 _ -> False 518 } 519} 520"#, 521 ); 522} 523 524// Variant of https://github.com/lpil/decode/pull/6 525#[test] 526fn constructor_function_in_guard() { 527 assert_js!( 528 r#"pub fn func(x) { 529 case [] { 530 _ if [] == [ Ok ] -> True 531 _ -> False 532 } 533} 534 "#, 535 ); 536} 537 538// https://github.com/gleam-lang/gleam/issues/4241 539#[test] 540fn int_division() { 541 assert_js!( 542 r#" 543pub fn main() { 544 case 5 / 2 { 545 x if x == 5 / 2 -> True 546 _ -> False 547 } 548} 549"#, 550 ); 551} 552 553// https://github.com/gleam-lang/gleam/issues/4241 554#[test] 555fn float_division() { 556 assert_js!( 557 r#" 558pub fn main() { 559 case 5.1 /. 0.0 { 560 x if x == 5.1 /. 0.0 -> True 561 _ -> False 562 } 563} 564"#, 565 ); 566} 567 568// https://github.com/gleam-lang/gleam/issues/4241 569#[test] 570fn int_remainder() { 571 assert_js!( 572 r#" 573pub fn main() { 574 case 4 % 0 { 575 x if x == 4 % 0 -> True 576 _ -> False 577 } 578} 579"#, 580 ); 581} 582 583// https://github.com/gleam-lang/gleam/issues/5094 584#[test] 585fn guard_pattern_does_not_shadow_outer_scope() { 586 assert_js!( 587 r#" 588pub type Option(a) { 589 Some(a) 590 None 591} 592 593pub type Container { 594 Container(x: Option(Int)) 595} 596 597pub fn main() { 598 let x: Option(Int) = Some(42) 599 case Some(1) { 600 Some(x) if x < 0 -> Container(None) 601 _ -> { 602 Container(x:) 603 } 604 } 605} 606"#, 607 ); 608} 609 610// https://github.com/gleam-lang/gleam/issues/5214 611#[test] 612fn bit_array_referencing_shadowed_variable() { 613 assert_js!( 614 " 615pub fn main() { 616 let a = 1 617 let a = 2 618 619 case Nil { 620 _ if <<a>> == <<1>> -> False 621 _ if <<a>> == <<2>> -> True 622 _ -> False 623 } 624} 625" 626 ); 627}