this repo has no description
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}