Migrate more tests

This commit is contained in:
Ayaz Hafiz 2023-03-31 18:35:45 -05:00
parent 32a59b7e72
commit 61adcd34d2
No known key found for this signature in database
GPG Key ID: 0E2A37416A25EF58
32 changed files with 217 additions and 475 deletions

View File

@ -3,6 +3,7 @@ test-gen-llvm = "test -p test_gen"
test-gen-dev = "test -p roc_gen_dev -p test_gen --no-default-features --features gen-dev"
test-gen-wasm = "test -p roc_gen_wasm -p test_gen --no-default-features --features gen-wasm"
test-gen-llvm-wasm = "test -p roc_gen_wasm -p test_gen --no-default-features --features gen-llvm-wasm"
uitest = "test -p roc_solve uitest"
[target.wasm32-unknown-unknown]
# Rust compiler flags for minimum-sized .wasm binary in the web REPL

View File

@ -7818,478 +7818,4 @@ mod solve_expr {
"O",
);
}
#[test]
fn custom_implement_eq() {
infer_eq_without_problem(
indoc!(
r#"
app "test" provides [main] to "./platform"
Trivial := {} has [Eq {isEq}]
isEq = \@Trivial {}, @Trivial {} -> Bool.true
main = Bool.isEq (@Trivial {}) (@Trivial {})
"#
),
"Bool",
);
}
#[test]
fn expand_able_variables_in_type_alias() {
infer_queries!(
indoc!(
r#"
app "test" provides [main] to "./platform"
F a : a | a has Hash
main : F a -> F a
#^^^^{-1}
"#
),
@"main : a -[[main(0)]]-> a | a has Hash"
print_only_under_alias: true
);
}
#[test]
fn self_recursive_function_not_syntactically_a_function() {
infer_eq_without_problem(
indoc!(
r#"
app "test" provides [fx] to "./platform"
after : ({} -> a), ({} -> b) -> ({} -> b)
fx = after (\{} -> {}) \{} -> if Bool.true then fx {} else {}
"#
),
"{} -> {}",
);
}
#[test]
fn self_recursive_function_not_syntactically_a_function_nested() {
infer_eq_without_problem(
indoc!(
r#"
app "test" provides [main] to "./platform"
main =
after : ({} -> a), ({} -> b) -> ({} -> b)
fx = after (\{} -> {}) \{} -> if Bool.true then fx {} else {}
fx
"#
),
"{} -> {}",
);
}
#[test]
fn derive_to_encoder_for_opaque() {
infer_queries!(
indoc!(
r#"
app "test" provides [main] to "./platform"
N := U8 has [Encoding]
main = Encode.toEncoder (@N 15)
# ^^^^^^^^^^^^^^^^
"#
),
@"N#Encode.toEncoder(3) : N -[[#N_toEncoder(3)]]-> Encoder fmt | fmt has EncoderFormatting"
);
}
#[test]
fn derive_decoder_for_opaque() {
infer_queries!(
indoc!(
r#"
app "test" provides [main] to "./platform"
N := U8 has [Decoding]
main : Decoder N _
main = Decode.custom \bytes, fmt ->
Decode.decodeWith bytes Decode.decoder fmt
# ^^^^^^^^^^^^^^
"#
),
@"N#Decode.decoder(3) : List U8, fmt -[[7]]-> { rest : List U8, result : [Err [TooShort], Ok U8] } | fmt has DecoderFormatting"
print_only_under_alias: true
);
}
#[test]
fn derive_hash_for_opaque() {
infer_queries!(
indoc!(
r#"
app "test" provides [main] to "./platform"
N := U8 has [Hash]
main = \hasher, @N n -> Hash.hash hasher (@N n)
# ^^^^^^^^^
"#
),
@"N#Hash.hash(3) : a, N -[[#N_hash(3)]]-> a | a has Hasher"
);
}
#[test]
fn derive_eq_for_opaque() {
infer_queries!(
indoc!(
r#"
app "test" provides [main] to "./platform"
N := U8 has [Eq]
main = Bool.isEq (@N 15) (@N 23)
# ^^^^^^^^^
"#
),
@"N#Bool.isEq(3) : N, N -[[#N_isEq(3)]]-> Bool"
);
}
#[test]
fn multiple_variables_bound_to_an_ability_from_type_def() {
infer_queries!(
indoc!(
r#"
app "test" provides [main] to "./platform"
F a : a | a has Hash & Eq & Decoding
main : F a -> F a
#^^^^{-1}
"#
),
@"main : a -[[main(0)]]-> a | a has Hash & Decoding & Eq"
print_only_under_alias: true
);
}
#[test]
fn rigid_able_bounds_are_superset_of_flex_bounds_admitted() {
infer_eq_without_problem(
indoc!(
r#"
app "test" provides [main] to "./platform"
f : x -> x | x has Hash
g : x -> x | x has Decoding & Encoding
main : x -> x | x has Hash & Decoding & Encoding
main = \x -> x |> f |> g
"#
),
"x -> x | x has Hash & Encoding & Decoding",
);
}
#[test]
fn extend_uninhabited_without_opening_union() {
infer_queries!(
indoc!(
r#"
app "test" provides [main] to "./platform"
walkHelp : {} -> [Continue {}, Break []]
main = when walkHelp {} is
# ^^^^^^^^^^^
Continue {} -> {}
"#
),
@"walkHelp {} : [Break [], Continue {}]"
);
}
#[test]
fn contextual_openness_for_type_alias() {
infer_queries!(
indoc!(
r#"
app "test" provides [accum] to "./platform"
Q : [Green, Blue]
f : Q -> Q
f = \q -> when q is
#^{-1}
Green -> Green
Blue -> Blue
accum = \q -> when q is
#^^^^^{-1}
A -> f Green
B -> Yellow
C -> Orange
"#
),
@r###"
f : Q -[[f(2)]]-> Q
accum : [A, B, C] -[[accum(0)]]-> [Blue, Green, Orange, Yellow]*
"###
);
}
#[test]
fn inferred_fixed_fixpoints() {
infer_queries!(
indoc!(
r#"
app "test" provides [job] to "./platform"
F : [Bar, FromG G]
G : [G {lst : List F}]
job : { lst : List F } -> G
job = \config -> G config
#^^^{-1}
# ^^^^^^ ^^^^^^^^
"#
),
@r###"
job : { lst : List [Bar, FromG ([G { lst : List [Bar, FromG a] }] as a)] } -[[job(0)]]-> [G { lst : List [Bar, FromG a] }] as a
config : { lst : List [Bar, FromG ([G { lst : List [Bar, FromG a] }] as a)] }
G config : [G { lst : List [Bar, FromG a] }] as a
"###
print_only_under_alias: true
);
}
#[test]
fn fix_recursion_under_alias_issue_4368() {
infer_eq_without_problem(
indoc!(
r#"
app "test" provides [doIt] to "./platform"
Effect : [
DoIt {} ({} -> Effect),
]
Task := ({} -> Effect) -> Effect
doIt : {} -> Task
doIt = \{} ->
@Task \toNext ->
DoIt {} \{} -> (toNext {})
"#
),
"{} -> Task",
);
}
#[test]
fn choose_ranged_num_for_hash() {
infer_queries!(
indoc!(
r#"
app "test" provides [main] to "./platform"
main =
\h -> Hash.hash h 7
# ^^^^^^^^^
"#
),
@"Hash#Hash.hash(1) : a, I64 -[[Hash.hashI64(13)]]-> a | a has Hasher"
)
}
#[test]
fn choose_bool_for_hash() {
infer_queries!(
indoc!(
r#"
app "test" provides [main] to "./platform"
main =
\h -> Hash.hash h Bool.true
# ^^^^^^^^^
"#
),
@"Hash#Hash.hash(1) : a, Bool -[[Hash.hashBool(9)]]-> a | a has Hasher"
)
}
#[test]
fn generalize_inferred_opaque_variable_bound_to_ability_issue_4408() {
infer_eq_without_problem(
indoc!(
r#"
app "test" provides [top] to "./platform"
MDict u := (List u) | u has Hash & Eq
bot : MDict k -> MDict k
bot = \@MDict data ->
when {} is
{} -> @MDict data
top : MDict v -> MDict v
top = \x -> bot x
"#
),
"MDict v -> MDict v | v has Hash & Eq",
);
}
#[test]
fn unify_types_with_fixed_fixpoints_outside_fixing_region() {
infer_queries!(indoc!(
r#"
app "test" provides [main] to "./platform"
Input := [
FromJob Job
]
Job := [
Job (List Input)
]
job : List Input -> Job
job = \inputs ->
@Job (Job inputs)
helloWorld : Job
helloWorld =
@Job ( Job [ @Input (FromJob greeting) ] )
# ^^^^^^^^^^^^^^^^^^^^^^^^^
greeting : Job
greeting =
job []
main = (\_ -> "Which platform am I running on now?\n") helloWorld
"#
),
@r###"
@Input (FromJob greeting) : [FromJob ([Job (List [FromJob a])] as a)]
"###
print_only_under_alias: true
)
}
#[test]
fn impl_ability_for_opaque_with_lambda_sets() {
infer_queries!(
indoc!(
r#"
app "test" provides [isEqQ] to "./platform"
Q := [ F (Str -> Str), G ] has [Eq { isEq: isEqQ }]
isEqQ = \@Q q1, @Q q2 -> when T q1 q2 is
#^^^^^{-1}
T (F _) (F _) -> Bool.true
T G G -> Bool.true
_ -> Bool.false
"#
),
@"isEqQ : Q, Q -[[isEqQ(0)]]-> Bool"
);
}
#[test]
fn impl_ability_for_opaque_with_lambda_sets_material() {
infer_queries!(
indoc!(
r#"
app "test" provides [main] to "./platform"
Q := ({} -> Str) has [Eq {isEq: isEqQ}]
isEqQ = \@Q f1, @Q f2 -> (f1 {} == f2 {})
#^^^^^{-1}
main = isEqQ (@Q \{} -> "a") (@Q \{} -> "a")
# ^^^^^
"#
),
@r###"
isEqQ : ({} -[[]]-> Str), ({} -[[]]-> Str) -[[isEqQ(2)]]-> [False, True]
isEqQ : ({} -[[6, 7]]-> Str), ({} -[[6, 7]]-> Str) -[[isEqQ(2)]]-> [False, True]
"###
print_only_under_alias: true
);
}
#[test]
fn infer_concrete_type_with_inference_var() {
infer_queries!(indoc!(
r#"
app "test" provides [f] to "./platform"
f : _ -> {}
f = \_ -> f {}
#^{-1}
"#
),
@r###"
f : {} -[[f(0)]]-> {}
"###
)
}
#[test]
fn solve_inference_var_in_annotation_requiring_recursion_fix() {
infer_queries!(indoc!(
r#"
app "test" provides [translateStatic] to "./platform"
translateStatic : _ -> _
translateStatic = \Element c ->
#^^^^^^^^^^^^^^^{-1}
Element (List.map c translateStatic)
"#
),
@"translateStatic : [Element (List a)] as a -[[translateStatic(0)]]-> [Element (List b)]* as b"
)
}
#[test]
fn infer_contextual_crash() {
infer_eq_without_problem(
indoc!(
r#"
app "test" provides [getInfallible] to "./platform"
getInfallible = \result -> when result is
Ok x -> x
_ -> crash "turns out this was fallible"
"#
),
"[Ok a]* -> a",
);
}
#[test]
fn resolve_eq_for_float_forces_dec() {
infer_queries!(
indoc!(
r#"
app "test" provides [main] to "./platform"
n : Num *
main = n == 1.
# ^
"#
),
@"n : Dec"
);
}
}

View File

@ -215,7 +215,7 @@ fn assemble_query_output(
// Otherwise, write the Roc source line.
if !is_query_line {
writeln!(writer, "{line}")?;
writeln!(writer, "{}", line.trim_end())?;
}
}

View File

@ -0,0 +1,7 @@
# +opt infer:print_only_under_alias
app "test" provides [main] to "./platform"
F a : a | a has Hash
main : F a -> F a
#^^^^{-1} a -[[main(0)]]-> a | a has Hash

View File

@ -0,0 +1,7 @@
# +opt infer:print_only_under_alias
app "test" provides [main] to "./platform"
F a : a | a has Hash & Eq & Decoding
main : F a -> F a
#^^^^{-1} a -[[main(0)]]-> a | a has Hash & Decoding & Eq

View File

@ -0,0 +1,8 @@
app "test" provides [main] to "./platform"
f : x -> x | x has Hash
g : x -> x | x has Decoding & Encoding
main : x -> x | x has Hash & Decoding & Encoding
main = \x -> x |> f |> g
#^^^^{-1} x -[[main(0)]]-> x | x has Hash & Encoding & Decoding

View File

@ -0,0 +1,12 @@
app "test" provides [top] to "./platform"
MDict u := (List u) | u has Hash & Eq
bot : MDict k -> MDict k
bot = \@MDict data ->
when {} is
{} -> @MDict data
top : MDict v -> MDict v
top = \x -> bot x
#^^^{-1} MDict v -[[top(0)]]-> MDict v | v has Hash & Eq

View File

@ -0,0 +1,9 @@
app "test" provides [isEqQ] to "./platform"
Q := [ F (Str -> Str), G ] has [Eq { isEq: isEqQ }]
isEqQ = \@Q q1, @Q q2 -> when T q1 q2 is
#^^^^^{-1} Q, Q -[[isEqQ(0)]]-> Bool
T (F _) (F _) -> Bool.true
T G G -> Bool.true
_ -> Bool.false

View File

@ -0,0 +1,10 @@
# +opt infer:print_only_under_alias
app "test" provides [main] to "./platform"
Q := ({} -> Str) has [Eq {isEq: isEqQ}]
isEqQ = \@Q f1, @Q f2 -> (f1 {} == f2 {})
#^^^^^{-1} ({} -[[]]-> Str), ({} -[[]]-> Str) -[[isEqQ(2)]]-> [False, True]
main = isEqQ (@Q \{} -> "a") (@Q \{} -> "a")
# ^^^^^ ({} -[[6, 7]]-> Str), ({} -[[6, 7]]-> Str) -[[isEqQ(2)]]-> [False, True]

View File

@ -0,0 +1,5 @@
app "test" provides [main] to "./platform"
main =
\h -> Hash.hash h Bool.true
# ^^^^^^^^^ Hash#Hash.hash(1): a, Bool -[[Hash.hashBool(9)]]-> a | a has Hasher

