#![cfg(any(
not(any(
feature = "parser_tests",
feature = "analyzer_tests",
feature = "codegen_tests",
feature = "interpreter_tests",
feature = "conformance_tests",
feature = "integration_tests",
)),
feature = "analyzer_tests",
))]
#[path = "common/test_utils.rs"]
mod test_utils;
#[test]
#[cfg_attr(tarpaulin, ignore)]
fn test_fn_arg_auto_borrow() {
let src = r#"
pub fn takes_ref(s: string) {}
pub fn caller(s: string) {
takes_ref(s)
}
"#;
let (result, success) = test_utils::compile_single_check(src);
let err = if !success { &result } else { "" };
assert!(success, "Must compile. Error:\n{}", err);
assert!(
result.contains("takes_ref(&s)") || result.contains("takes_ref(s)"),
"Should handle borrow. Got:\n{}",
result
);
}
#[test]
#[cfg_attr(tarpaulin, ignore)]
fn test_fn_arg_auto_borrow_mut() {
let src = r#"
pub fn takes_mut(mut n: i32) {}
pub fn caller(mut n: i32) {
takes_mut(n)
}
"#;
let (result, success) = test_utils::compile_single_check(src);
let err = if !success { &result } else { "" };
assert!(success, "Must compile. Error:\n{}", err);
assert!(
result.contains("takes_mut(&mut n)"),
"Should auto-borrow mut. Got:\n{}",
result
);
}
#[test]
#[cfg_attr(tarpaulin, ignore)]
fn test_fn_arg_auto_deref_copy() {
let src = r#"
pub fn takes_owned(x: i32) {}
pub fn caller(x: i32) {
takes_owned(x)
}
"#;
let (result, success) = test_utils::compile_single_check(src);
let err = if !success { &result } else { "" };
assert!(success, "Must compile. Error:\n{}", err);
assert!(
result.contains("takes_owned(x)")
|| result.contains("takes_owned(*x)")
|| result.contains("takes_owned((x).clone())")
|| result.contains("takes_owned(x.clone())"),
"Copy type in function arg. Got:\n{}",
result
);
}
#[test]
#[cfg_attr(tarpaulin, ignore)]
fn test_fn_arg_noncopy_needs_clone() {
let src = r#"
pub fn takes_owned(s: string) {}
pub fn caller(s: string) {
takes_owned(s)
}
"#;
let (result, success) = test_utils::compile_single_check(src);
let err = if !success { &result } else { "" };
assert!(success, "Must compile. Error:\n{}", err);
assert!(
result.contains(".clone()")
|| result.contains("takes_owned(s)")
|| result.contains("takes_owned(&s)"),
"String param coercion at call site. Got:\n{}",
result
);
}
#[test]
#[cfg_attr(tarpaulin, ignore)]
fn test_fn_arg_string_literal_to_owned() {
let src = r#"
pub fn takes_string(s: string) {}
pub fn caller() {
takes_string("hello")
}
"#;
let (result, success) = test_utils::compile_single_check(src);
let err = if !success { &result } else { "" };
assert!(success, "Must compile. Error:\n{}", err);
assert!(
result.contains("\"hello\"") || result.contains("hello"),
"String literal in call. Got:\n{}",
result
);
}
#[test]
#[cfg_attr(tarpaulin, ignore)]
fn test_fn_arg_string_literal_to_borrowed() {
let src = r#"
pub fn takes_ref(s: string) {}
pub fn caller() {
takes_ref("hello")
}
"#;
let (result, success) = test_utils::compile_single_check(src);
let err = if !success { &result } else { "" };
assert!(success, "Must compile. Error:\n{}", err);
assert!(
result.contains("takes_ref(\"hello\")") || result.contains("takes_ref(&\"hello\")"),
"String literal to &str param. Got:\n{}",
result
);
}
#[test]
#[cfg_attr(tarpaulin, ignore)]
fn test_fn_arg_float_inference_f32() {
let src = r#"
pub fn foo(x: f32) {}
pub fn caller() {
foo(1.0)
}
"#;
let (result, success) = test_utils::compile_single_check(src);
let err = if !success { &result } else { "" };
assert!(success, "Must compile. Error:\n{}", err);
assert!(
result.contains("1.0_f32") || result.contains("1_f32"),
"Float literal should infer f32 from param. Got:\n{}",
result
);
}
#[test]
#[cfg_attr(tarpaulin, ignore)]
fn test_fn_arg_copy_no_extra_borrow() {
let src = r#"
pub fn takes_int(x: i32) -> i32 { x }
pub fn caller(n: i32) -> i32 {
takes_int(n)
}
"#;
let (result, success) = test_utils::compile_single_check(src);
let err = if !success { &result } else { "" };
assert!(success, "Must compile. Error:\n{}", err);
assert!(
result.contains("takes_int(n)") && !result.contains("takes_int(&n)"),
"Copy type should not add &. Got:\n{}",
result
);
}
#[test]
#[cfg_attr(tarpaulin, ignore)]
fn test_fn_arg_borrowed_field_copy() {
let src = r#"
pub struct Item { pub id: i32 }
pub fn takes_id(id: i32) {}
pub fn caller(items: Vec<Item>) {
takes_id(items[0].id)
}
"#;
let (success, _result, err) = test_utils::compile_via_cli(src);
assert!(success, "Must compile. Error:\n{}", err);
}
#[test]
#[cfg_attr(tarpaulin, ignore)]
fn test_fn_arg_borrowed_field_noncopy() {
let src = r#"
pub struct Item { pub name: string }
pub fn takes_name(name: string) {}
pub fn caller(items: Vec<Item>) {
takes_name(items[0].name)
}
"#;
let (success, _result, err) = test_utils::compile_via_cli(src);
assert!(success, "Must compile. Error:\n{}", err);
}
#[test]
#[cfg_attr(tarpaulin, ignore)]
fn test_fn_arg_mixed_ownership() {
let src = r#"
pub fn mixed(a: i32, b: i32, c: string) {}
pub fn caller(x: i32, y: i32, z: string) {
mixed(x, y, z)
}
"#;
let (success, _result, err) = test_utils::compile_via_cli(src);
assert!(success, "Must compile. Error:\n{}", err);
}
#[test]
#[cfg_attr(tarpaulin, ignore)]
fn test_fn_arg_no_signature_passthrough() {
let src = r#"
pub fn unknown(a: i32, b: string) {}
pub fn caller(x: i32, s: string) {
unknown(x, s)
}
"#;
let (success, _result, err) = test_utils::compile_via_cli(src);
assert!(success, "Must compile. Error:\n{}", err);
}
#[test]
#[cfg_attr(tarpaulin, ignore)]
fn test_fn_arg_constructor_string() {
let src = r#"
pub struct Widget { name: string }
pub fn new(name: string) -> Widget { Widget { name } }
pub fn caller() {
let w = new("test")
}
"#;
let (success, _result, err) = test_utils::compile_via_cli(src);
assert!(success, "Must compile. Error:\n{}", err);
}
#[test]
#[cfg_attr(tarpaulin, ignore)]
fn test_fn_arg_for_loop_borrowed() {
let src = r#"
pub struct Item { pub id: string }
pub fn process(id: string) {}
pub fn caller(items: Vec<Item>) {
for item in items {
process(item.id)
}
}
"#;
let (success, _result, err) = test_utils::compile_via_cli(src);
assert!(success, "Must compile. Error:\n{}", err);
}
#[test]
#[cfg_attr(tarpaulin, ignore)]
fn test_fn_arg_format_macro() {
let src = r#"
pub fn greet(msg: string) {}
pub fn caller(name: string) {
let s = format!("Hello {}", name)
greet(s)
}
"#;
let (result, success) = test_utils::compile_single_check(src);
let err = if !success { &result } else { "" };
assert!(success, "Must compile. Error:\n{}", err);
assert!(
result.contains("format!") || result.contains("write!") || result.contains("Hello"),
"Format/write macro or string should be present. Got:\n{}",
result
);
}
#[test]
#[cfg_attr(tarpaulin, ignore)]
fn test_fn_arg_vec_new() {
let src = r#"
pub fn caller() {
let v: Vec<i32> = Vec::new()
}
"#;
let (success, _result, err) = test_utils::compile_via_cli(src);
assert!(success, "Must compile. Error:\n{}", err);
}
#[test]
#[cfg_attr(tarpaulin, ignore)]
fn test_fn_arg_enum_variant() {
let src = r#"
pub enum Event {
Message(string)
}
pub fn caller() {
let e = Event::Message("hi")
}
"#;
let (success, _result, err) = test_utils::compile_via_cli(src);
assert!(success, "Must compile. Error:\n{}", err);
}
#[test]
#[cfg_attr(tarpaulin, ignore)]
fn test_fn_arg_nested_call() {
let src = r#"
pub fn inner(x: i32) -> i32 { x }
pub fn outer(x: i32) {}
pub fn caller(n: i32) {
outer(inner(n))
}
"#;
let (success, _result, err) = test_utils::compile_via_cli(src);
assert!(success, "Must compile. Error:\n{}", err);
}
#[test]
#[cfg_attr(tarpaulin, ignore)]
fn test_fn_arg_temp_var_no_borrow() {
let src = r#"
pub fn takes_string(s: string) {}
pub fn caller(name: string) {
let msg = format!("Hello {}", name)
takes_string(msg)
}
"#;
let (result, success) = test_utils::compile_single_check(src);
let err = if !success { &result } else { "" };
assert!(success, "Must compile. Error:\n{}", err);
assert!(
result.contains("takes_string(") && result.contains("msg"),
"Temp var in call. Got:\n{}",
result
);
}