Fork of daniellemaywood.uk/gleam — Wasm codegen work
37 kB
2849 lines
1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: 2021 The Gleam contributors
3
4use hexpm::version::Version;
5use pubgrub::Range;
6
7use crate::{
8 assert_js, assert_js_no_warnings_with_gleam_version, assert_js_warnings_with_gleam_version,
9 assert_ts_def,
10};
11
12#[test]
13fn empty() {
14 assert_js!(
15 r#"
16pub fn go() {
17 <<>>
18}
19"#,
20 );
21}
22
23#[test]
24fn one() {
25 assert_js!(
26 r#"
27pub fn go() {
28 <<256>>
29}
30"#,
31 );
32}
33
34#[test]
35fn two() {
36 assert_js!(
37 r#"
38pub fn go() {
39 <<256, 4>>
40}
41"#,
42 );
43}
44
45#[test]
46fn integer() {
47 assert_js!(
48 r#"
49pub fn go() {
50 <<256:int>>
51}
52"#,
53 );
54}
55
56#[test]
57fn float() {
58 assert_js!(
59 r#"
60pub fn go() {
61 <<1.1:float>>
62}
63"#,
64 );
65}
66
67#[test]
68fn float_big_endian() {
69 assert_js!(
70 r#"
71pub fn go() {
72 <<1.1:float-big>>
73}
74"#,
75 );
76}
77
78#[test]
79fn float_little_endian() {
80 assert_js!(
81 r#"
82pub fn go() {
83 <<1.1:float-little>>
84}
85"#,
86 );
87}
88
89#[test]
90fn float_sized() {
91 assert_js!(
92 r#"
93pub fn go() {
94 <<1.1:float-32>>
95}
96"#,
97 );
98}
99
100#[test]
101fn float_sized_big_endian() {
102 assert_js!(
103 r#"
104pub fn go() {
105 <<1.1:float-32-big>>
106}
107"#,
108 );
109}
110
111#[test]
112fn float_sized_little_endian() {
113 assert_js!(
114 r#"
115pub fn go() {
116 <<1.1:float-32-little>>
117}
118"#,
119 );
120}
121
122#[test]
123fn sized_constant_value() {
124 assert_js!(
125 r#"
126pub fn go() {
127 <<256:64>>
128}
129"#,
130 );
131}
132
133#[test]
134fn sized_dynamic_value() {
135 assert_js!(
136 r#"
137pub fn go(i: Int) {
138 <<i:64>>
139}
140"#,
141 );
142}
143
144#[test]
145fn sized_constant_value_positive_overflow() {
146 assert_js!(
147 r#"
148pub fn go() {
149 <<80_000:16>>
150}
151"#,
152 );
153}
154
155#[test]
156fn sized_constant_value_negative_overflow() {
157 assert_js!(
158 r#"
159pub fn go() {
160 <<-80_000:16>>
161}
162"#,
163 );
164}
165
166#[test]
167fn sized_constant_value_max_size_for_compile_time_evaluation() {
168 assert_js!(
169 r#"
170pub fn go() {
171 <<-1:48>>
172}
173"#,
174 );
175}
176
177#[test]
178fn sized_big_endian_constant_value() {
179 assert_js!(
180 r#"
181pub fn go() {
182 <<256:16-big>>
183}
184"#,
185 );
186}
187
188#[test]
189fn sized_big_endian_dynamic_value() {
190 assert_js!(
191 r#"
192pub fn go(i: Int) {
193 <<i:16-big>>
194}
195"#,
196 );
197}
198
199#[test]
200fn sized_little_endian_constant_value() {
201 assert_js!(
202 r#"
203pub fn go() {
204 <<256:16-little>>
205}
206"#,
207 );
208}
209
210#[test]
211fn sized_little_endian_dynamic_value() {
212 assert_js!(
213 r#"
214pub fn go(i: Int) {
215 <<i:16-little>>
216}
217"#,
218 );
219}
220
221#[test]
222fn explicit_sized_constant_value() {
223 assert_js!(
224 r#"
225pub fn go() {
226 <<256:size(32)>>
227}
228"#,
229 );
230}
231
232#[test]
233fn explicit_sized_dynamic_value() {
234 assert_js!(
235 r#"
236pub fn go(i: Int) {
237 <<i:size(32)>>
238}
239"#,
240 );
241}
242
243#[test]
244fn variable_sized() {
245 assert_js!(
246 r#"
247pub fn go(x, y) {
248 <<x:size(y)>>
249}
250"#,
251 );
252}
253
254#[test]
255fn variable() {
256 assert_js!(
257 r#"
258pub fn go(x) {
259 <<256, 4, x>>
260}
261"#,
262 );
263}
264
265#[test]
266fn utf8() {
267 assert_js!(
268 r#"
269pub fn go(x) {
270 <<256, 4, x, "Gleam":utf8>>
271}
272"#,
273 );
274}
275
276#[test]
277fn match_utf8_with_escape_chars() {
278 assert_js!(
279 r#"
280pub fn go(x) {
281 let assert <<"\"\\\r\n\t\f\u{1f600}">> = x
282}
283"#,
284 );
285}
286
287#[test]
288fn match_utf8() {
289 assert_js!(
290 r#"
291pub fn go(x) {
292 let assert <<"Gleam 👍":utf8>> = x
293}
294"#,
295 );
296}
297
298#[test]
299fn match_case_utf8_with_escape_chars() {
300 assert_js!(
301 r#"
302pub fn go(x) {
303 case x {
304 <<"\"\\\r\n\t\f\u{1f600}">> -> 1
305 _ -> 2
306 }
307}
308"#,
309 );
310}
311
312#[test]
313fn match_case_utf8() {
314 assert_js!(
315 r#"
316pub fn go(x) {
317 case x {
318 <<"Gleam 👍":utf8>> -> 1
319 _ -> 2
320 }
321}
322"#,
323 );
324}
325
326#[test]
327fn utf8_codepoint() {
328 assert_js!(
329 r#"
330pub fn go(x) {
331 <<x:utf8_codepoint, "Gleam":utf8>>
332}
333"#,
334 );
335}
336
337#[test]
338fn utf8_codepoint_typescript() {
339 assert_ts_def!(
340 r#"
341pub fn go(x) {
342 <<x:utf8_codepoint, "Gleam":utf8>>
343}
344"#,
345 );
346}
347
348#[test]
349fn bit_string() {
350 assert_js!(
351 r#"
352pub fn go(x) {
353 <<x:bits>>
354}
355"#,
356 );
357}
358
359#[test]
360fn bits() {
361 assert_js!(
362 r#"
363pub fn go(x) {
364 <<x:bits>>
365}
366"#,
367 );
368}
369
370#[test]
371fn bit_array_sliced() {
372 assert_js!(
373 r#"
374pub fn go(x) {
375 <<<<0xAB>>:bits-4>>
376}
377"#,
378 );
379}
380
381#[test]
382fn bit_array_dynamic_slice() {
383 assert_js!(
384 r#"
385pub fn go(x) {
386 let i = 4
387 <<<<0xAB>>:bits-size(i)>>
388}
389"#,
390 );
391}
392
393#[test]
394fn bit_string_typescript() {
395 assert_ts_def!(
396 r#"
397pub fn go(x) {
398 <<x:bits>>
399}
400"#,
401 );
402}
403
404#[test]
405fn bits_typescript() {
406 assert_ts_def!(
407 r#"
408pub fn go(x) {
409 <<x:bits>>
410}
411"#,
412 );
413}
414
415#[test]
416fn empty_match() {
417 assert_js!(
418 r#"
419pub fn go(x) {
420 let assert <<>> = x
421}
422"#,
423 );
424}
425
426#[test]
427fn case_empty_match() {
428 assert_js!(
429 r#"
430pub fn go(x) {
431 case x {
432 <<>> -> 1
433 _ -> 2
434 }
435}
436"#,
437 );
438}
439
440#[test]
441fn match_bytes() {
442 assert_js!(
443 r#"
444pub fn go(x) {
445 let assert <<1, y>> = x
446}
447"#,
448 );
449}
450
451#[test]
452fn case_match_bytes() {
453 assert_js!(
454 r#"
455pub fn go(x) {
456 case x {
457 <<1, y>> -> y
458 _ -> 1
459 }
460}
461"#,
462 );
463}
464
465#[test]
466fn match_sized() {
467 assert_js!(
468 r#"
469pub fn go(x) {
470 let assert <<a:16, b:8>> = x
471}
472"#,
473 );
474}
475
476#[test]
477fn case_match_sized() {
478 assert_js!(
479 r#"
480pub fn go(x) {
481 case x {
482 <<a:16, b:8>> -> a + b
483 _ -> 1
484 }
485}
486"#,
487 );
488}
489
490#[test]
491fn match_sized_unaligned() {
492 assert_js!(
493 r#"
494pub fn go(x) {
495 let assert <<a:17, b:7>> = x
496}
497"#,
498 );
499}
500
501#[test]
502fn case_match_sized_unaligned() {
503 assert_js!(
504 r#"
505pub fn go(x) {
506 case x {
507 <<a:17, b:7>> -> b * 2
508 _ -> 1
509 }
510}
511"#,
512 );
513}
514
515#[test]
516fn match_sized_constant_pattern() {
517 assert_js!(
518 r#"
519pub fn go(x) {
520 let assert <<1234:16, 123:8>> = x
521}
522"#,
523 );
524}
525
526#[test]
527fn case_match_sized_constant_pattern() {
528 assert_js!(
529 r#"
530pub fn go(x) {
531 case x {
532 <<1234:16, 123:8>> -> 1
533 _ -> 2
534 }
535}
536"#,
537 );
538}
539
540#[test]
541fn match_unsigned() {
542 assert_js!(
543 r#"
544pub fn go(x) {
545 let assert <<a:unsigned>> = x
546}
547"#,
548 );
549}
550
551#[test]
552fn case_match_unsigned() {
553 assert_js!(
554 r#"
555pub fn go(x) {
556 case x {
557 <<a:unsigned>> -> a
558 _ -> 1
559 }
560}
561"#,
562 );
563}
564
565#[test]
566fn match_unsigned_constant_pattern() {
567 assert_js!(
568 r#"
569pub fn go(x) {
570 let assert <<-2:unsigned>> = x
571}
572"#,
573 );
574}
575
576#[test]
577fn case_match_unsigned_constant_pattern() {
578 assert_js!(
579 r#"
580pub fn go(x) {
581 case x {
582 <<-2:unsigned>> -> 1
583 _ -> 2
584 }
585}
586"#,
587 );
588}
589
590#[test]
591fn match_signed() {
592 assert_js!(
593 r#"
594pub fn go(x) {
595 let assert <<a:signed>> = x
596}
597"#,
598 );
599}
600
601#[test]
602fn case_match_signed() {
603 assert_js!(
604 r#"
605pub fn go(x) {
606 case x {
607 <<a:signed>> -> a
608 _ -> 1
609 }
610}
611"#,
612 );
613}
614
615#[test]
616fn match_signed_constant_pattern() {
617 assert_js!(
618 r#"
619pub fn go(x) {
620 let assert <<-1:signed>> = x
621}
622"#,
623 );
624}
625
626#[test]
627fn case_match_signed_constant_pattern() {
628 assert_js!(
629 r#"
630pub fn go(x) {
631 case x {
632 <<-1:signed>> -> 1
633 _ -> 2
634 }
635}
636"#,
637 );
638}
639
640#[test]
641fn match_sized_big_endian() {
642 assert_js!(
643 r#"
644pub fn go(x) {
645 let assert <<a:16-big>> = x
646}
647"#,
648 );
649}
650
651#[test]
652fn case_match_sized_big_endian() {
653 assert_js!(
654 r#"
655pub fn go(x) {
656 case x {
657 <<a:16-big>> -> a
658 _ -> 1
659 }
660}
661"#,
662 );
663}
664
665#[test]
666fn match_sized_big_endian_constant_pattern() {
667 assert_js!(
668 r#"
669pub fn go(x) {
670 let assert <<1234:16-big>> = x
671}
672"#,
673 );
674}
675
676#[test]
677fn case_match_sized_big_endian_constant_pattern() {
678 assert_js!(
679 r#"
680pub fn go(x) {
681 case x {
682 <<1234:16-big>> -> 1
683 _ -> 2
684 }
685}
686"#,
687 );
688}
689
690#[test]
691fn match_sized_little_endian() {
692 assert_js!(
693 r#"
694pub fn go(x) {
695 let assert <<a:16-little>> = x
696}
697"#,
698 );
699}
700
701#[test]
702fn case_match_sized_little_endian() {
703 assert_js!(
704 r#"
705pub fn go(x) {
706 case x {
707 <<a:16-little>> -> a
708 _ -> 1
709 }
710}
711"#,
712 );
713}
714
715#[test]
716fn match_sized_little_endian_constant_pattern() {
717 assert_js!(
718 r#"
719pub fn go(x) {
720 let assert <<1234:16-little>> = x
721}
722"#,
723 );
724}
725
726#[test]
727fn case_match_sized_little_endian_constant_pattern() {
728 assert_js!(
729 r#"
730pub fn go(x) {
731 case x {
732 <<1234:16-little>> -> 1
733 _ -> 2
734 }
735}
736"#,
737 );
738}
739
740#[test]
741fn match_sized_big_endian_unsigned() {
742 assert_js!(
743 r#"
744pub fn go(x) {
745 let assert <<a:16-big-unsigned>> = x
746}
747"#,
748 );
749}
750
751#[test]
752fn case_match_sized_big_endian_unsigned() {
753 assert_js!(
754 r#"
755pub fn go(x) {
756 case x {
757 <<a:16-big-unsigned>> -> a
758 _ -> 1
759 }
760}
761"#,
762 );
763}
764
765#[test]
766fn match_sized_big_endian_unsigned_constant_pattern() {
767 assert_js!(
768 r#"
769pub fn go(x) {
770 let assert <<1234:16-big-unsigned>> = x
771}
772"#,
773 );
774}
775
776#[test]
777fn case_match_sized_big_endian_unsigned_constant_pattern() {
778 assert_js!(
779 r#"
780pub fn go(x) {
781 case x {
782 <<1234:16-big-unsigned>> -> 1
783 _ -> 2
784 }
785}
786"#,
787 );
788}
789
790#[test]
791fn match_sized_big_endian_signed() {
792 assert_js!(
793 r#"
794pub fn go(x) {
795 let assert <<a:16-big-signed>> = x
796}
797"#,
798 );
799}
800
801#[test]
802fn case_match_sized_big_endian_signed() {
803 assert_js!(
804 r#"
805pub fn go(x) {
806 case x {
807 <<a:16-big-signed>> -> a
808 _ -> 1
809 }
810}
811"#,
812 );
813}
814
815#[test]
816fn match_sized_big_endian_signed_constant_pattern() {
817 assert_js!(
818 r#"
819pub fn go(x) {
820 let assert <<1234:16-big-signed>> = x
821}
822"#,
823 );
824}
825
826#[test]
827fn case_match_sized_big_endian_signed_constant_pattern() {
828 assert_js!(
829 r#"
830pub fn go(x) {
831 case x {
832 <<1234:16-big-signed>> -> 1
833 _ -> 2
834 }
835}
836"#,
837 );
838}
839
840#[test]
841fn match_sized_little_endian_unsigned() {
842 assert_js!(
843 r#"
844pub fn go(x) {
845 let assert <<a:16-little-unsigned>> = x
846}
847"#,
848 );
849}
850
851#[test]
852fn case_match_sized_little_endian_unsigned() {
853 assert_js!(
854 r#"
855pub fn go(x) {
856 case x {
857 <<a:16-little-unsigned>> -> a
858 _ -> 1
859 }
860}
861"#,
862 );
863}
864
865#[test]
866fn match_sized_little_endian_unsigned_constant_pattern() {
867 assert_js!(
868 r#"
869pub fn go(x) {
870 let assert <<1234:16-little-unsigned>> = x
871}
872"#,
873 );
874}
875
876#[test]
877fn case_match_sized_little_endian_unsigned_constant_pattern() {
878 assert_js!(
879 r#"
880pub fn go(x) {
881 case x {
882 <<1234:16-little-unsigned>> -> 1
883 _ -> 2
884 }
885}
886"#,
887 );
888}
889
890#[test]
891fn match_sized_little_endian_signed() {
892 assert_js!(
893 r#"
894pub fn go(x) {
895 let assert <<a:16-little-signed>> = x
896}
897"#,
898 );
899}
900
901#[test]
902fn case_match_sized_little_endian_signed() {
903 assert_js!(
904 r#"
905pub fn go(x) {
906 case x {
907 <<a:16-little-signed>> -> a
908 _ -> 1
909 }
910}
911"#,
912 );
913}
914
915#[test]
916fn match_sized_little_endian_signed_constant_pattern() {
917 assert_js!(
918 r#"
919pub fn go(x) {
920 let assert <<1234:16-little-signed>> = x
921}
922"#,
923 );
924}
925
926#[test]
927fn case_match_sized_little_endian_signed_constant_pattern() {
928 assert_js!(
929 r#"
930pub fn go(x) {
931 case x {
932 <<1234:16-little-signed>> -> 1
933 _ -> 2
934 }
935}
936"#,
937 );
938}
939
940#[test]
941fn match_dynamic_size() {
942 assert_js!(
943 r#"
944pub fn go(x) {
945 let n = 16
946 let assert <<a:size(n)>> = x
947}
948"#
949 );
950}
951
952#[test]
953fn case_match_dynamic_size() {
954 assert_js!(
955 r#"
956pub fn go(x) {
957 let n = 16
958 case x {
959 <<a:size(n)>> -> a
960 _ -> 1
961 }
962}
963"#
964 );
965}
966
967#[test]
968fn match_dynamic_size_with_other_segments() {
969 assert_js!(
970 r#"
971pub fn go(x) {
972 let n = 16
973 let m = 32
974 let assert <<first:size(8), a:size(n), b:size(m), rest:bits>> = x
975}
976"#
977 );
978}
979
980#[test]
981fn case_match_dynamic_size_with_other_segments() {
982 assert_js!(
983 r#"
984pub fn go(x) {
985 let n = 16
986 let m = 32
987 case x {
988 <<first:size(8), a:size(n), b:size(m), rest:bits>> -> first + a + b
989 _ -> 1
990 }
991}
992"#
993 );
994}
995
996#[test]
997fn match_dynamic_size_shadowed_variable() {
998 assert_js!(
999 r#"
1000pub fn go(x) {
1001 let n = 16
1002 let n = 5
1003 let assert <<a:size(n)>> = x
1004}
1005"#
1006 );
1007}
1008
1009#[test]
1010fn case_match_dynamic_size_shadowed_variable() {
1011 assert_js!(
1012 r#"
1013pub fn go(x) {
1014 let n = 16
1015 let n = 5
1016 case x {
1017 <<a:size(n)>> -> a
1018 _ -> 1
1019 }
1020}
1021"#
1022 );
1023}
1024
1025#[test]
1026fn match_dynamic_size_literal_value() {
1027 assert_js!(
1028 r#"
1029pub fn go(x) {
1030 let n = 8
1031 let assert <<a:size(n), 0b010101:size(8)>> = x
1032}
1033"#
1034 );
1035}
1036
1037#[test]
1038fn case_match_dynamic_size_literal_value() {
1039 assert_js!(
1040 r#"
1041pub fn go(x) {
1042 let n = 8
1043 case x {
1044 <<a:size(n), 0b010101:size(8)>> -> a
1045 _ -> 1
1046 }
1047}
1048"#
1049 );
1050}
1051
1052#[test]
1053fn match_dynamic_bits_size() {
1054 assert_js!(
1055 r#"
1056pub fn go(x) {
1057 let n = 16
1058 let assert <<a:bits-size(n)>> = x
1059}
1060"#
1061 );
1062}
1063
1064#[test]
1065fn case_match_dynamic_bits_size() {
1066 assert_js!(
1067 r#"
1068pub fn go(x) {
1069 let n = 16
1070 case x {
1071 <<a:bits-size(n)>> -> a
1072 _ -> x
1073 }
1074}
1075"#
1076 );
1077}
1078
1079#[test]
1080fn match_dynamic_bytes_size() {
1081 assert_js!(
1082 r#"
1083pub fn go(x) {
1084 let n = 3
1085 let assert <<a:bytes-size(n)>> = x
1086}
1087"#
1088 );
1089}
1090
1091#[test]
1092fn case_match_dynamic_bytes_size() {
1093 assert_js!(
1094 r#"
1095pub fn go(x) {
1096 let n = 3
1097 case x {
1098 <<a:bytes-size(n)>> -> a
1099 _ -> x
1100 }
1101}
1102"#
1103 );
1104}
1105
1106#[test]
1107fn discard_sized() {
1108 assert_js!(
1109 r#"
1110pub fn go(x) {
1111 let assert <<_:16, _:8>> = x
1112 let assert <<_:16-little-signed, _:8>> = x
1113}
1114"#,
1115 );
1116}
1117
1118#[test]
1119fn case_discard_sized() {
1120 assert_js!(
1121 r#"
1122pub fn go(x) {
1123 case x {
1124 <<_:16, _:8>> -> 1
1125 _ -> 2
1126 }
1127 case x {
1128 <<_:16-little-signed, _:8>> -> 1
1129 _ -> 2
1130 }
1131}
1132"#,
1133 );
1134}
1135
1136#[test]
1137fn match_sized_value() {
1138 assert_js!(
1139 r#"
1140pub fn go(x) {
1141 let assert <<i:16>> = x
1142}
1143"#,
1144 );
1145}
1146
1147#[test]
1148fn case_match_sized_value() {
1149 assert_js!(
1150 r#"
1151pub fn go(x) {
1152 case x {
1153 <<i:16>> -> i
1154 _ -> 1
1155 }
1156}
1157"#,
1158 );
1159}
1160
1161#[test]
1162fn match_sized_value_constant_pattern() {
1163 assert_js!(
1164 r#"
1165pub fn go(x) {
1166 let assert <<258:16>> = x
1167}
1168"#,
1169 );
1170}
1171
1172#[test]
1173fn case_match_sized_value_constant_pattern() {
1174 assert_js!(
1175 r#"
1176pub fn go(x) {
1177 case x {
1178 <<258:16>> -> 1
1179 _ -> 2
1180 }
1181}
1182"#,
1183 );
1184}
1185
1186#[test]
1187fn match_float() {
1188 assert_js!(
1189 r#"
1190pub fn go(x) {
1191 let assert <<a:float, b:int>> = x
1192}
1193"#,
1194 );
1195}
1196
1197#[test]
1198fn case_match_float() {
1199 assert_js!(
1200 r#"
1201pub fn go(x) {
1202 case x {
1203 <<a:float, b:int>> -> #(a, b)
1204 _ -> #(1.1, 2)
1205 }
1206}
1207"#,
1208 );
1209}
1210
1211#[test]
1212fn match_float_big_endian() {
1213 assert_js!(
1214 r#"
1215pub fn go(x) {
1216 let assert <<a:float-big, b:int>> = x
1217}
1218"#,
1219 );
1220}
1221
1222#[test]
1223fn case_match_float_big_endian() {
1224 assert_js!(
1225 r#"
1226pub fn go(x) {
1227 case x {
1228 <<a:float-big, b:int>> -> #(a, b)
1229 _ -> #(1.1, 1)
1230 }
1231}
1232"#,
1233 );
1234}
1235
1236#[test]
1237fn match_float_little_endian() {
1238 assert_js!(
1239 r#"
1240pub fn go(x) {
1241 let assert <<a:float-little, b:int>> = x
1242}
1243"#,
1244 );
1245}
1246
1247#[test]
1248fn case_match_float_little_endian() {
1249 assert_js!(
1250 r#"
1251pub fn go(x) {
1252 case x {
1253 <<a:float-little, b:int>> -> #(a, b)
1254 _ -> #(1.1, 2)
1255 }
1256}
1257"#,
1258 );
1259}
1260
1261#[test]
1262fn match_float_sized() {
1263 assert_js!(
1264 r#"
1265pub fn go(x) {
1266 let assert <<a:float-32, b:int>> = x
1267}
1268"#,
1269 );
1270}
1271
1272#[test]
1273fn case_match_float_sized() {
1274 assert_js!(
1275 r#"
1276pub fn go(x) {
1277 case x {
1278 <<a:float-32, b:int>> -> #(a, b)
1279 _ -> #(1.1, 2)
1280 }
1281}
1282"#,
1283 );
1284}
1285
1286#[test]
1287fn match_float_sized_big_endian() {
1288 assert_js!(
1289 r#"
1290pub fn go(x) {
1291 let assert <<a:float-32-big, b:int>> = x
1292}
1293"#,
1294 );
1295}
1296
1297#[test]
1298fn case_match_float_sized_big_endian() {
1299 assert_js!(
1300 r#"
1301pub fn go(x) {
1302 case x {
1303 <<a:float-32-big, b:int>> -> #(a, b)
1304 _ -> #(1.1, 2)
1305 }
1306}
1307"#,
1308 );
1309}
1310
1311#[test]
1312fn match_float_sized_little_endian() {
1313 assert_js!(
1314 r#"
1315pub fn go(x) {
1316 let assert <<a:float-32-little, b:int>> = x
1317}
1318"#,
1319 );
1320}
1321
1322#[test]
1323fn case_match_float_sized_little_endian() {
1324 assert_js!(
1325 r#"
1326pub fn go(x) {
1327 case x {
1328 <<a:float-32-little, b:int>> -> #(a, b)
1329 _ -> #(1.1, 2)
1330 }
1331}
1332"#,
1333 );
1334}
1335
1336#[test]
1337fn match_literal_float() {
1338 assert_js!(
1339 r#"
1340pub fn go(x) {
1341 let assert <<1.4, b:int>> = x
1342}
1343"#,
1344 );
1345}
1346
1347#[test]
1348fn case_match_literal_float() {
1349 assert_js!(
1350 r#"
1351pub fn go(x) {
1352 case x {
1353 <<1.4, b:int>> -> 1
1354 _ -> 2
1355 }
1356}
1357"#,
1358 );
1359}
1360
1361#[test]
1362fn match_literal_unaligned_float() {
1363 assert_js!(
1364 r#"
1365pub fn go(x) {
1366 let n = 1
1367 let assert <<_:size(n), 1.1, _:bits>> = x
1368}
1369"#,
1370 );
1371}
1372
1373#[test]
1374fn case_match_literal_unaligned_float() {
1375 assert_js!(
1376 r#"
1377pub fn go(x) {
1378 let n = 1
1379 case x {
1380 <<_:size(n), 1.1, _:int>> -> 1
1381 _ -> 2
1382 }
1383}
1384"#,
1385 );
1386}
1387
1388#[test]
1389fn match_literal_aligned_float() {
1390 assert_js!(
1391 r#"
1392pub fn go(x) {
1393 let assert <<_, 1.1, _:bits>> = x
1394}
1395"#,
1396 );
1397}
1398
1399#[test]
1400fn case_match_literal_aligned_float() {
1401 assert_js!(
1402 r#"
1403pub fn go(x) {
1404 case x {
1405 <<_, 1.1, _:int>> -> 1
1406 _ -> 2
1407 }
1408}
1409"#,
1410 );
1411}
1412
1413#[test]
1414fn match_float_16_bit() {
1415 assert_js!(
1416 r#"
1417pub fn go(x) {
1418 let assert <<a:float-size(16)>> = x
1419}
1420"#
1421 );
1422}
1423
1424#[test]
1425fn case_match_float_16_bit() {
1426 assert_js!(
1427 r#"
1428pub fn go(x) {
1429 case x {
1430 <<a:float-size(16)>> -> a
1431 _ -> 1.1
1432 }
1433}
1434"#
1435 );
1436}
1437
1438#[test]
1439fn match_rest() {
1440 assert_js!(
1441 r#"
1442pub fn go(x) {
1443 let assert <<_, b:bytes>> = <<1,2,3>>
1444}
1445"#,
1446 );
1447}
1448
1449#[test]
1450fn case_match_rest() {
1451 assert_js!(
1452 r#"
1453pub fn go(x) {
1454 case <<1, 2, 3>> {
1455 <<_, b:bytes>> -> b
1456 _ -> x
1457 }
1458}
1459"#,
1460 );
1461}
1462
1463#[test]
1464fn match_bytes_with_size() {
1465 assert_js!(
1466 r#"
1467pub fn go(x) {
1468 let assert <<f:bytes-2>> = <<1, 2>>
1469}
1470"#,
1471 );
1472}
1473
1474#[test]
1475fn case_match_bytes_with_size() {
1476 assert_js!(
1477 r#"
1478pub fn go(x) {
1479 case <<1, 2>> {
1480 <<f:bytes-2>> -> f
1481 _ -> x
1482 }
1483}
1484"#,
1485 );
1486}
1487
1488#[test]
1489fn match_bits_with_size() {
1490 assert_js!(
1491 r#"
1492pub fn go(x) {
1493 let assert <<_:4, f:bits-2, _:1>> = <<0x77:7>>
1494}
1495"#,
1496 );
1497}
1498
1499#[test]
1500fn case_match_bits_with_size() {
1501 assert_js!(
1502 r#"
1503pub fn go(x) {
1504 case <<0x77:7>> {
1505 <<_:4, f:bits-2, _:1>> -> f
1506 _ -> x
1507 }
1508}
1509"#,
1510 );
1511}
1512
1513#[test]
1514fn match_rest_bytes() {
1515 assert_js!(
1516 r#"
1517pub fn go(x) {
1518 let assert <<_, b:bytes>> = <<1,2,3>>
1519}
1520"#,
1521 );
1522}
1523
1524#[test]
1525fn case_match_rest_bytes() {
1526 assert_js!(
1527 r#"
1528pub fn go(x) {
1529 case x {
1530 <<_, b:bytes>> -> b
1531 _ -> x
1532 }
1533}
1534"#,
1535 );
1536}
1537
1538#[test]
1539fn match_rest_bits() {
1540 assert_js!(
1541 r#"
1542pub fn go(x) {
1543 let assert <<_, b:bits>> = <<1,2,3>>
1544}
1545"#,
1546 );
1547}
1548
1549#[test]
1550fn case_match_rest_bits() {
1551 assert_js!(
1552 r#"
1553pub fn go(x) {
1554 case x {
1555 <<_, b:bits>> -> b
1556 _ -> x
1557 }
1558}
1559"#,
1560 );
1561}
1562
1563#[test]
1564fn match_rest_bits_unaligned() {
1565 assert_js!(
1566 r#"
1567pub fn go(x) {
1568 let assert <<_:5, b:bits>> = <<1,2,3>>
1569}
1570"#,
1571 );
1572}
1573
1574#[test]
1575fn case_match_rest_bits_unaligned() {
1576 assert_js!(
1577 r#"
1578pub fn go(x) {
1579 case x {
1580 <<_:5, b:bits>> -> b
1581 _ -> x
1582 }
1583}
1584"#,
1585 );
1586}
1587
1588#[test]
1589fn match_binary_size() {
1590 assert_js!(
1591 r#"
1592pub fn go(x) {
1593 let assert <<_, a:2-bytes>> = x
1594 let assert <<_, b:bytes-size(2)>> = x
1595}
1596"#,
1597 );
1598}
1599
1600#[test]
1601fn case_match_binary_size() {
1602 assert_js!(
1603 r#"
1604pub fn go(x) {
1605 case x {
1606 <<_, a:2-bytes>> -> a
1607 _ -> x
1608 }
1609
1610 case x {
1611 <<_, b:bytes-size(2)>> -> b
1612 _ -> x
1613 }
1614}
1615"#,
1616 );
1617}
1618
1619#[test]
1620fn unaligned_int_expression_requires_v1_9() {
1621 assert_js_warnings_with_gleam_version!(
1622 Range::higher_than(Version::new(1, 8, 0)),
1623 "
1624pub fn main() {
1625 <<0:1>>
1626}
1627 ",
1628 );
1629}
1630
1631#[test]
1632fn bits_expression_does_not_require_v1_9() {
1633 assert_js_no_warnings_with_gleam_version!(
1634 Range::higher_than(Version::new(1, 8, 0)),
1635 "
1636pub fn main() {
1637 <<<<0>>:bits>>
1638}
1639 ",
1640 );
1641}
1642
1643#[test]
1644fn sized_bits_expression_requires_v1_9() {
1645 assert_js_warnings_with_gleam_version!(
1646 Range::higher_than(Version::new(1, 8, 0)),
1647 "
1648pub fn main() {
1649 <<<<0>>:bits-5>>
1650}
1651 ",
1652 );
1653}
1654
1655#[test]
1656fn unaligned_int_pattern_requires_v1_9() {
1657 assert_js_warnings_with_gleam_version!(
1658 Range::higher_than(Version::new(1, 8, 0)),
1659 "
1660pub fn main() {
1661 let assert <<_:3>> = <<0>>
1662}
1663 ",
1664 );
1665}
1666
1667#[test]
1668fn bits_pattern_requires_v1_9() {
1669 assert_js_warnings_with_gleam_version!(
1670 Range::higher_than(Version::new(1, 8, 0)),
1671 "
1672pub fn main() {
1673 let assert <<_:bits>> = <<0>>
1674}
1675 ",
1676 );
1677}
1678
1679#[test]
1680fn bytes_pattern_with_odd_size_does_not_require_v1_9() {
1681 assert_js_no_warnings_with_gleam_version!(
1682 Range::higher_than(Version::new(1, 8, 0)),
1683 "
1684pub fn main() {
1685 let assert <<_:bytes-3>> = <<0, 1, 2>>
1686}
1687 ",
1688 );
1689}
1690
1691#[test]
1692fn sized_bits_expression_with_javascript_external_does_not_require_v1_9() {
1693 assert_js_no_warnings_with_gleam_version!(
1694 Range::higher_than(Version::new(1, 8, 0)),
1695 r#"
1696@external(javascript, "test.mjs", "go")
1697pub fn go() -> BitArray {
1698 <<0:size(5)>>
1699}
1700 "#,
1701 );
1702}
1703
1704#[test]
1705fn bits_pattern_with_javascript_external_does_not_require_v1_9() {
1706 assert_js_no_warnings_with_gleam_version!(
1707 Range::higher_than(Version::new(1, 8, 0)),
1708 r#"
1709@external(javascript, "test.mjs", "go")
1710pub fn go() -> BitArray {
1711 let <<a:bits>> = <<>>
1712 a
1713}
1714 "#,
1715 );
1716}
1717
1718#[test]
1719fn as_module_const() {
1720 assert_js!(
1721 r#"
1722 pub const data = <<
1723 0x1,
1724 2,
1725 2:size(16),
1726 0x4:size(32),
1727 -1:32,
1728 "Gleam":utf8,
1729 4.2:float,
1730 4.2:32-float,
1731 <<0xFA>>:bits-6,
1732 -1:64,
1733 <<
1734 <<1, 2, 3>>:bits,
1735 "Gleam":utf8,
1736 1024
1737 >>:bits
1738 >>
1739 "#
1740 )
1741}
1742
1743#[test]
1744fn bit_array_literal_string_constant_is_treated_as_utf8() {
1745 assert_js!(r#"pub const a = <<"hello", " ", "world">>"#);
1746}
1747
1748#[test]
1749fn bit_array_literal_string_is_treated_as_utf8() {
1750 assert_js!(
1751 r#"
1752pub fn main() {
1753 <<"hello", " ", "world">>
1754}"#
1755 );
1756}
1757
1758#[test]
1759fn bit_array_literal_string_pattern_is_treated_as_utf8() {
1760 assert_js!(
1761 r#"
1762pub fn main() {
1763 case <<>> {
1764 <<"a", "b", _:bytes>> -> 1
1765 _ -> 2
1766 }
1767}"#
1768 );
1769}
1770
1771#[test]
1772fn with_unit() {
1773 assert_js!(
1774 r#"
1775pub fn main() {
1776 <<1:size(2)-unit(2), 2:size(3)-unit(4)>>
1777}
1778"#,
1779 );
1780}
1781
1782#[test]
1783fn dynamic_size_with_unit() {
1784 assert_js!(
1785 r#"
1786pub fn main() {
1787 let size = 3
1788 <<1:size(size)-unit(2)>>
1789}
1790"#,
1791 );
1792}
1793
1794#[test]
1795fn pattern_with_unit() {
1796 assert_js!(
1797 r#"
1798pub fn go(x) {
1799 let assert <<1:size(2)-unit(2), 2:size(3)-unit(4)>> = x
1800}
1801"#,
1802 );
1803}
1804
1805#[test]
1806fn case_pattern_with_unit() {
1807 assert_js!(
1808 r#"
1809pub fn go(x) {
1810 case x {
1811 <<1:size(2)-unit(2), 2:size(3)-unit(4)>> -> 1
1812 _ -> 2
1813 }
1814}
1815"#,
1816 );
1817}
1818
1819#[test]
1820fn dynamic_size_pattern_with_unit() {
1821 assert_js!(
1822 r#"
1823pub fn go(x) {
1824 let size = 3
1825 let assert <<1:size(size)-unit(2)>> = x
1826}
1827"#,
1828 );
1829}
1830
1831#[test]
1832fn case_dynamic_size_pattern_with_unit() {
1833 assert_js!(
1834 r#"
1835pub fn go(x) {
1836 let size = 3
1837 case x {
1838 <<1:size(size)-unit(2)>> -> 1
1839 _ -> 2
1840 }
1841}
1842"#,
1843 );
1844}
1845
1846#[test]
1847fn case_dynamic_size_float_pattern_with_unit() {
1848 assert_js!(
1849 r#"
1850pub fn go(x) {
1851 let size = 3
1852 case x {
1853 <<1.3:size(size)-unit(2)>> -> 1
1854 _ -> 2
1855 }
1856}
1857"#,
1858 );
1859}
1860
1861#[test]
1862fn case_with_remaining_bytes_after_constant_size() {
1863 assert_js!(
1864 r#"
1865pub fn go(x) {
1866 case x {
1867 <<_, _, _:bytes>> -> 1
1868 _ -> 2
1869 }
1870}
1871"#,
1872 );
1873}
1874
1875#[test]
1876fn case_with_remaining_bytes_after_variable_size() {
1877 assert_js!(
1878 r#"
1879pub fn go(x) {
1880 let n = 1
1881 case x {
1882 <<_:size(n), _, _:bytes>> -> 1
1883 _ -> 2
1884 }
1885}
1886"#,
1887 );
1888}
1889
1890#[test]
1891fn case_with_remaining_bytes_after_variable_size_2() {
1892 assert_js!(
1893 r#"
1894pub fn go(x) {
1895 let n = 1
1896 case x {
1897 <<m:size(n), _:size(m), _:bytes>> -> 1
1898 _ -> 2
1899 }
1900}
1901"#,
1902 );
1903}
1904
1905#[test]
1906fn case_is_byte_aligned() {
1907 assert_js!(
1908 r#"
1909pub fn is_byte_aligned(x) {
1910 case x {
1911 <<_:bytes>> -> True
1912 _ -> False
1913 }
1914}
1915"#,
1916 );
1917}
1918
1919#[test]
1920fn alternative_patterns_with_variable_size() {
1921 assert_js!(
1922 r#"
1923pub fn go(x) {
1924 case x {
1925 <<_, n, rest:size(n)>> |
1926 <<n, _, rest:size(n)>> -> True
1927 _ -> False
1928 }
1929}
1930"#,
1931 );
1932}
1933
1934#[test]
1935fn variable_sized_segment() {
1936 assert_js!(
1937 r#"
1938pub fn go(x) {
1939 case x {
1940 <<n, rest:size(n)>> -> 1
1941 _ -> 2
1942 }
1943}
1944"#
1945 )
1946}
1947
1948#[test]
1949fn segments_shadowing_each_other() {
1950 assert_js!(
1951 r#"
1952pub fn go(x) {
1953 let n = 1
1954 case x {
1955 <<n, rest:size(n)>> -> 1
1956 _ -> 2
1957 }
1958}
1959"#
1960 )
1961}
1962
1963#[test]
1964fn negative_size_pattern() {
1965 assert_js!(
1966 r#"
1967pub fn go(x) {
1968 let n = -10
1969 case x {
1970 <<int:size(n)>> -> int
1971 _ -> 2
1972 }
1973}
1974"#
1975 )
1976}
1977
1978#[test]
1979fn negative_size_pattern_2() {
1980 assert_js!(
1981 r#"
1982pub fn go(x) {
1983 case x {
1984 <<n:signed, int:size(n)>> -> int
1985 _ -> 2
1986 }
1987}
1988"#
1989 )
1990}
1991
1992// https://github.com/gleam-lang/gleam/issues/3375
1993#[test]
1994fn bit_array_assignment_int() {
1995 assert_js!(
1996 "
1997pub fn main() {
1998 let assert <<1 as a>> = <<1>>
1999 a
2000}
2001"
2002 );
2003}
2004
2005#[test]
2006fn case_bit_array_assignment_int() {
2007 assert_js!(
2008 "
2009pub fn go(x) {
2010 case x {
2011 <<1 as n>>
2012 | <<2 as n, _:bytes>> -> n
2013 _ -> 1
2014 }
2015}
2016"
2017 );
2018}
2019
2020// https://github.com/gleam-lang/gleam/issues/3375
2021#[test]
2022fn bit_array_assignment_float() {
2023 assert_js!(
2024 "
2025pub fn main() {
2026 let assert <<3.14 as pi:float>> = <<3.14>>
2027 pi
2028}
2029"
2030 );
2031}
2032
2033#[test]
2034fn case_bit_array_assignment_float() {
2035 assert_js!(
2036 "
2037pub fn go(x) {
2038 case x {
2039 <<3.14 as pi:float>>
2040 | <<1.1 as pi:float, _:bytes>> -> pi
2041 _ -> 1.1
2042 }
2043}
2044"
2045 );
2046}
2047
2048// https://github.com/gleam-lang/gleam/issues/3375
2049#[test]
2050fn bit_array_assignment_string() {
2051 assert_js!(
2052 r#"
2053pub fn main() {
2054 let assert <<"Hello, world!" as message:utf8>> = <<"Hello, world!">>
2055 message
2056}
2057"#
2058 );
2059}
2060
2061#[test]
2062fn case_bit_array_assignment_string() {
2063 assert_js!(
2064 r#"
2065pub fn go(x) {
2066 case x {
2067 <<"Hello" as message>>
2068 | <<"Jak" as message, _:bytes>> -> message
2069 _ -> "wibble"
2070 }
2071}
2072"#
2073 );
2074}
2075
2076// https://github.com/gleam-lang/gleam/issues/3375
2077#[test]
2078fn bit_array_assignment_discard() {
2079 assert_js!(
2080 r#"
2081pub fn main() {
2082 let assert <<_ as number>> = <<10>>
2083 number
2084}
2085"#
2086 );
2087}
2088
2089#[test]
2090fn case_bit_array_assignment_discard() {
2091 assert_js!(
2092 r#"
2093pub fn go(x) {
2094 case x {
2095 <<_ as n>>
2096 | <<_ as n, _:bytes>> -> n
2097 _ -> 1
2098 }
2099}
2100"#
2101 );
2102}
2103
2104#[test]
2105fn utf16() {
2106 assert_js!(
2107 r#"
2108pub fn main() {
2109 <<"Hello, world!":utf16>>
2110}
2111"#
2112 );
2113}
2114
2115#[test]
2116fn utf16_codepoint() {
2117 assert_js!(
2118 r#"
2119fn codepoint() -> UtfCodepoint { todo }
2120
2121pub fn main() {
2122 let my_codepoint = codepoint()
2123 <<my_codepoint:utf16_codepoint>>
2124}
2125"#
2126 );
2127}
2128
2129#[test]
2130fn utf32() {
2131 assert_js!(
2132 r#"
2133pub fn main() {
2134 <<"Hello, world!":utf32>>
2135}
2136"#
2137 );
2138}
2139
2140#[test]
2141fn utf32_codepoint() {
2142 assert_js!(
2143 r#"
2144fn codepoint() -> UtfCodepoint { todo }
2145
2146pub fn main() {
2147 let my_codepoint = codepoint()
2148 <<my_codepoint:utf32_codepoint>>
2149}
2150"#
2151 );
2152}
2153
2154#[test]
2155fn const_utf16() {
2156 assert_js!(
2157 r#"
2158pub const message = <<"Hello, world!":utf16>>
2159"#
2160 );
2161}
2162
2163#[test]
2164fn const_utf32() {
2165 assert_js!(
2166 r#"
2167pub const message = <<"Hello, world!":utf32>>
2168"#
2169 );
2170}
2171
2172#[test]
2173fn pattern_match_utf16() {
2174 assert_js!(
2175 r#"
2176pub fn go(x) {
2177 let assert <<"Hello":utf16, _rest:bytes>> = x
2178}
2179"#
2180 );
2181}
2182
2183#[test]
2184fn pattern_match_utf32() {
2185 assert_js!(
2186 r#"
2187pub fn go(x) {
2188 let assert <<"Hello":utf32, _rest:bytes>> = x
2189}
2190"#
2191 );
2192}
2193
2194#[test]
2195fn utf16_little_endian() {
2196 assert_js!(
2197 r#"
2198pub fn main() {
2199 <<"Hello, world!":utf16-little>>
2200}
2201"#
2202 );
2203}
2204
2205#[test]
2206fn utf32_little_endian() {
2207 assert_js!(
2208 r#"
2209pub fn main() {
2210 <<"Hello, world!":utf32-little>>
2211}
2212"#
2213 );
2214}
2215
2216#[test]
2217fn pattern_match_utf16_little_endian() {
2218 assert_js!(
2219 r#"
2220pub fn go(x) {
2221 let assert <<"Hello":utf16-little, _rest:bytes>> = x
2222}
2223"#
2224 );
2225}
2226
2227#[test]
2228fn pattern_match_utf32_little_endian() {
2229 assert_js!(
2230 r#"
2231pub fn go(x) {
2232 let assert <<"Hello":utf32-little, _rest:bytes>> = x
2233}
2234"#
2235 );
2236}
2237
2238// https://github.com/gleam-lang/gleam/issues/4630
2239#[test]
2240fn tuple_bit_array() {
2241 assert_js!(
2242 "
2243pub fn go(x) {
2244 let assert #(<<>>) = x
2245}
2246"
2247 );
2248}
2249
2250// https://github.com/gleam-lang/gleam/issues/4630
2251#[test]
2252fn tuple_bit_array_case() {
2253 assert_js!(
2254 "
2255pub fn go(x) {
2256 case x {
2257 #(<<>>) -> 1
2258 _ -> 2
2259 }
2260}
2261"
2262 );
2263}
2264
2265#[test]
2266fn tuple_multiple_bit_arrays() {
2267 assert_js!(
2268 "
2269pub fn go(x) {
2270 let assert #(<<>>, <<1>>, <<2, 3>>) = x
2271}
2272"
2273 );
2274}
2275
2276#[test]
2277fn tuple_multiple_bit_arrays_case() {
2278 assert_js!(
2279 "
2280pub fn go(x) {
2281 case x {
2282 #(<<>>, <<1>>, <<2, 3>>) -> True
2283 _ -> False
2284 }
2285}
2286"
2287 );
2288}
2289
2290// https://github.com/gleam-lang/gleam/issues/4637
2291#[test]
2292fn pattern_matching_on_32_float_plus_infinity_still_reachable() {
2293 assert_js!(
2294 r#"
2295pub fn go(x) {
2296 case x {
2297 <<_:32-float>> -> "Float"
2298 <<0x7f800000:32>> -> "+Infinity"
2299 _ -> "Other"
2300 }
2301}
2302"#
2303 );
2304}
2305
2306#[test]
2307fn pattern_matching_on_32_float_plus_infinity_still_reachable_2() {
2308 assert_js!(
2309 r#"
2310pub fn go(x) {
2311 case x {
2312 <<_:32-float>> -> "Float"
2313 <<0x7f80:16, 0x0000:16>> -> "+Infinity"
2314 _ -> "Other"
2315 }
2316}
2317"#
2318 );
2319}
2320
2321#[test]
2322fn pattern_matching_on_32_float_minus_infinity_still_reachable() {
2323 assert_js!(
2324 r#"
2325pub fn go(x) {
2326 case x {
2327 <<_:32-float>> -> "Float"
2328 <<0xff800000:32>> -> "-Infinity"
2329 _ -> "Other"
2330 }
2331}
2332"#
2333 );
2334}
2335
2336#[test]
2337fn pattern_matching_on_32_float_minus_infinity_still_reachable_2() {
2338 assert_js!(
2339 r#"
2340pub fn go(x) {
2341 case x {
2342 <<_:32-float>> -> "Float"
2343 <<0xff80:16, 0x0000:16>> -> "-Infinity"
2344 _ -> "Other"
2345 }
2346}
2347"#
2348 );
2349}
2350
2351#[test]
2352fn pattern_matching_on_32_float_nan_still_reachable() {
2353 assert_js!(
2354 r#"
2355pub fn go(x) {
2356 case x {
2357 <<_:32-float>> -> "Float"
2358 <<0x7fc00000:32>> -> "NaN"
2359 _ -> "Other"
2360 }
2361}
2362"#
2363 );
2364}
2365
2366#[test]
2367fn pattern_matching_on_32_float_nan_still_reachable_2() {
2368 assert_js!(
2369 r#"
2370pub fn go(x) {
2371 case x {
2372 <<_:32-float>> -> "Float"
2373 <<0x7fc0:16, 0x0000:16>> -> "NaN"
2374 _ -> "Other"
2375 }
2376}
2377"#
2378 );
2379}
2380
2381#[test]
2382fn pattern_matching_on_64_float_plus_infinity_still_reachable() {
2383 assert_js!(
2384 r#"
2385pub fn go(x) {
2386 case x {
2387 <<_:64-float>> -> "Float"
2388 <<0x7ff0000000000000:64>> -> "+Infinity"
2389 _ -> "Other"
2390 }
2391}
2392"#
2393 );
2394}
2395
2396#[test]
2397fn pattern_matching_on_64_float_plus_infinity_still_reachable_2() {
2398 assert_js!(
2399 r#"
2400pub fn go(x) {
2401 case x {
2402 <<_:64-float>> -> "Float"
2403 <<0x7ff00000:32, 0x00000000:32>> -> "+Infinity"
2404 _ -> "Other"
2405 }
2406}
2407"#
2408 );
2409}
2410
2411#[test]
2412fn pattern_matching_on_64_float_minus_infinity_still_reachable() {
2413 assert_js!(
2414 r#"
2415pub fn go(x) {
2416 case x {
2417 <<_:64-float>> -> "Float"
2418 <<0xfff0000000000000:64>> -> "-Infinity"
2419 _ -> "Other"
2420 }
2421}
2422"#
2423 );
2424}
2425
2426#[test]
2427fn pattern_matching_on_64_float_minus_infinity_still_reachable_2() {
2428 assert_js!(
2429 r#"
2430pub fn go(x) {
2431 case x {
2432 <<_:64-float>> -> "Float"
2433 <<0xfff00000:32, 0x00000000:32>> -> "-Infinity"
2434 _ -> "Other"
2435 }
2436}
2437"#
2438 );
2439}
2440
2441#[test]
2442fn pattern_matching_on_64_float_nan_still_reachable() {
2443 assert_js!(
2444 r#"
2445pub fn go(x) {
2446 case x {
2447 <<_:64-float>> -> "Float"
2448 <<0x7ff8000000000000:64>> -> "NaN"
2449 _ -> "Other"
2450 }
2451}
2452"#
2453 );
2454}
2455
2456#[test]
2457fn pattern_matching_on_64_float_nan_still_reachable_2() {
2458 assert_js!(
2459 r#"
2460pub fn go(x) {
2461 case x {
2462 <<_:64-float>> -> "Float"
2463 <<0x7ff80000:32, 0x00000000:32>> -> "NaN"
2464 _ -> "Other"
2465 }
2466}
2467"#
2468 );
2469}
2470
2471#[test]
2472fn pattern_matching_on_64_float_int_is_still_reachable() {
2473 assert_js!(
2474 r#"
2475pub fn go(x) {
2476 case x {
2477 <<_:64-float>> -> "Float"
2478 <<_:64-int>> -> "Int"
2479 _ -> "Other"
2480 }
2481}
2482"#
2483 );
2484}
2485
2486#[test]
2487fn pattern_matching_on_64_float_float_is_unreachable() {
2488 assert_js!(
2489 r#"
2490pub fn go(x) {
2491 case x {
2492 <<_:64-float>> -> "Float"
2493 <<_:64-float>> -> "unreachable"
2494 _ -> "Other"
2495 }
2496}
2497"#
2498 );
2499}
2500
2501#[test]
2502fn unit_with_bits_option() {
2503 assert_js!(
2504 "
2505pub fn go(x) {
2506 <<x:bits-size(4)-unit(8)>>
2507}
2508"
2509 );
2510}
2511
2512#[test]
2513fn unit_with_bits_option_constant() {
2514 assert_js!(
2515 "
2516pub const bits = <<1, 2, 3>>
2517pub const more_bits = <<bits:bits-size(3)-unit(8)>>
2518"
2519 );
2520}
2521
2522#[test]
2523fn operator_in_size_for_bit_array_segment() {
2524 assert_js!(
2525 "
2526pub fn go(x) {
2527 <<x:bits-size(4 + 1)>>
2528}
2529"
2530 );
2531}
2532
2533// https://github.com/gleam-lang/gleam/issues/4712
2534#[test]
2535fn multiple_variable_size_segments() {
2536 assert_js!(
2537 "
2538pub fn main() {
2539 let assert <<a, b:size(a), c:size(b)>> = <<1, 2, 3, 4>>
2540 a + b + c
2541}
2542"
2543 );
2544}
2545
2546#[test]
2547fn utf16_codepoint_little_endian() {
2548 assert_js!(
2549 "
2550pub fn go(codepoint) {
2551 <<codepoint:utf16_codepoint-little>>
2552}
2553"
2554 );
2555}
2556
2557#[test]
2558fn utf32_codepoint_little_endian() {
2559 assert_js!(
2560 "
2561pub fn go(codepoint) {
2562 <<codepoint:utf32_codepoint-little>>
2563}
2564"
2565 );
2566}
2567
2568#[test]
2569fn operator_in_pattern_size() {
2570 assert_js!(
2571 "
2572pub fn main() {
2573 let assert <<len, payload:size(len * 8)>> = <<>>
2574}
2575"
2576 );
2577}
2578
2579#[test]
2580fn operator_in_pattern_size2() {
2581 assert_js!(
2582 "
2583pub fn main() {
2584 let assert <<len, payload:size(len / 8 - 1)>> = <<>>
2585}
2586"
2587 );
2588}
2589
2590#[test]
2591fn operator_in_pattern_size3() {
2592 assert_js!(
2593 "
2594pub fn main() {
2595 let additional = 10
2596 let assert <<len, payload:size(len + additional * 8)>> = <<>>
2597}
2598"
2599 );
2600}
2601
2602#[test]
2603fn subtraction_in_pattern_size_is_left_associative() {
2604 assert_js!(
2605 "
2606pub fn main() {
2607 let a = 10
2608 let b = 3
2609 let c = 2
2610 let assert <<_:bytes-size(a - b - c)>> = <<>>
2611}
2612"
2613 );
2614}
2615
2616#[test]
2617fn subtraction_chain_in_pattern_size_is_left_associative() {
2618 assert_js!(
2619 "
2620pub fn main() {
2621 let a = 10
2622 let b = 3
2623 let c = 2
2624 let d = 1
2625 let assert <<_:bytes-size(a - b - c - d)>> = <<>>
2626}
2627"
2628 );
2629}
2630
2631#[test]
2632fn division_in_pattern_size_is_left_associative() {
2633 assert_js!(
2634 "
2635pub fn main() {
2636 let a = 100
2637 let b = 5
2638 let c = 2
2639 let assert <<_:bytes-size(a / b / c)>> = <<>>
2640}
2641"
2642 );
2643}
2644
2645#[test]
2646fn multiplication_in_pattern_size_is_left_associative() {
2647 assert_js!(
2648 "
2649pub fn main() {
2650 let a = 2
2651 let b = 3
2652 let c = 4
2653 let assert <<_:bytes-size(a * b * c)>> = <<>>
2654}
2655"
2656 );
2657}
2658
2659#[test]
2660fn mixed_mul_div_in_pattern_size_is_left_associative() {
2661 assert_js!(
2662 "
2663pub fn main() {
2664 let a = 100
2665 let b = 5
2666 let c = 2
2667 let assert <<_:bytes-size(a * b / c)>> = <<>>
2668}
2669"
2670 );
2671}
2672
2673#[test]
2674fn mul_binds_tighter_than_add_in_pattern_size() {
2675 assert_js!(
2676 "
2677pub fn main() {
2678 let a = 10
2679 let b = 3
2680 let c = 2
2681 let assert <<_:bytes-size(a + b * c)>> = <<>>
2682}
2683"
2684 );
2685}
2686
2687#[test]
2688fn mul_binds_tighter_than_sub_in_pattern_size() {
2689 assert_js!(
2690 "
2691pub fn main() {
2692 let a = 10
2693 let b = 3
2694 let c = 2
2695 let assert <<_:bytes-size(a * b + c)>> = <<>>
2696}
2697"
2698 );
2699}
2700
2701#[test]
2702fn add_and_sub_chain_in_pattern_size_is_left_associative() {
2703 assert_js!(
2704 "
2705pub fn main() {
2706 let a = 10
2707 let b = 3
2708 let c = 2
2709 let assert <<_:bytes-size(a + b - c)>> = <<>>
2710}
2711"
2712 );
2713}
2714
2715#[test]
2716fn remainder_in_pattern_size_is_left_associative() {
2717 assert_js!(
2718 "
2719pub fn main() {
2720 let a = 10
2721 let b = 3
2722 let c = 2
2723 let assert <<_:bytes-size(a % b % c)>> = <<>>
2724}
2725"
2726 );
2727}
2728
2729#[test]
2730fn block_in_pattern_size() {
2731 assert_js!(
2732 "
2733pub fn main() {
2734 let assert <<len, payload:size({ len - 1 } * 8)>> = <<>>
2735}
2736"
2737 );
2738}
2739
2740#[test]
2741fn non_byte_aligned_size_calculation() {
2742 assert_js!(
2743 "
2744pub fn main() {
2745 case <<>> {
2746 <<a:1, b:3, c:size(b - 2)>> -> c + b
2747 _ -> 1
2748 }
2749}
2750"
2751 );
2752}
2753
2754#[test]
2755fn pattern_match_on_negative_size_calculation() {
2756 assert_js!(
2757 "
2758pub fn main() {
2759 let assert <<a, b:size(a - 100000), c:size(b)>> = <<1, 2, 3, 4, 5>>
2760}
2761"
2762 );
2763}
2764
2765#[test]
2766fn pattern_match_unknown_size_and_literal_string() {
2767 assert_js!(
2768 r#"
2769pub fn go(x, n) {
2770 case x {
2771 <<_:size(n), "\r\n">> -> 1
2772 _ -> 2
2773 }
2774}
2775"#
2776 );
2777}
2778
2779#[test]
2780fn pattern_match_size_arithmetic() {
2781 assert_js!(
2782 r#"
2783pub fn wibble(bits, wobble) {
2784 case bits {
2785 <<_:size(1), _:size(wobble - 1), _:bits>> -> 0
2786 _ -> 1
2787 }
2788}
2789"#
2790 );
2791}
2792
2793#[test]
2794fn bit_array_pattern_match_all_reachable() {
2795 assert_js!(
2796 r#"
2797pub fn main(x) {
2798 case x {
2799 <<_, "==">> -> 1
2800 <<_, _, "=">> -> 2
2801 // ^^^ This should be reachable
2802 _ -> 3
2803 }
2804}
2805 "#
2806 )
2807}
2808
2809// https://github.com/gleam-lang/gleam/issues/5600
2810#[test]
2811fn bit_array_size_constant() {
2812 assert_js!(
2813 r#"
2814const some_size = 2
2815
2816pub fn run(data) {
2817 case data {
2818 <<x:bytes-size(some_size), _:bits>> -> x
2819 _ -> data
2820 }
2821}
2822 "#
2823 );
2824}
2825
2826// https://github.com/gleam-lang/gleam/issues/5208
2827#[test]
2828fn unit_option_ignores_bytes() {
2829 assert_js!(
2830 "
2831pub fn main() {
2832 let assert <<x:unit(2)-bytes-size(3)>> = <<1:6>>
2833 x
2834}
2835"
2836 );
2837}
2838
2839#[test]
2840fn unit_option_ignores_bytes_regardless_of_order() {
2841 assert_js!(
2842 "
2843pub fn main() {
2844 let assert <<x:bytes-unit(2)-size(3)>> = <<1:6>>
2845 x
2846}
2847"
2848 );
2849}