View File

@ -0,0 +1,6 @@
app "test" provides [main] to "./platform"
n : Num *
main = n == 1.
# ^ Dec

View File

@ -0,0 +1,9 @@
# +opt infer:print_only_under_alias
app "test" provides [main] to "./platform"
N := U8 has [Decoding]
main : Decoder N _
main = Decode.custom \bytes, fmt ->
Decode.decodeWith bytes Decode.decoder fmt
# ^^^^^^^^^^^^^^ N#Decode.decoder(3): List U8, fmt -[[7]]-> { rest : List U8, result : [Err [TooShort], Ok U8] } | fmt has DecoderFormatting

View File

@ -0,0 +1,6 @@
app "test" provides [main] to "./platform"
N := U8 has [Encoding]
main = Encode.toEncoder (@N 15)
# ^^^^^^^^^^^^^^^^ N#Encode.toEncoder(3): N -[[#N_toEncoder(3)]]-> Encoder fmt | fmt has EncoderFormatting

View File

@ -0,0 +1,8 @@
app "test" provides [main] to "./platform"
Trivial := {} has [Eq {isEq}]
isEq = \@Trivial {}, @Trivial {} -> Bool.true
main = Bool.isEq (@Trivial {}) (@Trivial {})
# ^^^^^^^^^ Trivial#Bool.isEq(2): Trivial, Trivial -[[isEq(2)]]-> Bool

View File

@ -0,0 +1,6 @@
app "test" provides [main] to "./platform"
N := U8 has [Eq]
main = Bool.isEq (@N 15) (@N 23)
# ^^^^^^^^^ N#Bool.isEq(3): N, N -[[#N_isEq(3)]]-> Bool

View File

@ -0,0 +1,6 @@
app "test" provides [main] to "./platform"
N := U8 has [Hash]
main = \hasher, @N n -> Hash.hash hasher (@N n)
# ^^^^^^^^^ N#Hash.hash(3): a, N -[[#N_hash(3)]]-> a | a has Hasher

View File

