mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 22:34:45 +00:00
Merge remote-tracking branch 'origin/trunk' into decimal-literals
This commit is contained in:
commit
5529841d68
404 changed files with 9919 additions and 6764 deletions
|
@ -1,19 +1,16 @@
|
|||
#![cfg(not(feature = "gen-wasm"))]
|
||||
|
||||
#[cfg(feature = "gen-llvm")]
|
||||
use crate::helpers::llvm::assert_evals_to;
|
||||
|
||||
#[cfg(feature = "gen-dev")]
|
||||
use crate::helpers::dev::assert_evals_to;
|
||||
|
||||
// #[cfg(feature = "gen-wasm")]
|
||||
// use crate::helpers::wasm::assert_evals_to;
|
||||
#[cfg(feature = "gen-wasm")]
|
||||
use crate::helpers::wasm::assert_evals_to;
|
||||
|
||||
// use crate::assert_wasm_evals_to as assert_evals_to;
|
||||
use indoc::indoc;
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
|
||||
fn eq_i64() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
|
@ -30,7 +27,7 @@ fn eq_i64() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
fn neq_i64() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
|
@ -47,7 +44,7 @@ fn neq_i64() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
|
||||
fn eq_u64() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
|
@ -64,7 +61,7 @@ fn eq_u64() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
fn neq_u64() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
|
@ -81,7 +78,7 @@ fn neq_u64() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
fn eq_f64() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
|
@ -98,7 +95,7 @@ fn eq_f64() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
fn neq_f64() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
|
@ -115,7 +112,7 @@ fn neq_f64() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
fn eq_bool_tag() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
|
@ -132,7 +129,7 @@ fn eq_bool_tag() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
fn neq_bool_tag() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
|
@ -163,7 +160,7 @@ fn unit() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
fn newtype() {
|
||||
assert_evals_to!("Identity 42 == Identity 42", true, bool);
|
||||
assert_evals_to!("Identity 42 != Identity 42", false, bool);
|
||||
|
|
|
@ -248,6 +248,47 @@ fn list_sublist() {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
fn list_split() {
|
||||
assert_evals_to!(
|
||||
r#"
|
||||
list = List.split [1, 2, 3] 0
|
||||
list.before
|
||||
"#,
|
||||
RocList::from_slice(&[]),
|
||||
RocList<i64>
|
||||
);
|
||||
assert_evals_to!(
|
||||
r#"
|
||||
list = List.split [1, 2, 3] 0
|
||||
list.others
|
||||
"#,
|
||||
RocList::from_slice(&[1, 2, 3]),
|
||||
RocList<i64>
|
||||
);
|
||||
|
||||
assert_evals_to!(
|
||||
"List.split [1, 2, 3] 1",
|
||||
(RocList::from_slice(&[1]), RocList::from_slice(&[2, 3]),),
|
||||
(RocList<i64>, RocList<i64>,)
|
||||
);
|
||||
assert_evals_to!(
|
||||
"List.split [1, 2, 3] 3",
|
||||
(RocList::from_slice(&[1, 2, 3]), RocList::from_slice(&[]),),
|
||||
(RocList<i64>, RocList<i64>,)
|
||||
);
|
||||
assert_evals_to!(
|
||||
"List.split [1, 2, 3] 4",
|
||||
(RocList::from_slice(&[1, 2, 3]), RocList::from_slice(&[]),),
|
||||
(RocList<i64>, RocList<i64>,)
|
||||
);
|
||||
assert_evals_to!(
|
||||
"List.split [] 1",
|
||||
(RocList::from_slice(&[]), RocList::from_slice(&[]),),
|
||||
(RocList<i64>, RocList<i64>,)
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
fn list_drop() {
|
||||
|
@ -277,6 +318,29 @@ fn list_drop_at() {
|
|||
assert_evals_to!("List.dropAt [0] 0", RocList::from_slice(&[]), RocList<i64>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
fn list_intersperse() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
List.intersperse [0, 0, 0] 1
|
||||
"#
|
||||
),
|
||||
RocList::from_slice(&[0, 1, 0, 1, 0]),
|
||||
RocList<i64>
|
||||
);
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
List.intersperse [] 1
|
||||
"#
|
||||
),
|
||||
RocList::from_slice(&[]),
|
||||
RocList<i64>
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
fn list_drop_at_shared() {
|
||||
|
@ -2352,6 +2416,28 @@ fn list_any_empty_with_unknown_element_type() {
|
|||
assert_evals_to!("List.any [] (\\_ -> True)", false, bool);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
fn list_all() {
|
||||
assert_evals_to!("List.all [] (\\e -> e > 3)", true, bool);
|
||||
assert_evals_to!("List.all [ 1, 2, 3 ] (\\e -> e > 3)", false, bool);
|
||||
assert_evals_to!("List.all [ 1, 2, 4 ] (\\e -> e > 3)", false, bool);
|
||||
assert_evals_to!("List.all [ 1, 2, 3 ] (\\e -> e >= 1)", true, bool);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
#[should_panic(expected = r#"Roc failed with message: "UnresolvedTypeVar"#)]
|
||||
fn list_all_empty_with_unknown_element_type() {
|
||||
// Segfaults with invalid memory reference. Running this as a stand-alone
|
||||
// Roc program, generates the following error message:
|
||||
//
|
||||
// Application crashed with message
|
||||
// UnresolvedTypeVar compiler/mono/src/ir.rs line 3775
|
||||
// Shutting down
|
||||
assert_evals_to!("List.all [] (\\_ -> True)", false, bool);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
#[should_panic(expected = r#"Roc failed with message: "invalid ret_layout""#)]
|
||||
|
|
|
@ -571,7 +571,7 @@ fn abs_min_int_overflow() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
|
||||
fn gen_if_fn() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
|
@ -713,7 +713,7 @@ fn gen_int_eq() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
|
||||
fn gen_int_neq() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
|
@ -726,6 +726,20 @@ fn gen_int_neq() {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
|
||||
fn gen_int_less_than() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
4 < 5
|
||||
"#
|
||||
),
|
||||
true,
|
||||
bool
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
fn gen_dec_eq() {
|
||||
|
@ -1214,7 +1228,18 @@ fn tail_call_elimination() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-wasm"))]
|
||||
#[cfg(any(feature = "gen-dev"))]
|
||||
fn int_negate_dev() {
|
||||
// TODO
|
||||
// dev backend yet to have `Num.maxInt` or `Num.minInt`.
|
||||
// add the "gen-dev" feature to the test below after implementing them both.
|
||||
assert_evals_to!("Num.neg 123", -123, i64);
|
||||
assert_evals_to!("Num.neg -123", 123, i64);
|
||||
assert_evals_to!("Num.neg 0", 0, i64);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
fn int_negate() {
|
||||
assert_evals_to!("Num.neg 123", -123, i64);
|
||||
assert_evals_to!("Num.neg Num.maxInt", -i64::MAX, i64);
|
||||
|
|
|
@ -85,7 +85,7 @@ fn branch_third_float() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
|
||||
fn branch_first_int() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
|
@ -101,7 +101,7 @@ fn branch_first_int() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
|
||||
fn branch_second_int() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
|
@ -134,7 +134,7 @@ fn branch_third_int() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
|
||||
fn branch_store_variable() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
|
@ -221,7 +221,7 @@ fn gen_when_one_branch() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
fn gen_large_when_int() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
|
@ -243,31 +243,31 @@ fn gen_large_when_int() {
|
|||
);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// #[cfg(any(feature = "gen-llvm"))]
|
||||
// fn gen_large_when_float() {
|
||||
// assert_evals_to!(
|
||||
// indoc!(
|
||||
// r#"
|
||||
// foo = \num ->
|
||||
// when num is
|
||||
// 0.5 -> 200.1
|
||||
// -3.6 -> 111.2 # TODO adding more negative numbers reproduces parsing bugs here
|
||||
// 3.6 -> 789.5
|
||||
// 1.7 -> 123.3
|
||||
// 2.8 -> 456.4
|
||||
// _ -> 1000.6
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-wasm"))]
|
||||
fn gen_large_when_float() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
foo = \num ->
|
||||
when num is
|
||||
0.5 -> 200.1
|
||||
-3.6 -> 111.2 # TODO adding more negative numbers reproduces parsing bugs here
|
||||
3.6 -> 789.5
|
||||
1.7 -> 123.3
|
||||
2.8 -> 456.4
|
||||
_ -> 1000.6
|
||||
|
||||
// foo -3.6
|
||||
// "#
|
||||
// ),
|
||||
// 111.2,
|
||||
// f64
|
||||
// );
|
||||
// }
|
||||
foo -3.6
|
||||
"#
|
||||
),
|
||||
111.2,
|
||||
f64
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
|
||||
fn or_pattern() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
|
@ -337,7 +337,7 @@ fn return_unnamed_fn() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
fn gen_when_fn() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
|
@ -385,7 +385,7 @@ fn gen_basic_def() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
fn gen_multiple_defs() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
|
@ -504,7 +504,7 @@ fn gen_multiple_defs() {
|
|||
// }
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
|
||||
fn factorial() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
|
|
|
@ -11,7 +11,7 @@ use crate::helpers::wasm::assert_evals_to;
|
|||
use indoc::indoc;
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
|
||||
fn basic_record() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
|
@ -45,7 +45,7 @@ fn basic_record() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
|
||||
fn f64_record() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
|
@ -137,7 +137,7 @@ fn fn_record() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
|
||||
fn def_record() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
|
@ -192,7 +192,7 @@ fn when_on_record() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
|
||||
fn when_record_with_guard_pattern() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
|
@ -207,7 +207,7 @@ fn when_record_with_guard_pattern() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
|
||||
fn let_with_record_pattern() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
|
@ -223,7 +223,7 @@ fn let_with_record_pattern() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
|
||||
fn record_guard_pattern() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
|
@ -239,7 +239,7 @@ fn record_guard_pattern() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
|
||||
fn twice_record_access() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
|
@ -254,7 +254,7 @@ fn twice_record_access() {
|
|||
);
|
||||
}
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-dev"))]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
|
||||
fn empty_record() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
|
@ -873,7 +873,7 @@ fn update_single_element_record() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
fn booleans_in_record() {
|
||||
assert_evals_to!(
|
||||
indoc!("{ x: 1 == 1, y: 1 == 1 }"),
|
||||
|
@ -908,7 +908,7 @@ fn alignment_in_record() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
fn blue_and_present() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
|
@ -927,7 +927,7 @@ fn blue_and_present() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
fn blue_and_absent() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
|
@ -968,3 +968,24 @@ fn update_the_only_field() {
|
|||
i64
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
// https://github.com/rtfeldman/roc/issues/1513
|
||||
fn both_have_unique_fields() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
a = { x: 42, y: 43 }
|
||||
b = { x: 42, z: 44 }
|
||||
|
||||
f : { x : I64 }a, { x : I64 }b -> I64
|
||||
f = \{ x: x1}, { x: x2 } -> x1 + x2
|
||||
|
||||
f a b
|
||||
"#
|
||||
),
|
||||
84,
|
||||
i64
|
||||
);
|
||||
}
|
||||
|
|
|
@ -189,3 +189,33 @@ fn is_ok() {
|
|||
bool
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
fn is_err() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
result : Result I64 {}
|
||||
result = Ok 2
|
||||
|
||||
Result.isErr result
|
||||
"#
|
||||
),
|
||||
false,
|
||||
bool
|
||||
);
|
||||
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
result : Result I64 {}
|
||||
result = Err {}
|
||||
|
||||
Result.isErr result
|
||||
"#
|
||||
),
|
||||
true,
|
||||
bool
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1244,3 +1244,96 @@ fn str_trim_left_small_to_small_shared() {
|
|||
(RocStr, RocStr)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
fn str_trim_right_small_blank_string() {
|
||||
assert_evals_to!(indoc!(r#"Str.trimRight " ""#), RocStr::from(""), RocStr);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
fn str_trim_right_small_to_small() {
|
||||
assert_evals_to!(
|
||||
indoc!(r#"Str.trimRight " hello world ""#),
|
||||
RocStr::from(" hello world"),
|
||||
RocStr
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
fn str_trim_right_large_to_large_unique() {
|
||||
assert_evals_to!(
|
||||
indoc!(r#"Str.trimRight (Str.concat " hello world from a large string" " ")"#),
|
||||
RocStr::from(" hello world from a large string"),
|
||||
RocStr
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
fn str_trim_right_large_to_small_unique() {
|
||||
assert_evals_to!(
|
||||
indoc!(r#"Str.trimRight (Str.concat " hello world" " ")"#),
|
||||
RocStr::from(" hello world"),
|
||||
RocStr
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
fn str_trim_right_large_to_large_shared() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
original : Str
|
||||
original = " hello world world "
|
||||
|
||||
{ trimmed: Str.trimRight original, original: original }
|
||||
"#
|
||||
),
|
||||
(
|
||||
RocStr::from(" hello world world "),
|
||||
RocStr::from(" hello world world"),
|
||||
),
|
||||
(RocStr, RocStr)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
fn str_trim_right_large_to_small_shared() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
original : Str
|
||||
original = " hello world "
|
||||
|
||||
{ trimmed: Str.trimRight original, original: original }
|
||||
"#
|
||||
),
|
||||
(
|
||||
RocStr::from(" hello world "),
|
||||
RocStr::from(" hello world"),
|
||||
),
|
||||
(RocStr, RocStr)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
fn str_trim_right_small_to_small_shared() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
original : Str
|
||||
original = " hello world "
|
||||
|
||||
{ trimmed: Str.trimRight original, original: original }
|
||||
"#
|
||||
),
|
||||
(RocStr::from(" hello world "), RocStr::from(" hello world"),),
|
||||
(RocStr, RocStr)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -453,7 +453,7 @@ fn result_with_guard_pattern() {
|
|||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
fn maybe_is_just() {
|
||||
fn maybe_is_just_not_nested() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
|
|
|
@ -198,6 +198,10 @@ fn create_llvm_module<'a>(
|
|||
if name.starts_with("roc_builtins.dict") {
|
||||
function.add_attribute(AttributeLoc::Function, attr);
|
||||
}
|
||||
|
||||
if name.starts_with("roc_builtins.list") {
|
||||
function.add_attribute(AttributeLoc::Function, attr);
|
||||
}
|
||||
}
|
||||
|
||||
// Compile and add all the Procs before adding main
|
||||
|
|
|
@ -1,16 +1,22 @@
|
|||
use bumpalo::collections::vec::Vec;
|
||||
use bumpalo::Bump;
|
||||
use std::cell::Cell;
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use tempfile::{tempdir, TempDir};
|
||||
|
||||
use crate::helpers::from_wasm32_memory::FromWasm32Memory;
|
||||
use crate::helpers::wasm32_test_result::Wasm32TestResult;
|
||||
use roc_builtins::bitcode;
|
||||
use roc_can::builtins::builtin_defs_map;
|
||||
use roc_collections::all::{MutMap, MutSet};
|
||||
use roc_gen_wasm::wasm_module::linking::{WasmObjectSymbol, WASM_SYM_UNDEFINED};
|
||||
use roc_gen_wasm::wasm_module::sections::{Import, ImportDesc};
|
||||
use roc_gen_wasm::wasm_module::{
|
||||
CodeBuilder, Export, ExportType, LocalId, Signature, SymInfo, ValueType, WasmModule,
|
||||
};
|
||||
use roc_gen_wasm::MEMORY_NAME;
|
||||
|
||||
use tempfile::tempdir;
|
||||
|
||||
const TEST_WRAPPER_NAME: &str = "test_wrapper";
|
||||
|
||||
std::thread_local! {
|
||||
|
@ -92,11 +98,6 @@ pub fn helper_wasm<'a, T: Wasm32TestResult>(
|
|||
// }
|
||||
|
||||
debug_assert_eq!(exposed_to_host.len(), 1);
|
||||
let main_fn_symbol = loaded.entry_point.symbol;
|
||||
let main_fn_index = procedures
|
||||
.keys()
|
||||
.position(|(s, _)| *s == main_fn_symbol)
|
||||
.unwrap();
|
||||
|
||||
let exposed_to_host = exposed_to_host.keys().copied().collect::<MutSet<_>>();
|
||||
|
||||
|
@ -106,63 +107,61 @@ pub fn helper_wasm<'a, T: Wasm32TestResult>(
|
|||
exposed_to_host,
|
||||
};
|
||||
|
||||
let mut wasm_module = roc_gen_wasm::build_module_help(&env, procedures).unwrap();
|
||||
let (mut wasm_module, main_fn_index) =
|
||||
roc_gen_wasm::build_module_help(&env, procedures).unwrap();
|
||||
|
||||
T::insert_test_wrapper(
|
||||
arena,
|
||||
&mut wasm_module,
|
||||
TEST_WRAPPER_NAME,
|
||||
main_fn_index as u32,
|
||||
);
|
||||
T::insert_test_wrapper(arena, &mut wasm_module, TEST_WRAPPER_NAME, main_fn_index);
|
||||
|
||||
// We can either generate the test platform or write an external source file, whatever works
|
||||
generate_test_platform(&mut wasm_module, arena);
|
||||
|
||||
let mut module_bytes = std::vec::Vec::with_capacity(4096);
|
||||
wasm_module.serialize_mut(&mut module_bytes);
|
||||
|
||||
// for debugging (e.g. with wasm2wat or wasm-objdump)
|
||||
if false {
|
||||
use std::io::Write;
|
||||
|
||||
let mut hash_state = DefaultHasher::new();
|
||||
src.hash(&mut hash_state);
|
||||
let src_hash = hash_state.finish();
|
||||
|
||||
// Filename contains a hash of the Roc test source code. Helpful when comparing across commits.
|
||||
let dir = "/tmp/roc/compiler/gen_wasm/output";
|
||||
std::fs::create_dir_all(dir).unwrap();
|
||||
let path = format!("{}/test-{:016x}.wasm", dir, src_hash);
|
||||
|
||||
// Print out filename (appears just after test name)
|
||||
println!("dumping file {:?}", path);
|
||||
|
||||
match std::fs::File::create(path) {
|
||||
Err(e) => eprintln!("Problem creating wasm debug file: {:?}", e),
|
||||
Ok(mut file) => {
|
||||
file.write_all(&module_bytes).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// now, do wasmer stuff
|
||||
|
||||
use wasmer::{Instance, Module, Store};
|
||||
|
||||
let store = Store::default();
|
||||
|
||||
// Keep the final .wasm file for debugging with wasm-objdump or wasm2wat
|
||||
const DEBUG_WASM_FILE: bool = true;
|
||||
|
||||
let wasmer_module = {
|
||||
let dir = tempdir().unwrap();
|
||||
let dirpath = dir.path();
|
||||
let final_wasm_file = dirpath.join("final.wasm");
|
||||
let app_o_file = dirpath.join("app.o");
|
||||
let tmp_dir: TempDir; // directory for normal test runs, deleted when dropped
|
||||
let debug_dir: String; // persistent directory for debugging
|
||||
|
||||
let wasm_build_dir: &Path = if DEBUG_WASM_FILE {
|
||||
// Directory name based on a hash of the Roc source
|
||||
let mut hash_state = DefaultHasher::new();
|
||||
src.hash(&mut hash_state);
|
||||
let src_hash = hash_state.finish();
|
||||
debug_dir = format!("/tmp/roc/gen_wasm/{:016x}", src_hash);
|
||||
std::fs::create_dir_all(&debug_dir).unwrap();
|
||||
println!(
|
||||
"Debug command:\n\twasm-objdump -sdx {}/final.wasm",
|
||||
&debug_dir
|
||||
);
|
||||
Path::new(&debug_dir)
|
||||
} else {
|
||||
tmp_dir = tempdir().unwrap();
|
||||
tmp_dir.path()
|
||||
};
|
||||
|
||||
let final_wasm_file = wasm_build_dir.join("final.wasm");
|
||||
let app_o_file = wasm_build_dir.join("app.o");
|
||||
let libc_a_file = "../gen_wasm/lib/libc.a";
|
||||
|
||||
// write the module to a file so the linker can access it
|
||||
std::fs::write(&app_o_file, &module_bytes).unwrap();
|
||||
|
||||
std::process::Command::new("zig")
|
||||
let _linker_output = std::process::Command::new("zig")
|
||||
.args(&[
|
||||
"wasm-ld",
|
||||
// input files
|
||||
app_o_file.to_str().unwrap(),
|
||||
bitcode::BUILTINS_WASM32_OBJ_PATH,
|
||||
libc_a_file,
|
||||
// output
|
||||
"-o",
|
||||
final_wasm_file.to_str().unwrap(),
|
||||
|
@ -182,6 +181,8 @@ pub fn helper_wasm<'a, T: Wasm32TestResult>(
|
|||
.output()
|
||||
.unwrap();
|
||||
|
||||
// dbg!(_linker_output);
|
||||
|
||||
Module::from_file(&store, &final_wasm_file).unwrap()
|
||||
};
|
||||
|
||||
|
@ -276,3 +277,123 @@ pub fn identity<T>(value: T) -> T {
|
|||
pub(crate) use assert_evals_to;
|
||||
#[allow(unused_imports)]
|
||||
pub(crate) use assert_wasm_evals_to;
|
||||
|
||||
fn wrap_libc_fn<'a>(
|
||||
module: &mut WasmModule<'a>,
|
||||
arena: &'a Bump,
|
||||
roc_name: &'a str,
|
||||
libc_name: &'a str,
|
||||
params: &'a [(ValueType, bool)],
|
||||
ret_type: Option<ValueType>,
|
||||
) {
|
||||
let symbol_table = module.linking.symbol_table_mut();
|
||||
|
||||
// Type signatures
|
||||
let mut wrapper_signature = Signature {
|
||||
param_types: Vec::with_capacity_in(params.len(), arena),
|
||||
ret_type,
|
||||
};
|
||||
let mut libc_signature = Signature {
|
||||
param_types: Vec::with_capacity_in(params.len(), arena),
|
||||
ret_type,
|
||||
};
|
||||
for (ty, used) in params.iter() {
|
||||
wrapper_signature.param_types.push(*ty);
|
||||
if *used {
|
||||
libc_signature.param_types.push(*ty);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Import a function from libc
|
||||
*/
|
||||
let libc_signature_index = module.types.insert(libc_signature);
|
||||
|
||||
// Import
|
||||
let import_index = module.import.entries.len() as u32;
|
||||
module.import.entries.push(Import {
|
||||
module: "env",
|
||||
name: libc_name.to_string(),
|
||||
description: ImportDesc::Func {
|
||||
signature_index: libc_signature_index,
|
||||
},
|
||||
});
|
||||
|
||||
// Linker info
|
||||
let libc_sym_idx = symbol_table.len() as u32;
|
||||
symbol_table.push(SymInfo::Function(WasmObjectSymbol::Imported {
|
||||
flags: WASM_SYM_UNDEFINED,
|
||||
index: import_index,
|
||||
}));
|
||||
|
||||
/*
|
||||
* Export a wrapper function
|
||||
*/
|
||||
|
||||
// Declaration
|
||||
let wrapper_sig_index = module.types.insert(wrapper_signature);
|
||||
module.function.signature_indices.push(wrapper_sig_index);
|
||||
|
||||
// Body
|
||||
let mut code_builder = CodeBuilder::new(arena);
|
||||
let mut num_libc_args = 0;
|
||||
for (i, (_, used)) in params.iter().enumerate() {
|
||||
if *used {
|
||||
code_builder.get_local(LocalId(i as u32));
|
||||
num_libc_args += 1;
|
||||
}
|
||||
}
|
||||
code_builder.call(
|
||||
import_index,
|
||||
libc_sym_idx,
|
||||
num_libc_args,
|
||||
ret_type.is_some(),
|
||||
);
|
||||
code_builder.build_fn_header(&[], 0, None);
|
||||
let wrapper_index = module.code.code_builders.len() as u32;
|
||||
module.code.code_builders.push(code_builder);
|
||||
|
||||
// Export
|
||||
module.export.entries.push(Export {
|
||||
name: roc_name.to_string(),
|
||||
ty: ExportType::Func,
|
||||
index: wrapper_index,
|
||||
});
|
||||
|
||||
// Linker symbol
|
||||
symbol_table.push(SymInfo::Function(WasmObjectSymbol::Defined {
|
||||
flags: 0,
|
||||
index: wrapper_index,
|
||||
name: roc_name.to_string(),
|
||||
}));
|
||||
}
|
||||
|
||||
fn generate_test_platform<'a>(module: &mut WasmModule<'a>, arena: &'a Bump) {
|
||||
use ValueType::I32;
|
||||
|
||||
wrap_libc_fn(
|
||||
module,
|
||||
arena,
|
||||
"roc_alloc",
|
||||
"malloc",
|
||||
// only the first argument of roc_alloc is passed to malloc
|
||||
&[(I32, true), (I32, false)],
|
||||
Some(I32),
|
||||
);
|
||||
wrap_libc_fn(
|
||||
module,
|
||||
arena,
|
||||
"roc_dealloc",
|
||||
"free",
|
||||
&[(I32, true), (I32, false)],
|
||||
None,
|
||||
);
|
||||
wrap_libc_fn(
|
||||
module,
|
||||
arena,
|
||||
"roc_realloc",
|
||||
"realloc",
|
||||
&[(I32, true), (I32, false), (I32, true), (I32, false)],
|
||||
Some(I32),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Wasm pointers are only 32bit. This effects RocStr.
|
||||
// These are versions of the str tests assuming 32bit pointers.
|
||||
#![cfg(not(feature = "gen-dev"))]
|
||||
#![cfg(feature = "gen-wasm")]
|
||||
|
||||
// TODO: We need to make these tests work with the llvm wasm backend.
|
||||
|
||||
|
@ -12,7 +12,7 @@ use crate::helpers::wasm::assert_evals_to;
|
|||
|
||||
#[allow(unused_imports)]
|
||||
use indoc::indoc;
|
||||
// use roc_std::RocStr;
|
||||
use roc_std::RocStr;
|
||||
|
||||
// #[test]
|
||||
// fn str_split_bigger_delimiter_small_str() {
|
||||
|
@ -287,165 +287,113 @@ fn small_str_zeroed_literal() {
|
|||
);
|
||||
}
|
||||
|
||||
// TODO: fix linking errors for undefined symbols roc_alloc, roc_dealloc
|
||||
// #[test]
|
||||
// fn long_str_literal() {
|
||||
// assert_evals_to!(
|
||||
// "\"0123456789 123456789 123456789\"",
|
||||
// RocStr::from_slice(b"0123456789 123456789 123456789"),
|
||||
// RocStr
|
||||
// );
|
||||
// }
|
||||
#[test]
|
||||
fn long_str_literal() {
|
||||
assert_evals_to!(
|
||||
"\"0123456789 123456789 123456789\"",
|
||||
RocStr::from_slice(b"0123456789 123456789 123456789"),
|
||||
RocStr
|
||||
);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn small_str_concat_empty_first_arg() {
|
||||
// assert_llvm_evals_to!(
|
||||
// r#"Str.concat "" "JJJJJJJJJJJJJJJ""#,
|
||||
// [
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0b1000_1111
|
||||
// ],
|
||||
// [u8; 16]
|
||||
// );
|
||||
// }
|
||||
#[test]
|
||||
fn small_str_concat_empty_first_arg() {
|
||||
assert_evals_to!(
|
||||
r#"Str.concat "" "JJJJJJJ""#,
|
||||
[0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0b1000_0111],
|
||||
[u8; 8]
|
||||
);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn small_str_concat_empty_second_arg() {
|
||||
// assert_llvm_evals_to!(
|
||||
// r#"Str.concat "JJJJJJJJJJJJJJJ" """#,
|
||||
// [
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0b1000_1111
|
||||
// ],
|
||||
// [u8; 16]
|
||||
// );
|
||||
// }
|
||||
#[test]
|
||||
fn small_str_concat_empty_second_arg() {
|
||||
assert_evals_to!(
|
||||
r#"Str.concat "JJJJJJJ" """#,
|
||||
[0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0b1000_0111],
|
||||
[u8; 8]
|
||||
);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn small_str_concat_small_to_big() {
|
||||
// assert_evals_to!(
|
||||
// r#"Str.concat "abc" " this is longer than 15 chars""#,
|
||||
// RocStr::from_slice(b"abc this is longer than 15 chars"),
|
||||
// RocStr
|
||||
// );
|
||||
// }
|
||||
#[test]
|
||||
fn small_str_concat_small_to_big() {
|
||||
assert_evals_to!(
|
||||
r#"Str.concat "abc" " this is longer than 7 chars""#,
|
||||
RocStr::from_slice(b"abc this is longer than 7 chars"),
|
||||
RocStr
|
||||
);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn small_str_concat_small_to_small_staying_small() {
|
||||
// assert_llvm_evals_to!(
|
||||
// r#"Str.concat "J" "JJJJJJJJJJJJJJ""#,
|
||||
// [
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0x4a,
|
||||
// 0b1000_1111
|
||||
// ],
|
||||
// [u8; 16]
|
||||
// );
|
||||
// }
|
||||
#[test]
|
||||
fn small_str_concat_small_to_small_staying_small() {
|
||||
assert_evals_to!(
|
||||
r#"Str.concat "J" "JJJJJJ""#,
|
||||
[0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0b1000_0111],
|
||||
[u8; 8]
|
||||
);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn small_str_concat_small_to_small_overflow_to_big() {
|
||||
// assert_evals_to!(
|
||||
// r#"Str.concat "abcdefghijklm" "nopqrstuvwxyz""#,
|
||||
// RocStr::from_slice(b"abcdefghijklmnopqrstuvwxyz"),
|
||||
// RocStr
|
||||
// );
|
||||
// }
|
||||
#[test]
|
||||
fn small_str_concat_small_to_small_overflow_to_big() {
|
||||
assert_evals_to!(
|
||||
r#"Str.concat "abcdefg" "hijklmn""#,
|
||||
RocStr::from_slice(b"abcdefghijklmn"),
|
||||
RocStr
|
||||
);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn str_concat_empty() {
|
||||
// assert_evals_to!(r#"Str.concat "" """#, RocStr::default(), RocStr);
|
||||
// }
|
||||
#[test]
|
||||
fn str_concat_empty() {
|
||||
assert_evals_to!(r#"Str.concat "" """#, RocStr::default(), RocStr);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn small_str_is_empty() {
|
||||
// assert_evals_to!(r#"Str.isEmpty "abc""#, false, bool);
|
||||
// }
|
||||
#[test]
|
||||
fn small_str_is_empty() {
|
||||
assert_evals_to!(r#"Str.isEmpty "abc""#, false, bool);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn big_str_is_empty() {
|
||||
// assert_evals_to!(
|
||||
// r#"Str.isEmpty "this is more than 15 chars long""#,
|
||||
// false,
|
||||
// bool
|
||||
// );
|
||||
// }
|
||||
#[test]
|
||||
fn big_str_is_empty() {
|
||||
assert_evals_to!(
|
||||
r#"Str.isEmpty "this is more than 15 chars long""#,
|
||||
false,
|
||||
bool
|
||||
);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn empty_str_is_empty() {
|
||||
// assert_evals_to!(r#"Str.isEmpty """#, true, bool);
|
||||
// }
|
||||
#[test]
|
||||
fn empty_str_is_empty() {
|
||||
assert_evals_to!(r#"Str.isEmpty """#, true, bool);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn str_starts_with() {
|
||||
// assert_evals_to!(r#"Str.startsWith "hello world" "hell""#, true, bool);
|
||||
// assert_evals_to!(r#"Str.startsWith "hello world" """#, true, bool);
|
||||
// assert_evals_to!(r#"Str.startsWith "nope" "hello world""#, false, bool);
|
||||
// assert_evals_to!(r#"Str.startsWith "hell" "hello world""#, false, bool);
|
||||
// assert_evals_to!(r#"Str.startsWith "" "hello world""#, false, bool);
|
||||
// }
|
||||
#[test]
|
||||
fn str_starts_with() {
|
||||
assert_evals_to!(r#"Str.startsWith "hello world" "hell""#, true, bool);
|
||||
assert_evals_to!(r#"Str.startsWith "hello world" """#, true, bool);
|
||||
assert_evals_to!(r#"Str.startsWith "nope" "hello world""#, false, bool);
|
||||
assert_evals_to!(r#"Str.startsWith "hell" "hello world""#, false, bool);
|
||||
assert_evals_to!(r#"Str.startsWith "" "hello world""#, false, bool);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn str_starts_with_code_point() {
|
||||
// assert_evals_to!(
|
||||
// &format!(r#"Str.startsWithCodePt "foobar" {}"#, 'f' as u32),
|
||||
// true,
|
||||
// bool
|
||||
// );
|
||||
// assert_evals_to!(
|
||||
// &format!(r#"Str.startsWithCodePt "zoobar" {}"#, 'f' as u32),
|
||||
// false,
|
||||
// bool
|
||||
// );
|
||||
// }
|
||||
#[test]
|
||||
fn str_starts_with_code_point() {
|
||||
assert_evals_to!(
|
||||
&format!(r#"Str.startsWithCodePt "foobar" {}"#, 'f' as u32),
|
||||
true,
|
||||
bool
|
||||
);
|
||||
assert_evals_to!(
|
||||
&format!(r#"Str.startsWithCodePt "zoobar" {}"#, 'f' as u32),
|
||||
false,
|
||||
bool
|
||||
);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn str_ends_with() {
|
||||
// assert_evals_to!(r#"Str.endsWith "hello world" "world""#, true, bool);
|
||||
// assert_evals_to!(r#"Str.endsWith "nope" "hello world""#, false, bool);
|
||||
// assert_evals_to!(r#"Str.endsWith "" "hello world""#, false, bool);
|
||||
// }
|
||||
#[test]
|
||||
fn str_ends_with() {
|
||||
assert_evals_to!(r#"Str.endsWith "hello world" "world""#, true, bool);
|
||||
assert_evals_to!(r#"Str.endsWith "nope" "hello world""#, false, bool);
|
||||
assert_evals_to!(r#"Str.endsWith "" "hello world""#, false, bool);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn str_count_graphemes_small_str() {
|
||||
|
@ -466,37 +414,37 @@ fn small_str_zeroed_literal() {
|
|||
// );
|
||||
// }
|
||||
|
||||
// #[test]
|
||||
// fn str_starts_with_same_big_str() {
|
||||
// assert_evals_to!(
|
||||
// r#"Str.startsWith "123456789123456789" "123456789123456789""#,
|
||||
// true,
|
||||
// bool
|
||||
// );
|
||||
// }
|
||||
#[test]
|
||||
fn str_starts_with_same_big_str() {
|
||||
assert_evals_to!(
|
||||
r#"Str.startsWith "123456789123456789" "123456789123456789""#,
|
||||
true,
|
||||
bool
|
||||
);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn str_starts_with_different_big_str() {
|
||||
// assert_evals_to!(
|
||||
// r#"Str.startsWith "12345678912345678910" "123456789123456789""#,
|
||||
// true,
|
||||
// bool
|
||||
// );
|
||||
// }
|
||||
#[test]
|
||||
fn str_starts_with_different_big_str() {
|
||||
assert_evals_to!(
|
||||
r#"Str.startsWith "12345678912345678910" "123456789123456789""#,
|
||||
true,
|
||||
bool
|
||||
);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn str_starts_with_same_small_str() {
|
||||
// assert_evals_to!(r#"Str.startsWith "1234" "1234""#, true, bool);
|
||||
// }
|
||||
#[test]
|
||||
fn str_starts_with_same_small_str() {
|
||||
assert_evals_to!(r#"Str.startsWith "1234" "1234""#, true, bool);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn str_starts_with_different_small_str() {
|
||||
// assert_evals_to!(r#"Str.startsWith "1234" "12""#, true, bool);
|
||||
// }
|
||||
// #[test]
|
||||
// fn str_starts_with_false_small_str() {
|
||||
// assert_evals_to!(r#"Str.startsWith "1234" "23""#, false, bool);
|
||||
// }
|
||||
#[test]
|
||||
fn str_starts_with_different_small_str() {
|
||||
assert_evals_to!(r#"Str.startsWith "1234" "12""#, true, bool);
|
||||
}
|
||||
#[test]
|
||||
fn str_starts_with_false_small_str() {
|
||||
assert_evals_to!(r#"Str.startsWith "1234" "23""#, false, bool);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn str_from_int() {
|
||||
|
@ -952,121 +900,239 @@ fn small_str_zeroed_literal() {
|
|||
// );
|
||||
// }
|
||||
|
||||
// #[test]
|
||||
// fn str_repeat_small() {
|
||||
// assert_evals_to!(
|
||||
// indoc!(r#"Str.repeat "Roc" 3"#),
|
||||
// RocStr::from("RocRocRoc"),
|
||||
// RocStr
|
||||
// );
|
||||
// }
|
||||
#[test]
|
||||
fn str_repeat_small() {
|
||||
assert_evals_to!(
|
||||
indoc!(r#"Str.repeat "Roc" 3"#),
|
||||
RocStr::from("RocRocRoc"),
|
||||
RocStr
|
||||
);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn str_repeat_big() {
|
||||
// assert_evals_to!(
|
||||
// indoc!(r#"Str.repeat "more than 16 characters" 2"#),
|
||||
// RocStr::from("more than 16 charactersmore than 16 characters"),
|
||||
// RocStr
|
||||
// );
|
||||
// }
|
||||
#[test]
|
||||
fn str_repeat_big() {
|
||||
assert_evals_to!(
|
||||
indoc!(r#"Str.repeat "more than 16 characters" 2"#),
|
||||
RocStr::from("more than 16 charactersmore than 16 characters"),
|
||||
RocStr
|
||||
);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn str_repeat_empty_string() {
|
||||
// assert_evals_to!(indoc!(r#"Str.repeat "" 3"#), RocStr::from(""), RocStr);
|
||||
// }
|
||||
#[test]
|
||||
fn str_repeat_empty_string() {
|
||||
assert_evals_to!(indoc!(r#"Str.repeat "" 3"#), RocStr::from(""), RocStr);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn str_repeat_zero_times() {
|
||||
// assert_evals_to!(indoc!(r#"Str.repeat "Roc" 0"#), RocStr::from(""), RocStr);
|
||||
// }
|
||||
#[test]
|
||||
fn str_repeat_zero_times() {
|
||||
assert_evals_to!(indoc!(r#"Str.repeat "Roc" 0"#), RocStr::from(""), RocStr);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn str_trim_empty_string() {
|
||||
// assert_evals_to!(indoc!(r#"Str.trim """#), RocStr::from(""), RocStr);
|
||||
// }
|
||||
#[test]
|
||||
fn str_trim_empty_string() {
|
||||
assert_evals_to!(indoc!(r#"Str.trim """#), RocStr::from(""), RocStr);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn str_trim_small_blank_string() {
|
||||
// assert_evals_to!(indoc!(r#"Str.trim " ""#), RocStr::from(""), RocStr);
|
||||
// }
|
||||
#[test]
|
||||
fn str_trim_small_blank_string() {
|
||||
assert_evals_to!(indoc!(r#"Str.trim " ""#), RocStr::from(""), RocStr);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn str_trim_small_to_small() {
|
||||
// assert_evals_to!(
|
||||
// indoc!(r#"Str.trim " hello world ""#),
|
||||
// RocStr::from("hello world"),
|
||||
// RocStr
|
||||
// );
|
||||
// }
|
||||
#[test]
|
||||
fn str_trim_small_to_small() {
|
||||
assert_evals_to!(
|
||||
indoc!(r#"Str.trim " hello world ""#),
|
||||
RocStr::from("hello world"),
|
||||
RocStr
|
||||
);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn str_trim_large_to_large_unique() {
|
||||
// assert_evals_to!(
|
||||
// indoc!(r#"Str.trim (Str.concat " " "hello world from a large string ")"#),
|
||||
// RocStr::from("hello world from a large string"),
|
||||
// RocStr
|
||||
// );
|
||||
// }
|
||||
#[test]
|
||||
fn str_trim_large_to_large_unique() {
|
||||
assert_evals_to!(
|
||||
indoc!(r#"Str.trim (Str.concat " " "hello world from a large string ")"#),
|
||||
RocStr::from("hello world from a large string"),
|
||||
RocStr
|
||||
);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn str_trim_large_to_small_unique() {
|
||||
// assert_evals_to!(
|
||||
// indoc!(r#"Str.trim (Str.concat " " "hello world ")"#),
|
||||
// RocStr::from("hello world"),
|
||||
// RocStr
|
||||
// );
|
||||
// }
|
||||
#[test]
|
||||
fn str_trim_large_to_small_unique() {
|
||||
assert_evals_to!(
|
||||
indoc!(r#"Str.trim (Str.concat " " "hello world ")"#),
|
||||
RocStr::from("hello world"),
|
||||
RocStr
|
||||
);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn str_trim_large_to_large_shared() {
|
||||
// assert_evals_to!(
|
||||
// indoc!(
|
||||
// r#"
|
||||
// original : Str
|
||||
// original = " hello world world "
|
||||
#[test]
|
||||
fn str_trim_large_to_large_shared() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
original : Str
|
||||
original = " hello world world "
|
||||
|
||||
// { trimmed: Str.trim original, original: original }
|
||||
// "#
|
||||
// ),
|
||||
// (
|
||||
// RocStr::from(" hello world world "),
|
||||
// RocStr::from("hello world world"),
|
||||
// ),
|
||||
// (RocStr, RocStr)
|
||||
// );
|
||||
// }
|
||||
{ trimmed: Str.trim original, original: original }
|
||||
"#
|
||||
),
|
||||
(
|
||||
RocStr::from(" hello world world "),
|
||||
RocStr::from("hello world world"),
|
||||
),
|
||||
(RocStr, RocStr)
|
||||
);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn str_trim_large_to_small_shared() {
|
||||
// assert_evals_to!(
|
||||
// indoc!(
|
||||
// r#"
|
||||
// original : Str
|
||||
// original = " hello world "
|
||||
#[test]
|
||||
fn str_trim_large_to_small_shared() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
original : Str
|
||||
original = " hello world "
|
||||
|
||||
// { trimmed: Str.trim original, original: original }
|
||||
// "#
|
||||
// ),
|
||||
// (
|
||||
// RocStr::from(" hello world "),
|
||||
// RocStr::from("hello world"),
|
||||
// ),
|
||||
// (RocStr, RocStr)
|
||||
// );
|
||||
// }
|
||||
{ trimmed: Str.trim original, original: original }
|
||||
"#
|
||||
),
|
||||
(
|
||||
RocStr::from(" hello world "),
|
||||
RocStr::from("hello world"),
|
||||
),
|
||||
(RocStr, RocStr)
|
||||
);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn str_trim_small_to_small_shared() {
|
||||
// assert_evals_to!(
|
||||
// indoc!(
|
||||
// r#"
|
||||
// original : Str
|
||||
// original = " hello world "
|
||||
#[test]
|
||||
fn str_trim_small_to_small_shared() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
original : Str
|
||||
original = " hello world "
|
||||
|
||||
// { trimmed: Str.trim original, original: original }
|
||||
// "#
|
||||
// ),
|
||||
// (RocStr::from(" hello world "), RocStr::from("hello world"),),
|
||||
// (RocStr, RocStr)
|
||||
// );
|
||||
// }
|
||||
{ trimmed: Str.trim original, original: original }
|
||||
"#
|
||||
),
|
||||
(RocStr::from(" hello world "), RocStr::from("hello world"),),
|
||||
(RocStr, RocStr)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn str_trim_left_small_blank_string() {
|
||||
assert_evals_to!(indoc!(r#"Str.trimLeft " ""#), RocStr::from(""), RocStr);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn str_trim_left_small_to_small() {
|
||||
assert_evals_to!(
|
||||
indoc!(r#"Str.trimLeft " hello world ""#),
|
||||
RocStr::from("hello world "),
|
||||
RocStr
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn str_trim_left_large_to_large_unique() {
|
||||
assert_evals_to!(
|
||||
indoc!(r#"Str.trimLeft (Str.concat " " "hello world from a large string ")"#),
|
||||
RocStr::from("hello world from a large string "),
|
||||
RocStr
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn str_trim_left_large_to_small_unique() {
|
||||
assert_evals_to!(
|
||||
indoc!(r#"Str.trimLeft (Str.concat " " "hello world ")"#),
|
||||
RocStr::from("hello world "),
|
||||
RocStr
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn str_trim_right_small_blank_string() {
|
||||
assert_evals_to!(indoc!(r#"Str.trimRight " ""#), RocStr::from(""), RocStr);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn str_trim_right_small_to_small() {
|
||||
assert_evals_to!(
|
||||
indoc!(r#"Str.trimRight " hello world ""#),
|
||||
RocStr::from(" hello world"),
|
||||
RocStr
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn str_trim_right_large_to_large_unique() {
|
||||
assert_evals_to!(
|
||||
indoc!(r#"Str.trimRight (Str.concat " hello world from a large string" " ")"#),
|
||||
RocStr::from(" hello world from a large string"),
|
||||
RocStr
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn str_trim_right_large_to_small_unique() {
|
||||
assert_evals_to!(
|
||||
indoc!(r#"Str.trimRight (Str.concat " hello world" " ")"#),
|
||||
RocStr::from(" hello world"),
|
||||
RocStr
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn str_trim_right_large_to_large_shared() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
original : Str
|
||||
original = " hello world world "
|
||||
|
||||
{ trimmed: Str.trimRight original, original: original }
|
||||
"#
|
||||
),
|
||||
(
|
||||
RocStr::from(" hello world world "),
|
||||
RocStr::from(" hello world world"),
|
||||
),
|
||||
(RocStr, RocStr)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn str_trim_right_large_to_small_shared() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
original : Str
|
||||
original = " hello world "
|
||||
|
||||
{ trimmed: Str.trimRight original, original: original }
|
||||
"#
|
||||
),
|
||||
(
|
||||
RocStr::from(" hello world "),
|
||||
RocStr::from(" hello world"),
|
||||
),
|
||||
(RocStr, RocStr)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn str_trim_right_small_to_small_shared() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
original : Str
|
||||
original = " hello world "
|
||||
|
||||
{ trimmed: Str.trimRight original, original: original }
|
||||
"#
|
||||
),
|
||||
(RocStr::from(" hello world "), RocStr::from(" hello world"),),
|
||||
(RocStr, RocStr)
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue