Fork of daniellemaywood.uk/gleam — Wasm codegen work
Something went wrong. Try again.
16 kB · 1129 lines
Rust
at wasm
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130// SPDX-License-Identifier: Apache-2.0// SPDX-FileCopyrightText: 2021 The Gleam contributors
use crate::assert_js;
#[test]fn case_on_error() { assert_js!( r#"fn a_result() { Error(1) }
pub fn main() { case a_result() { Error(_) -> 1 _ -> 2 }}"# );}
#[test]fn tuple_and_guard() { assert_js!( r#"pub fn go(x) { case #(1, 2) { #(1, a) if a == 2 -> 1 #(_, _) -> 2 }}"#, )}
#[test]fn guard_variable_only_brought_into_scope_when_needed() { assert_js!( r#"pub fn go(x) { case x { // We want `a` to be defined before the guard check, and // `b` to be defined only if the predicate on a matches! [a, b] if a == 1 -> a + b _ -> 2 }}"# )}
// https://github.com/gleam-lang/gleam/issues/4221#[test]fn guard_variable_only_brought_into_scope_when_needed_1() { assert_js!( r#"pub fn main() { case 1 { i if i == 1 -> True i if i < 2 -> True _ -> False }}"# )}
// https://github.com/gleam-lang/gleam/issues/1187#[test]fn pointless() { assert_js!( r#"pub fn go(x) { case x { _ -> x }}"#, )}
// https://github.com/gleam-lang/gleam/issues/1188#[test]fn following_todo() { assert_js!( r#"pub fn go(x) { case x { True -> todo _ -> 1 }}"#, )}
#[test]fn multi_subject_catch_all() { assert_js!( r#"pub fn go(x, y) { case x, y { True, True -> 1 _, _ -> 0 }}"#, )}
#[test]fn multi_subject_or() { assert_js!( r#"pub fn go(x, y) { case x, y { True, _ | _, True -> 1 _, _ -> 0 }}"#, )}
#[test]fn multi_subject_no_catch_all() { assert_js!( r#"pub fn go(x, y) { case x, y { True, _ -> 1 _, True -> 2 False, False -> 0 }}"#, )}
#[test]fn multi_subject_subject_assignments() { assert_js!( r#"pub fn go() { case True, False { True, True -> 1 _, _ -> 0 }}"#, )}
#[test]fn assignment() { assert_js!( r#"pub fn go(x) { let y = case x { True -> 1 _ -> 0 } y}"#, )}
#[test]fn preassign_assignment() { assert_js!( r#"pub fn go(x) { let y = case x() { True -> 1 _ -> 0 } y}"#, )}
// https://github.com/gleam-lang/gleam/issues/1237#[test]fn pipe() { assert_js!( r#"pub fn go(x, f) { case x |> f { 0 -> 1 _ -> 2 }}"#, )}
#[test]fn result() { assert_js!( r#"pub fn go(x) { case x { Ok(_) -> 1 Error(_) -> 0 }}"#, )}
// https://github.com/gleam-lang/gleam/issues/1506#[test]fn called_case() { assert_js!( r#"pub fn go(x, y) { case x { 0 -> y _ -> y }()}"#, )}
// https://github.com/gleam-lang/gleam/issues/1978#[test]fn case_local_var_in_tuple() { assert_js!( r#"pub fn go(x, y) { let z = False case True { x if #(x, z) == #(True, False) -> x _ -> False }}"#, )}
// https://github.com/gleam-lang/gleam/issues/2665#[test]fn case_branches_guards_are_wrapped_in_parentheses() { assert_js!( r#"pub fn anything() -> a { case [] { [a] if False || True -> a _ -> anything() }}"#, )}
// https://github.com/gleam-lang/gleam/issues/2759#[test]fn nested_string_prefix_match() { assert_js!( r#"pub fn main() { case Ok(["a", "b c", "d"]) { Ok(["a", "b " <> _, "d"]) -> 1 _ -> 1 }}"# );}
// https://github.com/gleam-lang/gleam/issues/2759#[test]fn nested_string_prefix_match_that_would_crash_on_js() { assert_js!( r#"pub fn main() { case Ok(["b c", "d"]) { Ok(["b " <> _, "d"]) -> 1 _ -> 1 }}"# );}
#[test]fn slicing_is_handled_properly_with_multiple_branches() { assert_js!( r#"pub fn main() { case "12345" { "0" <> rest -> rest "123" <> rest -> rest _ -> "" }}"# )}
// https://github.com/gleam-lang/gleam/issues/3379#[test]fn single_clause_variables() { assert_js!( r#"pub fn main() { let text = "first defined" case "defined again" { text -> Nil } let text = "a third time"}"# )}
// https://github.com/gleam-lang/gleam/issues/3379#[test]fn single_clause_variables_assigned() { assert_js!( r#"pub fn main() { let text = "first defined" let other = case "defined again" { text -> Nil } let text = "a third time"}"# )}
// https://github.com/gleam-lang/gleam/issues/3894#[test]fn nested_string_prefix_assignment() { assert_js!( r#"type Wibble { Wibble(wobble: String)}
pub fn main() { let tmp = Wibble(wobble: "wibble") case tmp { Wibble(wobble: "w" as wibble <> rest) -> wibble <> rest _ -> panic }}"# )}
#[test]fn deeply_nested_string_prefix_assignment() { assert_js!( r#"type Wibble { Wibble(Wobble)}type Wobble { Wobble(wabble: Wabble)}type Wabble { Wabble(tuple: #(Int, String))}
pub fn main() { let tmp = Wibble(Wobble(Wabble(#(42, "wibble")))) case tmp { Wibble(Wobble(Wabble(#(_int, "w" as wibble <> rest)))) -> wibble <> rest _ -> panic }}"# )}
// https://github.com/gleam-lang/gleam/issues/4383#[test]fn record_update_in_pipeline_in_case_clause() { assert_js!( "pub type Wibble { Wibble(wibble: Int, wobble: Int)}
fn identity(x) { x}
pub fn go(x) { case x { Wibble(1, _) -> Wibble(..x, wibble: 4) |> identity Wibble(_, 3) -> Wibble(..x, wobble: 10) |> identity _ -> panic }}" );}
#[test]fn pattern_matching_on_aliased_result_constructor() { assert_js!( "import gleam.{Error as E, Ok as O}
pub fn go(x) { case x { E(_) -> 1 O(_) -> 2 }}" );}
#[test]fn list_with_guard() { assert_js!( "pub fn go(x) { case x { [] -> 0 [first, ..] if first < 10 -> first * 2 [first, ..] -> first }}" );}
#[test]fn list_with_guard_no_binding() { assert_js!( "pub fn go(x) { case x { [] -> 0 [first, ..] if 1 < 10 -> first * 2 [first, ..] -> first }}" );}
#[test]fn case_building_simple_value_matched_by_pattern() { assert_js!( "pub fn go(x) { case x { 1 -> 2 n -> n }}" )}
#[test]fn case_building_list_matched_by_pattern() { assert_js!( "pub fn go(x) { case x { [] -> [] [a, b] -> [a, b] [1, ..rest] -> [1, ..rest] _ -> x }}" )}
#[test]fn case_building_record_matched_by_pattern() { assert_js!( "pub fn go(x) { case x { Ok(1) -> Ok(1) Ok(n) -> Ok(n) Error(_) -> Error(Nil) }}" )}
#[test]fn case_building_record_with_select_matched_by_pattern() { assert_js!( "import gleam
pub fn go(x) { case x { Ok(1) -> gleam.Ok(1) _ -> Error(Nil) }}" )}
#[test]fn case_building_record_with_select_matched_by_pattern_2() { assert_js!( "import gleam
pub fn go(x) { case x { gleam.Ok(1) -> gleam.Ok(1) _ -> Error(Nil) }}" )}
#[test]fn case_building_record_with_select_matched_by_pattern_3() { assert_js!( "import gleam
pub fn go(x) { case x { gleam.Ok(1) -> Ok(1) _ -> Error(Nil) }}" )}
#[test]fn case_building_matched_string_1() { assert_js!( r#"import gleam
pub fn go(x) { case x { "a" <> rest -> "a" <> rest _ -> "" }}"# )}
#[test]fn case_building_matched_string_2() { assert_js!( r#"import gleam
pub fn go(x) { case x { "a" as a <> rest -> a <> rest _ -> "" }}"# )}
#[test]fn case_building_matched_value_wrapped_in_block() { assert_js!( r#"import gleam
pub fn go(x) { case x { 1 -> { 1 } _ -> 2 }}"# )}
#[test]fn case_building_matched_value_alias() { assert_js!( r#"import gleam
pub fn go(x) { case x { Ok(_) as a -> a Error(Nil) -> Error(Nil) }}"# )}
#[test]fn case_building_matched_value_alias_2() { assert_js!( r#"import gleam
pub fn go(x) { case x { Ok(1) as a -> Ok(1) Ok(_) -> Ok(2) Error(Nil) -> Error(Nil) }}"# )}
#[test]fn case_building_matched_value_alias_3() { assert_js!( r#"import gleam
pub fn go(x) { case x { Ok(1 as a) -> Ok(a) Ok(_) -> Ok(2) Error(Nil) -> Error(Nil) }}"# )}
#[test]fn case_building_matched_no_variant_record() { assert_js!( r#"pub fn go(x) { case x { Ok(Nil) -> Ok(Nil) _ -> Error(Nil) }}"# )}
#[test]fn case_building_matched_no_variant_record_2() { assert_js!( r#"import gleam
pub fn go(x) { case x { Ok(gleam.Nil) -> Ok(Nil) _ -> Error(Nil) }}"# )}
#[test]fn case_building_matched_no_variant_record_3() { assert_js!( r#"import gleam
pub fn go(x) { case x { Ok(Nil) -> Ok(gleam.Nil) _ -> Error(Nil) }}"# )}
#[test]fn case_building_matched_no_variant_record_4() { assert_js!( r#"import gleam
pub fn go(x) { case x { Ok(gleam.Nil) -> Ok(gleam.Nil) _ -> Error(Nil) }}"# )}
#[test]fn case_building_record_with_labels_matched_by_pattern_1() { assert_js!( "pub type Wibble { Wibble(int: Int, string: String) Wobble(Int)}
pub fn go(x) { case x { Wibble(1, s) -> Wibble(1, s) _ -> Wobble(1) }}" )}
#[test]fn case_building_record_with_labels_matched_by_pattern_2() { assert_js!( "pub type Wibble { Wibble(int: Int, string: String) Wobble(Int)}
pub fn go(x) { case x { Wibble(string:, int:) -> Wibble(string:, int:) _ -> Wobble(1) }}" )}
#[test]fn case_building_record_with_labels_matched_by_pattern_3() { assert_js!( "pub type Wibble { Wibble(int: Int, string: String) Wobble(Int)}
pub fn go(x) { case x { // This should not be optimised away! Wibble(string:, int:) -> Wibble(string:, int: 1) _ -> Wobble(1) }}" )}
#[test]fn case_building_record_with_labels_matched_by_pattern_4() { assert_js!( "pub type Wibble { Wibble(int: Int, string: String) Wobble(Int)}
pub fn go(x) { case x { Wibble(string:, int:) -> Wibble(int:, string:) _ -> Wobble(1) }}" )}
#[test]fn case_building_record_with_labels_matched_by_pattern_5() { assert_js!( "pub type Wibble { Wibble(int: Int, string: String) Wobble(Int)}
pub fn go(x) { case x { Wibble(string:, int: 1) -> Wibble(1, string:) _ -> Wobble(1) }}" )}
#[test]fn case_building_record_with_labels_matched_by_pattern_6() { assert_js!( "pub type Wibble { Wibble(int: Int, string: String) Wobble(Int)}
pub fn go(x) { case x { Wibble(1, string:) -> Wibble(string:, int: 1) _ -> Wobble(1) }}" )}
#[test]fn case_with_multiple_subjects_building_simple_value_matched_by_pattern() { assert_js!( "pub fn go(x) { case x, x + 1 { 1, _ -> 2 _, n -> n }}" )}
#[test]fn case_with_multiple_subjects_building_list_matched_by_pattern() { assert_js!( "pub fn go(n, x) { case n, x { 1, [] -> [] _, [a, b] -> [a, b] 3, [1, ..rest] -> [1, ..rest] _, _ -> x }}" )}
#[test]fn case_with_multiple_subjects_building_record_matched_by_pattern() { assert_js!( "pub fn go(x, y) { case x, y { Ok(1), Error(_) -> Ok(1) Error(_), Ok(n) -> Ok(n) _, _ -> Error(Nil) }}" )}
#[test]fn case_with_multiple_subjects_building_same_value_as_two_subjects_one_is_picked() { assert_js!( "import gleam
pub fn go(x, y) { case x, y { gleam.Ok(1), Ok(1) -> Ok(1) _, Error(Nil) -> Error(Nil) _, _ -> Error(Nil) }}" )}
#[test]fn interfering_string_pattern_succeeds_if_succeeding() { assert_js!( r#"pub fn wibble(bits) { case bits { <<"aaa", 0, _:bits>> -> 1 // If the first one succeeds, so will the second check, so it won't be // performed twice inside the first if branch! <<"aaa", 1, _:bits>> -> 2 _ -> 3 }}"# );}
#[test]fn string_concatenation_in_clause_guards() { assert_js!( r#"pub fn main() { let wibble = "wob" case wibble { x if x <> "ble" == "wobble" -> 1 _ -> 0 }}"# );}
#[test]fn var_true() { assert_js!( r#"fn true() { True }pub fn main() { let true_ = true() assert 0 == case Nil { _ if true_ -> 0 _ -> 1 }}"# )}
#[test]// https://github.com/gleam-lang/gleam/issues/5283fn duplicate_name_for_variables_used_in_guards() { assert_js!( r#"pub fn wibble() { let a = case 1337 { n if n == 1347 -> Nil _ -> Nil } let b = case 1337 { n -> Nil }}"# )}
#[test]// https://github.com/gleam-lang/gleam/issues/5283fn duplicate_name_for_variables_used_in_guards_shadowing_outer_name() { assert_js!( r#"pub fn wibble() { let n = 1 let a = case 1337 { n if n == 1347 -> n _ -> n } let b = case 1337 { n -> Nil }}"# )}
#[test]fn directly_matching_case_subject() { assert_js!( r#"pub fn go() { let x = "ABC" case True { True -> { let x = 79 0 } False -> { let x = True 0 } } x}"# )}
// https://github.com/gleam-lang/gleam/issues/5400#[test]fn case_matching_single_character_prefixes() { assert_js!( r#"pub fn parse_digit(s: String) -> Int { case s { "0" <> s -> 0 "1" <> s -> 1 "2" <> s -> 2 "3" <> s -> 3 "4" <> s -> 4 "5" <> s -> 5 "6" <> s -> 6 "7" <> s -> 7 "8" <> s -> 8 "9" <> s -> 9 "" -> todo _ -> panic }}"# );}
// https://github.com/gleam-lang/gleam/issues/5467#[test]fn no_duplicate_let_after_directly_matching_case() { assert_js!( r#"pub fn go() { let x = case #(1, 2) { #(1, b) -> b #(_, b) -> b }
let #(a, _b) = #(x, 3)
a}"# )}
// https://github.com/gleam-lang/gleam/issues/5743#[test]fn no_duplicate_pipe_variable_with_case_in_pipeline() { assert_js!( r#"pub fn main() { 0 |> case True { True -> add_one |> identity False -> add_one } |> add_one}
fn identity(x) { x}
fn add_one(x) { x + 1}"# )}
#[test]fn list_with_tail_used_in_guard() { assert_js!( r#"pub fn go(x: List(Int), y: List(Int)) { case x { [1, ..x] if [1, 2, ..x] == y -> True _ -> False }}"# )}
// https://github.com/gleam-lang/gleam/issues/5612#[test]fn no_duplicate_let_after_case_with_same_named_variable_with_declaration_before_and_after() { assert_js!( r#"pub fn go() { let x = 0 let x = x let x = case #(1, 2) { #(_, x) -> x }
let x = x x}"# )}
// https://github.com/gleam-lang/gleam/issues/5612#[test]fn no_duplicate_let_after_case_with_same_named_variable() { assert_js!( r#"pub fn go() { let x = case #(1, 2) { #(_, x) -> x }
x}"# )}
// https://github.com/gleam-lang/gleam/issues/5748#[test]fn no_duplicate_let_when_rebinding_variable_after_directly_matching_case() { assert_js!( r#"pub fn go() { let n = 1 case True { True -> { let n = 99 n } False -> 0 } let n = n + 5 n}"# )}
#[test]fn semicolon_exists_with_directly_matching_case() { assert_js!( r#"pub fn go() { case #(1, 2) { #(a, _) -> a } {2 + 4} * 2}"# )}
#[test]fn semicolon_exists_with_case() { assert_js!( r#"pub fn go() { case #(1, 2) { #(2, b) -> b #(1, 3) -> 2 #(a, _) -> a } {2 + 4} * 2}"# )}
// https://github.com/gleam-lang/gleam/issues/6029#[test]fn bit_array_slice_float_with_number_constructor() { assert_js!( "pub type Number { Number(Int)}
pub fn go(bit_array) { case bit_array { <<f:float>> -> f _ -> 0.0 }}" );}