@ -0,0 +1,5 @@
app "test" provides [main] to "./platform"
main =
\h -> Hash.hash h 7
# ^^^^^^^^^ Hash#Hash.hash(1): a, I64 -[[Hash.hashI64(13)]]-> a | a has Hasher

View File

@ -0,0 +1,7 @@
app "test" provides [main] to "./platform"
walkHelp : {} -> [Continue {}, Break []]
main = when walkHelp {} is
# ^^^^^^^^^^^ [Break [], Continue {}]
Continue {} -> {}

View File

@ -0,0 +1,5 @@
app "test" provides [f] to "./platform"
f : _ -> {}
f = \_ -> f {}
#^{-1} {} -[[f(0)]]-> {}

View File

@ -0,0 +1,6 @@
app "test" provides [getInfallible] to "./platform"
getInfallible = \result -> when result is
#^^^^^^^^^^^^^{-1} [Ok a]w_b -[[getInfallible(0)]]-> a
Ok x -> x
_ -> crash "turns out this was fallible"

View File

@ -0,0 +1,15 @@
app "test" provides [accum] to "./platform"
Q : [Green, Blue]
f : Q -> Q
f = \q -> when q is
#^{-1} Q -[[f(2)]]-> Q
Green -> Green
Blue -> Blue
accum = \q -> when q is
#^^^^^{-1} [A, B, C] -[[accum(0)]]-> [Blue, Green, Orange, Yellow]*
A -> f Green
B -> Yellow
C -> Orange

View File

@ -0,0 +1,8 @@
app "test" provides [b] to "./platform"
O := {} -> {}
a = @O \{} -> ((\@O f -> f {}) b)
b = a
#^{-1} O

View File

@ -0,0 +1,6 @@
app "test" provides [fx] to "./platform"
after : ({} -> a), ({} -> b) -> ({} -> b)
fx = after (\{} -> {}) \{} -> if Bool.true then fx {} else {}
#^^{-1} {} -[[]]-> {}

View File

@ -0,0 +1,9 @@
app "test" provides [main] to "./platform"
main =
after : ({} -> a), ({} -> b) -> ({} -> b)
fx = after (\{} -> {}) \{} -> if Bool.true then fx {} else {}
fx
# ^^ {} -[[]]-> {}

View File

@ -0,0 +1,13 @@
app "test" provides [doIt] to "./platform"
Effect : [
DoIt {} ({} -> Effect),
]
Task := ({} -> Effect) -> Effect
doIt : {} -> Task
doIt = \{} ->
#^^^^{-1} {} -[[doIt(0)]]-> Task
@Task \toNext ->
DoIt {} \{} -> (toNext {})

View File

@ -0,0 +1,11 @@
# +opt infer:print_only_under_alias
app "test" provides [job] to "./platform"
F : [Bar, FromG G]
G : [G {lst : List F}]
job : { lst : List F } -> G
job = \config -> G config
#^^^{-1} { lst : List [Bar, FromG ([G { lst : List [Bar, FromG a] }] as a)] } -[[job(0)]]-> [G { lst : List [Bar, FromG a] }] as a
# ^^^^^^^^ [G { lst : List [Bar, FromG a] }] as a
# ^^^^^^ { lst : List [Bar, FromG ([G { lst : List [Bar, FromG a] }] as a)] }

View File

@ -0,0 +1,6 @@
app "test" provides [translateStatic] to "./platform"
translateStatic : _ -> _
translateStatic = \Element c ->
#^^^^^^^^^^^^^^^{-1} [Element (List a)] as a -[[translateStatic(0)]]-> [Element (List b)]* as b
Element (List.map c translateStatic)

View File

@ -0,0 +1,25 @@
# +opt infer:print_only_under_alias
app "test" provides [main] to "./platform"
Input := [
FromJob Job
]
Job := [
Job (List Input)
]
job : List Input -> Job
job = \inputs ->
@Job (Job inputs)
helloWorld : Job
helloWorld =
@Job ( Job [ @Input (FromJob greeting) ] )
# ^^^^^^^^^^^^^^^^^^^^^^^^^ [FromJob ([Job (List [FromJob a])] as a)]
greeting : Job
greeting =
job []
main = (\_ -> "Which platform am I running on now?\n") helloWorld