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